aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjohndoe1232014-01-30 20:18:55 +0100
committerjohndoe1232014-01-30 20:18:55 +0100
commitcf51529cfd0fedb33b1b0c70beb59997b21cfc5b (patch)
tree1df30e23c7f1eac7ca4a8ddfba40c89c2577dda7
parent542197a891eac799855571fe2849e0dca43bdd2b (diff)
parent462f7c1c24a48b7555316a3afae357bad14cc14b (diff)
downloadscummvm-rg350-cf51529cfd0fedb33b1b0c70beb59997b21cfc5b.tar.gz
scummvm-rg350-cf51529cfd0fedb33b1b0c70beb59997b21cfc5b.tar.bz2
scummvm-rg350-cf51529cfd0fedb33b1b0c70beb59997b21cfc5b.zip
Merge remote-tracking branch 'origin/master' into bbvs
-rw-r--r--.gitignore7
-rw-r--r--AUTHORS398
-rw-r--r--COPYRIGHT2
-rw-r--r--Makefile16
-rw-r--r--Makefile.common6
-rw-r--r--NEWS42
-rw-r--r--README63
-rw-r--r--audio/decoders/voc.cpp2
-rw-r--r--audio/midiparser.cpp22
-rw-r--r--audio/midiparser.h2
-rw-r--r--audio/softsynth/eas.cpp2
-rw-r--r--audio/softsynth/fluidsynth.cpp3
-rw-r--r--audio/softsynth/mt32.cpp14
-rw-r--r--backends/events/maemosdl/maemosdl-events.cpp2
-rw-r--r--backends/events/sdl/sdl-events.cpp11
-rw-r--r--backends/fs/amigaos4/amigaos4-fs.cpp27
-rw-r--r--backends/fs/amigaos4/amigaos4-fs.h6
-rw-r--r--backends/fs/wii/wii-fs-factory.cpp15
-rw-r--r--backends/fs/wii/wii-fs.cpp44
-rw-r--r--backends/fs/wii/wii-fs.h2
-rw-r--r--backends/graphics/opengl/debug.cpp65
-rw-r--r--backends/graphics/opengl/debug.h39
-rw-r--r--backends/graphics/opengl/extensions.cpp48
-rw-r--r--backends/graphics/opengl/extensions.h41
-rw-r--r--backends/graphics/opengl/gltexture.cpp225
-rw-r--r--backends/graphics/opengl/gltexture.h131
-rw-r--r--backends/graphics/opengl/opengl-graphics.cpp1827
-rw-r--r--backends/graphics/opengl/opengl-graphics.h492
-rw-r--r--backends/graphics/opengl/opengl-sys.h (renamed from backends/graphics/opengl/glerrorcheck.cpp)50
-rw-r--r--backends/graphics/opengl/texture.cpp371
-rw-r--r--backends/graphics/opengl/texture.h175
-rw-r--r--backends/graphics/openglsdl/openglsdl-graphics.cpp907
-rw-r--r--backends/graphics/openglsdl/openglsdl-graphics.h132
-rw-r--r--backends/graphics/sdl/sdl-graphics.cpp9
-rw-r--r--backends/graphics/sdl/sdl-graphics.h20
-rw-r--r--backends/graphics/surfacesdl/surfacesdl-graphics.cpp41
-rw-r--r--backends/graphics/surfacesdl/surfacesdl-graphics.h6
-rw-r--r--backends/module.mk22
-rw-r--r--backends/platform/android/android.cpp3
-rw-r--r--backends/platform/android/android.h1
-rw-r--r--backends/platform/android/android.mk8
-rw-r--r--backends/platform/android/events.cpp111
-rw-r--r--backends/platform/android/gfx.cpp11
-rw-r--r--backends/platform/android/org/scummvm/scummvm/MouseHelper.java18
-rw-r--r--backends/platform/android/org/scummvm/scummvm/ScummVMActivity.java8
-rw-r--r--backends/platform/android/org/scummvm/scummvm/ScummVMEvents.java36
-rw-r--r--backends/platform/android/texture.cpp17
-rw-r--r--backends/platform/android/texture.h12
-rw-r--r--backends/platform/dc/dc-fs.cpp2
-rw-r--r--backends/platform/dc/dc.h2
-rw-r--r--backends/platform/dc/dcmain.cpp6
-rw-r--r--backends/platform/dc/icon.cpp4
-rw-r--r--backends/platform/dc/input.cpp11
-rw-r--r--backends/platform/dc/ip.txt.in2
-rw-r--r--backends/platform/dc/softkbd.h1
-rw-r--r--backends/platform/gph/gph-backend.cpp2
-rw-r--r--backends/platform/null/null.cpp16
-rw-r--r--backends/platform/openpandora/op-backend.cpp2
-rw-r--r--backends/platform/sdl/posix/posix.cpp15
-rw-r--r--backends/platform/sdl/sdl.cpp308
-rw-r--r--backends/platform/sdl/sdl.h15
-rw-r--r--backends/platform/symbian/AdaptAllMMPs.pl40
-rw-r--r--backends/platform/symbian/BuildPackageUpload_AllVersions.pl7
-rw-r--r--backends/platform/symbian/BuildPackageUpload_LocalSettings.pl108
-rw-r--r--backends/platform/symbian/README14
-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/BLD.INF.in1
-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/S60v3/scummvm-CVS-SymbianS60v3.pkg41
-rw-r--r--backends/platform/symbian/S60v3/scummvm-CVS-SymbianS60v3_split.pkg43
-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/UIQ2/ScummVM_UIQ2.mmp.in2
-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-CVS-SymbianUIQ3.pkg2
-rw-r--r--backends/platform/symbian/UIQ3/scummvm-CVS-SymbianUIQ3_split.pkg2
-rw-r--r--backends/platform/symbian/UIQ3/scummvm_A0000658_loc.rss2
-rw-r--r--backends/platform/symbian/help/Custom.xml18
-rw-r--r--backends/platform/symbian/help/ScummVM.rtf266
-rw-r--r--backends/platform/symbian/help/ScummVM.xml19
-rw-r--r--backends/platform/symbian/help/build_help.mk29
-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.in62
-rw-r--r--backends/platform/symbian/mmp/scummvm_base.mmp.in11
-rw-r--r--backends/platform/symbian/mmp/scummvm_cge.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.in62
-rw-r--r--backends/platform/symbian/mmp/scummvm_fullpipe.mmp.in62
-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.in9
-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_mohawk.mmp.in21
-rw-r--r--backends/platform/symbian/mmp/scummvm_mortevielle.mmp.in62
-rw-r--r--backends/platform/symbian/mmp/scummvm_neverhood.mmp.in61
-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_queen.mmp.in2
-rw-r--r--backends/platform/symbian/mmp/scummvm_saga.mmp.in2
-rw-r--r--backends/platform/symbian/mmp/scummvm_sci.mmp.in10
-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.in63
-rw-r--r--backends/platform/symbian/mmp/scummvm_teenagent.mmp.in2
-rw-r--r--backends/platform/symbian/mmp/scummvm_testbed.mmp.in62
-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_wintermute.mmp.in2
-rw-r--r--backends/platform/symbian/mmp/scummvm_zvision.mmp.in62
-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.cpp5
-rw-r--r--backends/platform/symbian/src/portdefs.h2
-rw-r--r--backends/platform/tizen/graphics.cpp106
-rw-r--r--backends/platform/tizen/graphics.h21
-rw-r--r--backends/platform/tizen/system.cpp2
-rw-r--r--backends/platform/wii/main.cpp3
-rw-r--r--backends/platform/wii/osystem_events.cpp2
-rw-r--r--backends/platform/wii/wii.mk4
-rw-r--r--backends/platform/wince/CEActionsPocket.cpp2
-rw-r--r--backends/platform/wince/CEActionsSmartphone.cpp2
-rw-r--r--backends/platform/wince/CELauncherDialog.cpp4
-rw-r--r--backends/platform/wince/wince-sdl.cpp14
-rw-r--r--backends/taskbar/unity/unity-taskbar.cpp2
-rw-r--r--backends/taskbar/unity/unity-taskbar.h2
-rw-r--r--base/main.cpp15
-rw-r--r--base/plugins.cpp2
-rw-r--r--base/plugins.h2
-rw-r--r--common/c++11-compat.h2
-rw-r--r--common/ini-file.cpp4
-rw-r--r--common/ini-file.h4
-rw-r--r--common/language.cpp3
-rw-r--r--common/language.h3
-rw-r--r--common/module.mk1
-rw-r--r--common/quicktime.cpp3
-rw-r--r--common/recorderfile.cpp2
-rw-r--r--common/scummsys.h6
-rw-r--r--common/str.h7
-rw-r--r--common/unarj.cpp11
-rw-r--r--common/ustr.cpp329
-rw-r--r--common/ustr.h194
-rw-r--r--common/winexe_ne.cpp2
-rw-r--r--common/winexe_ne.h2
-rw-r--r--common/zlib.cpp22
-rwxr-xr-xconfigure135
-rw-r--r--devtools/convbdf.cpp4
-rw-r--r--devtools/create_mortdat/create_mortdat.cpp6
-rw-r--r--devtools/create_neverhood/create_neverhood.cpp2
-rw-r--r--devtools/create_project/codeblocks.cpp1
-rw-r--r--devtools/create_project/config.h3
-rw-r--r--devtools/create_project/create_project.cpp226
-rw-r--r--devtools/create_project/create_project.h54
-rw-r--r--devtools/create_project/msbuild.cpp10
-rw-r--r--devtools/create_project/scripts/install-natvis.bat41
-rw-r--r--devtools/create_project/scripts/scummvm.natvis91
-rw-r--r--devtools/create_project/visualstudio.cpp2
-rw-r--r--devtools/create_project/xcode.cpp31
-rw-r--r--devtools/create_translations/create_translations.cpp3
-rw-r--r--devtools/create_translations/create_translations.h4
-rwxr-xr-xdevtools/credits.pl40
-rw-r--r--devtools/extract_mort/extract_mort.cpp4
-rw-r--r--devtools/scumm-md5.txt1
-rw-r--r--dists/android/AndroidManifest.xml1
-rw-r--r--dists/android/AndroidManifest.xml.in1
-rw-r--r--dists/android/res-ouya/values-television/margins.xml5
-rw-r--r--dists/android/res/drawable-xhdpi/ouya_icon.pngbin0 -> 110822 bytes
-rw-r--r--dists/android/res/layout/main.xml4
-rw-r--r--dists/android/res/values/margins.xml5
-rw-r--r--dists/debian/copyright2
-rw-r--r--dists/engine-data/README5
-rw-r--r--dists/macosx/Info.plist4
-rw-r--r--dists/macosx/Info.plist.in4
-rw-r--r--dists/msvc11/readme.txt5
-rw-r--r--dists/msvc12/readme.txt5
-rw-r--r--dists/scummvm.rc2
-rw-r--r--dists/scummvm.rc.in2
-rw-r--r--dists/win32/ScummVM.iss2
-rw-r--r--dists/win32/migration.bat2
-rw-r--r--dists/win32/scummvm.nsi2
-rw-r--r--dists/win32/scummvm.nsi.in2
-rw-r--r--engines/agi/configure.engine3
-rw-r--r--engines/agi/detection_tables.h1
-rw-r--r--engines/agi/loader_v1.cpp2
-rw-r--r--engines/agi/loader_v2.cpp2
-rw-r--r--engines/agi/loader_v3.cpp2
-rw-r--r--engines/agi/opcodes.cpp24
-rw-r--r--engines/agi/preagi_mickey.cpp2
-rw-r--r--engines/agi/words.cpp23
-rw-r--r--engines/agos/agos.h24
-rw-r--r--engines/agos/animation.cpp16
-rw-r--r--engines/agos/configure.engine4
-rw-r--r--engines/agos/detection.cpp9
-rw-r--r--engines/agos/detection_tables.h24
-rw-r--r--engines/agos/icons.cpp6
-rw-r--r--engines/agos/res.cpp158
-rw-r--r--engines/agos/res_snd.cpp21
-rw-r--r--engines/agos/saveload.cpp14
-rw-r--r--engines/agos/subroutine.cpp4
-rw-r--r--engines/avalanche/animation.cpp1562
-rw-r--r--engines/avalanche/animation.h177
-rw-r--r--engines/avalanche/avalanche.cpp540
-rw-r--r--engines/avalanche/avalanche.h312
-rw-r--r--engines/avalanche/avalot.cpp1664
-rw-r--r--engines/avalanche/avalot.h69
-rw-r--r--engines/avalanche/background.cpp370
-rw-r--r--engines/avalanche/background.h79
-rw-r--r--engines/avalanche/clock.cpp116
-rw-r--r--engines/avalanche/clock.h60
-rw-r--r--engines/avalanche/closing.cpp75
-rw-r--r--engines/avalanche/closing.h62
-rw-r--r--engines/avalanche/configure.engine3
-rw-r--r--engines/avalanche/console.cpp53
-rw-r--r--engines/avalanche/console.h51
-rw-r--r--engines/avalanche/detection.cpp209
-rw-r--r--engines/avalanche/dialogs.cpp1218
-rw-r--r--engines/avalanche/dialogs.h119
-rw-r--r--engines/avalanche/enums.h132
-rw-r--r--engines/avalanche/graphics.cpp836
-rw-r--r--engines/avalanche/graphics.h165
-rw-r--r--engines/avalanche/menu.cpp844
-rw-r--r--engines/avalanche/menu.h182
-rw-r--r--engines/avalanche/module.mk28
-rw-r--r--engines/avalanche/nim.cpp575
-rw-r--r--engines/avalanche/nim.h79
-rw-r--r--engines/avalanche/parser.cpp2488
-rw-r--r--engines/avalanche/parser.h153
-rw-r--r--engines/avalanche/pingo.cpp94
-rw-r--r--engines/avalanche/pingo.h56
-rw-r--r--engines/avalanche/sequence.cpp230
-rw-r--r--engines/avalanche/sequence.h80
-rw-r--r--engines/avalanche/sound.cpp88
-rw-r--r--engines/avalanche/sound.h53
-rw-r--r--engines/avalanche/timer.cpp693
-rw-r--r--engines/avalanche/timer.h178
-rw-r--r--engines/cge/bitmap.cpp6
-rw-r--r--engines/cge/cge_main.cpp20
-rw-r--r--engines/cge/configure.engine3
-rw-r--r--engines/cge/detection.cpp12
-rw-r--r--engines/cge/fileio.cpp12
-rw-r--r--engines/cge/fileio.h8
-rw-r--r--engines/cge/sound.cpp4
-rw-r--r--engines/cge/text.cpp5
-rw-r--r--engines/cge/vga13h.cpp3
-rw-r--r--engines/cine/configure.engine3
-rw-r--r--engines/cine/script_fw.cpp3
-rw-r--r--engines/cine/sound.cpp6
-rw-r--r--engines/composer/composer.cpp34
-rw-r--r--engines/composer/composer.h6
-rw-r--r--engines/composer/configure.engine3
-rw-r--r--engines/composer/console.cpp31
-rw-r--r--engines/composer/console.h40
-rw-r--r--engines/composer/module.mk1
-rw-r--r--engines/configure.engines56
-rw-r--r--engines/cruise/configure.engine3
-rw-r--r--engines/draci/barchive.cpp12
-rw-r--r--engines/draci/configure.engine3
-rw-r--r--engines/draci/draci.cpp26
-rw-r--r--engines/draci/game.cpp55
-rw-r--r--engines/draci/script.cpp110
-rw-r--r--engines/draci/sprite.cpp4
-rw-r--r--engines/draci/surface.cpp2
-rw-r--r--engines/draci/walking.cpp6
-rw-r--r--engines/draci/walking.h12
-rw-r--r--engines/drascula/animation.cpp4
-rw-r--r--engines/drascula/configure.engine3
-rw-r--r--engines/drascula/converse.cpp6
-rw-r--r--engines/drascula/drascula.cpp100
-rw-r--r--engines/drascula/drascula.h9
-rw-r--r--engines/drascula/graphics.cpp10
-rw-r--r--engines/drascula/objects.cpp5
-rw-r--r--engines/dreamweb/configure.engine3
-rw-r--r--engines/dreamweb/dreamweb.cpp43
-rw-r--r--engines/dreamweb/dreamweb.h5
-rw-r--r--engines/engine.cpp6
-rw-r--r--engines/engine.h11
-rw-r--r--engines/engines.mk258
-rw-r--r--engines/fullpipe/behavior.cpp58
-rw-r--r--engines/fullpipe/behavior.h6
-rw-r--r--engines/fullpipe/configure.engine3
-rw-r--r--engines/fullpipe/console.cpp52
-rw-r--r--engines/fullpipe/console.h42
-rw-r--r--engines/fullpipe/constants.h1317
-rw-r--r--engines/fullpipe/floaters.cpp255
-rw-r--r--engines/fullpipe/floaters.h75
-rw-r--r--engines/fullpipe/fullpipe.cpp57
-rw-r--r--engines/fullpipe/fullpipe.h70
-rw-r--r--engines/fullpipe/gameloader.cpp161
-rw-r--r--engines/fullpipe/gameloader.h5
-rw-r--r--engines/fullpipe/gfx.cpp150
-rw-r--r--engines/fullpipe/gfx.h15
-rw-r--r--engines/fullpipe/init.cpp32
-rw-r--r--engines/fullpipe/input.cpp80
-rw-r--r--engines/fullpipe/interaction.cpp55
-rw-r--r--engines/fullpipe/interaction.h5
-rw-r--r--engines/fullpipe/inventory.cpp26
-rw-r--r--engines/fullpipe/inventory.h4
-rw-r--r--engines/fullpipe/lift.cpp275
-rw-r--r--engines/fullpipe/messagehandlers.cpp744
-rw-r--r--engines/fullpipe/messages.cpp308
-rw-r--r--engines/fullpipe/messages.h36
-rw-r--r--engines/fullpipe/modal.cpp720
-rw-r--r--engines/fullpipe/modal.h118
-rw-r--r--engines/fullpipe/module.mk42
-rw-r--r--engines/fullpipe/motion.cpp2059
-rw-r--r--engines/fullpipe/motion.h362
-rw-r--r--engines/fullpipe/ngiarchive.cpp4
-rw-r--r--engines/fullpipe/objectnames.h67
-rw-r--r--engines/fullpipe/objects.h2
-rw-r--r--engines/fullpipe/scene.cpp153
-rw-r--r--engines/fullpipe/scene.h5
-rw-r--r--engines/fullpipe/scenes.cpp1446
-rw-r--r--engines/fullpipe/scenes.h514
-rw-r--r--engines/fullpipe/scenes/scene01.cpp118
-rw-r--r--engines/fullpipe/scenes/scene02.cpp138
-rw-r--r--engines/fullpipe/scenes/scene03.cpp295
-rw-r--r--engines/fullpipe/scenes/scene04.cpp1558
-rw-r--r--engines/fullpipe/scenes/scene05.cpp386
-rw-r--r--engines/fullpipe/scenes/scene06.cpp770
-rw-r--r--engines/fullpipe/scenes/scene07.cpp175
-rw-r--r--engines/fullpipe/scenes/scene08.cpp546
-rw-r--r--engines/fullpipe/scenes/scene10.cpp220
-rw-r--r--engines/fullpipe/scenes/scene11.cpp786
-rw-r--r--engines/fullpipe/scenes/scene12.cpp85
-rw-r--r--engines/fullpipe/scenes/scene13.cpp380
-rw-r--r--engines/fullpipe/scenes/scene14.cpp849
-rw-r--r--engines/fullpipe/scenes/scene15.cpp209
-rw-r--r--engines/fullpipe/scenes/scene16.cpp484
-rw-r--r--engines/fullpipe/scenes/scene17.cpp285
-rw-r--r--engines/fullpipe/scenes/scene18and19.cpp49
-rw-r--r--engines/fullpipe/scenes/scene20.cpp155
-rw-r--r--engines/fullpipe/scenes/scene21.cpp148
-rw-r--r--engines/fullpipe/scenes/scene22.cpp395
-rw-r--r--engines/fullpipe/scenes/scene23.cpp555
-rw-r--r--engines/fullpipe/scenes/scene24.cpp129
-rw-r--r--engines/fullpipe/scenes/scene25.cpp723
-rw-r--r--engines/fullpipe/scenes/scene26.cpp355
-rw-r--r--engines/fullpipe/scenes/scene28.cpp474
-rw-r--r--engines/fullpipe/scenes/scene30.cpp152
-rw-r--r--engines/fullpipe/scenes/scene31.cpp126
-rw-r--r--engines/fullpipe/scenes/scene32.cpp431
-rw-r--r--engines/fullpipe/scenes/scene33.cpp314
-rw-r--r--engines/fullpipe/scenes/scene34.cpp479
-rw-r--r--engines/fullpipe/scenes/scene35.cpp264
-rw-r--r--engines/fullpipe/scenes/scene36.cpp94
-rw-r--r--engines/fullpipe/scenes/scene37.cpp316
-rw-r--r--engines/fullpipe/scenes/scene38.cpp409
-rw-r--r--engines/fullpipe/scenes/sceneDbg.cpp108
-rw-r--r--engines/fullpipe/scenes/sceneFinal.cpp174
-rw-r--r--engines/fullpipe/scenes/sceneIntro.cpp110
-rw-r--r--engines/fullpipe/sound.cpp74
-rw-r--r--engines/fullpipe/sound.h20
-rw-r--r--engines/fullpipe/stateloader.cpp30
-rw-r--r--engines/fullpipe/statics.cpp414
-rw-r--r--engines/fullpipe/statics.h31
-rw-r--r--engines/fullpipe/utils.cpp21
-rw-r--r--engines/fullpipe/utils.h13
-rw-r--r--engines/gob/configure.engine3
-rw-r--r--engines/groovie/configure.engine4
-rw-r--r--engines/groovie/font.cpp4
-rw-r--r--engines/groovie/font.h6
-rw-r--r--engines/hopkins/computer.cpp33
-rw-r--r--engines/hopkins/configure.engine3
-rw-r--r--engines/hopkins/dialogs.cpp11
-rw-r--r--engines/hopkins/events.cpp2
-rw-r--r--engines/hopkins/globals.cpp2
-rw-r--r--engines/hopkins/graphics.cpp4
-rw-r--r--engines/hopkins/hopkins.cpp40
-rw-r--r--engines/hopkins/hopkins.h7
-rw-r--r--engines/hopkins/menu.cpp38
-rw-r--r--engines/hopkins/objects.cpp2
-rw-r--r--engines/hopkins/script.cpp18
-rw-r--r--engines/hopkins/sound.cpp57
-rw-r--r--engines/hopkins/talk.cpp15
-rw-r--r--engines/hugo/configure.engine3
-rw-r--r--engines/hugo/dialogs.cpp12
-rw-r--r--engines/hugo/display.cpp8
-rw-r--r--engines/hugo/file.cpp6
-rw-r--r--engines/hugo/hugo.cpp46
-rw-r--r--engines/hugo/hugo.h5
-rw-r--r--engines/hugo/intro.cpp4
-rw-r--r--engines/hugo/inventory.cpp4
-rw-r--r--engines/hugo/mouse.cpp6
-rw-r--r--engines/hugo/object.cpp42
-rw-r--r--engines/hugo/parser.cpp26
-rw-r--r--engines/hugo/route.cpp13
-rw-r--r--engines/hugo/route.h4
-rw-r--r--engines/hugo/schedule.cpp62
-rw-r--r--engines/hugo/sound.cpp5
-rw-r--r--engines/hugo/text.cpp31
-rw-r--r--engines/kyra/animator_lok.cpp2
-rw-r--r--engines/kyra/chargen.cpp4
-rw-r--r--engines/kyra/configure.engine5
-rw-r--r--engines/kyra/kyra_mr.cpp1
-rw-r--r--engines/kyra/resource.cpp8
-rw-r--r--engines/kyra/screen_v2.cpp2
-rw-r--r--engines/kyra/sequences_lok.cpp3
-rw-r--r--engines/kyra/sound_towns.cpp1
-rw-r--r--engines/kyra/staticres.cpp2
-rw-r--r--engines/kyra/vqa.cpp1017
-rw-r--r--engines/kyra/vqa.h139
-rw-r--r--engines/lastexpress/configure.engine3
-rw-r--r--engines/lastexpress/entities/abbot.cpp162
-rw-r--r--engines/lastexpress/entities/abbot.h56
-rw-r--r--engines/lastexpress/entities/alexei.cpp230
-rw-r--r--engines/lastexpress/entities/alexei.h56
-rw-r--r--engines/lastexpress/entities/alouan.cpp48
-rw-r--r--engines/lastexpress/entities/alouan.h10
-rw-r--r--engines/lastexpress/entities/anna.cpp398
-rw-r--r--engines/lastexpress/entities/anna.h113
-rw-r--r--engines/lastexpress/entities/august.cpp32
-rw-r--r--engines/lastexpress/entities/chapters.cpp32
-rw-r--r--engines/lastexpress/entities/coudert.cpp54
-rw-r--r--engines/lastexpress/entities/entity.cpp4
-rw-r--r--engines/lastexpress/entities/entity.h138
-rw-r--r--engines/lastexpress/entities/francois.cpp150
-rw-r--r--engines/lastexpress/entities/francois.h29
-rw-r--r--engines/lastexpress/entities/gendarmes.cpp10
-rw-r--r--engines/lastexpress/entities/kahina.cpp24
-rw-r--r--engines/lastexpress/entities/kronos.cpp4
-rw-r--r--engines/lastexpress/entities/mertens.cpp60
-rw-r--r--engines/lastexpress/entities/milos.cpp30
-rw-r--r--engines/lastexpress/entities/rebecca.cpp8
-rw-r--r--engines/lastexpress/entities/servers0.cpp4
-rw-r--r--engines/lastexpress/entities/tatiana.cpp14
-rw-r--r--engines/lastexpress/entities/vassili.cpp8
-rw-r--r--engines/lastexpress/entities/verges.cpp4
-rw-r--r--engines/lastexpress/entities/yasmin.cpp74
-rw-r--r--engines/lastexpress/entities/yasmin.h16
-rw-r--r--engines/lastexpress/fight/fight.cpp2
-rw-r--r--engines/lastexpress/game/action.cpp116
-rw-r--r--engines/lastexpress/game/action.h28
-rw-r--r--engines/lastexpress/game/entities.h8
-rw-r--r--engines/lastexpress/game/inventory.cpp58
-rw-r--r--engines/lastexpress/game/inventory.h20
-rw-r--r--engines/lastexpress/game/logic.cpp6
-rw-r--r--engines/lastexpress/game/logic.h2
-rw-r--r--engines/lastexpress/game/object.cpp29
-rw-r--r--engines/lastexpress/game/object.h28
-rw-r--r--engines/lastexpress/game/savegame.h54
-rw-r--r--engines/lastexpress/game/scenes.cpp12
-rw-r--r--engines/lastexpress/game/state.h12
-rw-r--r--engines/lastexpress/shared.h30
-rw-r--r--engines/lastexpress/sound/sound.cpp2
-rw-r--r--engines/lure/configure.engine3
-rw-r--r--engines/made/configure.engine3
-rw-r--r--engines/made/detection.cpp114
-rw-r--r--engines/made/made.cpp6
-rw-r--r--engines/made/screenfx.cpp2
-rw-r--r--engines/made/sound.cpp2
-rw-r--r--engines/mohawk/configure.engine6
-rw-r--r--engines/mohawk/cstime.cpp9
-rw-r--r--engines/mohawk/cstime_game.cpp2
-rw-r--r--engines/mohawk/cstime_ui.cpp2
-rw-r--r--engines/mohawk/cstime_ui.h3
-rw-r--r--engines/mortevielle/actions.cpp235
-rw-r--r--engines/mortevielle/configure.engine3
-rw-r--r--engines/mortevielle/debugger.cpp7
-rw-r--r--engines/mortevielle/debugger.h3
-rw-r--r--engines/mortevielle/dialogs.cpp99
-rw-r--r--engines/mortevielle/dialogs.h3
-rw-r--r--engines/mortevielle/graphics.cpp25
-rw-r--r--engines/mortevielle/graphics.h3
-rw-r--r--engines/mortevielle/menu.cpp84
-rw-r--r--engines/mortevielle/menu.h3
-rw-r--r--engines/mortevielle/mortevielle.cpp110
-rw-r--r--engines/mortevielle/mortevielle.h28
-rw-r--r--engines/mortevielle/mouse.cpp10
-rw-r--r--engines/mortevielle/mouse.h5
-rw-r--r--engines/mortevielle/outtext.cpp32
-rw-r--r--engines/mortevielle/outtext.h3
-rw-r--r--engines/mortevielle/saveload.cpp12
-rw-r--r--engines/mortevielle/saveload.h3
-rw-r--r--engines/mortevielle/sound.cpp9
-rw-r--r--engines/mortevielle/sound.h4
-rw-r--r--engines/mortevielle/utils.cpp489
-rw-r--r--engines/neverhood/configure.engine3
-rw-r--r--engines/neverhood/console.cpp1
-rw-r--r--engines/neverhood/detection.cpp27
-rw-r--r--engines/neverhood/diskplayerscene.cpp6
-rw-r--r--engines/neverhood/gamemodule.cpp32
-rw-r--r--engines/neverhood/gamemodule.h2
-rw-r--r--engines/neverhood/graphics.cpp2
-rw-r--r--engines/neverhood/klaymen.cpp3605
-rw-r--r--engines/neverhood/klaymen.h413
-rw-r--r--engines/neverhood/menumodule.cpp34
-rw-r--r--engines/neverhood/messages.h48
-rw-r--r--engines/neverhood/module.cpp2
-rw-r--r--engines/neverhood/module.mk17
-rw-r--r--engines/neverhood/modules/module1000.cpp1009
-rw-r--r--engines/neverhood/modules/module1000.h181
-rw-r--r--engines/neverhood/modules/module1000_sprites.cpp1632
-rw-r--r--engines/neverhood/modules/module1000_sprites.h262
-rw-r--r--engines/neverhood/modules/module1100.cpp211
-rw-r--r--engines/neverhood/modules/module1100.h51
-rw-r--r--engines/neverhood/modules/module1100_sprites.cpp265
-rw-r--r--engines/neverhood/modules/module1100_sprites.h88
-rw-r--r--engines/neverhood/modules/module1200.cpp660
-rw-r--r--engines/neverhood/modules/module1200.h136
-rw-r--r--engines/neverhood/modules/module1200_sprites.cpp810
-rw-r--r--engines/neverhood/modules/module1200_sprites.h187
-rw-r--r--engines/neverhood/modules/module1300.cpp728
-rw-r--r--engines/neverhood/modules/module1300.h129
-rw-r--r--engines/neverhood/modules/module1300_sprites.cpp935
-rw-r--r--engines/neverhood/modules/module1300_sprites.h200
-rw-r--r--engines/neverhood/modules/module1400.cpp924
-rw-r--r--engines/neverhood/modules/module1400.h151
-rw-r--r--engines/neverhood/modules/module1400_sprites.cpp1129
-rw-r--r--engines/neverhood/modules/module1400_sprites.h198
-rw-r--r--engines/neverhood/modules/module1500.cpp6
-rw-r--r--engines/neverhood/modules/module1600.cpp861
-rw-r--r--engines/neverhood/modules/module1600.h91
-rw-r--r--engines/neverhood/modules/module1600_sprites.cpp934
-rw-r--r--engines/neverhood/modules/module1600_sprites.h126
-rw-r--r--engines/neverhood/modules/module1700.cpp48
-rw-r--r--engines/neverhood/modules/module1700.h17
-rw-r--r--engines/neverhood/modules/module1700_sprites.cpp156
-rw-r--r--engines/neverhood/modules/module1700_sprites.h55
-rw-r--r--engines/neverhood/modules/module1800.cpp5
-rw-r--r--engines/neverhood/modules/module1900.cpp397
-rw-r--r--engines/neverhood/modules/module1900.h73
-rw-r--r--engines/neverhood/modules/module1900_sprites.cpp456
-rw-r--r--engines/neverhood/modules/module1900_sprites.h107
-rw-r--r--engines/neverhood/modules/module2000.cpp5
-rw-r--r--engines/neverhood/modules/module2000.h3
-rw-r--r--engines/neverhood/modules/module2000_sprites.cpp92
-rw-r--r--engines/neverhood/modules/module2000_sprites.h41
-rw-r--r--engines/neverhood/modules/module2100.cpp135
-rw-r--r--engines/neverhood/modules/module2100.h32
-rw-r--r--engines/neverhood/modules/module2100_sprites.cpp260
-rw-r--r--engines/neverhood/modules/module2100_sprites.h75
-rw-r--r--engines/neverhood/modules/module2200.cpp934
-rw-r--r--engines/neverhood/modules/module2200.h176
-rw-r--r--engines/neverhood/modules/module2200_sprites.cpp1429
-rw-r--r--engines/neverhood/modules/module2200_sprites.h275
-rw-r--r--engines/neverhood/modules/module2300.cpp2
-rw-r--r--engines/neverhood/modules/module2400.cpp363
-rw-r--r--engines/neverhood/modules/module2400.h71
-rw-r--r--engines/neverhood/modules/module2400_sprites.cpp741
-rw-r--r--engines/neverhood/modules/module2400_sprites.h139
-rw-r--r--engines/neverhood/modules/module2500.cpp88
-rw-r--r--engines/neverhood/modules/module2500.h18
-rw-r--r--engines/neverhood/modules/module2500_sprites.cpp127
-rw-r--r--engines/neverhood/modules/module2500_sprites.h51
-rw-r--r--engines/neverhood/modules/module2600.cpp97
-rw-r--r--engines/neverhood/modules/module2600.h18
-rw-r--r--engines/neverhood/modules/module2600_sprites.cpp115
-rw-r--r--engines/neverhood/modules/module2600_sprites.h54
-rw-r--r--engines/neverhood/modules/module2700.cpp176
-rw-r--r--engines/neverhood/modules/module2700.h35
-rw-r--r--engines/neverhood/modules/module2700_sprites.cpp178
-rw-r--r--engines/neverhood/modules/module2700_sprites.h74
-rw-r--r--engines/neverhood/modules/module2800.cpp187
-rw-r--r--engines/neverhood/modules/module2800_sprites.cpp712
-rw-r--r--engines/neverhood/modules/module2800_sprites.h69
-rw-r--r--engines/neverhood/modules/module2900.cpp211
-rw-r--r--engines/neverhood/modules/module2900.h36
-rw-r--r--engines/neverhood/modules/module2900_sprites.cpp232
-rw-r--r--engines/neverhood/modules/module2900_sprites.h72
-rw-r--r--engines/neverhood/modules/module3000.cpp677
-rw-r--r--engines/neverhood/modules/module3000.h156
-rw-r--r--engines/neverhood/modules/module3000_sprites.cpp763
-rw-r--r--engines/neverhood/modules/module3000_sprites.h185
-rw-r--r--engines/neverhood/navigationscene.cpp8
-rw-r--r--engines/neverhood/neverhood.cpp16
-rw-r--r--engines/neverhood/neverhood.h4
-rw-r--r--engines/neverhood/palette.cpp18
-rw-r--r--engines/neverhood/palette.h1
-rw-r--r--engines/neverhood/resourceman.cpp25
-rw-r--r--engines/neverhood/scene.cpp25
-rw-r--r--engines/neverhood/scene.h2
-rw-r--r--engines/neverhood/screen.cpp3
-rw-r--r--engines/neverhood/screen.h1
-rw-r--r--engines/neverhood/smackerplayer.cpp14
-rw-r--r--engines/neverhood/smackerscene.cpp6
-rw-r--r--engines/neverhood/sound.cpp36
-rw-r--r--engines/neverhood/sound.h1
-rw-r--r--engines/neverhood/sprite.cpp6
-rw-r--r--engines/neverhood/staticdata.cpp16
-rw-r--r--engines/parallaction/configure.engine3
-rw-r--r--engines/parallaction/debug.cpp4
-rw-r--r--engines/parallaction/exec.h2
-rw-r--r--engines/parallaction/font.cpp3
-rw-r--r--engines/parallaction/graphics.cpp2
-rw-r--r--engines/parallaction/graphics.h4
-rw-r--r--engines/parallaction/gui.h2
-rw-r--r--engines/parallaction/gui_br.cpp5
-rw-r--r--engines/parallaction/gui_ns.cpp3
-rw-r--r--engines/parallaction/input.h2
-rw-r--r--engines/parallaction/objects.h6
-rw-r--r--engines/parallaction/parallaction.cpp30
-rw-r--r--engines/parallaction/parallaction.h4
-rw-r--r--engines/parallaction/parallaction_br.cpp12
-rw-r--r--engines/parallaction/parallaction_ns.cpp12
-rw-r--r--engines/parallaction/parser.h11
-rw-r--r--engines/parallaction/sound.h6
-rw-r--r--engines/parallaction/sound_br.cpp1
-rw-r--r--engines/parallaction/sound_ns.cpp1
-rw-r--r--engines/pegasus/configure.engine3
-rw-r--r--engines/pegasus/neighborhood/caldoria/caldoria.cpp18
-rw-r--r--engines/pegasus/neighborhood/mars/mars.cpp2
-rw-r--r--engines/pegasus/neighborhood/norad/delta/globegame.cpp10
-rw-r--r--engines/pegasus/neighborhood/norad/delta/noraddelta.cpp5
-rw-r--r--engines/pegasus/neighborhood/prehistoric/prehistoric.cpp20
-rw-r--r--engines/pegasus/neighborhood/tsa/fulltsa.cpp1
-rw-r--r--engines/pegasus/neighborhood/tsa/tinytsa.cpp1
-rw-r--r--engines/pegasus/neighborhood/wsc/wsc.cpp13
-rw-r--r--engines/pegasus/pegasus.cpp34
-rw-r--r--engines/pegasus/pegasus.h2
-rw-r--r--engines/pegasus/timers.cpp1
-rw-r--r--engines/plugins_table.h127
-rw-r--r--engines/queen/configure.engine3
-rw-r--r--engines/saga/configure.engine5
-rw-r--r--engines/saga/introproc_ite.cpp4
-rw-r--r--engines/saga/saga.h2
-rw-r--r--engines/saga/sprite.cpp28
-rw-r--r--engines/sci/configure.engine4
-rw-r--r--engines/sci/console.cpp15
-rw-r--r--engines/sci/detection_tables.h816
-rw-r--r--engines/sci/engine/kernel.cpp12
-rw-r--r--engines/sci/engine/kernel.h4
-rw-r--r--engines/sci/engine/kernel_tables.h2
-rw-r--r--engines/sci/engine/kfile.cpp2
-rw-r--r--engines/sci/engine/kgraphics.cpp3
-rw-r--r--engines/sci/engine/object.cpp1
-rw-r--r--engines/sci/engine/savegame.cpp41
-rw-r--r--engines/sci/engine/script.cpp7
-rw-r--r--engines/sci/engine/script.h9
-rw-r--r--engines/sci/engine/script_patches.cpp3378
-rw-r--r--engines/sci/engine/script_patches.h108
-rw-r--r--engines/sci/engine/scriptdebug.cpp58
-rw-r--r--engines/sci/engine/seg_manager.cpp17
-rw-r--r--engines/sci/engine/seg_manager.h5
-rw-r--r--engines/sci/engine/state.cpp2
-rw-r--r--engines/sci/engine/vm.cpp17
-rw-r--r--engines/sci/engine/workarounds.cpp220
-rw-r--r--engines/sci/engine/workarounds.h1
-rw-r--r--engines/sci/graphics/picture.cpp151
-rw-r--r--engines/sci/graphics/picture.h2
-rw-r--r--engines/sci/graphics/portrait.cpp261
-rw-r--r--engines/sci/graphics/portrait.h11
-rw-r--r--engines/sci/graphics/ports.cpp5
-rw-r--r--engines/sci/graphics/view.cpp112
-rw-r--r--engines/sci/parser/vocabulary.cpp7
-rw-r--r--engines/sci/resource.cpp42
-rw-r--r--engines/sci/resource.h34
-rw-r--r--engines/sci/resource_audio.cpp122
-rw-r--r--engines/sci/sci.cpp69
-rw-r--r--engines/sci/sci.h52
-rw-r--r--engines/sci/sound/midiparser_sci.cpp235
-rw-r--r--engines/sci/sound/midiparser_sci.h22
-rw-r--r--engines/sci/sound/music.cpp582
-rw-r--r--engines/sci/sound/music.h44
-rw-r--r--engines/sci/sound/soundcmd.cpp16
-rw-r--r--engines/scumm/configure.engine5
-rw-r--r--engines/scumm/detection.cpp26
-rw-r--r--engines/scumm/he/animation_he.cpp6
-rw-r--r--engines/scumm/he/animation_he.h8
-rw-r--r--engines/scumm/he/intern_he.h15
-rw-r--r--engines/scumm/he/logic/football.cpp19
-rw-r--r--engines/scumm/he/script_v100he.cpp7
-rw-r--r--engines/scumm/he/script_v60he.cpp276
-rw-r--r--engines/scumm/he/script_v72he.cpp66
-rw-r--r--engines/scumm/he/script_v80he.cpp49
-rw-r--r--engines/scumm/he/script_v90he.cpp5
-rw-r--r--engines/scumm/he/wiz_he.cpp31
-rw-r--r--engines/scumm/imuse_digi/dimuse_sndmgr.cpp13
-rw-r--r--engines/scumm/module.mk34
-rw-r--r--engines/scumm/players/player_ad.cpp (renamed from engines/scumm/player_ad.cpp)2
-rw-r--r--engines/scumm/players/player_ad.h (renamed from engines/scumm/player_ad.h)4
-rw-r--r--engines/scumm/players/player_apple2.cpp (renamed from engines/scumm/player_apple2.cpp)2
-rw-r--r--engines/scumm/players/player_apple2.h (renamed from engines/scumm/player_apple2.h)4
-rw-r--r--engines/scumm/players/player_mac.cpp (renamed from engines/scumm/player_mac.cpp)2
-rw-r--r--engines/scumm/players/player_mac.h (renamed from engines/scumm/player_mac.h)4
-rw-r--r--engines/scumm/players/player_mod.cpp (renamed from engines/scumm/player_mod.cpp)2
-rw-r--r--engines/scumm/players/player_mod.h (renamed from engines/scumm/player_mod.h)4
-rw-r--r--engines/scumm/players/player_nes.cpp (renamed from engines/scumm/player_nes.cpp)2
-rw-r--r--engines/scumm/players/player_nes.h (renamed from engines/scumm/player_nes.h)4
-rw-r--r--engines/scumm/players/player_pce.cpp (renamed from engines/scumm/player_pce.cpp)2
-rw-r--r--engines/scumm/players/player_pce.h (renamed from engines/scumm/player_pce.h)4
-rw-r--r--engines/scumm/players/player_sid.cpp (renamed from engines/scumm/player_sid.cpp)2
-rw-r--r--engines/scumm/players/player_sid.h (renamed from engines/scumm/player_sid.h)4
-rw-r--r--engines/scumm/players/player_towns.cpp (renamed from engines/scumm/player_towns.cpp)2
-rw-r--r--engines/scumm/players/player_towns.h (renamed from engines/scumm/player_towns.h)4
-rw-r--r--engines/scumm/players/player_v1.cpp (renamed from engines/scumm/player_v1.cpp)2
-rw-r--r--engines/scumm/players/player_v1.h (renamed from engines/scumm/player_v1.h)6
-rw-r--r--engines/scumm/players/player_v2.cpp (renamed from engines/scumm/player_v2.cpp)2
-rw-r--r--engines/scumm/players/player_v2.h (renamed from engines/scumm/player_v2.h)6
-rw-r--r--engines/scumm/players/player_v2a.cpp (renamed from engines/scumm/player_v2a.cpp)2
-rw-r--r--engines/scumm/players/player_v2a.h (renamed from engines/scumm/player_v2a.h)6
-rw-r--r--engines/scumm/players/player_v2base.cpp (renamed from engines/scumm/player_v2base.cpp)2
-rw-r--r--engines/scumm/players/player_v2base.h (renamed from engines/scumm/player_v2base.h)4
-rw-r--r--engines/scumm/players/player_v2cms.cpp (renamed from engines/scumm/player_v2cms.cpp)2
-rw-r--r--engines/scumm/players/player_v2cms.h (renamed from engines/scumm/player_v2cms.h)6
-rw-r--r--engines/scumm/players/player_v3a.cpp (renamed from engines/scumm/player_v3a.cpp)2
-rw-r--r--engines/scumm/players/player_v3a.h (renamed from engines/scumm/player_v3a.h)6
-rw-r--r--engines/scumm/players/player_v3m.cpp (renamed from engines/scumm/player_v3m.cpp)2
-rw-r--r--engines/scumm/players/player_v3m.h (renamed from engines/scumm/player_v3m.h)6
-rw-r--r--engines/scumm/players/player_v4a.cpp (renamed from engines/scumm/player_v4a.cpp)2
-rw-r--r--engines/scumm/players/player_v4a.h (renamed from engines/scumm/player_v4a.h)4
-rw-r--r--engines/scumm/players/player_v5m.cpp (renamed from engines/scumm/player_v5m.cpp)2
-rw-r--r--engines/scumm/players/player_v5m.h (renamed from engines/scumm/player_v5m.h)6
-rw-r--r--engines/scumm/saveload.cpp143
-rw-r--r--engines/scumm/script_v5.cpp2
-rw-r--r--engines/scumm/scumm-md5.h3
-rw-r--r--engines/scumm/scumm.cpp34
-rw-r--r--engines/scumm/scumm.h19
-rw-r--r--engines/scumm/sound.cpp10
-rw-r--r--engines/sky/configure.engine3
-rw-r--r--engines/sword1/configure.engine3
-rw-r--r--engines/sword1/music.cpp6
-rw-r--r--engines/sword1/music.h2
-rw-r--r--engines/sword1/screen.cpp24
-rw-r--r--engines/sword1/sound.cpp3
-rw-r--r--engines/sword1/sword1.cpp11
-rw-r--r--engines/sword2/configure.engine3
-rw-r--r--engines/sword25/configure.engine3
-rw-r--r--engines/sword25/gfx/animation.cpp20
-rw-r--r--engines/sword25/gfx/animation.h12
-rw-r--r--engines/sword25/gfx/animationdescription.cpp4
-rw-r--r--engines/sword25/gfx/animationdescription.h8
-rw-r--r--engines/sword25/gfx/animationtemplate.cpp4
-rw-r--r--engines/sword25/gfx/animationtemplateregistry.cpp6
-rw-r--r--engines/sword25/gfx/bitmap.h6
-rw-r--r--engines/sword25/gfx/image/art.cpp3
-rw-r--r--engines/sword25/gfx/image/renderedimage.cpp50
-rw-r--r--engines/sword25/gfx/panel.cpp2
-rw-r--r--engines/sword25/gfx/panel.h2
-rw-r--r--engines/sword25/gfx/renderobject.cpp38
-rw-r--r--engines/sword25/gfx/renderobject.h36
-rw-r--r--engines/sword25/gfx/renderobjectmanager.cpp25
-rw-r--r--engines/sword25/gfx/text.cpp12
-rw-r--r--engines/sword25/gfx/text.h10
-rw-r--r--engines/sword25/input/inputengine.cpp8
-rw-r--r--engines/sword25/kernel/inputpersistenceblock.cpp10
-rw-r--r--engines/sword25/kernel/inputpersistenceblock.h4
-rw-r--r--engines/sword25/kernel/objectregistry.h6
-rw-r--r--engines/sword25/kernel/outputpersistenceblock.cpp8
-rw-r--r--engines/sword25/kernel/outputpersistenceblock.h4
-rw-r--r--engines/sword25/kernel/persistenceservice.cpp2
-rw-r--r--engines/sword25/math/polygon.cpp8
-rw-r--r--engines/sword25/math/polygon.h2
-rw-r--r--engines/sword25/math/region.cpp20
-rw-r--r--engines/sword25/math/regionregistry.cpp6
-rw-r--r--engines/sword25/math/walkregion.cpp22
-rw-r--r--engines/sword25/sfx/soundengine.cpp15
-rw-r--r--engines/sword25/sfx/soundengine.h8
-rw-r--r--engines/sword25/util/lua/lcode.cpp2
-rw-r--r--engines/sword25/util/lua/ldebug.cpp5
-rw-r--r--engines/sword25/util/lua/lfunc.cpp2
-rw-r--r--engines/sword25/util/lua/lgc.cpp2
-rw-r--r--engines/sword25/util/lua/llimits.h3
-rw-r--r--engines/sword25/util/lua/lmem.cpp2
-rw-r--r--engines/sword25/util/lua/lopcodes.cpp3
-rw-r--r--engines/sword25/util/lua/lparser.cpp2
-rw-r--r--engines/sword25/util/lua/lstate.cpp2
-rw-r--r--engines/sword25/util/lua/lstring.cpp2
-rw-r--r--engines/sword25/util/lua/lstrlib.cpp6
-rw-r--r--engines/sword25/util/lua/ltablib.cpp2
-rw-r--r--engines/sword25/util/lua/lua.h2
-rw-r--r--engines/sword25/util/pluto/pluto.cpp1
-rw-r--r--engines/teenagent/callbacks.cpp12
-rw-r--r--engines/teenagent/configure.engine3
-rw-r--r--engines/teenagent/teenagent.h6
-rw-r--r--engines/testbed/config-params.cpp2
-rw-r--r--engines/testbed/config.h2
-rw-r--r--engines/testbed/configure.engine3
-rw-r--r--engines/testbed/events.cpp5
-rw-r--r--engines/tinsel/configure.engine3
-rw-r--r--engines/tinsel/detection_tables.h2
-rw-r--r--engines/tinsel/music.cpp35
-rw-r--r--engines/tinsel/scene.cpp44
-rw-r--r--engines/tinsel/tinsel.cpp19
-rw-r--r--engines/tinsel/tinsel.h4
-rw-r--r--engines/toltecs/configure.engine3
-rw-r--r--engines/toltecs/render.cpp2
-rw-r--r--engines/toltecs/saveload.cpp2
-rw-r--r--engines/toltecs/screen.cpp4
-rw-r--r--engines/toltecs/script.cpp10
-rw-r--r--engines/toltecs/toltecs.cpp8
-rw-r--r--engines/toltecs/toltecs.h7
-rw-r--r--engines/tony/configure.engine3
-rw-r--r--engines/tony/gfxcore.cpp1
-rw-r--r--engines/tony/mpal/mpal.cpp10
-rw-r--r--engines/tony/sound.cpp2
-rw-r--r--engines/tony/tony.h2
-rw-r--r--engines/tony/window.cpp12
-rw-r--r--engines/tony/window.h1
-rw-r--r--engines/toon/anim.cpp8
-rw-r--r--engines/toon/audio.cpp3
-rw-r--r--engines/toon/character.cpp1
-rw-r--r--engines/toon/configure.engine3
-rw-r--r--engines/toon/font.cpp5
-rw-r--r--engines/toon/movie.cpp9
-rw-r--r--engines/toon/movie.h3
-rw-r--r--engines/toon/path.cpp2
-rw-r--r--engines/toon/picture.cpp5
-rw-r--r--engines/toon/resource.cpp1
-rw-r--r--engines/toon/resource.h1
-rw-r--r--engines/toon/script.cpp5
-rw-r--r--engines/toon/script_func.cpp6
-rw-r--r--engines/toon/state.cpp4
-rw-r--r--engines/toon/tools.cpp7
-rw-r--r--engines/toon/toon.cpp42
-rw-r--r--engines/touche/configure.engine3
-rw-r--r--engines/touche/touche.cpp79
-rw-r--r--engines/touche/touche.h2
-rw-r--r--engines/tsage/blue_force/blueforce_logic.cpp43
-rw-r--r--engines/tsage/blue_force/blueforce_logic.h18
-rw-r--r--engines/tsage/blue_force/blueforce_scenes0.cpp11
-rw-r--r--engines/tsage/blue_force/blueforce_scenes0.h2
-rw-r--r--engines/tsage/blue_force/blueforce_scenes1.cpp18
-rw-r--r--engines/tsage/blue_force/blueforce_scenes2.cpp6
-rw-r--r--engines/tsage/blue_force/blueforce_scenes3.cpp91
-rw-r--r--engines/tsage/blue_force/blueforce_scenes3.h6
-rw-r--r--engines/tsage/blue_force/blueforce_scenes4.cpp126
-rw-r--r--engines/tsage/blue_force/blueforce_scenes4.h12
-rw-r--r--engines/tsage/blue_force/blueforce_scenes5.cpp37
-rw-r--r--engines/tsage/blue_force/blueforce_scenes5.h4
-rw-r--r--engines/tsage/blue_force/blueforce_scenes6.cpp4
-rw-r--r--engines/tsage/blue_force/blueforce_scenes7.cpp2
-rw-r--r--engines/tsage/blue_force/blueforce_scenes8.cpp30
-rw-r--r--engines/tsage/blue_force/blueforce_scenes8.h3
-rw-r--r--engines/tsage/blue_force/blueforce_scenes9.cpp66
-rw-r--r--engines/tsage/blue_force/blueforce_scenes9.h1
-rw-r--r--engines/tsage/blue_force/blueforce_speakers.cpp4
-rw-r--r--engines/tsage/blue_force/blueforce_speakers.h2
-rw-r--r--engines/tsage/configure.engine3
-rw-r--r--engines/tsage/converse.cpp102
-rw-r--r--engines/tsage/converse.h13
-rw-r--r--engines/tsage/core.cpp238
-rw-r--r--engines/tsage/core.h25
-rw-r--r--engines/tsage/debugger.cpp146
-rw-r--r--engines/tsage/debugger.h2
-rw-r--r--engines/tsage/detection.cpp1
-rw-r--r--engines/tsage/detection_tables.h17
-rw-r--r--engines/tsage/events.cpp4
-rw-r--r--engines/tsage/globals.cpp290
-rw-r--r--engines/tsage/globals.h54
-rw-r--r--engines/tsage/graphics.cpp93
-rw-r--r--engines/tsage/graphics.h7
-rw-r--r--engines/tsage/ringworld/ringworld_logic.cpp5
-rw-r--r--engines/tsage/ringworld/ringworld_scenes1.cpp698
-rw-r--r--engines/tsage/ringworld/ringworld_scenes1.h82
-rw-r--r--engines/tsage/ringworld/ringworld_scenes10.cpp2
-rw-r--r--engines/tsage/ringworld/ringworld_scenes3.cpp38
-rw-r--r--engines/tsage/ringworld/ringworld_scenes3.h2
-rw-r--r--engines/tsage/ringworld/ringworld_scenes5.cpp15
-rw-r--r--engines/tsage/ringworld/ringworld_scenes5.h2
-rw-r--r--engines/tsage/ringworld/ringworld_scenes6.cpp13
-rw-r--r--engines/tsage/ringworld/ringworld_scenes6.h6
-rw-r--r--engines/tsage/ringworld/ringworld_scenes8.cpp8
-rw-r--r--engines/tsage/ringworld/ringworld_scenes8.h2
-rw-r--r--engines/tsage/ringworld2/ringworld2_dialogs.cpp32
-rw-r--r--engines/tsage/ringworld2/ringworld2_dialogs.h3
-rw-r--r--engines/tsage/ringworld2/ringworld2_logic.cpp221
-rw-r--r--engines/tsage/ringworld2/ringworld2_logic.h19
-rw-r--r--engines/tsage/ringworld2/ringworld2_scenes0.cpp1929
-rw-r--r--engines/tsage/ringworld2/ringworld2_scenes0.h187
-rw-r--r--engines/tsage/ringworld2/ringworld2_scenes1.cpp8491
-rw-r--r--engines/tsage/ringworld2/ringworld2_scenes1.h566
-rw-r--r--engines/tsage/ringworld2/ringworld2_scenes2.cpp1197
-rw-r--r--engines/tsage/ringworld2/ringworld2_scenes2.h222
-rw-r--r--engines/tsage/ringworld2/ringworld2_scenes3.cpp2874
-rw-r--r--engines/tsage/ringworld2/ringworld2_scenes3.h296
-rw-r--r--engines/tsage/ringworld2/ringworld2_speakers.cpp766
-rw-r--r--engines/tsage/ringworld2/ringworld2_speakers.h163
-rw-r--r--engines/tsage/saveload.cpp9
-rw-r--r--engines/tsage/saveload.h7
-rw-r--r--engines/tsage/scenes.cpp18
-rw-r--r--engines/tsage/scenes.h4
-rw-r--r--engines/tsage/sound.cpp254
-rw-r--r--engines/tsage/sound.h48
-rw-r--r--engines/tsage/staticres.cpp17
-rw-r--r--engines/tsage/staticres.h15
-rw-r--r--engines/tsage/tsage.cpp39
-rw-r--r--engines/tsage/tsage.h3
-rw-r--r--engines/tsage/user_interface.cpp30
-rw-r--r--engines/tsage/user_interface.h3
-rw-r--r--engines/tucker/configure.engine3
-rw-r--r--engines/wintermute/ad/ad_actor.cpp84
-rw-r--r--engines/wintermute/ad/ad_actor.h4
-rw-r--r--engines/wintermute/ad/ad_entity.cpp86
-rw-r--r--engines/wintermute/ad/ad_entity.h4
-rw-r--r--engines/wintermute/ad/ad_game.cpp64
-rw-r--r--engines/wintermute/ad/ad_game.h4
-rw-r--r--engines/wintermute/ad/ad_inventory.cpp2
-rw-r--r--engines/wintermute/ad/ad_inventory_box.cpp56
-rw-r--r--engines/wintermute/ad/ad_inventory_box.h2
-rw-r--r--engines/wintermute/ad/ad_item.cpp68
-rw-r--r--engines/wintermute/ad/ad_item.h4
-rw-r--r--engines/wintermute/ad/ad_layer.cpp40
-rw-r--r--engines/wintermute/ad/ad_layer.h2
-rw-r--r--engines/wintermute/ad/ad_node_state.cpp12
-rw-r--r--engines/wintermute/ad/ad_object.cpp36
-rw-r--r--engines/wintermute/ad/ad_object.h2
-rw-r--r--engines/wintermute/ad/ad_path.cpp4
-rw-r--r--engines/wintermute/ad/ad_path_point.cpp4
-rw-r--r--engines/wintermute/ad/ad_region.cpp42
-rw-r--r--engines/wintermute/ad/ad_region.h2
-rw-r--r--engines/wintermute/ad/ad_response.cpp8
-rw-r--r--engines/wintermute/ad/ad_response_box.cpp122
-rw-r--r--engines/wintermute/ad/ad_response_box.h2
-rw-r--r--engines/wintermute/ad/ad_response_context.cpp4
-rw-r--r--engines/wintermute/ad/ad_rot_level.cpp16
-rw-r--r--engines/wintermute/ad/ad_rot_level.h2
-rw-r--r--engines/wintermute/ad/ad_scale_level.cpp16
-rw-r--r--engines/wintermute/ad/ad_scale_level.h2
-rw-r--r--engines/wintermute/ad/ad_scene.cpp149
-rw-r--r--engines/wintermute/ad/ad_scene.h2
-rw-r--r--engines/wintermute/ad/ad_scene_node.cpp2
-rw-r--r--engines/wintermute/ad/ad_scene_state.cpp2
-rw-r--r--engines/wintermute/ad/ad_sentence.cpp26
-rw-r--r--engines/wintermute/ad/ad_sprite_set.cpp30
-rw-r--r--engines/wintermute/ad/ad_sprite_set.h2
-rw-r--r--engines/wintermute/ad/ad_talk_def.cpp20
-rw-r--r--engines/wintermute/ad/ad_talk_def.h2
-rw-r--r--engines/wintermute/ad/ad_talk_node.cpp32
-rw-r--r--engines/wintermute/ad/ad_talk_node.h2
-rw-r--r--engines/wintermute/ad/ad_waypoint_group.cpp28
-rw-r--r--engines/wintermute/ad/ad_waypoint_group.h2
-rw-r--r--engines/wintermute/base/base.cpp18
-rw-r--r--engines/wintermute/base/base.h4
-rw-r--r--engines/wintermute/base/base_active_rect.cpp4
-rw-r--r--engines/wintermute/base/base_fader.cpp20
-rw-r--r--engines/wintermute/base/base_file_manager.cpp86
-rw-r--r--engines/wintermute/base/base_frame.cpp26
-rw-r--r--engines/wintermute/base/base_frame.h2
-rw-r--r--engines/wintermute/base/base_game.cpp138
-rw-r--r--engines/wintermute/base/base_game.h5
-rw-r--r--engines/wintermute/base/base_game_music.cpp14
-rw-r--r--engines/wintermute/base/base_game_settings.cpp40
-rw-r--r--engines/wintermute/base/base_keyboard_state.cpp26
-rw-r--r--engines/wintermute/base/base_object.cpp58
-rw-r--r--engines/wintermute/base/base_object.h2
-rw-r--r--engines/wintermute/base/base_parser.cpp4
-rw-r--r--engines/wintermute/base/base_persistence_manager.cpp53
-rw-r--r--engines/wintermute/base/base_persistence_manager.h23
-rw-r--r--engines/wintermute/base/base_point.cpp4
-rw-r--r--engines/wintermute/base/base_region.cpp40
-rw-r--r--engines/wintermute/base/base_region.h2
-rw-r--r--engines/wintermute/base/base_script_holder.cpp24
-rw-r--r--engines/wintermute/base/base_script_holder.h2
-rw-r--r--engines/wintermute/base/base_scriptable.cpp2
-rw-r--r--engines/wintermute/base/base_sprite.cpp76
-rw-r--r--engines/wintermute/base/base_sprite.h2
-rw-r--r--engines/wintermute/base/base_sub_frame.cpp72
-rw-r--r--engines/wintermute/base/base_sub_frame.h2
-rw-r--r--engines/wintermute/base/base_viewport.cpp11
-rw-r--r--engines/wintermute/base/file/base_disk_file.cpp7
-rw-r--r--engines/wintermute/base/font/base_font.cpp6
-rw-r--r--engines/wintermute/base/font/base_font_bitmap.cpp31
-rw-r--r--engines/wintermute/base/font/base_font_bitmap.h2
-rw-r--r--engines/wintermute/base/font/base_font_truetype.cpp95
-rw-r--r--engines/wintermute/base/font/base_font_truetype.h15
-rw-r--r--engines/wintermute/base/gfx/base_renderer.cpp16
-rw-r--r--engines/wintermute/base/gfx/base_surface.h2
-rw-r--r--engines/wintermute/base/gfx/osystem/base_render_osystem.cpp254
-rw-r--r--engines/wintermute/base/gfx/osystem/base_render_osystem.h24
-rw-r--r--engines/wintermute/base/gfx/osystem/base_surface_osystem.cpp56
-rw-r--r--engines/wintermute/base/gfx/osystem/base_surface_osystem.h2
-rw-r--r--engines/wintermute/base/gfx/osystem/render_ticket.cpp90
-rw-r--r--engines/wintermute/base/gfx/osystem/render_ticket.h4
-rw-r--r--engines/wintermute/base/particles/part_emitter.cpp73
-rw-r--r--engines/wintermute/base/particles/part_force.cpp10
-rw-r--r--engines/wintermute/base/particles/part_particle.cpp36
-rw-r--r--engines/wintermute/base/saveload.cpp1
-rw-r--r--engines/wintermute/base/scriptables/script.cpp34
-rw-r--r--engines/wintermute/base/scriptables/script_ext_array.cpp2
-rw-r--r--engines/wintermute/base/scriptables/script_ext_date.cpp14
-rw-r--r--engines/wintermute/base/scriptables/script_ext_file.cpp10
-rw-r--r--engines/wintermute/base/scriptables/script_ext_mem_buffer.cpp2
-rw-r--r--engines/wintermute/base/scriptables/script_ext_string.cpp20
-rw-r--r--engines/wintermute/base/scriptables/script_stack.cpp2
-rw-r--r--engines/wintermute/base/scriptables/script_value.cpp22
-rw-r--r--engines/wintermute/base/sound/base_sound.cpp20
-rw-r--r--engines/wintermute/base/sound/base_sound_buffer.cpp10
-rw-r--r--engines/wintermute/base/sound/base_sound_buffer.h1
-rw-r--r--engines/wintermute/base/timer.cpp6
-rw-r--r--engines/wintermute/coll_templ.h20
-rw-r--r--engines/wintermute/configure.engine3
-rw-r--r--engines/wintermute/dctypes.h3
-rw-r--r--engines/wintermute/detection.cpp1
-rw-r--r--engines/wintermute/detection_tables.h352
-rw-r--r--engines/wintermute/graphics/transform_struct.cpp15
-rw-r--r--engines/wintermute/graphics/transform_struct.h7
-rw-r--r--engines/wintermute/graphics/transform_tools.cpp26
-rw-r--r--engines/wintermute/graphics/transform_tools.h2
-rw-r--r--engines/wintermute/graphics/transparent_surface.cpp530
-rw-r--r--engines/wintermute/graphics/transparent_surface.h57
-rw-r--r--engines/wintermute/math/rect32.h12
-rw-r--r--engines/wintermute/platform_osystem.cpp48
-rw-r--r--engines/wintermute/platform_osystem.h6
-rw-r--r--engines/wintermute/ui/ui_button.cpp118
-rw-r--r--engines/wintermute/ui/ui_button.h58
-rw-r--r--engines/wintermute/ui/ui_edit.cpp68
-rw-r--r--engines/wintermute/ui/ui_edit.h27
-rw-r--r--engines/wintermute/ui/ui_entity.cpp26
-rw-r--r--engines/wintermute/ui/ui_entity.h6
-rw-r--r--engines/wintermute/ui/ui_object.cpp100
-rw-r--r--engines/wintermute/ui/ui_object.h56
-rw-r--r--engines/wintermute/ui/ui_text.cpp54
-rw-r--r--engines/wintermute/ui/ui_text.h6
-rw-r--r--engines/wintermute/ui/ui_tiled_image.cpp153
-rw-r--r--engines/wintermute/ui/ui_tiled_image.h4
-rw-r--r--engines/wintermute/ui/ui_window.cpp142
-rw-r--r--engines/wintermute/ui/ui_window.h49
-rw-r--r--engines/wintermute/utils/string_util.cpp206
-rw-r--r--engines/wintermute/utils/string_util.h3
-rw-r--r--engines/wintermute/video/video_theora_player.cpp32
-rw-r--r--engines/wintermute/video/video_theora_player.h4
-rw-r--r--engines/zvision/animation/rlf_animation.cpp331
-rw-r--r--engines/zvision/animation/rlf_animation.h163
-rw-r--r--engines/zvision/archives/zfs_archive.cpp157
-rw-r--r--engines/zvision/archives/zfs_archive.h126
-rw-r--r--engines/zvision/configure.engine3
-rw-r--r--engines/zvision/core/console.cpp218
-rw-r--r--engines/zvision/core/console.h55
-rw-r--r--engines/zvision/core/events.cpp186
-rw-r--r--engines/zvision/core/menu.h (renamed from backends/graphics/opengl/glerrorcheck.h)15
-rw-r--r--engines/zvision/core/save_manager.cpp206
-rw-r--r--engines/zvision/core/save_manager.h91
-rw-r--r--engines/zvision/cursors/cursor.cpp94
-rw-r--r--engines/zvision/cursors/cursor.h66
-rw-r--r--engines/zvision/cursors/cursor_manager.cpp152
-rw-r--r--engines/zvision/cursors/cursor_manager.h114
-rw-r--r--engines/zvision/detection.cpp272
-rw-r--r--engines/zvision/detection.h44
-rw-r--r--engines/zvision/fonts/truetype_font.cpp116
-rw-r--r--engines/zvision/fonts/truetype_font.h81
-rw-r--r--engines/zvision/graphics/render_manager.cpp526
-rw-r--r--engines/zvision/graphics/render_manager.h328
-rw-r--r--engines/zvision/graphics/render_table.cpp240
-rw-r--r--engines/zvision/graphics/render_table.h85
-rw-r--r--engines/zvision/inventory/inventory_manager.h28
-rw-r--r--engines/zvision/module.mk43
-rw-r--r--engines/zvision/scripting/actions.cpp401
-rw-r--r--engines/zvision/scripting/actions.h346
-rw-r--r--engines/zvision/scripting/control.cpp124
-rw-r--r--engines/zvision/scripting/control.h146
-rw-r--r--engines/zvision/scripting/controls/animation_control.cpp263
-rw-r--r--engines/zvision/scripting/controls/animation_control.h87
-rw-r--r--engines/zvision/scripting/controls/input_control.cpp142
-rw-r--r--engines/zvision/scripting/controls/input_control.h60
-rw-r--r--engines/zvision/scripting/controls/lever_control.cpp402
-rw-r--r--engines/zvision/scripting/controls/lever_control.h127
-rw-r--r--engines/zvision/scripting/controls/push_toggle_control.cpp98
-rw-r--r--engines/zvision/scripting/controls/push_toggle_control.h67
-rw-r--r--engines/zvision/scripting/controls/timer_node.cpp73
-rw-r--r--engines/zvision/scripting/controls/timer_node.h55
-rw-r--r--engines/zvision/scripting/puzzle.h74
-rw-r--r--engines/zvision/scripting/scr_file_handling.cpp302
-rw-r--r--engines/zvision/scripting/script_manager.cpp444
-rw-r--r--engines/zvision/scripting/script_manager.h225
-rw-r--r--engines/zvision/sound/zork_raw.cpp217
-rw-r--r--engines/zvision/sound/zork_raw.h120
-rw-r--r--engines/zvision/strings/string_manager.cpp255
-rw-r--r--engines/zvision/strings/string_manager.h85
-rw-r--r--engines/zvision/subtitles/subtitles.h29
-rw-r--r--engines/zvision/utility/clock.cpp70
-rw-r--r--engines/zvision/utility/clock.h78
-rw-r--r--engines/zvision/utility/lzss_read_stream.cpp103
-rw-r--r--engines/zvision/utility/lzss_read_stream.h72
-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.h115
-rw-r--r--engines/zvision/video/video.cpp171
-rw-r--r--engines/zvision/video/zork_avi_decoder.cpp53
-rw-r--r--engines/zvision/video/zork_avi_decoder.h60
-rw-r--r--engines/zvision/zvision.cpp184
-rw-r--r--engines/zvision/zvision.h152
-rw-r--r--graphics/VectorRendererSpec.cpp41
-rw-r--r--graphics/cursorman.cpp1
-rw-r--r--graphics/decoders/iff.cpp6
-rw-r--r--graphics/decoders/iff.h4
-rw-r--r--graphics/decoders/image_decoder.h6
-rw-r--r--graphics/decoders/png.cpp12
-rw-r--r--graphics/decoders/tga.cpp2
-rw-r--r--graphics/decoders/tga.h1
-rw-r--r--graphics/font.cpp217
-rw-r--r--graphics/font.h10
-rw-r--r--graphics/fonts/bdf.cpp8
-rw-r--r--graphics/fonts/bdf.h6
-rw-r--r--graphics/fonts/ttf.cpp81
-rw-r--r--graphics/fonts/ttf.h18
-rw-r--r--graphics/fonts/winfont.cpp6
-rw-r--r--graphics/fonts/winfont.h6
-rw-r--r--graphics/sjis.cpp20
-rw-r--r--graphics/surface.cpp24
-rw-r--r--graphics/surface.h28
-rw-r--r--gui/ThemeEngine.cpp10
-rw-r--r--gui/about.cpp2
-rw-r--r--gui/console.cpp23
-rw-r--r--gui/console.h6
-rw-r--r--gui/credits.h37
-rw-r--r--gui/debugger.cpp10
-rw-r--r--gui/gui-manager.cpp13
-rw-r--r--gui/predictivedialog.cpp18
-rw-r--r--gui/recorderdialog.h2
-rw-r--r--gui/themes/default.inc1231
-rw-r--r--gui/themes/scummclassic.zipbin113348 -> 110107 bytes
-rw-r--r--gui/themes/scummclassic/classic_layout_lowres.stx77
-rw-r--r--gui/widgets/editable.cpp36
-rw-r--r--gui/widgets/editable.h5
-rw-r--r--gui/widgets/edittext.cpp2
-rw-r--r--gui/widgets/list.cpp5
-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/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/se_SE.po2
-rw-r--r--po/uk_UA.po2
-rw-r--r--ports.mk10
-rw-r--r--video/avi_decoder.cpp138
-rw-r--r--video/avi_decoder.h23
-rw-r--r--video/bink_decoder.cpp10
-rw-r--r--video/bink_decoder.h2
-rw-r--r--video/codecs/jpeg.cpp66
-rw-r--r--video/codecs/jpeg.h60
-rw-r--r--video/codecs/mjpeg.cpp163
-rw-r--r--video/codecs/mjpeg.h8
-rw-r--r--video/codecs/mpeg.h2
-rw-r--r--video/codecs/truemotion1.h4
-rw-r--r--video/module.mk1
-rw-r--r--video/qt_decoder.cpp4
-rw-r--r--video/smk_decoder.cpp40
-rw-r--r--video/smk_decoder.h2
-rw-r--r--video/video_decoder.cpp60
-rw-r--r--video/video_decoder.h44
1169 files changed, 88661 insertions, 35594 deletions
diff --git a/.gitignore b/.gitignore
index 0fe212098c..3868edbbda 100644
--- a/.gitignore
+++ b/.gitignore
@@ -105,6 +105,9 @@ project.xcworkspace
/plugins
+/engines/plugins_table.h
+/engines/engines.mk
+
/test/runner
/test/runner.cpp
/test/*.dSYM
@@ -182,3 +185,7 @@ ScummVM.includes
#Ignore Mac DS_Store files
.DS_Store
+
+#Ignore MS Visual C++ temporary files/subdirectories (except create_project.bat)
+dists/msvc*/**
+!dists/msvc*/create_project.bat
diff --git a/AUTHORS b/AUTHORS
index fd5407b460..2800b6242a 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -6,9 +6,9 @@ ScummVM Team
PR Office
---------
- Arnaud Boutonne - Public Relations Officer, Project
- Administrator
- Eugene Sandulenko - Project Leader
+ Arnaud Boutonne - Public Relations Officer, Project
+ Administrator
+ Eugene Sandulenko - Project Leader
Core Team
---------
@@ -19,30 +19,30 @@ ScummVM Team
Retired Project Leaders
-----------------------
James Brown
- Vincent Hamm - ScummVM co-founder, Original Cruise/CinE
- author
+ Vincent Hamm - ScummVM co-founder, Original Cruise/CinE
+ author
Max Horn
- Ludvig Strigeus - Original ScummVM and SimonVM author
+ Ludvig Strigeus - Original ScummVM and SimonVM author
Engine Teams
------------
SCUMM:
Torbjorn Andersson
- James Brown - (retired)
- Jonathan Gray - (retired)
- Vincent Hamm - (retired)
- Max Horn - (retired)
+ James Brown - (retired)
+ Jonathan Gray - (retired)
+ Vincent Hamm - (retired)
+ Max Horn - (retired)
Travis Howell
- Pawel Kolodziejski - Codecs, iMUSE, Smush, etc.
- Gregory Montoir - (retired)
- Eugene Sandulenko - FT INSANE, MM NES, MM C64, game detection,
- Herc/CGA
- Ludvig Strigeus - (retired)
+ Pawel Kolodziejski - Codecs, iMUSE, Smush, etc.
+ Gregory Montoir - (retired)
+ Eugene Sandulenko - FT INSANE, MM NES, MM C64, game
+ detection, Herc/CGA
+ Ludvig Strigeus - (retired)
HE:
- Jonathan Gray - (retired)
+ Jonathan Gray - (retired)
Travis Howell
- Gregory Montoir - (retired)
+ Gregory Montoir - (retired)
Eugene Sandulenko
AGI:
@@ -50,26 +50,30 @@ ScummVM Team
Matthew Hoops
Filippos Karapetis
Pawel Kolodziejski
- Walter van Niftrik - (retired)
+ Walter van Niftrik - (retired)
Kari Salminen
Eugene Sandulenko
- David Symonds - (retired)
+ David Symonds - (retired)
AGOS:
Torbjorn Andersson
Paul Gilbert
Travis Howell
- Oliver Kiehl - (retired)
- Ludvig Strigeus - (retired)
+ Oliver Kiehl - (retired)
+ Ludvig Strigeus - (retired)
+
+ Avalanche:
+ Peter Bozso
+ Arnaud Boutonne
CGE:
Arnaud Boutonne
Paul Gilbert
Cine:
- Vincent Hamm - (retired)
+ Vincent Hamm - (retired)
Pawel Kolodziejski
- Gregory Montoir - (retired)
+ Gregory Montoir - (retired)
Kari Salminen
Eugene Sandulenko
@@ -78,7 +82,7 @@ ScummVM Team
CruisE:
Paul Gilbert
- Vincent Hamm - (retired)
+ Vincent Hamm - (retired)
Draci:
Denis Kasak
@@ -92,7 +96,7 @@ ScummVM Team
Torbjorn Andersson
Bertrand Augereau
Filippos Karapetis
- Vladimir Menshakov - (retired)
+ Vladimir Menshakov - (retired)
Willem Jan Palenstijn
Gob:
@@ -116,10 +120,10 @@ ScummVM Team
Eugene Sandulenko
Kyra:
- Torbjorn Andersson - VQA Player
+ Torbjorn Andersson - VQA Player
Oystein Eftevaag
Florian Kagerer
- Gregory Montoir - (retired)
+ Gregory Montoir - (retired)
Johannes Schickel
Lastexpress:
@@ -157,14 +161,14 @@ ScummVM Team
Matthew Hoops
Queen:
- David Eriksson - (retired)
- Gregory Montoir - (retired)
+ David Eriksson - (retired)
+ Gregory Montoir - (retired)
Joost Peters
SAGA:
Torbjorn Andersson
- Daniel Balsom - Original engine reimplementation author
- (retired)
+ Daniel Balsom - Original engine reimplementation author
+ (retired)
Filippos Karapetis
Andrew Kurushin
Eugene Sandulenko
@@ -172,46 +176,46 @@ ScummVM Team
SCI:
Greg Frieger
Paul Gilbert
- Max Horn - (retired)
+ Max Horn - (retired)
Filippos Karapetis
Martin Kiewitz
- Walter van Niftrik - (retired)
+ Walter van Niftrik - (retired)
Willem Jan Palenstijn
Jordi Vilalta Prat
Lars Skovlund
Sky:
- Robert Goeffringmann - (retired)
- Oliver Kiehl - (retired)
+ Robert Goeffringmann - (retired)
+ Oliver Kiehl - (retired)
Joost Peters
Sword1:
- Fabio Battaglia - PSX version support
- Thierry Crozat - Mac version support
- Robert Goeffringmann - (retired)
+ Fabio Battaglia - PSX version support
+ Thierry Crozat - Mac version support
+ Robert Goeffringmann - (retired)
Sword2:
Torbjorn Andersson
- Fabio Battaglia - PSX version support
- Jonathan Gray - (retired)
+ Fabio Battaglia - PSX version support
+ Jonathan Gray - (retired)
Sword25:
Torbjorn Andersson
Paul Gilbert
- Max Horn - (retired)
+ Max Horn - (retired)
Filippos Karapetis
Eugene Sandulenko
TeenAgent:
- Robert Megone - Help with callback rewriting
- Vladimir Menshakov - (retired)
+ Robert Megone - Help with callback rewriting
+ Vladimir Menshakov - (retired)
Tinsel:
Torbjorn Andersson
- Fabio Battaglia - PSX version support
+ Fabio Battaglia - PSX version support
Paul Gilbert
Sven Hesse
- Max Horn - (retired)
+ Max Horn - (retired)
Filippos Karapetis
Joost Peters
@@ -228,18 +232,21 @@ ScummVM Team
Sylvain Dupont
Touche:
- Gregory Montoir - (retired)
+ Gregory Montoir - (retired)
TsAGE:
Arnaud Boutonne
Paul Gilbert
Tucker:
- Gregory Montoir - (retired)
+ Gregory Montoir - (retired)
Wintermute:
Einar Johan T. Somaaen
+ ZVision:
+ Adrian Astley
+
Backend Teams
-------------
Android:
@@ -259,26 +266,26 @@ ScummVM Team
Lubomyr Lisen
Maemo:
- Frantisek Dufka - (retired)
+ Frantisek Dufka - (retired)
Tarek Soliman
Nintendo 64:
Fabio Battaglia
Nintendo DS:
- Bertrand Augereau - HQ software scaler
+ Bertrand Augereau - HQ software scaler
Neil Millstone
OpenPandora:
John Willis
PocketPC / WinCE:
- Nicolas Bacca - (retired)
+ Nicolas Bacca - (retired)
Ismail Khatib
- Kostas Nakos - (retired)
+ Kostas Nakos - (retired)
PlayStation 2:
- Robert Goeffringmann - (retired)
+ Robert Goeffringmann - (retired)
Max Lingua
PSP (PlayStation Portable):
@@ -286,8 +293,8 @@ ScummVM Team
Joost Peters
SDL (Win/Linux/OS X/etc.):
- Max Horn - (retired)
- Eugene Sandulenko - Asm routines, GFX layers
+ Max Horn - (retired)
+ Eugene Sandulenko - Asm routines, GFX layers
SymbianOS:
Jurgen Braam
@@ -305,9 +312,9 @@ ScummVM Team
Other subsystems
----------------
Infrastructure:
- Max Horn - Backend & Engine APIs, file API, sound
- mixer, audiostreams, data structures, etc.
- (retired)
+ Max Horn - Backend & Engine APIs, file API, sound
+ mixer, audiostreams, data structures,
+ etc. (retired)
Eugene Sandulenko
Johannes Schickel
@@ -317,33 +324,35 @@ ScummVM Team
Johannes Schickel
Miscellaneous:
- David Corrales-Lopez - Filesystem access improvements (GSoC 2007
- task) (retired)
- Jerome Fisher - MT-32 emulator
- Benjamin Haisch - Heavily improved de-/encoder for DXA videos
- Jochen Hoenicke - Speaker & PCjr sound support, AdLib work
- (retired)
- Daniel ter Laan - Restoring original Drascula tracks, and
- writing convert_dxa.bat
- Chris Page - Return to launcher, savestate improvements,
- leak fixes, ... (GSoC 2008 task) (retired)
- Robin Watts - ARM assembly routines for nice speedups on
- several ports; improvements to the sound
- mixer
+ David Corrales-Lopez - Filesystem access improvements (GSoC
+ 2007 task) (retired)
+ Jerome Fisher - MT-32 emulator
+ Benjamin Haisch - Heavily improved de-/encoder for DXA
+ videos
+ Jochen Hoenicke - Speaker & PCjr sound support, AdLib
+ work (retired)
+ Daniel ter Laan - Restoring original Drascula tracks, and
+ writing convert_dxa.bat
+ Chris Page - Return to launcher, savestate
+ improvements, leak fixes, ... (GSoC
+ 2008 task) (retired)
+ Robin Watts - ARM assembly routines for nice speedups
+ on several ports; improvements to the
+ sound mixer
Website (code)
--------------
- Fredrik Wendel - (retired)
+ Fredrik Wendel - (retired)
Website (maintenance)
---------------------
- James Brown - IRC Logs maintainer
- Thierry Crozat - Wiki maintainer
- Andre Heider - Buildbot maintainer
- Joost Peters - Doxygen Project Documentation maintainer
- Jordi Vilalta Prat - Wiki maintainer
- Eugene Sandulenko - Forum, IRC channel, Screen Shots and Mailing
- list maintainer
+ James Brown - IRC Logs maintainer
+ Thierry Crozat - Wiki maintainer
+ Andre Heider - Buildbot maintainer
+ Joost Peters - Doxygen Project Documentation maintainer
+ Jordi Vilalta Prat - Wiki maintainer
+ Eugene Sandulenko - Forum, IRC channel, Screen Shots and
+ Mailing list maintainer
John Willis
Website (content)
@@ -352,31 +361,31 @@ ScummVM Team
Documentation
-------------
- Thierry Crozat - Numerous contributions to documentation
- Joachim Eberhard - Numerous contributions to documentation
- (retired)
- Matthew Hoops - Wiki editor
+ Thierry Crozat - Numerous contributions to documentation
+ Joachim Eberhard - Numerous contributions to documentation
+ (retired)
+ Matthew Hoops - Wiki editor
Retired Team Members
--------------------
- Chris Apers - Former PalmOS porter
- Ralph Brorsen - Help with GUI implementation
- Jamieson Christian - iMUSE, MIDI, all things musical
- Felix Jakschitsch - Zak256 reverse engineering
- Mutwin Kraus - Original MacOS porter
- Peter Moraliyski - Port: GP32
- Jeremy Newman - Former webmaster
- Lionel Ulmer - Port: X11
- Won Star - Former GP32 porter
+ Chris Apers - Former PalmOS porter
+ Ralph Brorsen - Help with GUI implementation
+ Jamieson Christian - iMUSE, MIDI, all things musical
+ Felix Jakschitsch - Zak256 reverse engineering
+ Mutwin Kraus - Original MacOS porter
+ Peter Moraliyski - Port: GP32
+ Jeremy Newman - Former webmaster
+ Lionel Ulmer - Port: X11
+ Won Star - Former GP32 porter
Other contributions
*******************
Packages
--------
AmigaOS 4:
- Hans-Joerg Frieden - (retired)
+ Hans-Joerg Frieden - (retired)
Hubert Maier
- Juha Niemimaki - (retired)
+ Juha Niemimaki - (retired)
Atari/FreeMiNT:
Keith Scroggins
@@ -386,22 +395,22 @@ Other contributions
Luc Schrijvers
Debian GNU/Linux:
- Tore Anderson - (retired)
+ Tore Anderson - (retired)
David Weinehall
Fedora / RedHat:
Willem Jan Palenstijn
Mac OS X:
- Max Horn - (retired)
+ Max Horn - (retired)
Oystein Eftevaag
Mandriva:
- Dominik Scherer - (retired)
+ Dominik Scherer - (retired)
MorphOS:
Fabien Coeurjoly
- Ruediger Hanke - (retired)
+ Ruediger Hanke - (retired)
OS/2:
Paul Smedley
@@ -419,12 +428,12 @@ Other contributions
Travis Howell
Win64:
- Chris Gray - (retired)
+ Chris Gray - (retired)
Johannes Schickel
- Translations
- ------------
- Thierry Crozat - Translation Lead
+ GUI Translations
+ ----------------
+ Thierry Crozat - Translation Lead
Basque:
Mikel Iturbe Urretxa
@@ -452,7 +461,7 @@ Other contributions
German:
Simon Sawatzki
- Lothar Serra Mari - (retired)
+ Lothar Serra Mari - (retired)
Hungarian:
Alex Bevilacqua
@@ -486,97 +495,118 @@ Other contributions
Ukrainian:
Lubomyr Lisen
+ Game Translations
+ -----------------
+ CGE:
+ Dan Serban - Soltys English translation
+ Victor Gonzalez - Soltys Spanish translation
+ Alejandro Gomez de la Munoza - Soltys Spanish translation
+
+ Drascula:
+ Thierry Crozat - Improve French translation
+
+ Mortevielle:
+ Hugo Labrande - Improve English translation
+ Thierry Crozat - Improve English translation
+
Websites (design)
-----------------
- Dobo Balazs - Website design
- William Claydon - Skins for doxygen, buildbot and wiki
- Yaroslav Fedevych - HTML/CSS for the website
- Jean Marc Gimenez - ScummVM logo
- David Jensen - SVG logo conversion
- Raina - ScummVM forum buttons
+ Dobo Balazs - Website design
+ William Claydon - Skins for doxygen, buildbot and wiki
+ Yaroslav Fedevych - HTML/CSS for the website
+ Jean Marc Gimenez - ScummVM logo
+ David Jensen - SVG logo conversion
+ Raina - ScummVM forum buttons
Code contributions
------------------
- Ori Avtalion - Subtitle control options in the GUI; BASS GUI
- fixes
- Stuart Caie - Decoders for Amiga and AtariST data files
- (AGOS engine)
- Paolo Costabel - PSP port contributions
- Martin Doucha - CinE engine objectification
- Thomas Fach-Pedersen - ProTracker module player, Smacker video
- decoder
- Tobias Gunkel - Sound support for C64 version of MM/Zak, Loom
- PCE support
- Janne Huttunen - V3 actor mask support, Dig/FT SMUSH audio
- Kovacs Endre Janos - Several fixes for Simon1
- Jeroen Janssen - Numerous readability and bugfix patches
- Andreas Karlsson - Initial port for SymbianOS
- Claudio Matsuoka - Daily Linux builds
- Thomas Mayer - PSP port contributions
- Sean Murray - ScummVM tools GUI application (GSoC 2007 task)
- n0p - Windows CE port aspect ratio correction scaler
- and right click input method
- Mikesch Nepomuk - MI1 VGA floppy patches
- Nicolas Noble - Config file and ALSA support
- Tim Phillips - Initial MI1 CD music support
- Quietust - Sound support for Amiga SCUMM V2/V3 games, MM
- NES support
- Robert Crossfield - Improved support for Apple II/C64 versions of
- MM
- Andreas Roever - Broken Sword I & II MPEG2 cutscene support
- Edward Rudd - Fixes for playing MP3 versions of MI1/Loom
- audio
- Daniel Schepler - Final MI1 CD music support, initial Ogg Vorbis
- support
- Andre Souza - SDL-based OpenGL renderer
- Tom Frost - WebOS port contributions
+ Ori Avtalion - Subtitle control options in the GUI; BASS
+ GUI fixes
+ Stuart Caie - Decoders for Amiga and AtariST data files
+ (AGOS engine)
+ Paolo Costabel - PSP port contributions
+ Martin Doucha - CinE engine objectification
+ Thomas Fach-Pedersen - ProTracker module player, Smacker video
+ decoder
+ Tobias Gunkel - Sound support for C64 version of MM/Zak,
+ Loom PCE support
+ Janne Huttunen - V3 actor mask support, Dig/FT SMUSH audio
+ Kovacs Endre Janos - Several fixes for Simon1
+ Jeroen Janssen - Numerous readability and bugfix patches
+ Keith Kaisershot - Several Pegasus Prime patches
+ Andreas Karlsson - Initial port for SymbianOS
+ Claudio Matsuoka - Daily Linux builds
+ Thomas Mayer - PSP port contributions
+ Sean Murray - ScummVM tools GUI application (GSoC 2007
+ task)
+ n0p - Windows CE port aspect ratio correction
+ scaler and right click input method
+ Mikesch Nepomuk - MI1 VGA floppy patches
+ Nicolas Noble - Config file and ALSA support
+ Tim Phillips - Initial MI1 CD music support
+ Quietust - Sound support for Amiga SCUMM V2/V3
+ games, MM NES support
+ Robert Crossfield - Improved support for Apple II/C64
+ versions of MM
+ Andreas Roever - Broken Sword I & II MPEG2 cutscene
+ support
+ Edward Rudd - Fixes for playing MP3 versions of
+ MI1/Loom audio
+ Daniel Schepler - Final MI1 CD music support, initial Ogg
+ Vorbis support
+ Andre Souza - SDL-based OpenGL renderer
+ Tom Frost - WebOS port contributions
FreeSCI Contributors
--------------------
- Francois-R Boyer - MT-32 information and mapping code
- Rainer Canavan - IRIX MIDI driver and bug fixes
+ Francois-R Boyer - MT-32 information and mapping code
+ Rainer Canavan - IRIX MIDI driver and bug fixes
Xiaojun Chen
- Paul David Doherty - Game version information
- Vyacheslav Dikonov - Config script improvements
- Ruediger Hanke - Port to the MorphOS platform
- Matt Hargett - Clean-ups, bugfixes, Hardcore QA, Win32
- Max Horn - SetJump implementation
- Ravi I. - SCI0 sound resource specification
- Emmanuel Jeandel - Bugfixes and bug reports
- Dmitry Jemerov - Port to the Win32 platform, numerous bugfixes
- Chris Kehler - Makefile enhancements
- Christopher T. Lansdown - Original CVS maintainer, Alpha compatibility
- fixes
- Sergey Lapin - Port of Carl's type 2 decompression code
- Rickard Lind - MT-32->GM MIDI mapping magic, sound research
- Hubert Maier - AmigaOS 4 port
- Johannes Manhave - Document format translation
- Claudio Matsuoka - CVS snapshots, daily builds, BeOS and cygwin
- ports
- Dark Minister - SCI research (bytecode and parser)
- Carl Muckenhoupt - Sources to the SCI resource viewer tools that
- started it all
- Anders Baden Nielsen - PPC testing
- Walter van Niftrik - Ports to the Dreamcast and GP32 platforms
- Rune Orsval - Configuration file editor
- Solomon Peachy - SDL ports and much of the sound subsystem
- Robey Pointer - Bug tracking system hosting
- Magnus Reftel - Heap implementation, Python class viewer,
- bugfixes
- Christoph Reichenbach - UN*X code, VM/Graphics/Sound/other
- infrastructure
- George Reid - FreeBSD package management
- Lars Skovlund - Project maintenance, most documentation,
- bugfixes, SCI1 support
- Rink Springer - Port to the DOS platform, several bug fixes
- Rainer De Temple - SCI research
+ Paul David Doherty - Game version information
+ Vyacheslav Dikonov - Config script improvements
+ Ruediger Hanke - Port to the MorphOS platform
+ Matt Hargett - Clean-ups, bugfixes, Hardcore QA, Win32
+ Max Horn - SetJump implementation
+ Ravi I. - SCI0 sound resource specification
+ Emmanuel Jeandel - Bugfixes and bug reports
+ Dmitry Jemerov - Port to the Win32 platform, numerous
+ bugfixes
+ Chris Kehler - Makefile enhancements
+ Christopher T. Lansdown - Original CVS maintainer, Alpha
+ compatibility fixes
+ Sergey Lapin - Port of Carl's type 2 decompression code
+ Rickard Lind - MT-32->GM MIDI mapping magic, sound
+ research
+ Hubert Maier - AmigaOS 4 port
+ Johannes Manhave - Document format translation
+ Claudio Matsuoka - CVS snapshots, daily builds, BeOS and
+ cygwin ports
+ Dark Minister - SCI research (bytecode and parser)
+ Carl Muckenhoupt - Sources to the SCI resource viewer tools
+ that started it all
+ Anders Baden Nielsen - PPC testing
+ Walter van Niftrik - Ports to the Dreamcast and GP32 platforms
+ Rune Orsval - Configuration file editor
+ Solomon Peachy - SDL ports and much of the sound subsystem
+ Robey Pointer - Bug tracking system hosting
+ Magnus Reftel - Heap implementation, Python class viewer,
+ bugfixes
+ Christoph Reichenbach - UN*X code, VM/Graphics/Sound/other
+ infrastructure
+ George Reid - FreeBSD package management
+ Lars Skovlund - Project maintenance, most documentation,
+ bugfixes, SCI1 support
+ Rink Springer - Port to the DOS platform, several bug
+ fixes
+ Rainer De Temple - SCI research
Sean Terrell
- Hugues Valois - Game selection menu
- Jordi Vilalta - Numerous code and website clean-up patches
- Petr Vyhnak - The DCL-INFLATE algorithm, many Win32
- improvements
- Bas Zoetekouw - Man pages, debian package management, CVS
- maintenance
+ Hugues Valois - Game selection menu
+ Jordi Vilalta - Numerous code and website clean-up
+ patches
+ Petr Vyhnak - The DCL-INFLATE algorithm, many Win32
+ improvements
+ Bas Zoetekouw - Man pages, debian package management, CVS
+ maintenance
Special thanks to Prof. Dr. Gary Nutt for allowing the FreeSCI VM
extension as a course project in his Advanced OS course.
@@ -609,6 +639,8 @@ Special thanks to
Jimmi Thogersen - For ScummRev, and much obscure code/documentation
Tristan - For additional work on the original MT-32 emulator
James Woodcock - Soundtrack enhancements
+ Anton Yartsev - For the original re-implementation of the ZVision
+ engine
Tony Warriner and everyone at Revolution Software Ltd. for sharing with us
the source of some of their brilliant games, allowing us to release
diff --git a/COPYRIGHT b/COPYRIGHT
index e964d8c0a1..2050c6d98f 100644
--- a/COPYRIGHT
+++ b/COPYRIGHT
@@ -1,5 +1,5 @@
ScummVM
-Copyright (C) 2001-2013 by the following:
+Copyright (C) 2001-2014 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 09c38b2598..93a84a5c7b 100644
--- a/Makefile
+++ b/Makefile
@@ -33,8 +33,9 @@ ifeq "$(HAVE_GCC)" "1"
#CXXFLAGS+= -Wmissing-format-attribute
ifneq "$(BACKEND)" "tizen"
- # Disable RTTI and exceptions. These settings cause tizen apps to crash
- CXXFLAGS+= -fno-rtti -fno-exceptions
+ # Disable exceptions. This setting causes tizen apps to crash
+ # TODO: Does this still apply after enabling RTTI again?
+ CXXFLAGS+= -fno-exceptions
endif
ifneq "$(HAVE_CLANG)" "1"
@@ -82,7 +83,8 @@ EXECUTABLE := $(EXEPRE)scummvm$(EXEEXT)
include $(srcdir)/Makefile.common
# check if configure has been run or has been changed since last run
-config.h config.mk: $(srcdir)/configure $(srcdir)/engines/configure.engines
+ENGINE_SUBDIRS_CONFIGURE := $(wildcard $(srcdir)/engines/*/configure.engine)
+config.h: $(srcdir)/configure $(ENGINE_SUBDIRS_CONFIGURE)
ifeq "$(findstring config.mk,$(MAKEFILE_LIST))" "config.mk"
@echo "Running $(srcdir)/configure with the last specified parameters"
@sleep 2
@@ -94,6 +96,14 @@ else
$(error You need to run $(srcdir)/configure before you can run make. Check $(srcdir)/configure --help for a list of parameters)
endif
+config.mk engines/plugins_table.h engines/engines.mk: config.h
+ @if test -f $@; then \
+ touch $@; \
+ else \
+ rm -f config.h; \
+ $(MAKE) config.h; \
+ fi
+
ifneq ($(origin port_mk), undefined)
include $(srcdir)/$(port_mk)
endif
diff --git a/Makefile.common b/Makefile.common
index 02c3408684..b56300a115 100644
--- a/Makefile.common
+++ b/Makefile.common
@@ -16,7 +16,7 @@ all: $(EXECUTABLE) plugins
PLUGINS :=
MODULES := test devtools base $(MODULES)
--include $(srcdir)/engines/engines.mk
+-include engines/engines.mk
# After the game specific modules follow the shared modules
MODULES += \
@@ -79,7 +79,7 @@ $(EXECUTABLE): $(OBJS)
$(QUIET_LINK)$(LD) $(LDFLAGS) $(PRE_OBJS_FLAGS) $+ $(POST_OBJS_FLAGS) $(LIBS) -o $@
distclean: clean clean-devtools
- $(RM) config.h config.mk config.log
+ $(RM) config.h config.mk config.log engines/engines.mk engines/plugins_table.h
clean:
$(RM_REC) $(DEPDIRS)
@@ -147,7 +147,7 @@ endif
# recreate them (which it can't), and in particular from looking for potential
# source files. This can save quite a bit of disk access time.
.PHONY: $(wildcard $(addsuffix /*.d,$(DEPDIRS))) $(addprefix $(srcdir)/, $(addsuffix /module.mk,$(MODULES))) \
- $(srcdir)/$(port_mk) $(srcdir)/rules.mk $(srcdir)/engines/engines.mk
+ $(srcdir)/$(port_mk) $(srcdir)/rules.mk
######################################################################
# Get the current version information
diff --git a/NEWS b/NEWS
index 7a0487cdc9..eb1213df13 100644
--- a/NEWS
+++ b/NEWS
@@ -2,17 +2,47 @@ For a more comprehensive changelog of the latest experimental code, see:
https://github.com/scummvm/scummvm/commits/
1.7.0 (????-??-??)
- General:
- - Updated MT-32 emulation code to version 1.3.0.
+ New Games:
+ - Added support for Return to Ringworld.
+ - Added support for The Neverhood.
+ - Added support for Mortville Manor.
- Gob:
- - Improved video quality in Urban Runner
+ General:
+ - Updated Munt MT-32 emulation code to version 1.3.0.
+ - Switched from our custom JPEG and PNG decoders to libjpeg(-turbo) and
+ libpng, which are faster and can handle more images.
+ (NOTE: The change to libpng was done in version 1.6.0, but it was not
+ added to the NEWS file).
Broken Sword 1:
- - Added back support for MPEG-2 videos
+ - Added back support for MPEG-2 videos.
Broken Sword 2:
- - Added back support for MPEG-2 videos
+ - Added back support for MPEG-2 videos.
+
+ Gob:
+ - Improved video quality in Urban Runner.
+
+ SCI:
+ - Added support for the more detailed RAVE lip syncing data in the Windows
+ version of King's Quest 6. Portraits should now be much more expressive
+ when talking.
+ - Added support for simultaneous speech and subtitles in the CD versions
+ of Laura Bow 2 and King's Quest 6 (toggled either in-game with the new
+ "Dual" audio state, or via the ScummVM audio options).
+ - Fixed music fading.
+ - Fixed several script bugs in Camelot, Crazy Nick's, Hoyle 3, QFG1VGA, KQ5,
+ KQ6, LB2, LSL2, LSL5, Pharkas, PQ1VGA, SQ4, SQ5.
+ - Improved the MIDI parser so that music event processing is done more
+ properly.
+
+ SCUMM:
+ - Changed the saved game naming scheme of HE games to always contain
+ the target name.
+ - Fixed having multiple coaches in Backyard Football.
+
+ Tinsel:
+ - Discworld 1 and 2 no longer crash on big-endian systems.
1.6.0 (2013-05-31)
New Games:
diff --git a/README b/README
index a6c3d9773a..5391c5f2d6 100644
--- a/README
+++ b/README
@@ -33,7 +33,8 @@ Table of Contents:
* 3.17 Winnie the Pooh notes
* 3.18 Troll's Tale notes
* 3.19 Dragon History notes
- * 3.20 Known Problems
+ * 3.20 Simultaneous speech and subtitles in Sierra SCI games
+ * 3.21 Known Problems
4.0) Supported Platforms
5.0) Running ScummVM
* 5.1 Command Line Options
@@ -815,7 +816,55 @@ All game files and the walkthrough can be downloaded from
http://www.ucw.cz/draci-historie/index-en.html
-3.20) Known Problems:
+3.20) 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
+some cases where there wasn't any option to enable both simultaneously.
+In ScummVM, it is possible to enjoy a combined mode, where both speech
+and text are shown at the same time. This mode can be toggled in the
+ScummVM audio options, but each game has different behavior in-game
+regarding speech and text toggling.
+
+The CD games where speech and subtitles can be shown simultaneously
+are:
+ EcoQuest 1 CD
+ Freddy Pharkas CD
+ King's Quest 6 CD
+ Laura Bow 2 CD
+ Leisure Suit Larry 6 CD
+ Space Quest 4 CD
+
+EcoQuest 1 CD:
+ Speech and text can be toggled via the game's "Mode" option in the
+ options dialog, or via ScummVM's audio options.
+
+Freddy Pharkas CD:
+ There is no in-game option to toggle speech and text. Only ScummVM's
+ audio options can be used to toggle this feature. Note that some
+ spoken dialog is missing from the game texts.
+
+King's Quest 6 CD:
+ Speech and text can be toggled via the "Mode" button in the options
+ dialog (with an extra "Dual" setting added in ScummVM), or via
+ ScummVM's audio options.
+
+Laura Bow 2 CD:
+ Speech and text can be toggled via the "Mode" button in the options
+ dialog (with an extra "Dual" setting added in ScummVM), or via
+ ScummVM's audio options.
+
+Leisure Suit Larry 6 CD:
+ Either speech only or speech and text can be selected. There is no
+ in-game option to toggle text only. Only ScummVM's audio options can
+ be used to enable the text only mode.
+
+Space Quest 4 CD:
+ Speech and text can be toggled via the "Display Mode" button in the
+ options dialog, or via ScummVM's audio options.
+
+
+3.21) 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
@@ -2164,6 +2213,16 @@ keywords:
helium_mode bool If true, people sound like they've inhaled
Helium
+The Neverhood adds the following non-standard keywords:
+
+ originalsaveload bool If true, the original save/load screens are
+ used instead of the enhanced ScummVM ones
+ skiphallofrecordsscenes bool
+ If true, allows the player to skip
+ past the Hall of Records storyboard scenes
+ scalemakingofvideos bool If true, the making of videos are scaled, so that
+ they use the whole screen
+
The 7th Guest adds the following non-standard keyword:
fast_movie_speed bool If true, movies are played at an increased
diff --git a/audio/decoders/voc.cpp b/audio/decoders/voc.cpp
index fa330c6f2c..ec589533eb 100644
--- a/audio/decoders/voc.cpp
+++ b/audio/decoders/voc.cpp
@@ -559,7 +559,7 @@ SeekableAudioStream *makeVOCStream(Common::SeekableReadStream *stream, byte flag
SeekableAudioStream *audioStream = new VocStream(stream, (flags & Audio::FLAG_UNSIGNED) != 0, disposeAfterUse);
- if (audioStream && audioStream->endOfData()) {
+ if (audioStream->endOfData()) {
delete audioStream;
return 0;
} else {
diff --git a/audio/midiparser.cpp b/audio/midiparser.cpp
index 2454575413..61f82c4ca4 100644
--- a/audio/midiparser.cpp
+++ b/audio/midiparser.cpp
@@ -214,13 +214,16 @@ void MidiParser::onTimer() {
activeNote(info.channel(), info.basic.param1, true);
}
- processEvent(info);
-
- if (_abortParse)
- break;
+ // Player::metaEvent() in SCUMM will delete the parser object,
+ // so return immediately if that might have happened.
+ bool ret = processEvent(info);
+ if (!ret)
+ return;
- _position._lastEventTime = eventTime;
- parseNextEvent(_nextEvent);
+ if (!_abortParse) {
+ _position._lastEventTime = eventTime;
+ parseNextEvent(_nextEvent);
+ }
}
if (!_abortParse) {
@@ -229,7 +232,7 @@ void MidiParser::onTimer() {
}
}
-void MidiParser::processEvent(const EventInfo &info, bool fireEvents) {
+bool MidiParser::processEvent(const EventInfo &info, bool fireEvents) {
if (info.event == 0xF0) {
// SysEx event
// Check for trailing 0xF7 -- if present, remove it.
@@ -252,8 +255,7 @@ void MidiParser::processEvent(const EventInfo &info, bool fireEvents) {
if (fireEvents)
_driver->metaEvent(info.ext.type, info.ext.data, (uint16)info.length);
}
- _abortParse = true;
- return;
+ return false;
} else if (info.ext.type == 0x51) {
if (info.length >= 3) {
setTempo(info.ext.data[0] << 16 | info.ext.data[1] << 8 | info.ext.data[2]);
@@ -265,6 +267,8 @@ void MidiParser::processEvent(const EventInfo &info, bool fireEvents) {
if (fireEvents)
sendToDriver(info.event, info.basic.param1, info.basic.param2);
}
+
+ return true;
}
diff --git a/audio/midiparser.h b/audio/midiparser.h
index 05d0cbe1db..9499d01512 100644
--- a/audio/midiparser.h
+++ b/audio/midiparser.h
@@ -294,7 +294,7 @@ protected:
virtual void resetTracking();
virtual void allNotesOff();
virtual void parseNextEvent(EventInfo &info) = 0;
- virtual void processEvent(const EventInfo &info, bool fireEvents = true);
+ virtual bool processEvent(const EventInfo &info, bool fireEvents = true);
void activeNote(byte channel, byte note, bool active);
void hangingNote(byte channel, byte note, uint32 ticksLeft, bool recycle = true);
diff --git a/audio/softsynth/eas.cpp b/audio/softsynth/eas.cpp
index ea79b25329..0631df2a7c 100644
--- a/audio/softsynth/eas.cpp
+++ b/audio/softsynth/eas.cpp
@@ -305,7 +305,7 @@ int MidiDriver_EAS::open() {
warning("error opening EAS dump file");
#endif
- g_system->getMixer()->playStream(Audio::Mixer::kMusicSoundType,
+ g_system->getMixer()->playStream(Audio::Mixer::kPlainSoundType,
&_soundHandle, this, -1,
Audio::Mixer::kMaxChannelVolume, 0,
DisposeAfterUse::NO, true);
diff --git a/audio/softsynth/fluidsynth.cpp b/audio/softsynth/fluidsynth.cpp
index efcf1be615..218a06ecc0 100644
--- a/audio/softsynth/fluidsynth.cpp
+++ b/audio/softsynth/fluidsynth.cpp
@@ -184,8 +184,7 @@ int MidiDriver_FluidSynth::open() {
MidiDriver_Emulated::open();
- // The MT-32 emulator uses kSFXSoundType here. I don't know why.
- _mixer->playStream(Audio::Mixer::kMusicSoundType, &_mixerSoundHandle, this, -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO, true);
+ _mixer->playStream(Audio::Mixer::kPlainSoundType, &_mixerSoundHandle, this, -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO, true);
return 0;
}
diff --git a/audio/softsynth/mt32.cpp b/audio/softsynth/mt32.cpp
index 29f5e3577c..7f46e926bc 100644
--- a/audio/softsynth/mt32.cpp
+++ b/audio/softsynth/mt32.cpp
@@ -80,15 +80,6 @@ protected:
void showLCDMessage(const char *message) {
g_system->displayMessageOnOSD(message);
}
- void onDeviceReset() {}
- void onDeviceReconfig() {}
- void onNewReverbMode(Bit8u /* mode */) {}
- void onNewReverbTime(Bit8u /* time */) {}
- void onNewReverbLevel(Bit8u /* level */) {}
- void onPartStateChanged(int /* partNum */, bool /* isActive */) {}
- void onPolyStateChanged(int /* partNum */) {}
- void onPartialStateChanged(int /* partialNum */, int /* oldPartialPhase */, int /* newPartialPhase */) {}
- void onProgramChanged(int /* partNum */, char * /* patchName */) {}
};
} // end of namespace MT32Emu
@@ -230,7 +221,7 @@ int MidiDriver_MT32::open() {
g_system->updateScreen();
- _mixer->playStream(Audio::Mixer::kSFXSoundType, &_mixerSoundHandle, this, -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO, true);
+ _mixer->playStream(Audio::Mixer::kPlainSoundType, &_mixerSoundHandle, this, -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO, true);
return 0;
}
@@ -460,9 +451,6 @@ bool MT32EmuMusicPlugin::checkDevice(MidiDriver::DeviceHandle) const {
}
Common::Error MT32EmuMusicPlugin::createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle) const {
- if (ConfMan.hasKey("extrapath"))
- SearchMan.addDirectory("extrapath", ConfMan.get("extrapath"));
-
*mididriver = new MidiDriver_MT32(g_system->getMixer());
return Common::kNoError;
diff --git a/backends/events/maemosdl/maemosdl-events.cpp b/backends/events/maemosdl/maemosdl-events.cpp
index dcdf0384e3..eaf2f48b60 100644
--- a/backends/events/maemosdl/maemosdl-events.cpp
+++ b/backends/events/maemosdl/maemosdl-events.cpp
@@ -188,7 +188,7 @@ bool MaemoSdlEventSource::handleMouseButtonUp(SDL_Event &ev, Common::Event &even
bool MaemoSdlEventSource::toggleClickMode() {
_clickEnabled = !_clickEnabled;
- ((SurfaceSdlGraphicsManager *) _graphicsManager)->displayMessageOnOSD(
+ _graphicsManager->displayMessageOnOSD(
_clickEnabled ? _("Clicking Enabled") : _("Clicking Disabled"));
return _clickEnabled;
diff --git a/backends/events/sdl/sdl-events.cpp b/backends/events/sdl/sdl-events.cpp
index e2ef7f6bf6..e84a8f8c01 100644
--- a/backends/events/sdl/sdl-events.cpp
+++ b/backends/events/sdl/sdl-events.cpp
@@ -391,8 +391,17 @@ bool SdlEventSource::dispatchSDLEvent(SDL_Event &ev, Common::Event &event) {
return false;
case SDL_VIDEORESIZE:
- if (_graphicsManager)
+ 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;
case SDL_QUIT:
diff --git a/backends/fs/amigaos4/amigaos4-fs.cpp b/backends/fs/amigaos4/amigaos4-fs.cpp
index fe388c2a6e..bd8bf1978a 100644
--- a/backends/fs/amigaos4/amigaos4-fs.cpp
+++ b/backends/fs/amigaos4/amigaos4-fs.cpp
@@ -81,6 +81,7 @@ AmigaOSFilesystemNode::AmigaOSFilesystemNode(const Common::String &p) {
_sDisplayName = ::lastPathComponent(_sPath);
_pFileLock = 0;
_bIsDirectory = false;
+ _bIsValid = false;
// Check whether the node exists and if it is a directory
struct ExamineData * pExd = IDOS->ExamineObjectTags(EX_StringNameInput,_sPath.c_str(),TAG_END);
@@ -305,12 +306,6 @@ bool AmigaOSFilesystemNode::getChildren(AbstractFSList &myList, ListMode mode, b
AbstractFSNode *AmigaOSFilesystemNode::getParent() const {
ENTER();
- if (!_bIsDirectory) {
- debug(6, "Not a directory");
- LEAVE();
- return 0;
- }
-
if (_pFileLock == 0) {
debug(6, "Root node");
LEAVE();
@@ -332,19 +327,25 @@ AbstractFSNode *AmigaOSFilesystemNode::getParent() const {
}
bool AmigaOSFilesystemNode::isReadable() const {
+ if (!_bIsValid)
+ return false;
+
// Regular RWED protection flags are low-active or inverted, thus the negation.
// moreover pseudo root filesystem (null _pFileLock) is readable whatever the
// protection says
- bool readable = !(_nProt & EXDF_READ) || _pFileLock == 0;
+ bool readable = !(_nProt & EXDF_OTR_READ) || _pFileLock == 0;
return readable;
}
bool AmigaOSFilesystemNode::isWritable() const {
+ if (!_bIsValid)
+ return false;
+
// Regular RWED protection flags are low-active or inverted, thus the negation.
// moreover pseudo root filesystem (null _pFileLock) is never writable whatever
// the protection says (because of the pseudo nature)
- bool writable = !(_nProt & EXDF_WRITE) && _pFileLock !=0;
+ bool writable = !(_nProt & EXDF_OTR_WRITE) && _pFileLock !=0;
return writable;
}
@@ -367,8 +368,14 @@ AbstractFSList AmigaOSFilesystemNode::listVolumes() const {
dosList = IDOS->NextDosEntry(dosList, LDF_VOLUMES);
while (dosList) {
if (dosList->dol_Type == DLT_VOLUME &&
- dosList->dol_Name &&
- dosList->dol_Task) {
+ dosList->dol_Name) {
+
+ // Original was
+ // 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.
// Copy name to buffer
IDOS->CopyStringBSTRToC(dosList->dol_Name, buffer, MAXPATHLEN);
diff --git a/backends/fs/amigaos4/amigaos4-fs.h b/backends/fs/amigaos4/amigaos4-fs.h
index c5ca61476f..7ce9981479 100644
--- a/backends/fs/amigaos4/amigaos4-fs.h
+++ b/backends/fs/amigaos4/amigaos4-fs.h
@@ -43,7 +43,13 @@
*/
class AmigaOSFilesystemNode : public AbstractFSNode {
protected:
+ /**
+ * The main file lock.
+ * If this is NULL but _bIsValid is true, then this Node references
+ * the virtual filesystem root.
+ */
BPTR _pFileLock;
+
Common::String _sDisplayName;
Common::String _sPath;
bool _bIsDirectory;
diff --git a/backends/fs/wii/wii-fs-factory.cpp b/backends/fs/wii/wii-fs-factory.cpp
index 760e5316e7..f234c1e300 100644
--- a/backends/fs/wii/wii-fs-factory.cpp
+++ b/backends/fs/wii/wii-fs-factory.cpp
@@ -33,6 +33,9 @@
#ifdef USE_WII_DI
#include <di/di.h>
#include <iso9660.h>
+#ifdef GAMECUBE
+#include <ogc/dvd.h>
+#endif
#endif
#ifdef USE_WII_SMB
@@ -125,6 +128,14 @@ bool WiiFilesystemFactory::failedToMount(FileSystemType type) {
return false;
}
+#ifdef USE_WII_DI
+#ifndef GAMECUBE
+ const DISC_INTERFACE* dvd = &__io_wiidvd;
+#else
+ const DISC_INTERFACE* dvd = &__io_gcdvd;
+#endif
+#endif
+
void WiiFilesystemFactory::mount(FileSystemType type) {
switch (type) {
case kDVD:
@@ -133,7 +144,7 @@ void WiiFilesystemFactory::mount(FileSystemType type) {
break;
printf("mount dvd\n");
- if (ISO9660_Mount()) {
+ if (ISO9660_Mount("dvd", dvd)) {
_dvdMounted = true;
_dvdError = false;
printf("ISO9660 mounted\n");
@@ -179,7 +190,7 @@ void WiiFilesystemFactory::umount(FileSystemType type) {
printf("umount dvd\n");
- ISO9660_Unmount();
+ ISO9660_Unmount("dvd:");
_dvdMounted = false;
_dvdError = false;
diff --git a/backends/fs/wii/wii-fs.cpp b/backends/fs/wii/wii-fs.cpp
index 4a19e18240..43f4f592b7 100644
--- a/backends/fs/wii/wii-fs.cpp
+++ b/backends/fs/wii/wii-fs.cpp
@@ -80,9 +80,9 @@ void WiiFilesystemNode::clearFlags() {
void WiiFilesystemNode::setFlags(const struct stat *st) {
_exists = true;
- _isDirectory = S_ISDIR(st->st_mode);
- _isReadable = (st->st_mode & S_IRUSR) > 0;
- _isWritable = (st->st_mode & S_IWUSR) > 0;
+ _isDirectory = ( (st->st_mode & S_IFDIR) != 0 );
+ _isReadable = ( (st->st_mode & S_IRUSR) != 0 );
+ _isWritable = ( (st->st_mode & S_IWUSR) != 0 );
}
WiiFilesystemNode::WiiFilesystemNode() {
@@ -106,7 +106,7 @@ WiiFilesystemNode::WiiFilesystemNode(const Common::String &p) {
_displayName = lastPathComponent(_path, '/');
struct stat st;
- if (!stat(_path.c_str(), &st))
+ if(stat(_path.c_str(), &st) != -1)
setFlags(&st);
else
clearFlags();
@@ -152,33 +152,45 @@ bool WiiFilesystemNode::getChildren(AbstractFSList &list, ListMode mode, bool hi
if (_path.empty())
return getDevopChildren(list, mode, hidden);
- DIR_ITER* dp = diropen (_path.c_str());
+ DIR* dp = opendir (_path.c_str());
+ DIR* tmpdir;
if (dp == NULL)
return false;
- char filename[MAXPATHLEN];
- struct stat st;
+ struct dirent *pent;
- while (dirnext(dp, filename, &st) == 0) {
- if (strcmp(filename, ".") == 0 || strcmp(filename, "..") == 0)
+ while ((pent = readdir(dp)) != NULL) {
+ if (strcmp(pent->d_name, ".") == 0 || strcmp(pent->d_name, "..") == 0)
continue;
Common::String newPath(_path);
if (newPath.lastChar() != '/')
- newPath += '/';
- newPath += filename;
-
- bool isDir = S_ISDIR(st.st_mode);
-
+ newPath += '/';
+ newPath += pent->d_name;
+
+ bool isDir = false;
+ tmpdir = opendir(newPath.c_str());
+ if(tmpdir)
+ {
+ isDir = true;
+ closedir(tmpdir);
+ }
+
if ((mode == Common::FSNode::kListFilesOnly && isDir) ||
(mode == Common::FSNode::kListDirectoriesOnly && !isDir))
continue;
-
+
+ struct stat st;
+ st.st_mode = 0;
+ st.st_mode |= ( isDir ? S_IFDIR : 0 );
+ st.st_mode |= S_IRUSR;
+ st.st_mode |= S_IWUSR;
+
list.push_back(new WiiFilesystemNode(newPath, &st));
}
- dirclose(dp);
+ closedir(dp);
return true;
}
diff --git a/backends/fs/wii/wii-fs.h b/backends/fs/wii/wii-fs.h
index 11679d0c36..f785101099 100644
--- a/backends/fs/wii/wii-fs.h
+++ b/backends/fs/wii/wii-fs.h
@@ -51,7 +51,7 @@ public:
*
* @param path Common::String with the path the new node should point to.
*/
- WiiFilesystemNode(const Common::String &path);
+ WiiFilesystemNode(const Common::String &p);
WiiFilesystemNode(const Common::String &p, const struct stat *st);
virtual bool exists() const;
diff --git a/backends/graphics/opengl/debug.cpp b/backends/graphics/opengl/debug.cpp
new file mode 100644
index 0000000000..d5d73fb5ec
--- /dev/null
+++ b/backends/graphics/opengl/debug.cpp
@@ -0,0 +1,65 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "backends/graphics/opengl/debug.h"
+#include "backends/graphics/opengl/opengl-sys.h"
+
+#include "common/str.h"
+#include "common/textconsole.h"
+
+#ifdef OPENGL_DEBUG
+
+namespace OpenGL {
+
+namespace {
+Common::String getGLErrStr(GLenum error) {
+ switch (error) {
+ case GL_INVALID_ENUM:
+ return "GL_INVALID_ENUM";
+ case GL_INVALID_VALUE:
+ return "GL_INVALID_VALUE";
+ case GL_INVALID_OPERATION:
+ return "GL_INVALID_OPERATION";
+ case GL_STACK_OVERFLOW:
+ return "GL_STACK_OVERFLOW";
+ case GL_STACK_UNDERFLOW:
+ return "GL_STACK_UNDERFLOW";
+ case GL_OUT_OF_MEMORY:
+ return "GL_OUT_OF_MEMORY";
+ }
+
+ return Common::String::format("(Unknown GL error code 0x%X)", error);
+}
+} // End of anonymous namespace
+
+void checkGLError(const char *expr, const char *file, int line) {
+ GLenum error;
+
+ while ((error = glGetError()) != GL_NO_ERROR) {
+ // We cannot use error here because we do not know whether we have a
+ // working screen or not.
+ warning("GL ERROR: %s on %s (%s:%d)", getGLErrStr(error).c_str(), expr, file, line);
+ }
+}
+} // End of namespace OpenGL
+
+#endif
diff --git a/backends/graphics/opengl/debug.h b/backends/graphics/opengl/debug.h
new file mode 100644
index 0000000000..ff6b678870
--- /dev/null
+++ b/backends/graphics/opengl/debug.h
@@ -0,0 +1,39 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public 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_GRAPHICS_OPENGL_DEBUG_H
+#define BACKENDS_GRAPHICS_OPENGL_DEBUG_H
+
+#define OPENGL_DEBUG
+
+#ifdef OPENGL_DEBUG
+
+namespace OpenGL {
+void checkGLError(const char *expr, const char *file, int line);
+} // End of namespace OpenGL
+
+#define GLCALL(x) do { (x); OpenGL::checkGLError(#x, __FILE__, __LINE__); } while (false)
+#else
+#define GLCALL(x) do { (x); } while (false)
+#endif
+
+#endif
diff --git a/backends/graphics/opengl/extensions.cpp b/backends/graphics/opengl/extensions.cpp
new file mode 100644
index 0000000000..4482ef82b5
--- /dev/null
+++ b/backends/graphics/opengl/extensions.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 "backends/graphics/opengl/extensions.h"
+#include "backends/graphics/opengl/opengl-sys.h"
+
+#include "common/tokenizer.h"
+
+namespace OpenGL {
+
+bool g_extNPOTSupported = false;
+
+void initializeGLExtensions() {
+ const char *extString = (const char *)glGetString(GL_EXTENSIONS);
+
+ // Initialize default state.
+ g_extNPOTSupported = false;
+
+ Common::StringTokenizer tokenizer(extString, " ");
+ while (!tokenizer.empty()) {
+ Common::String token = tokenizer.nextToken();
+
+ if (token == "GL_ARB_texture_non_power_of_two") {
+ g_extNPOTSupported = true;
+ }
+ }
+}
+
+} // End of namespace OpenGL
diff --git a/backends/graphics/opengl/extensions.h b/backends/graphics/opengl/extensions.h
new file mode 100644
index 0000000000..87452429e2
--- /dev/null
+++ b/backends/graphics/opengl/extensions.h
@@ -0,0 +1,41 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef BACKENDS_GRAPHICS_OPENGL_EXTENSIONS_H
+#define BACKENDS_GRAPHICS_OPENGL_EXTENSIONS_H
+
+namespace OpenGL {
+
+/**
+ * Checks for availability of extensions we want to use and initializes them
+ * when available.
+ */
+void initializeGLExtensions();
+
+/**
+ * Whether non power of two textures are supported
+ */
+extern bool g_extNPOTSupported;
+
+} // End of namespace OpenGL
+
+#endif
diff --git a/backends/graphics/opengl/gltexture.cpp b/backends/graphics/opengl/gltexture.cpp
deleted file mode 100644
index ca674563df..0000000000
--- a/backends/graphics/opengl/gltexture.cpp
+++ /dev/null
@@ -1,225 +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"
-
-#if defined(USE_OPENGL)
-
-#include "backends/graphics/opengl/gltexture.h"
-#include "backends/graphics/opengl/glerrorcheck.h"
-
-#include "common/rect.h"
-#include "common/array.h"
-#include "common/util.h"
-#include "common/tokenizer.h"
-
-// Supported GL extensions
-static bool npot_supported = false;
-static bool glext_inited = false;
-
-/*static inline GLint xdiv(int numerator, int denominator) {
- assert(numerator < (1 << 16));
- return (numerator << 16) / denominator;
-}*/
-
-static GLuint nextHigher2(GLuint v) {
- if (v == 0)
- return 1;
- v--;
- v |= v >> 1;
- v |= v >> 2;
- v |= v >> 4;
- v |= v >> 8;
- v |= v >> 16;
- return ++v;
-}
-
-void GLTexture::initGLExtensions() {
-
- // Return if extensions were already checked
- if (glext_inited)
- return;
-
- // Get a string with all extensions
- const char *ext_string = (const char *)glGetString(GL_EXTENSIONS);
- CHECK_GL_ERROR();
- Common::StringTokenizer tokenizer(ext_string, " ");
- // Iterate all string tokens
- while (!tokenizer.empty()) {
- Common::String token = tokenizer.nextToken();
- if (token == "GL_ARB_texture_non_power_of_two")
- npot_supported = true;
- }
-
- glext_inited = true;
-}
-
-GLTexture::GLTexture(byte bpp, GLenum internalFormat, GLenum format, GLenum type)
- :
- _bytesPerPixel(bpp),
- _internalFormat(internalFormat),
- _glFormat(format),
- _glType(type),
- _textureWidth(0),
- _textureHeight(0),
- _realWidth(0),
- _realHeight(0),
- _refresh(false),
- _filter(GL_NEAREST) {
-
- // Generate the texture ID
- glGenTextures(1, &_textureName); CHECK_GL_ERROR();
-}
-
-GLTexture::~GLTexture() {
- // Delete the texture
- glDeleteTextures(1, &_textureName); CHECK_GL_ERROR();
-}
-
-void GLTexture::refresh() {
- // Delete previous texture
- glDeleteTextures(1, &_textureName); CHECK_GL_ERROR();
-
- // Generate the texture ID
- glGenTextures(1, &_textureName); CHECK_GL_ERROR();
- _refresh = true;
-}
-
-void GLTexture::allocBuffer(GLuint w, GLuint h) {
- _realWidth = w;
- _realHeight = h;
-
- if (!_refresh) {
- if (npot_supported && _filter == GL_LINEAR) {
- // Check if we already allocated a correctly-sized buffer
- // This is so we don't need to duplicate the last row/column
- if (w == _textureWidth && h == _textureHeight)
- return;
- } else {
- // Check if we already have a large enough buffer
- if (w <= _textureWidth && h <= _textureHeight)
- return;
- }
- }
-
- if (npot_supported) {
- _textureWidth = w;
- _textureHeight = h;
- } else {
- _textureWidth = nextHigher2(w);
- _textureHeight = nextHigher2(h);
- }
-
- // Select this OpenGL texture
- glBindTexture(GL_TEXTURE_2D, _textureName); CHECK_GL_ERROR();
-
- // Set the texture parameters
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, _filter); CHECK_GL_ERROR();
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, _filter); CHECK_GL_ERROR();
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); CHECK_GL_ERROR();
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); CHECK_GL_ERROR();
-
- // Allocate room for the texture
- glTexImage2D(GL_TEXTURE_2D, 0, _internalFormat,
- _textureWidth, _textureHeight, 0, _glFormat, _glType, NULL); CHECK_GL_ERROR();
-
- _refresh = false;
-}
-
-void GLTexture::updateBuffer(const void *buf, int pitch, GLuint x, GLuint y, GLuint w, GLuint h) {
- // Skip empty updates.
- if (w * h == 0)
- return;
-
- // Select this OpenGL texture
- glBindTexture(GL_TEXTURE_2D, _textureName); CHECK_GL_ERROR();
-
- // Check if the buffer has its data contiguously
- if ((int)w * _bytesPerPixel == pitch) {
- glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, w, h,
- _glFormat, _glType, buf); CHECK_GL_ERROR();
- } else {
- // Update the texture row by row
- const byte *src = (const byte *)buf;
- GLuint curY = y;
- GLuint height = h;
- do {
- glTexSubImage2D(GL_TEXTURE_2D, 0, x, curY,
- w, 1, _glFormat, _glType, src); CHECK_GL_ERROR();
- curY++;
- src += pitch;
- } while (--height);
- }
-
- // If we're in linear filter mode, repeat the last row/column if the real dimensions
- // doesn't match the texture dimensions.
- if (_filter == GL_LINEAR) {
- if (_realWidth != _textureWidth && x + w == _realWidth) {
- const byte *src = (const byte *)buf + (w - 1) * _bytesPerPixel;
- GLuint curY = y;
- GLuint height = h;
-
- do {
- glTexSubImage2D(GL_TEXTURE_2D, 0, x + w,
- curY, 1, 1, _glFormat, _glType, src); CHECK_GL_ERROR();
-
- curY++;
- src += pitch;
- } while (--height);
- }
-
- if (_realHeight != _textureHeight && y + h == _realHeight) {
- glTexSubImage2D(GL_TEXTURE_2D, 0, x, y + h,
- w, 1, _glFormat, _glType, (const byte *)buf + pitch * (h - 1)); CHECK_GL_ERROR();
- }
- }
-}
-
-void GLTexture::drawTexture(GLshort x, GLshort y, GLshort w, GLshort h) {
- // Select this OpenGL texture
- glBindTexture(GL_TEXTURE_2D, _textureName); CHECK_GL_ERROR();
-
- // Calculate the texture rect that will be drawn
- const GLfloat texWidth = (GLfloat)_realWidth / _textureWidth;//xdiv(_surface.w, _textureWidth);
- const GLfloat texHeight = (GLfloat)_realHeight / _textureHeight;//xdiv(_surface.h, _textureHeight);
- const GLfloat texcoords[] = {
- 0, 0,
- texWidth, 0,
- 0, texHeight,
- texWidth, texHeight,
- };
- glTexCoordPointer(2, GL_FLOAT, 0, texcoords); CHECK_GL_ERROR();
-
- // Calculate the screen rect where the texture will be drawn
- const GLshort vertices[] = {
- x, y,
- (GLshort)(x + w), y,
- x, (GLshort)(y + h),
- (GLshort)(x + w), (GLshort)(y + h),
- };
- glVertexPointer(2, GL_SHORT, 0, vertices); CHECK_GL_ERROR();
-
- // Draw the texture to the screen buffer
- glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); CHECK_GL_ERROR();
-}
-
-#endif
diff --git a/backends/graphics/opengl/gltexture.h b/backends/graphics/opengl/gltexture.h
deleted file mode 100644
index 6ef80923ae..0000000000
--- a/backends/graphics/opengl/gltexture.h
+++ /dev/null
@@ -1,131 +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 BACKENDS_GRAPHICS_OPENGL_GLTEXTURE_H
-#define BACKENDS_GRAPHICS_OPENGL_GLTEXTURE_H
-
-#include "common/scummsys.h"
-
-#ifdef WIN32
-#if defined(ARRAYSIZE) && !defined(_WINDOWS_)
-#undef ARRAYSIZE
-#endif
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
-#undef ARRAYSIZE
-#endif
-
-// HACK: At this point in Windows platforms, common/util.h has been included
-// via common/rect.h (from backends/graphics/sdl/sdl-graphics.h), via
-// backends/graphics/openglsdl/openglsdl-graphics.h. Thus, we end up with
-// COMMON_UTIL_H defined, and ARRAYSIZE undefined (bad!). Therefore,
-// ARRAYSIZE is undefined in openglsdl-graphics.cpp. This is a temporary
-// hackish solution fo fix compilation under Windows.
-#if !defined(ARRAYSIZE) && defined(COMMON_UTIL_H)
-#define ARRAYSIZE(x) ((int)(sizeof(x) / sizeof(x[0])))
-#endif
-
-#if defined(TIZEN)
-#include <FGraphicsOpengl.h>
-using namespace Tizen::Graphics::Opengl;
-#elif defined(USE_GLES)
-#include <GLES/gl.h>
-#elif defined(SDL_BACKEND)
-#include <SDL_opengl.h>
-#else
-#include <GL/gl.h>
-#endif
-
-#include "graphics/surface.h"
-
-/**
- * OpenGL texture manager class
- */
-class GLTexture {
-public:
- /**
- * Initialize OpenGL Extensions
- */
- static void initGLExtensions();
-
- GLTexture(byte bpp, GLenum internalFormat, GLenum format, GLenum type);
- ~GLTexture();
-
- /**
- * Refresh the texture after a context change. The
- * process will be completed on next allocBuffer call.
- */
- void refresh();
-
- /**
- * Allocates memory needed for the given size.
- */
- void allocBuffer(GLuint width, GLuint height);
-
- /**
- * Updates the texture pixels.
- */
- void updateBuffer(const void *buf, int pitch, GLuint x, GLuint y,
- GLuint w, GLuint h);
-
- /**
- * Draws the texture to the screen buffer.
- */
- void drawTexture(GLshort x, GLshort y, GLshort w, GLshort h);
-
- /**
- * Get the texture width.
- */
- GLuint getWidth() const { return _realWidth; }
-
- /**
- * Get the texture height.
- */
- GLuint getHeight() const { return _realHeight; }
-
- /**
- * Get the bytes per pixel.
- */
- uint getBytesPerPixel() const { return _bytesPerPixel; }
-
- /**
- * Set the texture filter.
- * @filter the filter type, GL_NEAREST or GL_LINEAR
- */
- void setFilter(GLint filter) { _filter = filter; }
-
-private:
- const byte _bytesPerPixel;
- const GLenum _internalFormat;
- const GLenum _glFormat;
- const GLenum _glType;
-
- GLuint _realWidth;
- GLuint _realHeight;
- GLuint _textureName;
- GLuint _textureWidth;
- GLuint _textureHeight;
- GLint _filter;
- bool _refresh;
-};
-
-#endif
diff --git a/backends/graphics/opengl/opengl-graphics.cpp b/backends/graphics/opengl/opengl-graphics.cpp
index 84be83d524..a97f680f15 100644
--- a/backends/graphics/opengl/opengl-graphics.cpp
+++ b/backends/graphics/opengl/opengl-graphics.cpp
@@ -8,102 +8,90 @@
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
-
+ *
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-
+ *
* You should have received a copy of the GNU General Public 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"
-
-#if defined(USE_OPENGL)
#include "backends/graphics/opengl/opengl-graphics.h"
-#include "backends/graphics/opengl/glerrorcheck.h"
-#include "common/config-manager.h"
-#include "common/file.h"
-#include "common/mutex.h"
+#include "backends/graphics/opengl/texture.h"
+#include "backends/graphics/opengl/debug.h"
+#include "backends/graphics/opengl/extensions.h"
+
#include "common/textconsole.h"
#include "common/translation.h"
+#include "common/algorithm.h"
+#include "common/file.h"
#ifdef USE_OSD
#include "common/tokenizer.h"
+#include "common/rect.h"
#endif
-#include "graphics/font.h"
+
+#include "graphics/conversion.h"
+#ifdef USE_OSD
#include "graphics/fontman.h"
+#include "graphics/font.h"
+#endif
+
+namespace OpenGL {
OpenGLGraphicsManager::OpenGLGraphicsManager()
- :
+ : _currentState(), _oldState(), _transactionMode(kTransactionNone), _screenChangeID(1 << (sizeof(int) * 8 - 2)),
+ _outputScreenWidth(0), _outputScreenHeight(0), _displayX(0), _displayY(0),
+ _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)
#ifdef USE_OSD
- _osdTexture(0), _osdAlpha(0), _osdFadeStartTime(0), _requireOSDUpdate(false),
+ , _osdAlpha(0), _osdFadeStartTime(0), _osd(nullptr)
#endif
- _gameTexture(0), _overlayTexture(0), _cursorTexture(0),
- _screenChangeCount(1 << (sizeof(int) * 8 - 2)), _screenNeedsRedraw(false),
- _shakePos(0),
- _overlayVisible(false), _overlayNeedsRedraw(false),
- _transactionMode(kTransactionNone),
- _cursorNeedsRedraw(false), _cursorPaletteDisabled(true),
- _cursorVisible(false), _cursorKeyColor(0),
- _cursorDontScale(false),
- _formatBGR(false),
- _displayX(0), _displayY(0), _displayWidth(0), _displayHeight(0) {
-
- memset(&_oldVideoMode, 0, sizeof(_oldVideoMode));
- memset(&_videoMode, 0, sizeof(_videoMode));
- memset(&_transactionDetails, 0, sizeof(_transactionDetails));
-
- _videoMode.mode = OpenGL::GFX_NORMAL;
- _videoMode.scaleFactor = 2;
- _videoMode.fullscreen = ConfMan.getBool("fullscreen");
- _videoMode.antialiasing = false;
-
- _gamePalette = (byte *)calloc(sizeof(byte) * 3, 256);
- _cursorPalette = (byte *)calloc(sizeof(byte) * 3, 256);
+ {
+ memset(_gamePalette, 0, sizeof(_gamePalette));
}
OpenGLGraphicsManager::~OpenGLGraphicsManager() {
- free(_gamePalette);
- free(_cursorPalette);
-
- _screenData.free();
- _overlayData.free();
- _cursorData.free();
- _osdSurface.free();
-
- delete _gameTexture;
- delete _overlayTexture;
- delete _cursorTexture;
+ delete _gameScreen;
+ delete _overlay;
+ delete _cursor;
+#ifdef USE_OSD
+ delete _osd;
+#endif
}
-//
-// Feature
-//
-
bool OpenGLGraphicsManager::hasFeature(OSystem::Feature f) {
- return
- (f == OSystem::kFeatureAspectRatioCorrection) ||
- (f == OSystem::kFeatureCursorPalette);
+ switch (f) {
+ case OSystem::kFeatureAspectRatioCorrection:
+ case OSystem::kFeatureCursorPalette:
+ return true;
+
+ case OSystem::kFeatureOverlaySupportsAlpha:
+ return _defaultFormatAlpha.aBits() > 3;
+
+ default:
+ return false;
+ }
}
void OpenGLGraphicsManager::setFeatureState(OSystem::Feature f, bool enable) {
switch (f) {
- case OSystem::kFeatureFullscreenMode:
- setFullscreenMode(enable);
- break;
-
case OSystem::kFeatureAspectRatioCorrection:
- _videoMode.aspectRatioCorrection = enable;
- _transactionDetails.needRefresh = true;
+ assert(_transactionMode != kTransactionNone);
+ _currentState.aspectRatioCorrection = enable;
break;
case OSystem::kFeatureCursorPalette:
- _cursorPaletteDisabled = !enable;
- _cursorNeedsRedraw = true;
+ _cursorPaletteEnabled = enable;
+ updateCursorPalette();
break;
default:
@@ -113,1189 +101,1013 @@ void OpenGLGraphicsManager::setFeatureState(OSystem::Feature f, bool enable) {
bool OpenGLGraphicsManager::getFeatureState(OSystem::Feature f) {
switch (f) {
- case OSystem::kFeatureFullscreenMode:
- return _videoMode.fullscreen;
-
case OSystem::kFeatureAspectRatioCorrection:
- return _videoMode.aspectRatioCorrection;
+ return _currentState.aspectRatioCorrection;
case OSystem::kFeatureCursorPalette:
- return !_cursorPaletteDisabled;
+ return _cursorPaletteEnabled;
default:
return false;
}
}
-//
-// Screen format and modes
-//
+namespace {
-static const OSystem::GraphicsMode s_supportedGraphicsModes[] = {
- {"gl1", _s("OpenGL Normal"), OpenGL::GFX_NORMAL},
- {"gl2", _s("OpenGL Conserve"), OpenGL::GFX_CONSERVE},
- {"gl4", _s("OpenGL Original"), OpenGL::GFX_ORIGINAL},
- {0, 0, 0}
+const OSystem::GraphicsMode glGraphicsModes[] = {
+ { "opengl_linear", _s("OpenGL"), GFX_LINEAR },
+ { "opengl_nearest", _s("OpenGL (No filtering)"), GFX_NEAREST },
+ { nullptr, nullptr, 0 }
};
-const OSystem::GraphicsMode *OpenGLGraphicsManager::supportedGraphicsModes() {
- return s_supportedGraphicsModes;
-}
+} // End of anonymous namespace
const OSystem::GraphicsMode *OpenGLGraphicsManager::getSupportedGraphicsModes() const {
- return s_supportedGraphicsModes;
+ return glGraphicsModes;
}
int OpenGLGraphicsManager::getDefaultGraphicsMode() const {
- return OpenGL::GFX_NORMAL;
+ return GFX_LINEAR;
}
bool OpenGLGraphicsManager::setGraphicsMode(int mode) {
- assert(_transactionMode == kTransactionActive);
+ assert(_transactionMode != kTransactionNone);
+
+ switch (mode) {
+ case GFX_LINEAR:
+ case GFX_NEAREST:
+ _currentState.graphicsMode = mode;
+
+ if (_gameScreen) {
+ _gameScreen->enableLinearFiltering(mode == GFX_LINEAR);
+ }
- setScale(2);
+ if (_cursor) {
+ _cursor->enableLinearFiltering(mode == GFX_LINEAR);
+ }
- if (_oldVideoMode.setup && _oldVideoMode.mode == mode)
return true;
- switch (mode) {
- case OpenGL::GFX_NORMAL:
- case OpenGL::GFX_CONSERVE:
- case OpenGL::GFX_ORIGINAL:
- break;
default:
- warning("Unknown gfx mode %d", mode);
+ warning("OpenGLGraphicsManager::setGraphicsMode(%d): Unknown graphics mode", mode);
return false;
}
-
- _videoMode.mode = mode;
- _transactionDetails.needRefresh = true;
-
- return true;
}
int OpenGLGraphicsManager::getGraphicsMode() const {
- assert(_transactionMode == kTransactionNone);
- return _videoMode.mode;
-}
-
-void OpenGLGraphicsManager::resetGraphicsScale() {
- setScale(1);
+ return _currentState.graphicsMode;
}
#ifdef USE_RGB_COLOR
Graphics::PixelFormat OpenGLGraphicsManager::getScreenFormat() const {
- return _screenFormat;
+ return _currentState.gameFormat;
}
#endif
-void OpenGLGraphicsManager::initSize(uint width, uint height, const Graphics::PixelFormat *format) {
- assert(_transactionMode == kTransactionActive);
-
-#ifdef USE_RGB_COLOR
- Graphics::PixelFormat newFormat;
- if (!format)
- newFormat = Graphics::PixelFormat::createFormatCLUT8();
- else
- newFormat = *format;
-
- assert(newFormat.bytesPerPixel > 0);
-
- // Avoid redundant format changes
- if (newFormat != _videoMode.format) {
- _videoMode.format = newFormat;
- _transactionDetails.formatChanged = true;
- _screenFormat = newFormat;
- }
-#endif
-
- // Avoid redundant res changes
- if ((int)width == _videoMode.screenWidth && (int)height == _videoMode.screenHeight)
- return;
-
- _videoMode.screenWidth = width;
- _videoMode.screenHeight = height;
-
- _transactionDetails.sizeChanged = true;
-}
-
-int OpenGLGraphicsManager::getScreenChangeID() const {
- return _screenChangeCount;
-}
-
-//
-// GFX
-//
-
void OpenGLGraphicsManager::beginGFXTransaction() {
assert(_transactionMode == kTransactionNone);
+ // Start a transaction.
+ _oldState = _currentState;
_transactionMode = kTransactionActive;
- _transactionDetails.sizeChanged = false;
- _transactionDetails.needRefresh = false;
- _transactionDetails.needUpdatescreen = false;
- _transactionDetails.filterChanged = false;
-#ifdef USE_RGB_COLOR
- _transactionDetails.formatChanged = false;
-#endif
-
- _oldVideoMode = _videoMode;
}
OSystem::TransactionError OpenGLGraphicsManager::endGFXTransaction() {
- int errors = OSystem::kTransactionSuccess;
+ assert(_transactionMode == kTransactionActive);
- assert(_transactionMode != kTransactionNone);
+ uint transactionError = OSystem::kTransactionSuccess;
+
+ bool setupNewGameScreen = false;
+ if ( _oldState.gameWidth != _currentState.gameWidth
+ || _oldState.gameHeight != _currentState.gameHeight) {
+ setupNewGameScreen = true;
+ }
- if (_transactionMode == kTransactionRollback) {
- if (_videoMode.fullscreen != _oldVideoMode.fullscreen) {
- errors |= OSystem::kTransactionFullscreenFailed;
+#ifdef USE_RGB_COLOR
+ if (_oldState.gameFormat != _currentState.gameFormat) {
+ setupNewGameScreen = true;
+ }
+
+ // Check whether the requested format can actually be used.
+ Common::List<Graphics::PixelFormat> supportedFormats = getSupportedFormats();
+ // In case the requested format is not usable we will fall back to CLUT8.
+ if (Common::find(supportedFormats.begin(), supportedFormats.end(), _currentState.gameFormat) == supportedFormats.end()) {
+ _currentState.gameFormat = Graphics::PixelFormat::createFormatCLUT8();
+ transactionError |= OSystem::kTransactionFormatNotSupported;
+ }
+#endif
- _videoMode.fullscreen = _oldVideoMode.fullscreen;
- } else if (_videoMode.mode != _oldVideoMode.mode) {
- errors |= OSystem::kTransactionModeSwitchFailed;
+ do {
+ uint requestedWidth = _currentState.gameWidth;
+ uint requestedHeight = _currentState.gameHeight;
+ const uint desiredAspect = getDesiredGameScreenAspect();
+ requestedHeight = intToFrac(requestedWidth) / desiredAspect;
- _videoMode.mode = _oldVideoMode.mode;
- _videoMode.scaleFactor = _oldVideoMode.scaleFactor;
+ if (!loadVideoMode(requestedWidth, requestedHeight,
#ifdef USE_RGB_COLOR
- } else if (_videoMode.format != _oldVideoMode.format) {
- errors |= OSystem::kTransactionFormatNotSupported;
+ _currentState.gameFormat
+#else
+ Graphics::PixelFormat::createFormatCLUT8()
+#endif
+ )
+ // HACK: This is really nasty but we don't have any guarantees of
+ // a context existing before, which means we don't know the maximum
+ // supported texture size before this. Thus, we check whether the
+ // requested game resolution is supported over here.
+ || ( _currentState.gameWidth > (uint)Texture::getMaximumTextureSize()
+ || _currentState.gameHeight > (uint)Texture::getMaximumTextureSize())) {
+ if (_transactionMode == kTransactionActive) {
+ // Try to setup the old state in case its valid and is
+ // actually different from the new one.
+ if (_oldState.valid && _oldState != _currentState) {
+ // Give some hints on what failed to set up.
+ if ( _oldState.gameWidth != _currentState.gameWidth
+ || _oldState.gameHeight != _currentState.gameHeight) {
+ transactionError |= OSystem::kTransactionSizeChangeFailed;
+ }
- _videoMode.format = _oldVideoMode.format;
- _screenFormat = _videoMode.format;
+#ifdef USE_RGB_COLOR
+ if (_oldState.gameFormat != _currentState.gameFormat) {
+ transactionError |= OSystem::kTransactionFormatNotSupported;
+ }
#endif
- } else if (_videoMode.screenWidth != _oldVideoMode.screenWidth || _videoMode.screenHeight != _oldVideoMode.screenHeight) {
- errors |= OSystem::kTransactionSizeChangeFailed;
- _videoMode.screenWidth = _oldVideoMode.screenWidth;
- _videoMode.screenHeight = _oldVideoMode.screenHeight;
- _videoMode.overlayWidth = _oldVideoMode.overlayWidth;
- _videoMode.overlayHeight = _oldVideoMode.overlayHeight;
- }
+ if (_oldState.aspectRatioCorrection != _currentState.aspectRatioCorrection) {
+ transactionError |= OSystem::kTransactionAspectRatioFailed;
+ }
- if (_videoMode.fullscreen == _oldVideoMode.fullscreen &&
- _videoMode.mode == _oldVideoMode.mode &&
- _videoMode.screenWidth == _oldVideoMode.screenWidth &&
- _videoMode.screenHeight == _oldVideoMode.screenHeight) {
+ if (_oldState.graphicsMode != _currentState.graphicsMode) {
+ transactionError |= OSystem::kTransactionModeSwitchFailed;
+ }
- _oldVideoMode.setup = false;
- }
- }
+ // Roll back to the old state.
+ _currentState = _oldState;
+ _transactionMode = kTransactionRollback;
- if (_transactionDetails.sizeChanged || _transactionDetails.needRefresh) {
- unloadGFXMode();
- if (!loadGFXMode()) {
- if (_oldVideoMode.setup) {
- _transactionMode = kTransactionRollback;
- errors |= endGFXTransaction();
+ // Try to set up the old state.
+ continue;
+ }
}
- } else {
- clearOverlay();
- _videoMode.setup = true;
- _screenChangeCount++;
+ // DON'T use error(), as this tries to bring up the debug
+ // console, which WON'T WORK now that we might no have a
+ // proper screen.
+ warning("OpenGLGraphicsManager::endGFXTransaction: Could not load any graphics mode!");
+ g_system->quit();
}
+
+ // In case we reach this we have a valid state, yay.
+ _transactionMode = kTransactionNone;
+ _currentState.valid = true;
+ } while (_transactionMode == kTransactionRollback);
+
+ if (setupNewGameScreen) {
+ delete _gameScreen;
+ _gameScreen = nullptr;
+
+ GLenum glIntFormat, glFormat, glType;
#ifdef USE_RGB_COLOR
- } else if (_transactionDetails.filterChanged || _transactionDetails.formatChanged) {
-#else
- } else if (_transactionDetails.filterChanged) {
+ if (_currentState.gameFormat.bytesPerPixel == 1) {
#endif
- loadTextures();
- internUpdateScreen();
- } else if (_transactionDetails.needUpdatescreen) {
- internUpdateScreen();
+ const bool supported = getGLPixelFormat(_defaultFormat, glIntFormat, glFormat, glType);
+ assert(supported);
+ _gameScreen = new TextureCLUT8(glIntFormat, glFormat, glType, _defaultFormat);
+ _gameScreen->setPalette(0, 255, _gamePalette);
+#ifdef USE_RGB_COLOR
+ } else {
+ const bool supported = getGLPixelFormat(_currentState.gameFormat, glIntFormat, glFormat, glType);
+ assert(supported);
+ _gameScreen = new Texture(glIntFormat, glFormat, glType, _currentState.gameFormat);
+ }
+#endif
+
+ _gameScreen->allocate(_currentState.gameWidth, _currentState.gameHeight);
+ _gameScreen->enableLinearFiltering(_currentState.graphicsMode == GFX_LINEAR);
+ // We fill the screen to all black or index 0 for CLUT8.
+ if (_currentState.gameFormat.bytesPerPixel == 1) {
+ _gameScreen->fill(0);
+ } else {
+ _gameScreen->fill(_gameScreen->getSurface()->format.RGBToColor(0, 0, 0));
+ }
}
- _transactionMode = kTransactionNone;
- return (OSystem::TransactionError)errors;
-}
+ // Update our display area and cursor scaling. This makes sure we pick up
+ // aspect ratio correction and game screen changes correctly.
+ recalculateDisplayArea();
+ recalculateCursorScaling();
-//
-// Screen
-//
+ // Something changed, so update the screen change ID.
+ ++_screenChangeID;
-int16 OpenGLGraphicsManager::getHeight() {
- return _videoMode.screenHeight;
+ // Since transactionError is a ORd list of TransactionErrors this is
+ // clearly wrong. But our API is simply broken.
+ return (OSystem::TransactionError)transactionError;
}
-int16 OpenGLGraphicsManager::getWidth() {
- return _videoMode.screenWidth;
+int OpenGLGraphicsManager::getScreenChangeID() const {
+ return _screenChangeID;
}
-void OpenGLGraphicsManager::setPalette(const byte *colors, uint start, uint num) {
- assert(colors);
-
+void OpenGLGraphicsManager::initSize(uint width, uint height, const Graphics::PixelFormat *format) {
+ Graphics::PixelFormat requestedFormat;
#ifdef USE_RGB_COLOR
- assert(_screenFormat.bytesPerPixel == 1);
+ if (!format) {
+ requestedFormat = Graphics::PixelFormat::createFormatCLUT8();
+ } else {
+ requestedFormat = *format;
+ }
+ _currentState.gameFormat = requestedFormat;
#endif
- // Save the screen palette
- memcpy(_gamePalette + start * 3, colors, num * 3);
-
- _screenNeedsRedraw = true;
-
- if (_cursorPaletteDisabled)
- _cursorNeedsRedraw = true;
+ _currentState.gameWidth = width;
+ _currentState.gameHeight = height;
}
-void OpenGLGraphicsManager::grabPalette(byte *colors, uint start, uint num) {
- assert(colors);
-
-#ifdef USE_RGB_COLOR
- assert(_screenFormat.bytesPerPixel == 1);
-#endif
+int16 OpenGLGraphicsManager::getWidth() {
+ return _currentState.gameWidth;
+}
- // Copies current palette to buffer
- memcpy(colors, _gamePalette + start * 3, num * 3);
+int16 OpenGLGraphicsManager::getHeight() {
+ return _currentState.gameHeight;
}
void OpenGLGraphicsManager::copyRectToScreen(const void *buf, int pitch, int x, int y, int w, int h) {
- assert(x >= 0 && x < _screenData.w);
- assert(y >= 0 && y < _screenData.h);
- assert(h > 0 && y + h <= _screenData.h);
- assert(w > 0 && x + w <= _screenData.w);
-
- // Copy buffer data to game screen internal buffer
- const byte *src = (const byte *)buf;
- byte *dst = (byte *)_screenData.getBasePtr(x, y);
- for (int i = 0; i < h; i++) {
- memcpy(dst, src, w * _screenData.format.bytesPerPixel);
- src += pitch;
- dst += _screenData.pitch;
- }
-
- // Extend dirty area if not full screen redraw is flagged
- if (!_screenNeedsRedraw) {
- const Common::Rect dirtyRect(x, y, x + w, y + h);
- _screenDirtyRect.extend(dirtyRect);
- }
+ _gameScreen->copyRectToTexture(x, y, w, h, buf, pitch);
}
-Graphics::Surface *OpenGLGraphicsManager::lockScreen() {
- return &_screenData;
+void OpenGLGraphicsManager::fillScreen(uint32 col) {
+ // FIXME: This does not conform to the OSystem specs because fillScreen
+ // is always taking CLUT8 color values and use color indexed mode. This is,
+ // however, plain odd and probably was a forgotten when we introduced
+ // RGB support. Thus, we simply do the "sane" thing here and hope OSystem
+ // gets fixed one day.
+ _gameScreen->fill(col);
}
-void OpenGLGraphicsManager::unlockScreen() {
- _screenNeedsRedraw = true;
+void OpenGLGraphicsManager::setShakePos(int shakeOffset) {
+ _gameScreenShakeOffset = shakeOffset;
}
-void OpenGLGraphicsManager::fillScreen(uint32 col) {
- if (_gameTexture == NULL)
+void OpenGLGraphicsManager::updateScreen() {
+ if (!_gameScreen) {
return;
+ }
-#ifdef USE_RGB_COLOR
- if (_screenFormat.bytesPerPixel == 1) {
- memset(_screenData.getPixels(), col, _screenData.h * _screenData.pitch);
- } else if (_screenFormat.bytesPerPixel == 2) {
- uint16 *pixels = (uint16 *)_screenData.getPixels();
- uint16 col16 = (uint16)col;
- for (int i = 0; i < _screenData.w * _screenData.h; i++) {
- pixels[i] = col16;
- }
- } else if (_screenFormat.bytesPerPixel == 3) {
- uint8 *pixels = (uint8 *)_screenData.getPixels();
- byte r = (col >> 16) & 0xFF;
- byte g = (col >> 8) & 0xFF;
- byte b = col & 0xFF;
- for (int i = 0; i < _screenData.w * _screenData.h; i++) {
- pixels[0] = r;
- pixels[1] = g;
- pixels[2] = b;
- pixels += 3;
+ // Clear the screen buffer
+ GLCALL(glClear(GL_COLOR_BUFFER_BIT));
+
+ const GLfloat shakeOffset = _gameScreenShakeOffset * (GLfloat)_displayHeight / _gameScreen->getHeight();
+
+ // First step: Draw the (virtual) game screen.
+ glPushMatrix();
+
+ // Adjust game screen shake position
+ GLCALL(glTranslatef(0, shakeOffset, 0));
+
+ // Draw the game screen
+ _gameScreen->draw(_displayX, _displayY, _displayWidth, _displayHeight);
+
+ glPopMatrix();
+
+ // Second step: Draw the overlay if visible.
+ if (_overlayVisible) {
+ _overlay->draw(0, 0, _outputScreenWidth, _outputScreenHeight);
+ }
+
+ // Third step: Draw the cursor if visible.
+ if (_cursorVisible && _cursor) {
+ glPushMatrix();
+
+ // Adjust game screen shake position, but only when the overlay is not
+ // visible.
+ if (!_overlayVisible) {
+ GLCALL(glTranslatef(0, shakeOffset, 0));
}
- } else if (_screenFormat.bytesPerPixel == 4) {
- uint32 *pixels = (uint32 *)_screenData.getPixels();
- for (int i = 0; i < _screenData.w * _screenData.h; i++) {
- pixels[i] = col;
+
+ _cursor->draw(_cursorX - _cursorHotspotXScaled, _cursorY - _cursorHotspotYScaled,
+ _cursorWidthScaled, _cursorHeightScaled);
+
+ glPopMatrix();
+ }
+
+#ifdef USE_OSD
+ // Fourth step: Draw the OSD.
+ if (_osdAlpha > 0) {
+ Common::StackLock lock(_osdMutex);
+
+ // Update alpha value.
+ const int diff = g_system->getMillis(false) - _osdFadeStartTime;
+ if (diff > 0) {
+ if (diff >= kOSDFadeOutDuration) {
+ // Back to full transparency.
+ _osdAlpha = 0;
+ } else {
+ // Do a fade out.
+ _osdAlpha = kOSDInitialAlpha - diff * kOSDInitialAlpha / kOSDFadeOutDuration;
+ }
}
+
+ // Set the OSD transparency.
+ GLCALL(glColor4f(1.0f, 1.0f, 1.0f, _osdAlpha / 100.0f));
+
+ // Draw the OSD texture.
+ _osd->draw(0, 0, _outputScreenWidth, _outputScreenHeight);
+
+ // Reset color.
+ GLCALL(glColor4f(1.0f, 1.0f, 1.0f, 1.0f));
}
-#else
- memset(_screenData.getPixels(), col, _screenData.h * _screenData.pitch);
#endif
- _screenNeedsRedraw = true;
}
-void OpenGLGraphicsManager::updateScreen() {
- assert(_transactionMode == kTransactionNone);
- internUpdateScreen();
+Graphics::Surface *OpenGLGraphicsManager::lockScreen() {
+ return _gameScreen->getSurface();
}
-void OpenGLGraphicsManager::setShakePos(int shakeOffset) {
- assert(_transactionMode == kTransactionNone);
- _shakePos = shakeOffset;
+void OpenGLGraphicsManager::unlockScreen() {
+ _gameScreen->flagDirty();
}
-void OpenGLGraphicsManager::setFocusRectangle(const Common::Rect &rect) {
+void OpenGLGraphicsManager::setFocusRectangle(const Common::Rect& rect) {
}
void OpenGLGraphicsManager::clearFocusRectangle() {
}
-//
-// Overlay
-//
-
-void OpenGLGraphicsManager::showOverlay() {
- assert(_transactionMode == kTransactionNone);
+int16 OpenGLGraphicsManager::getOverlayWidth() {
+ if (_overlay) {
+ return _overlay->getWidth();
+ } else {
+ return 0;
+ }
+}
- if (_overlayVisible)
- return;
+int16 OpenGLGraphicsManager::getOverlayHeight() {
+ if (_overlay) {
+ return _overlay->getHeight();
+ } else {
+ return 0;
+ }
+}
+void OpenGLGraphicsManager::showOverlay() {
_overlayVisible = true;
-
- clearOverlay();
}
void OpenGLGraphicsManager::hideOverlay() {
- assert(_transactionMode == kTransactionNone);
-
- if (!_overlayVisible)
- return;
-
_overlayVisible = false;
-
- clearOverlay();
}
Graphics::PixelFormat OpenGLGraphicsManager::getOverlayFormat() const {
- return _overlayFormat;
+ return _overlay->getFormat();
}
-void OpenGLGraphicsManager::clearOverlay() {
- // Set all pixels to 0
- memset(_overlayData.getPixels(), 0, _overlayData.h * _overlayData.pitch);
- _overlayNeedsRedraw = true;
+void OpenGLGraphicsManager::copyRectToOverlay(const void *buf, int pitch, int x, int y, int w, int h) {
+ _overlay->copyRectToTexture(x, y, w, h, buf, pitch);
}
-void OpenGLGraphicsManager::grabOverlay(void *buf, int pitch) {
- const byte *src = (byte *)_overlayData.getPixels();
- byte *dst = (byte *)buf;
- for (int i = 0; i < _overlayData.h; i++) {
- // Copy overlay data to buffer
- memcpy(dst, src, _overlayData.pitch);
- dst += pitch;
- src += _overlayData.pitch;
- }
+void OpenGLGraphicsManager::clearOverlay() {
+ _overlay->fill(0);
}
-void OpenGLGraphicsManager::copyRectToOverlay(const void *buf, int pitch, int x, int y, int w, int h) {
- assert(_transactionMode == kTransactionNone);
-
- if (_overlayTexture == NULL)
- return;
-
- const byte *src = (const byte *)buf;
-
- // Clip the coordinates
- if (x < 0) {
- w += x;
- src -= x * 2;
- x = 0;
- }
-
- if (y < 0) {
- h += y;
- src -= y * pitch;
- y = 0;
- }
-
- if (w > _overlayData.w - x)
- w = _overlayData.w - x;
-
- if (h > _overlayData.h - y)
- h = _overlayData.h - y;
-
- if (w <= 0 || h <= 0)
- return;
+void OpenGLGraphicsManager::grabOverlay(void *buf, int pitch) {
+ const Graphics::Surface *overlayData = _overlay->getSurface();
- // Copy buffer data to internal overlay surface
- byte *dst = (byte *)_overlayData.getBasePtr(0, y);
- for (int i = 0; i < h; i++) {
- memcpy(dst + x * _overlayData.format.bytesPerPixel, src, w * _overlayData.format.bytesPerPixel);
- src += pitch;
- dst += _overlayData.pitch;
- }
+ const byte *src = (const byte *)overlayData->getPixels();
+ byte *dst = (byte *)buf;
- // Extend dirty area if not full screen redraw is flagged
- if (!_overlayNeedsRedraw) {
- const Common::Rect dirtyRect(x, y, x + w, y + h);
- _overlayDirtyRect.extend(dirtyRect);
+ for (uint h = overlayData->h; h > 0; --h) {
+ memcpy(dst, src, overlayData->w * overlayData->format.bytesPerPixel);
+ dst += pitch;
+ src += overlayData->pitch;
}
}
-int16 OpenGLGraphicsManager::getOverlayHeight() {
- return _videoMode.overlayHeight;
-}
-
-int16 OpenGLGraphicsManager::getOverlayWidth() {
- return _videoMode.overlayWidth;
-}
-
-//
-// Cursor
-//
-
bool OpenGLGraphicsManager::showMouse(bool visible) {
- if (_cursorVisible == visible)
- return visible;
-
bool last = _cursorVisible;
_cursorVisible = visible;
-
return last;
}
void OpenGLGraphicsManager::warpMouse(int x, int y) {
- int scaledX = x;
- int scaledY = y;
-
- int16 currentX = _cursorState.x;
- int16 currentY = _cursorState.y;
-
+ int16 currentX = _cursorX;
+ int16 currentY = _cursorY;
adjustMousePosition(currentX, currentY);
- // Do not adjust the real screen position, when the current game / overlay
- // coordinates match the requested coordinates. This avoids a slight
- // movement which might occur otherwise when the mouse is at a subpixel
- // position.
- if (x == currentX && y == currentY)
+ // Check whether the (virtual) coordinate actually changed. If not, then
+ // simply do nothing. This avoids ugly "jittering" due to the actual
+ // output screen having a bigger resolution than the virtual coordinates.
+ if (currentX == x && currentY == y) {
return;
+ }
- if (_videoMode.mode == OpenGL::GFX_NORMAL) {
- if (_videoMode.hardwareWidth != _videoMode.overlayWidth)
- scaledX = scaledX * _videoMode.hardwareWidth / _videoMode.overlayWidth;
- if (_videoMode.hardwareHeight != _videoMode.overlayHeight)
- scaledY = scaledY * _videoMode.hardwareHeight / _videoMode.overlayHeight;
-
- if (!_overlayVisible) {
- scaledX *= _videoMode.scaleFactor;
- scaledY *= _videoMode.scaleFactor;
+ // Scale the virtual coordinates into actual physical coordinates.
+ if (_overlayVisible) {
+ 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
+ // for that.
+ x = (x * _outputScreenWidth) / _overlay->getWidth();
+ y = (y * _outputScreenHeight) / _overlay->getHeight();
} else {
- if (_overlayVisible) {
- if (_displayWidth != _videoMode.overlayWidth)
- scaledX = scaledX * _displayWidth / _videoMode.overlayWidth;
- if (_displayHeight != _videoMode.overlayHeight)
- scaledY = scaledY * _displayHeight / _videoMode.overlayHeight;
- } else {
- if (_displayWidth != _videoMode.screenWidth)
- scaledX = scaledX * _displayWidth / _videoMode.screenWidth;
- if (_displayHeight != _videoMode.screenHeight)
- scaledY = scaledY * _displayHeight / _videoMode.screenHeight;
+ if (!_gameScreen) {
+ return;
}
- scaledX += _displayX;
- scaledY += _displayY;
+ x = (x * _displayWidth) / _gameScreen->getWidth();
+ y = (y * _displayHeight) / _gameScreen->getHeight();
+
+ x += _displayX;
+ y += _displayY;
}
- setMousePosition(scaledX, scaledY);
- setInternalMousePosition(scaledX, scaledY);
+ setMousePosition(x, y);
+ setInternalMousePosition(x, y);
+}
+
+namespace {
+template<typename DstPixel, typename SrcPixel>
+void applyColorKey(DstPixel *dst, const SrcPixel *src, uint w, uint h, uint dstPitch, uint srcPitch, SrcPixel keyColor, DstPixel alphaMask) {
+ const uint srcAdd = srcPitch - w * sizeof(SrcPixel);
+ const uint dstAdd = dstPitch - w * sizeof(DstPixel);
+
+ while (h-- > 0) {
+ for (uint x = w; x > 0; --x, ++dst, ++src) {
+ if (*src == keyColor) {
+ *dst &= ~alphaMask;
+ }
+ }
+
+ dst = (DstPixel *)((byte *)dst + dstAdd);
+ src = (const SrcPixel *)((const byte *)src + srcAdd);
+ }
}
+} // End of anonymous namespace
void OpenGLGraphicsManager::setMouseCursor(const void *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, bool dontScale, const Graphics::PixelFormat *format) {
+ Graphics::PixelFormat inputFormat;
#ifdef USE_RGB_COLOR
- if (format)
- _cursorFormat = *format;
- else
- _cursorFormat = Graphics::PixelFormat::createFormatCLUT8();
+ if (format) {
+ inputFormat = *format;
+ } else {
+ inputFormat = Graphics::PixelFormat::createFormatCLUT8();
+ }
#else
- assert(keycolor <= 255);
- _cursorFormat = Graphics::PixelFormat::createFormatCLUT8();
+ inputFormat = Graphics::PixelFormat::createFormatCLUT8();
#endif
- // Allocate space for cursor data
- if (_cursorData.w != w || _cursorData.h != h ||
- _cursorData.format.bytesPerPixel != _cursorFormat.bytesPerPixel)
- _cursorData.create(w, h, _cursorFormat);
+ // In case the color format has changed we will need to create the texture.
+ if (!_cursor || _cursor->getFormat() != inputFormat) {
+ delete _cursor;
+ _cursor = nullptr;
- // Save cursor data
- memcpy(_cursorData.getPixels(), buf, h * _cursorData.pitch);
+ GLenum glIntFormat, glFormat, glType;
+
+ if (inputFormat.bytesPerPixel == 1) {
+ // In case this is not supported this is a serious programming
+ // error and the assert a bit below will trigger!
+ const bool supported = getGLPixelFormat(_defaultFormatAlpha, glIntFormat, glFormat, glType);
+ assert(supported);
+ _cursor = new TextureCLUT8(glIntFormat, glFormat, glType, _defaultFormatAlpha);
+ } else {
+ // Try to use the format specified as input directly. We can only
+ // do so when it actually has alpha bits.
+ if (inputFormat.aBits() != 0 && getGLPixelFormat(inputFormat, glIntFormat, glFormat, glType)) {
+ _cursor = new Texture(glIntFormat, glFormat, glType, inputFormat);
+ }
+
+ // Otherwise fall back to the default alpha format.
+ if (!_cursor) {
+ const bool supported = getGLPixelFormat(_defaultFormatAlpha, glIntFormat, glFormat, glType);
+ assert(supported);
+ _cursor = new Texture(glIntFormat, glFormat, glType, _defaultFormatAlpha);
+ }
+ }
+
+ assert(_cursor);
+ _cursor->enableLinearFiltering(_currentState.graphicsMode == GFX_LINEAR);
+ }
- // Set cursor info
- _cursorState.w = w;
- _cursorState.h = h;
- _cursorState.hotX = hotspotX;
- _cursorState.hotY = hotspotY;
_cursorKeyColor = keycolor;
+ _cursorHotspotX = hotspotX;
+ _cursorHotspotY = hotspotY;
_cursorDontScale = dontScale;
- _cursorNeedsRedraw = true;
- refreshCursorScale();
+ _cursor->allocate(w, h);
+ if (inputFormat.bytesPerPixel == 1) {
+ // For CLUT8 cursors we can simply copy the input data into the
+ // texture.
+ _cursor->copyRectToTexture(0, 0, w, h, buf, w * inputFormat.bytesPerPixel);
+ } else {
+ // Otherwise it is a bit more ugly because we have to handle a key
+ // color properly.
+
+ Graphics::Surface *dst = _cursor->getSurface();
+ const uint srcPitch = w * inputFormat.bytesPerPixel;
+
+ // Copy the cursor data to the actual texture surface. This will make
+ // sure that the data is also converted to the expected format.
+ Graphics::crossBlit((byte *)dst->getPixels(), (const byte *)buf, dst->pitch, srcPitch,
+ w, h, dst->format, inputFormat);
+
+ // We apply the color key by setting the alpha bits of the pixels to
+ // fully transparent.
+ const uint32 aMask = (0xFF >> dst->format.aLoss) << dst->format.aShift;
+ if (dst->format.bytesPerPixel == 2) {
+ if (inputFormat.bytesPerPixel == 2) {
+ applyColorKey<uint16, uint16>((uint16 *)dst->getPixels(), (const uint16 *)buf, w, h,
+ dst->pitch, srcPitch, keycolor, aMask);
+ } else if (inputFormat.bytesPerPixel == 4) {
+ applyColorKey<uint16, uint32>((uint16 *)dst->getPixels(), (const uint32 *)buf, w, h,
+ dst->pitch, srcPitch, keycolor, aMask);
+ }
+ } else {
+ if (inputFormat.bytesPerPixel == 2) {
+ applyColorKey<uint32, uint16>((uint32 *)dst->getPixels(), (const uint16 *)buf, w, h,
+ dst->pitch, srcPitch, keycolor, aMask);
+ } else if (inputFormat.bytesPerPixel == 4) {
+ applyColorKey<uint32, uint32>((uint32 *)dst->getPixels(), (const uint32 *)buf, w, h,
+ dst->pitch, srcPitch, keycolor, aMask);
+ }
+ }
+
+ // Flag the texture as dirty.
+ _cursor->flagDirty();
+ }
+
+ // In case we actually use a palette set that up properly.
+ if (inputFormat.bytesPerPixel == 1) {
+ updateCursorPalette();
+ }
+
+ // Update the scaling.
+ recalculateCursorScaling();
}
void OpenGLGraphicsManager::setCursorPalette(const byte *colors, uint start, uint num) {
- assert(colors);
+ // FIXME: For some reason client code assumes that usage of this function
+ // automatically enables the cursor palette.
+ _cursorPaletteEnabled = true;
- // Save the cursor palette
memcpy(_cursorPalette + start * 3, colors, num * 3);
-
- _cursorPaletteDisabled = false;
- _cursorNeedsRedraw = true;
+ updateCursorPalette();
}
-//
-// Misc
-//
-
void OpenGLGraphicsManager::displayMessageOnOSD(const char *msg) {
- assert(_transactionMode == kTransactionNone);
- assert(msg);
-
#ifdef USE_OSD
- // Split the message into separate lines.
- _osdLines.clear();
+ // HACK: Actually no client code should use graphics functions from
+ // another thread. But the MT-32 emulator still does, thus we need to
+ // make sure this doesn't happen while a updateScreen call is done.
+ Common::StackLock lock(_osdMutex);
+ // Slip up the lines.
+ Common::Array<Common::String> osdLines;
Common::StringTokenizer tokenizer(msg, "\n");
- while (!tokenizer.empty())
- _osdLines.push_back(tokenizer.nextToken());
+ while (!tokenizer.empty()) {
+ osdLines.push_back(tokenizer.nextToken());
+ }
- // Request update of the texture
- _requireOSDUpdate = true;
+ // Do the actual drawing like the SDL backend.
+ const Graphics::Font *font = getFontOSD();
+ Graphics::Surface *dst = _osd->getSurface();
+ _osd->fill(0);
+ _osd->flagDirty();
- // Init the OSD display parameters, and the fade out
+ // Determine a rect which would contain the message string (clipped to the
+ // screen dimensions).
+ const int vOffset = 6;
+ const int lineSpacing = 1;
+ const int lineHeight = font->getFontHeight() + 2 * lineSpacing;
+ int width = 0;
+ int height = lineHeight * osdLines.size() + 2 * vOffset;
+ for (uint i = 0; i < osdLines.size(); i++) {
+ width = MAX(width, font->getStringWidth(osdLines[i]) + 14);
+ }
+
+ // Clip the rect
+ width = MIN<int>(width, dst->w);
+ height = MIN<int>(height, dst->h);
+
+ int dstX = (dst->w - width) / 2;
+ int dstY = (dst->h - height) / 2;
+
+ // Draw a dark gray rect.
+ const uint32 color = dst->format.RGBToColor(40, 40, 40);
+ dst->fillRect(Common::Rect(dstX, dstY, dstX + width, dstY + height), color);
+
+ // Render the message, centered, and in white
+ const uint32 white = dst->format.RGBToColor(255, 255, 255);
+ for (uint i = 0; i < osdLines.size(); ++i) {
+ font->drawString(dst, osdLines[i],
+ dstX, dstY + i * lineHeight + vOffset + lineSpacing, width,
+ white, Graphics::kTextAlignCenter);
+ }
+
+ // Init the OSD display parameters.
_osdAlpha = kOSDInitialAlpha;
_osdFadeStartTime = g_system->getMillis() + kOSDFadeOutDelay;
#endif
}
-//
-// Intern
-//
+void OpenGLGraphicsManager::setPalette(const byte *colors, uint start, uint num) {
+ assert(_gameScreen->hasPalette());
-void OpenGLGraphicsManager::setFullscreenMode(bool enable) {
- assert(_transactionMode == kTransactionActive);
+ memcpy(_gamePalette + start * 3, colors, num * 3);
+ _gameScreen->setPalette(start, num, colors);
- if (_oldVideoMode.setup && _oldVideoMode.fullscreen == enable)
- return;
+ // We might need to update the cursor palette here.
+ updateCursorPalette();
+}
- if (_transactionMode == kTransactionActive) {
- _videoMode.fullscreen = enable;
- _transactionDetails.needRefresh = true;
- }
+void OpenGLGraphicsManager::grabPalette(byte *colors, uint start, uint num) {
+ assert(_gameScreen->hasPalette());
+
+ memcpy(colors, _gamePalette + start * 3, num * 3);
}
-void OpenGLGraphicsManager::refreshGameScreen() {
- if (_screenNeedsRedraw)
- _screenDirtyRect = Common::Rect(0, 0, _screenData.w, _screenData.h);
-
- int x = _screenDirtyRect.left;
- int y = _screenDirtyRect.top;
- int w = _screenDirtyRect.width();
- int h = _screenDirtyRect.height();
-
- if (_screenData.format.bytesPerPixel == 1) {
- // Create a temporary RGB888 surface
- byte *surface = new byte[w * h * 3];
-
- // Convert the paletted buffer to RGB888
- const byte *src = (byte *)_screenData.getBasePtr(0, y);
- src += x * _screenData.format.bytesPerPixel;
- byte *dst = surface;
- for (int i = 0; i < h; i++) {
- for (int j = 0; j < w; j++) {
- dst[0] = _gamePalette[src[j] * 3];
- dst[1] = _gamePalette[src[j] * 3 + 1];
- dst[2] = _gamePalette[src[j] * 3 + 2];
- dst += 3;
- }
- src += _screenData.pitch;
+void OpenGLGraphicsManager::setActualScreenSize(uint width, uint height) {
+ _outputScreenWidth = width;
+ _outputScreenHeight = height;
+
+ // Setup coordinates system.
+ GLCALL(glViewport(0, 0, _outputScreenWidth, _outputScreenHeight));
+
+ GLCALL(glMatrixMode(GL_PROJECTION));
+ GLCALL(glLoadIdentity());
+#ifdef USE_GLES
+ GLCALL(glOrthof(0, _outputScreenWidth, _outputScreenHeight, 0, -1, 1));
+#else
+ GLCALL(glOrtho(0, _outputScreenWidth, _outputScreenHeight, 0, -1, 1));
+#endif
+ GLCALL(glMatrixMode(GL_MODELVIEW));
+ GLCALL(glLoadIdentity());
+
+ uint overlayWidth = width;
+ uint overlayHeight = height;
+
+ // WORKAROUND: We can only support surfaces up to the maximum supported
+ // texture size. Thus, in case we encounter a physical size bigger than
+ // this maximum texture size we will simply use an overlay as big as
+ // possible and then scale it to the physical display size. This sounds
+ // bad but actually all recent chips should support full HD resolution
+ // anyway. Thus, it should not be a real issue for modern hardware.
+ if ( overlayWidth > (uint)Texture::getMaximumTextureSize()
+ || overlayHeight > (uint)Texture::getMaximumTextureSize()) {
+ const frac_t outputAspect = intToFrac(_outputScreenWidth) / _outputScreenHeight;
+
+ if (outputAspect > (frac_t)FRAC_ONE) {
+ overlayWidth = Texture::getMaximumTextureSize();
+ overlayHeight = intToFrac(overlayWidth) / outputAspect;
+ } else {
+ overlayHeight = Texture::getMaximumTextureSize();
+ overlayWidth = fracToInt(overlayHeight * outputAspect);
}
+ }
- // Update the texture
- _gameTexture->updateBuffer(surface, w * 3, x, y, w, h);
+ // HACK: We limit the minimal overlay size to 256x200, which is the
+ // minimum of the dimensions of the two resolutions 256x240 (NES) and
+ // 320x200 (many DOS games use this). This hopefully assure that our
+ // GUI has working layouts.
+ overlayWidth = MAX<uint>(overlayWidth, 256);
+ overlayHeight = MAX<uint>(overlayHeight, 200);
+
+ if (!_overlay || _overlay->getFormat() != _defaultFormatAlpha) {
+ delete _overlay;
+ _overlay = nullptr;
+
+ GLenum glIntFormat, glFormat, glType;
+ const bool supported = getGLPixelFormat(_defaultFormatAlpha, glIntFormat, glFormat, glType);
+ assert(supported);
+ _overlay = new Texture(glIntFormat, glFormat, glType, _defaultFormatAlpha);
+ // We always filter the overlay with GL_LINEAR. This assures it's
+ // readable in case it needs to be scaled and does not affect it
+ // otherwise.
+ _overlay->enableLinearFiltering(true);
+ }
+ _overlay->allocate(overlayWidth, overlayHeight);
+ _overlay->fill(0);
- // Free the temp surface
- delete[] surface;
- } else {
- // Update the texture
- _gameTexture->updateBuffer((byte *)_screenData.getBasePtr(x, y), _screenData.pitch, x, y, w, h);
+#ifdef USE_OSD
+ if (!_osd || _osd->getFormat() != _defaultFormatAlpha) {
+ delete _osd;
+ _osd = nullptr;
+
+ GLenum glIntFormat, glFormat, glType;
+ const bool supported = getGLPixelFormat(_defaultFormatAlpha, glIntFormat, glFormat, glType);
+ assert(supported);
+ _osd = new Texture(glIntFormat, glFormat, glType, _defaultFormatAlpha);
+ // We always filter the osd with GL_LINEAR. This assures it's
+ // readable in case it needs to be scaled and does not affect it
+ // otherwise.
+ _osd->enableLinearFiltering(true);
}
+ _osd->allocate(_overlay->getWidth(), _overlay->getHeight());
+ _osd->fill(0);
+#endif
- _screenNeedsRedraw = false;
- _screenDirtyRect = Common::Rect();
+ // Re-setup the scaling for the screen and cursor
+ recalculateDisplayArea();
+ recalculateCursorScaling();
+
+ // Something changed, so update the screen change ID.
+ ++_screenChangeID;
}
-void OpenGLGraphicsManager::refreshOverlay() {
- if (_overlayNeedsRedraw)
- _overlayDirtyRect = Common::Rect(0, 0, _overlayData.w, _overlayData.h);
-
- int x = _overlayDirtyRect.left;
- int y = _overlayDirtyRect.top;
- int w = _overlayDirtyRect.width();
- int h = _overlayDirtyRect.height();
-
- if (_overlayData.format.bytesPerPixel == 1) {
- // Create a temporary RGB888 surface
- byte *surface = new byte[w * h * 3];
-
- // Convert the paletted buffer to RGB888
- const byte *src = (byte *)_overlayData.getBasePtr(0, y);
- src += x * _overlayData.format.bytesPerPixel;
- byte *dst = surface;
- for (int i = 0; i < h; i++) {
- for (int j = 0; j < w; j++) {
- dst[0] = _gamePalette[src[j] * 3];
- dst[1] = _gamePalette[src[j] * 3 + 1];
- dst[2] = _gamePalette[src[j] * 3 + 2];
- dst += 3;
- }
- src += _screenData.pitch;
- }
+void OpenGLGraphicsManager::notifyContextChange(const Graphics::PixelFormat &defaultFormat, const Graphics::PixelFormat &defaultFormatAlpha) {
+ // Initialize all extensions.
+ initializeGLExtensions();
- // Update the texture
- _overlayTexture->updateBuffer(surface, w * 3, x, y, w, h);
+ // Disable 3D properties.
+ GLCALL(glDisable(GL_CULL_FACE));
+ GLCALL(glDisable(GL_DEPTH_TEST));
+ GLCALL(glDisable(GL_LIGHTING));
+ GLCALL(glDisable(GL_FOG));
+ GLCALL(glDisable(GL_DITHER));
+ GLCALL(glShadeModel(GL_FLAT));
+ GLCALL(glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST));
- // Free the temp surface
- delete[] surface;
- } else {
- // Update the texture
- _overlayTexture->updateBuffer((byte *)_overlayData.getBasePtr(x, y), _overlayData.pitch, x, y, w, h);
- }
+ // Default to black as clear color.
+ GLCALL(glClearColor(0.0f, 0.0f, 0.0f, 0.0f));
+ GLCALL(glColor4f(1.0f, 1.0f, 1.0f, 1.0f));
- _overlayNeedsRedraw = false;
- _overlayDirtyRect = Common::Rect();
-}
+ // Setup alpha blend (for overlay and cursor).
+ GLCALL(glEnable(GL_BLEND));
+ GLCALL(glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA));
-void OpenGLGraphicsManager::refreshCursor() {
- _cursorNeedsRedraw = false;
-
- // Allocate a texture big enough for cursor
- _cursorTexture->allocBuffer(_cursorState.w, _cursorState.h);
-
- // Create a temporary RGBA8888 surface
- byte *surface = new byte[_cursorState.w * _cursorState.h * 4];
- memset(surface, 0, _cursorState.w * _cursorState.h * 4);
-
- byte *dst = surface;
-
- // Convert the paletted cursor to RGBA8888
- if (_cursorFormat.bytesPerPixel == 1) {
- // Select palette
- byte *palette;
- if (_cursorPaletteDisabled)
- palette = _gamePalette;
- else
- palette = _cursorPalette;
-
- // Convert the paletted cursor to RGBA8888
- const byte *src = (byte *)_cursorData.getPixels();
- for (int i = 0; i < _cursorState.w * _cursorState.h; i++) {
- // Check for keycolor
- if (src[i] != _cursorKeyColor) {
- dst[0] = palette[src[i] * 3];
- dst[1] = palette[src[i] * 3 + 1];
- dst[2] = palette[src[i] * 3 + 2];
- dst[3] = 255;
- }
- dst += 4;
- }
- } else {
- const bool gotNoAlpha = (_cursorFormat.aLoss == 8);
-
- // Convert the RGB cursor to RGBA8888
- if (_cursorFormat.bytesPerPixel == 2) {
- const uint16 *src = (uint16 *)_cursorData.getPixels();
- for (int i = 0; i < _cursorState.w * _cursorState.h; i++) {
- // Check for keycolor
- if (src[i] != _cursorKeyColor) {
- _cursorFormat.colorToARGB(src[i], dst[3], dst[0], dst[1], dst[2]);
-
- if (gotNoAlpha)
- dst[3] = 255;
- }
- dst += 4;
- }
- } else if (_cursorFormat.bytesPerPixel == 4) {
- const uint32 *src = (uint32 *)_cursorData.getPixels();
- for (int i = 0; i < _cursorState.w * _cursorState.h; i++) {
- // Check for keycolor
- if (src[i] != _cursorKeyColor) {
- _cursorFormat.colorToARGB(src[i], dst[3], dst[0], dst[1], dst[2]);
-
- if (gotNoAlpha)
- dst[3] = 255;
- }
- dst += 4;
- }
- }
- }
+ // Enable rendering with vertex and coord arrays.
+ GLCALL(glEnableClientState(GL_VERTEX_ARRAY));
+ GLCALL(glEnableClientState(GL_TEXTURE_COORD_ARRAY));
- // Update the texture with new cursor
- _cursorTexture->updateBuffer(surface, _cursorState.w * 4, 0, 0, _cursorState.w, _cursorState.h);
+ GLCALL(glEnable(GL_TEXTURE_2D));
- // Free the temp surface
- delete[] surface;
-}
+ // We use a "pack" alignment (when reading from textures) to 4 here,
+ // since the only place where we really use it is the BMP screenshot
+ // code and that requires the same alignment too.
+ GLCALL(glPixelStorei(GL_PACK_ALIGNMENT, 4));
-void OpenGLGraphicsManager::refreshCursorScale() {
- // Calculate the scale factors of the screen.
- // We also totally ignore the aspect of the overlay cursor, since aspect
- // ratio correction only applies to the game screen.
- // TODO: It might make sense to always ignore scaling of the mouse cursor
- // when the overlay is visible.
- uint screenScaleFactorX = _videoMode.hardwareWidth * 10000 / _videoMode.screenWidth;
- uint screenScaleFactorY = _videoMode.hardwareHeight * 10000 / _videoMode.screenHeight;
-
- // Ignore scaling when the cursor should not be scaled.
- if (_cursorDontScale) {
- screenScaleFactorX = 10000;
- screenScaleFactorY = 10000;
- }
+ // Query information needed by textures.
+ Texture::queryTextureInformation();
- // Apply them (without any possible) aspect ratio correction to the
- // overlay.
- _cursorState.rW = (int16)(_cursorState.w * screenScaleFactorX / 10000);
- _cursorState.rH = (int16)(_cursorState.h * screenScaleFactorY / 10000);
- _cursorState.rHotX = (int16)(_cursorState.hotX * screenScaleFactorX / 10000);
- _cursorState.rHotY = (int16)(_cursorState.hotY * screenScaleFactorY / 10000);
-
- // Only apply scaling when it's desired.
- if (_cursorDontScale) {
- screenScaleFactorX = 10000;
- screenScaleFactorY = 10000;
- } else {
- // Make sure we properly scale the cursor according to the desired aspect.
- int width, height;
- calculateDisplaySize(width, height);
- screenScaleFactorX = (width * 10000 / _videoMode.screenWidth);
- screenScaleFactorY = (height * 10000 / _videoMode.screenHeight);
+ // Refresh the output screen dimensions if some are set up.
+ if (_outputScreenWidth != 0 && _outputScreenHeight != 0) {
+ setActualScreenSize(_outputScreenWidth, _outputScreenHeight);
}
- // Apply the scale cursor scaling for the game screen.
- _cursorState.vW = (int16)(_cursorState.w * screenScaleFactorX / 10000);
- _cursorState.vH = (int16)(_cursorState.h * screenScaleFactorY / 10000);
- _cursorState.vHotX = (int16)(_cursorState.hotX * screenScaleFactorX / 10000);
- _cursorState.vHotY = (int16)(_cursorState.hotY * screenScaleFactorY / 10000);
-}
+ // TODO: Should we try to convert textures into one of those formats if
+ // possible? For example, when _gameScreen is CLUT8 we might want to use
+ // defaultFormat now.
+ _defaultFormat = defaultFormat;
+ _defaultFormatAlpha = defaultFormatAlpha;
-void OpenGLGraphicsManager::calculateDisplaySize(int &width, int &height) {
- if (_videoMode.mode == OpenGL::GFX_ORIGINAL) {
- width = _videoMode.screenWidth;
- height = _videoMode.screenHeight;
- } else {
- width = _videoMode.hardwareWidth;
- height = _videoMode.hardwareHeight;
+ if (_gameScreen) {
+ _gameScreen->recreateInternalTexture();
+ }
+
+ if (_overlay) {
+ _overlay->recreateInternalTexture();
+ }
- uint aspectRatio = (_videoMode.hardwareWidth * 10000 + 5000) / _videoMode.hardwareHeight;
- uint desiredAspectRatio = getAspectRatio();
+ if (_cursor) {
+ _cursor->recreateInternalTexture();
+ }
- // Adjust one screen dimension for mantaining the aspect ratio
- if (aspectRatio < desiredAspectRatio)
- height = (width * 10000 + 5000) / desiredAspectRatio;
- else if (aspectRatio > desiredAspectRatio)
- width = (height * desiredAspectRatio + 5000) / 10000;
+#ifdef USE_OSD
+ if (_osd) {
+ _osd->recreateInternalTexture();
}
+#endif
}
-void OpenGLGraphicsManager::refreshDisplaySize() {
- calculateDisplaySize(_displayWidth, _displayHeight);
+void OpenGLGraphicsManager::adjustMousePosition(int16 &x, int16 &y) {
+ if (_overlayVisible) {
+ // 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
+ // for that.
+ // This can also happen when the overlay is smaller than the actual
+ // display size because of texture size limitations.
+ if (_overlay) {
+ x = (x * _overlay->getWidth()) / _outputScreenWidth;
+ y = (y * _overlay->getHeight()) / _outputScreenHeight;
+ }
+ } else if (_gameScreen) {
+ x -= _displayX;
+ y -= _displayY;
+
+ const int16 width = _gameScreen->getWidth();
+ const int16 height = _gameScreen->getHeight();
+
+ x = (x * width) / _displayWidth;
+ y = (y * height) / _displayHeight;
- // Adjust x and y for centering the screen
- _displayX = (_videoMode.hardwareWidth - _displayWidth) / 2;
- _displayY = (_videoMode.hardwareHeight - _displayHeight) / 2;
+ // Make sure we only supply valid coordinates.
+ x = CLIP<int16>(x, 0, width - 1);
+ y = CLIP<int16>(y, 0, height - 1);
+ }
}
-void OpenGLGraphicsManager::getGLPixelFormat(Graphics::PixelFormat pixelFormat, byte &bpp, GLenum &intFormat, GLenum &glFormat, GLenum &gltype) {
+bool OpenGLGraphicsManager::getGLPixelFormat(const Graphics::PixelFormat &pixelFormat, GLenum &glIntFormat, GLenum &glFormat, GLenum &glType) const {
if (pixelFormat == Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0)) { // RGBA8888
- bpp = 4;
- intFormat = GL_RGBA;
+ glIntFormat = GL_RGBA;
glFormat = GL_RGBA;
- gltype = GL_UNSIGNED_INT_8_8_8_8;
- } else if (pixelFormat == Graphics::PixelFormat(3, 8, 8, 8, 0, 16, 8, 0, 0)) { // RGB888
- bpp = 3;
- intFormat = GL_RGB;
- glFormat = GL_RGB;
- gltype = GL_UNSIGNED_BYTE;
+ glType = GL_UNSIGNED_INT_8_8_8_8;
+ return true;
} else if (pixelFormat == Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0)) { // RGB565
- bpp = 2;
- intFormat = GL_RGB;
+ glIntFormat = GL_RGB;
glFormat = GL_RGB;
- gltype = GL_UNSIGNED_SHORT_5_6_5;
- } else if (pixelFormat == Graphics::PixelFormat(2, 5, 5, 5, 1, 11, 6, 1, 0)) { // RGB5551
- bpp = 2;
- intFormat = GL_RGBA;
+ glType = GL_UNSIGNED_SHORT_5_6_5;
+ return true;
+ } else if (pixelFormat == Graphics::PixelFormat(2, 5, 5, 5, 1, 11, 6, 1, 0)) { // RGBA5551
+ glIntFormat = GL_RGBA;
glFormat = GL_RGBA;
- gltype = GL_UNSIGNED_SHORT_5_5_5_1;
+ glType = GL_UNSIGNED_SHORT_5_5_5_1;
+ return true;
} else if (pixelFormat == Graphics::PixelFormat(2, 4, 4, 4, 4, 12, 8, 4, 0)) { // RGBA4444
- bpp = 2;
- intFormat = GL_RGBA;
+ glIntFormat = GL_RGBA;
glFormat = GL_RGBA;
- gltype = GL_UNSIGNED_SHORT_4_4_4_4;
- } else if (pixelFormat.bytesPerPixel == 1) { // CLUT8
- // If uses a palette, create texture as RGB888. The pixel data will be converted
- // later.
- bpp = 3;
- intFormat = GL_RGB;
- glFormat = GL_RGB;
- gltype = GL_UNSIGNED_BYTE;
+ glType = GL_UNSIGNED_SHORT_4_4_4_4;
+ return true;
#ifndef USE_GLES
} else if (pixelFormat == Graphics::PixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0)) { // RGB555
// GL_BGRA does not exist in every GLES implementation so should not be configured if
// USE_GLES is set.
- bpp = 2;
- intFormat = GL_RGB;
+ glIntFormat = GL_RGB;
glFormat = GL_BGRA;
- gltype = GL_UNSIGNED_SHORT_1_5_5_5_REV;
+ glType = GL_UNSIGNED_SHORT_1_5_5_5_REV;
+ return true;
} else if (pixelFormat == Graphics::PixelFormat(4, 8, 8, 8, 8, 16, 8, 0, 24)) { // ARGB8888
- bpp = 4;
- intFormat = GL_RGBA;
+ glIntFormat = GL_RGBA;
glFormat = GL_BGRA;
- gltype = GL_UNSIGNED_INT_8_8_8_8_REV;
+ glType = GL_UNSIGNED_INT_8_8_8_8_REV;
+ return true;
} else if (pixelFormat == Graphics::PixelFormat(2, 4, 4, 4, 4, 8, 4, 0, 12)) { // ARGB4444
- bpp = 2;
- intFormat = GL_RGBA;
+ glIntFormat = GL_RGBA;
glFormat = GL_BGRA;
- gltype = GL_UNSIGNED_SHORT_4_4_4_4_REV;
+ glType = GL_UNSIGNED_SHORT_4_4_4_4_REV;
+ return true;
} else if (pixelFormat == Graphics::PixelFormat(4, 8, 8, 8, 8, 0, 8, 16, 24)) { // ABGR8888
- bpp = 4;
- intFormat = GL_RGBA;
+ glIntFormat = GL_RGBA;
glFormat = GL_RGBA;
- gltype = GL_UNSIGNED_INT_8_8_8_8_REV;
+ glType = GL_UNSIGNED_INT_8_8_8_8_REV;
+ return true;
} else if (pixelFormat == Graphics::PixelFormat(4, 8, 8, 8, 8, 8, 16, 24, 0)) { // BGRA8888
- bpp = 4;
- intFormat = GL_RGBA;
+ glIntFormat = GL_RGBA;
glFormat = GL_BGRA;
- gltype = GL_UNSIGNED_BYTE;
- } else if (pixelFormat == Graphics::PixelFormat(3, 8, 8, 8, 0, 0, 8, 16, 0)) { // BGR888
- bpp = 3;
- intFormat = GL_RGB;
- glFormat = GL_BGR;
- gltype = GL_UNSIGNED_BYTE;
+ glType = GL_UNSIGNED_INT_8_8_8_8;
+ return true;
} else if (pixelFormat == Graphics::PixelFormat(2, 5, 6, 5, 0, 0, 5, 11, 0)) { // BGR565
- bpp = 2;
- intFormat = GL_RGB;
+ glIntFormat = GL_RGB;
glFormat = GL_BGR;
- gltype = GL_UNSIGNED_SHORT_5_6_5;
+ glType = GL_UNSIGNED_SHORT_5_6_5;
+ return true;
} else if (pixelFormat == Graphics::PixelFormat(2, 5, 5, 5, 1, 1, 6, 11, 0)) { // BGRA5551
- bpp = 2;
- intFormat = GL_RGBA;
+ glIntFormat = GL_RGBA;
glFormat = GL_BGRA;
- gltype = GL_UNSIGNED_SHORT_5_5_5_1;
+ glType = GL_UNSIGNED_SHORT_5_5_5_1;
+ return true;
} else if (pixelFormat == Graphics::PixelFormat(2, 4, 4, 4, 4, 0, 4, 8, 12)) { // ABGR4444
- bpp = 2;
- intFormat = GL_RGBA;
+ glIntFormat = GL_RGBA;
glFormat = GL_RGBA;
- gltype = GL_UNSIGNED_SHORT_4_4_4_4_REV;
+ glType = GL_UNSIGNED_SHORT_4_4_4_4_REV;
+ return true;
} else if (pixelFormat == Graphics::PixelFormat(2, 4, 4, 4, 4, 4, 8, 12, 0)) { // BGRA4444
- bpp = 2;
- intFormat = GL_RGBA;
+ glIntFormat = GL_RGBA;
glFormat = GL_BGRA;
- gltype = GL_UNSIGNED_SHORT_4_4_4_4;
+ glType = GL_UNSIGNED_SHORT_4_4_4_4;
+ return true;
#endif
} else {
- error("OpenGLGraphicsManager: Pixel format not supported");
+ return false;
}
}
-void OpenGLGraphicsManager::internUpdateScreen() {
- // Clear the screen buffer
- glClear(GL_COLOR_BUFFER_BIT); CHECK_GL_ERROR();
-
- if (_screenNeedsRedraw || !_screenDirtyRect.isEmpty())
- // Refresh texture if dirty
- refreshGameScreen();
-
- int scaleFactor = _videoMode.hardwareHeight / _videoMode.screenHeight;
-
- glPushMatrix();
-
- // Adjust game screen shake position
- glTranslatef(0, _shakePos * scaleFactor, 0); CHECK_GL_ERROR();
-
- // Draw the game screen
- _gameTexture->drawTexture(_displayX, _displayY, _displayWidth, _displayHeight);
-
- glPopMatrix();
-
- if (_overlayVisible) {
- if (_overlayNeedsRedraw || !_overlayDirtyRect.isEmpty())
- // Refresh texture if dirty
- refreshOverlay();
-
- // Draw the overlay
- _overlayTexture->drawTexture(0, 0, _videoMode.overlayWidth, _videoMode.overlayHeight);
- }
-
- if (_cursorVisible) {
- if (_cursorNeedsRedraw)
- // Refresh texture if dirty
- refreshCursor();
-
- glPushMatrix();
-
- // Adjust mouse shake position, unless the overlay is visible
- glTranslatef(0, _overlayVisible ? 0 : _shakePos * scaleFactor, 0); CHECK_GL_ERROR();
-
- // Draw the cursor
- if (_overlayVisible)
- _cursorTexture->drawTexture(_cursorState.x - _cursorState.rHotX,
- _cursorState.y - _cursorState.rHotY, _cursorState.rW, _cursorState.rH);
- else
- _cursorTexture->drawTexture(_cursorState.x - _cursorState.vHotX,
- _cursorState.y - _cursorState.vHotY, _cursorState.vW, _cursorState.vH);
-
- glPopMatrix();
- }
+frac_t OpenGLGraphicsManager::getDesiredGameScreenAspect() const {
+ const uint width = _currentState.gameWidth;
+ const uint height = _currentState.gameHeight;
-#ifdef USE_OSD
- if (_osdAlpha > 0) {
- if (_requireOSDUpdate) {
- updateOSD();
- _requireOSDUpdate = false;
+ if (_currentState.aspectRatioCorrection) {
+ // In case we enable aspect ratio correction we force a 4/3 ratio.
+ // But just for 320x200 and 640x400 games, since other games do not need
+ // this.
+ if ((width == 320 && height == 200) || (width == 640 && height == 400)) {
+ return intToFrac(4) / 3;
}
-
- // Update alpha value
- const int diff = g_system->getMillis() - _osdFadeStartTime;
- if (diff > 0) {
- if (diff >= kOSDFadeOutDuration) {
- // Back to full transparency
- _osdAlpha = 0;
- } else {
- // Do a fade out
- _osdAlpha = kOSDInitialAlpha - diff * kOSDInitialAlpha / kOSDFadeOutDuration;
- }
- }
- // Set the osd transparency
- glColor4f(1.0f, 1.0f, 1.0f, _osdAlpha / 100.0f); CHECK_GL_ERROR();
-
- // Draw the osd texture
- _osdTexture->drawTexture(0, 0, _videoMode.hardwareWidth, _videoMode.hardwareHeight);
-
- // Reset color
- glColor4f(1.0f, 1.0f, 1.0f, 1.0f); CHECK_GL_ERROR();
}
-#endif
-}
-
-void OpenGLGraphicsManager::initGL() {
- // Check available GL Extensions
- GLTexture::initGLExtensions();
-
- // Disable 3D properties
- glDisable(GL_CULL_FACE); CHECK_GL_ERROR();
- glDisable(GL_DEPTH_TEST); CHECK_GL_ERROR();
- glDisable(GL_LIGHTING); CHECK_GL_ERROR();
- glDisable(GL_FOG); CHECK_GL_ERROR();
- glDisable(GL_DITHER); CHECK_GL_ERROR();
- glShadeModel(GL_FLAT); CHECK_GL_ERROR();
- glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST); CHECK_GL_ERROR();
- // Setup alpha blend (For overlay and cursor)
- glEnable(GL_BLEND); CHECK_GL_ERROR();
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); CHECK_GL_ERROR();
-
- // Enable rendering with vertex and coord arrays
- glEnableClientState(GL_VERTEX_ARRAY); CHECK_GL_ERROR();
- glEnableClientState(GL_TEXTURE_COORD_ARRAY); CHECK_GL_ERROR();
-
- glEnable(GL_TEXTURE_2D); CHECK_GL_ERROR();
-
- // Setup the GL viewport
- glViewport(0, 0, _videoMode.hardwareWidth, _videoMode.hardwareHeight); CHECK_GL_ERROR();
-
- // Setup coordinates system
- glMatrixMode(GL_PROJECTION); CHECK_GL_ERROR();
- glLoadIdentity(); CHECK_GL_ERROR();
-#ifdef USE_GLES
- glOrthof(0, _videoMode.hardwareWidth, _videoMode.hardwareHeight, 0, -1, 1); CHECK_GL_ERROR();
-#else
- glOrtho(0, _videoMode.hardwareWidth, _videoMode.hardwareHeight, 0, -1, 1); CHECK_GL_ERROR();
-#endif
- glMatrixMode(GL_MODELVIEW); CHECK_GL_ERROR();
- glLoadIdentity(); CHECK_GL_ERROR();
+ return intToFrac(width) / height;
}
-void OpenGLGraphicsManager::loadTextures() {
-#ifdef USE_RGB_COLOR
- if (_transactionDetails.formatChanged && _gameTexture) {
- delete _gameTexture;
- _gameTexture = 0;
+void OpenGLGraphicsManager::recalculateDisplayArea() {
+ if (!_gameScreen || _outputScreenHeight == 0) {
+ return;
}
-#endif
-
- if (!_gameTexture) {
- byte bpp;
- GLenum intformat;
- GLenum format;
- GLenum type;
-#ifdef USE_RGB_COLOR
- getGLPixelFormat(_screenFormat, bpp, intformat, format, type);
-#else
- getGLPixelFormat(Graphics::PixelFormat::createFormatCLUT8(), bpp, intformat, format, type);
-#endif
- _gameTexture = new GLTexture(bpp, intformat, format, type);
- } else
- _gameTexture->refresh();
-
- _overlayFormat = Graphics::PixelFormat(2, 5, 5, 5, 1, 11, 6, 1, 0);
-
- if (!_overlayTexture) {
- byte bpp;
- GLenum intformat;
- GLenum format;
- GLenum type;
- getGLPixelFormat(_overlayFormat, bpp, intformat, format, type);
- _overlayTexture = new GLTexture(bpp, intformat, format, type);
- } else
- _overlayTexture->refresh();
-
- if (!_cursorTexture)
- _cursorTexture = new GLTexture(4, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE);
- else
- _cursorTexture->refresh();
-
- GLint filter = _videoMode.antialiasing ? GL_LINEAR : GL_NEAREST;
- _gameTexture->setFilter(filter);
- _overlayTexture->setFilter(filter);
- _cursorTexture->setFilter(filter);
-
- // Allocate texture memory and finish refreshing
- _gameTexture->allocBuffer(_videoMode.screenWidth, _videoMode.screenHeight);
- _overlayTexture->allocBuffer(_videoMode.overlayWidth, _videoMode.overlayHeight);
- _cursorTexture->allocBuffer(_cursorState.w, _cursorState.h);
-
- if (
-#ifdef USE_RGB_COLOR
- _transactionDetails.formatChanged ||
-#endif
- _oldVideoMode.screenWidth != _videoMode.screenWidth ||
- _oldVideoMode.screenHeight != _videoMode.screenHeight)
- _screenData.create(_videoMode.screenWidth, _videoMode.screenHeight,
-#ifdef USE_RGB_COLOR
- _screenFormat
-#else
- Graphics::PixelFormat::createFormatCLUT8()
-#endif
- );
-
-
- if (_oldVideoMode.overlayWidth != _videoMode.overlayWidth ||
- _oldVideoMode.overlayHeight != _videoMode.overlayHeight)
- _overlayData.create(_videoMode.overlayWidth, _videoMode.overlayHeight,
- _overlayFormat);
- _screenNeedsRedraw = true;
- _overlayNeedsRedraw = true;
- _cursorNeedsRedraw = true;
+ const frac_t outputAspect = intToFrac(_outputScreenWidth) / _outputScreenHeight;
+ const frac_t desiredAspect = getDesiredGameScreenAspect();
- // We need to setup a proper unpack alignment value here, else we will
- // get problems with the texture updates, in case the surface data is
- // not properly aligned.
- // It is noteworthy this assumes the OSD uses the same BPP as the overlay
- // and that the cursor works with any alignment setting.
- int newAlignment = Common::gcd(_gameTexture->getBytesPerPixel(), _overlayTexture->getBytesPerPixel());
- assert(newAlignment == 1 || newAlignment == 2 || newAlignment == 4);
- glPixelStorei(GL_UNPACK_ALIGNMENT, newAlignment);
+ _displayWidth = _outputScreenWidth;
+ _displayHeight = _outputScreenHeight;
- // We use a "pack" alignment (when reading from textures) to 4 here,
- // since the only place where we really use it is the BMP screenshot
- // code and that requires the same alignment too.
- glPixelStorei(GL_PACK_ALIGNMENT, 4);
-
-#ifdef USE_OSD
- if (!_osdTexture)
- _osdTexture = new GLTexture(2, GL_RGBA, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1);
- else
- _osdTexture->refresh();
-
- _osdTexture->allocBuffer(_videoMode.overlayWidth, _videoMode.overlayHeight);
+ // Adjust one dimension for mantaining the aspect ratio.
+ if (outputAspect < desiredAspect) {
+ _displayHeight = intToFrac(_displayWidth) / desiredAspect;
+ } else if (outputAspect > desiredAspect) {
+ _displayWidth = fracToInt(_displayHeight * desiredAspect);
+ }
- // Update the OSD in case it is used right now
- _requireOSDUpdate = true;
-#endif
+ // We center the screen in the middle for now.
+ _displayX = (_outputScreenWidth - _displayWidth ) / 2;
+ _displayY = (_outputScreenHeight - _displayHeight) / 2;
}
-bool OpenGLGraphicsManager::loadGFXMode() {
- // Initialize OpenGL settings
- initGL();
-
- loadTextures();
-
- refreshCursorScale();
-
- refreshDisplaySize();
-
- internUpdateScreen();
-
- return true;
-}
+void OpenGLGraphicsManager::updateCursorPalette() {
+ if (!_cursor || !_cursor->hasPalette()) {
+ return;
+ }
-void OpenGLGraphicsManager::unloadGFXMode() {
+ if (_cursorPaletteEnabled) {
+ _cursor->setPalette(0, 256, _cursorPalette);
+ } else {
+ _cursor->setPalette(0, 256, _gamePalette);
+ }
+ // We remove all alpha bits from the palette entry of the color key.
+ // This makes sure its properly handled as color key.
+ const Graphics::PixelFormat &hardwareFormat = _cursor->getHardwareFormat();
+ const uint32 aMask = (0xFF >> hardwareFormat.aLoss) << hardwareFormat.aShift;
+
+ if (hardwareFormat.bytesPerPixel == 2) {
+ uint16 *palette = (uint16 *)_cursor->getPalette() + _cursorKeyColor;
+ *palette &= ~aMask;
+ } else if (hardwareFormat.bytesPerPixel == 4) {
+ uint32 *palette = (uint32 *)_cursor->getPalette() + _cursorKeyColor;
+ *palette &= ~aMask;
+ } else {
+ warning("OpenGLGraphicsManager::updateCursorPalette: Unsupported pixel depth %d", hardwareFormat.bytesPerPixel);
+ }
}
-void OpenGLGraphicsManager::setScale(int newScale) {
- assert(_transactionMode == kTransactionActive);
-
- if (newScale == _videoMode.scaleFactor)
+void OpenGLGraphicsManager::recalculateCursorScaling() {
+ if (!_cursor || !_gameScreen) {
return;
+ }
- _videoMode.scaleFactor = newScale;
- _transactionDetails.sizeChanged = true;
-}
+ // By default we use the unscaled versions.
+ _cursorHotspotXScaled = _cursorHotspotX;
+ _cursorHotspotYScaled = _cursorHotspotY;
+ _cursorWidthScaled = _cursor->getWidth();
+ _cursorHeightScaled = _cursor->getHeight();
-void OpenGLGraphicsManager::toggleAntialiasing() {
- assert(_transactionMode == kTransactionActive);
+ // In case scaling is actually enabled we will scale the cursor according
+ // to the game screen.
+ if (!_cursorDontScale) {
+ const uint screenScaleFactorX = _displayWidth * 10000 / _gameScreen->getWidth();
+ const uint screenScaleFactorY = _displayHeight * 10000 / _gameScreen->getHeight();
- _videoMode.antialiasing = !_videoMode.antialiasing;
- _transactionDetails.filterChanged = true;
-}
+ _cursorHotspotXScaled = (_cursorHotspotXScaled * screenScaleFactorX) / 10000;
+ _cursorWidthScaled = (_cursorWidthScaled * screenScaleFactorX) / 10000;
-uint OpenGLGraphicsManager::getAspectRatio() const {
- // In case we enable aspect ratio correction we force a 4/3 ratio.
- // But just for 320x200 and 640x400 games, since other games do not need
- // this.
- // TODO: This makes OpenGL Normal behave like OpenGL Conserve, when aspect
- // ratio correction is enabled, but it's better than the previous 4/3 mode
- // mess at least...
- if (_videoMode.aspectRatioCorrection
- && ((_videoMode.screenWidth == 320 && _videoMode.screenHeight == 200)
- || (_videoMode.screenWidth == 640 && _videoMode.screenHeight == 400)))
- return 13333;
- else if (_videoMode.mode == OpenGL::GFX_NORMAL)
- return _videoMode.hardwareWidth * 10000 / _videoMode.hardwareHeight;
- else
- return _videoMode.screenWidth * 10000 / _videoMode.screenHeight;
+ _cursorHotspotYScaled = (_cursorHotspotYScaled * screenScaleFactorY) / 10000;
+ _cursorHeightScaled = (_cursorHeightScaled * screenScaleFactorY) / 10000;
+ }
}
-void OpenGLGraphicsManager::adjustMousePosition(int16 &x, int16 &y) {
- if (_overlayVisible)
- return;
-
- x -= _displayX;
- y -= _displayY;
-
- if (_displayWidth != _videoMode.screenWidth)
- x = x * _videoMode.screenWidth / _displayWidth;
- if (_displayHeight != _videoMode.screenHeight)
- y = y * _videoMode.screenHeight / _displayHeight;
+#ifdef USE_OSD
+const Graphics::Font *OpenGLGraphicsManager::getFontOSD() {
+ return FontMan.getFontByUsage(Graphics::FontManager::kLocalizedFont);
}
+#endif
-bool OpenGLGraphicsManager::saveScreenshot(const char *filename) {
- int width = _videoMode.hardwareWidth;
- int height = _videoMode.hardwareHeight;
+void OpenGLGraphicsManager::saveScreenshot(const Common::String &filename) const {
+ const uint width = _outputScreenWidth;
+ const uint height = _outputScreenHeight;
// A line of a BMP image must have a size divisible by 4.
// We calculate the padding bytes needed here.
// Since we use a 3 byte per pixel mode, we can use width % 4 here, since
// it is equal to 4 - (width * 3) % 4. (4 - (width * Bpp) % 4, is the
// usual way of computing the padding bytes required).
- const int linePaddingSize = width % 4;
- const int lineSize = width * 3 + linePaddingSize;
+ const uint linePaddingSize = width % 4;
+ const uint lineSize = width * 3 + linePaddingSize;
// Allocate memory for screenshot
uint8 *pixels = new uint8[lineSize * height];
// Get pixel data from OpenGL buffer
-#ifdef USE_GLES
- glReadPixels(0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, pixels); CHECK_GL_ERROR();
-#else
- if (_formatBGR) {
- glReadPixels(0, 0, width, height, GL_BGR, GL_UNSIGNED_BYTE, pixels); CHECK_GL_ERROR();
- } else {
- glReadPixels(0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, pixels); CHECK_GL_ERROR();
+ GLCALL(glReadPixels(0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, pixels));
+
+ // BMP stores as BGR. Since we can't assume that GL_BGR is supported we
+ // will swap the components from the RGB we read to BGR on our own.
+ for (uint y = height; y-- > 0;) {
+ uint8 *line = pixels + y * lineSize;
+
+ for (uint x = width; x > 0; --x, line += 3) {
+ SWAP(line[0], line[2]);
+ }
}
-#endif
// Open file
Common::DumpFile out;
@@ -1324,73 +1136,6 @@ bool OpenGLGraphicsManager::saveScreenshot(const char *filename) {
// Free allocated memory
delete[] pixels;
-
- return true;
-}
-
-const char *OpenGLGraphicsManager::getCurrentModeName() {
- const char *modeName = 0;
- const OSystem::GraphicsMode *g = getSupportedGraphicsModes();
- while (g->name) {
- if (g->id == _videoMode.mode) {
- modeName = g->description;
- break;
- }
- g++;
- }
- return modeName;
-}
-
-#ifdef USE_OSD
-const Graphics::Font *OpenGLGraphicsManager::getFontOSD() {
- return FontMan.getFontByUsage(Graphics::FontManager::kLocalizedFont);
-}
-
-void OpenGLGraphicsManager::updateOSD() {
- // The font we are going to use:
- const Graphics::Font *font = getFontOSD();
-
- if (_osdSurface.w != _osdTexture->getWidth() || _osdSurface.h != _osdTexture->getHeight())
- _osdSurface.create(_osdTexture->getWidth(), _osdTexture->getHeight(), _overlayFormat);
- else
- // Clear everything
- memset(_osdSurface.getPixels(), 0, _osdSurface.h * _osdSurface.pitch);
-
- // Determine a rect which would contain the message string (clipped to the
- // screen dimensions).
- const int vOffset = 6;
- const int lineSpacing = 1;
- const int lineHeight = font->getFontHeight() + 2 * lineSpacing;
- int width = 0;
- int height = lineHeight * _osdLines.size() + 2 * vOffset;
- for (uint i = 0; i < _osdLines.size(); i++) {
- width = MAX(width, font->getStringWidth(_osdLines[i]) + 14);
- }
-
- // Clip the rect
- if (width > _osdSurface.w)
- width = _osdSurface.w;
- if (height > _osdSurface.h)
- height = _osdSurface.h;
-
- int dstX = (_osdSurface.w - width) / 2;
- int dstY = (_osdSurface.h - height) / 2;
-
- // Draw a dark gray rect (R = 40, G = 40, B = 40)
- const uint16 color = 0x294B;
- _osdSurface.fillRect(Common::Rect(dstX, dstY, dstX + width, dstY + height), color);
-
- // Render the message, centered, and in white
- for (uint i = 0; i < _osdLines.size(); i++) {
- font->drawString(&_osdSurface, _osdLines[i],
- dstX, dstY + i * lineHeight + vOffset + lineSpacing, width,
- 0xFFFF, Graphics::kTextAlignCenter);
- }
-
- // Update the texture
- _osdTexture->updateBuffer(_osdSurface.getPixels(), _osdSurface.pitch, 0, 0,
- _osdSurface.w, _osdSurface.h);
}
-#endif
-#endif
+} // End of namespace OpenGL
diff --git a/backends/graphics/opengl/opengl-graphics.h b/backends/graphics/opengl/opengl-graphics.h
index 9d8d418d11..93c0c5bc83 100644
--- a/backends/graphics/opengl/opengl-graphics.h
+++ b/backends/graphics/opengl/opengl-graphics.h
@@ -8,338 +8,464 @@
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
-
+ *
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-
+ *
* You should have received a copy of the GNU General Public 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_GRAPHICS_OPENGL_H
-#define BACKENDS_GRAPHICS_OPENGL_H
+#ifndef BACKENDS_GRAPHICS_OPENGL_OPENGL_GRAPHICS_H
+#define BACKENDS_GRAPHICS_OPENGL_OPENGL_GRAPHICS_H
-#include "backends/graphics/opengl/gltexture.h"
+#include "backends/graphics/opengl/opengl-sys.h"
#include "backends/graphics/graphics.h"
-#include "common/array.h"
-#include "common/rect.h"
-#include "graphics/font.h"
-#include "graphics/pixelformat.h"
-// Uncomment this to enable the 'on screen display' code.
-#define USE_OSD 1
+#include "common/frac.h"
+#include "common/mutex.h"
+
+namespace Graphics {
+class Font;
+} // End of namespace Graphics
namespace OpenGL {
-// The OpenGL GFX modes. They have to be inside the OpenGL namespace so they
-// do not clash with the SDL GFX modes.
+
+// HACK: We use glColor in the OSD code. This might not be working on GL ES but
+// we still enable it because Tizen already shipped with it. Also, the
+// SurfaceSDL backend enables it and disabling it can cause issues in sdl.cpp.
+#define USE_OSD 1
+
+class Texture;
+
enum {
- GFX_NORMAL = 0,
- GFX_CONSERVE = 1,
- GFX_ORIGINAL = 2
+ GFX_LINEAR = 0,
+ GFX_NEAREST = 1
};
-}
-
-/**
- * OpenGL graphics manager. This is an abstract class, it does not do the
- * window and OpenGL context initialization.
- * Derived classes should at least override internUpdateScreen for doing
- * the buffers swap, and implement loadGFXMode for handling the window/context if
- * needed. If USE_RGB_COLOR is enabled, getSupportedFormats must be implemented.
- */
-class OpenGLGraphicsManager : public GraphicsManager {
+class OpenGLGraphicsManager : virtual public GraphicsManager {
public:
OpenGLGraphicsManager();
virtual ~OpenGLGraphicsManager();
+ // GraphicsManager API
virtual bool hasFeature(OSystem::Feature f);
virtual void setFeatureState(OSystem::Feature f, bool enable);
virtual bool getFeatureState(OSystem::Feature f);
- static const OSystem::GraphicsMode *supportedGraphicsModes();
virtual const OSystem::GraphicsMode *getSupportedGraphicsModes() const;
virtual int getDefaultGraphicsMode() const;
virtual bool setGraphicsMode(int mode);
virtual int getGraphicsMode() const;
- virtual void resetGraphicsScale();
+
+ virtual void resetGraphicsScale() {}
+
#ifdef USE_RGB_COLOR
virtual Graphics::PixelFormat getScreenFormat() const;
virtual Common::List<Graphics::PixelFormat> getSupportedFormats() const = 0;
#endif
- virtual void initSize(uint width, uint height, const Graphics::PixelFormat *format = NULL);
- virtual int getScreenChangeID() const;
virtual void beginGFXTransaction();
virtual OSystem::TransactionError endGFXTransaction();
- virtual int16 getHeight();
+ virtual int getScreenChangeID() const;
+
+ virtual void initSize(uint width, uint height, const Graphics::PixelFormat *format);
+
virtual int16 getWidth();
-protected:
- // PaletteManager API
- virtual void setPalette(const byte *colors, uint start, uint num);
- virtual void grabPalette(byte *colors, uint start, uint num);
+ virtual int16 getHeight();
-public:
virtual void copyRectToScreen(const void *buf, int pitch, int x, int y, int w, int h);
- virtual Graphics::Surface *lockScreen();
- virtual void unlockScreen();
virtual void fillScreen(uint32 col);
- virtual void updateScreen();
+
virtual void setShakePos(int shakeOffset);
- virtual void setFocusRectangle(const Common::Rect &rect);
+
+ virtual void updateScreen();
+
+ virtual Graphics::Surface *lockScreen();
+ virtual void unlockScreen();
+
+ virtual void setFocusRectangle(const Common::Rect& rect);
virtual void clearFocusRectangle();
+ virtual int16 getOverlayWidth();
+ virtual int16 getOverlayHeight();
+
virtual void showOverlay();
virtual void hideOverlay();
+
virtual Graphics::PixelFormat getOverlayFormat() const;
+
+ virtual void copyRectToOverlay(const void *buf, int pitch, int x, int y, int w, int h);
virtual void clearOverlay();
virtual void grabOverlay(void *buf, int pitch);
- virtual void copyRectToOverlay(const void *buf, int pitch, int x, int y, int w, int h);
- virtual int16 getOverlayHeight();
- virtual int16 getOverlayWidth();
virtual bool showMouse(bool visible);
virtual void warpMouse(int x, int y);
- virtual void setMouseCursor(const void *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, bool dontScale = false, const Graphics::PixelFormat *format = NULL);
+ virtual void setMouseCursor(const void *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, bool dontScale, const Graphics::PixelFormat *format);
virtual void setCursorPalette(const byte *colors, uint start, uint num);
virtual void displayMessageOnOSD(const char *msg);
+
+ // PaletteManager interface
+ virtual void setPalette(const byte *colors, uint start, uint num);
+ virtual void grabPalette(byte *colors, uint start, uint num);
+
protected:
/**
- * Setup OpenGL settings
+ * Set up the actual screen size available for the OpenGL code to do any
+ * drawing.
+ *
+ * @param width The width of the screen.
+ * @param height The height of the screen.
+ */
+ void setActualScreenSize(uint width, uint height);
+
+ /**
+ * Notify the manager of a OpenGL context change. This should be the first
+ * thing to call when you create an OpenGL (ES) context!
+ *
+ * @param defaultFormat The new default format for the game screen
+ * (this is used for the CLUT8 game screens).
+ * @param defaultFromatAlpha The new default format with an alpha channel
+ * (this is used for the overlay and cursor).
+ */
+ void notifyContextChange(const Graphics::PixelFormat &defaultFormat, const Graphics::PixelFormat &defaultFormatAlpha);
+
+ /**
+ * Adjust the physical mouse coordinates according to the currently visible screen.
+ */
+ void adjustMousePosition(int16 &x, int16 &y);
+
+ /**
+ * Set up the mouse position for graphics output.
+ *
+ * @param x X coordinate in physical coordinates.
+ * @param y Y coordinate in physical coordinates.
+ */
+ void setMousePosition(int x, int y) { _cursorX = x; _cursorY = y; }
+
+ /**
+ * Query the mouse position in physical coordinates.
*/
- virtual void initGL();
+ void getMousePosition(int16 &x, int16 &y) const { x = _cursorX; y = _cursorY; }
/**
- * Creates and refreshs OpenGL textures.
+ * Set up the mouse position for the (event) system.
+ *
+ * @param x X coordinate in physical coordinates.
+ * @param y Y coordinate in physical coordinates.
*/
- virtual void loadTextures();
+ virtual void setInternalMousePosition(int x, int y) = 0;
+private:
//
- // GFX and video
+ // Transaction support
//
- enum {
- kTransactionNone = 0,
- kTransactionActive = 1,
- kTransactionRollback = 2
- };
-
- struct TransactionDetails {
- bool sizeChanged;
- bool needRefresh;
- bool needUpdatescreen;
- bool filterChanged;
+ struct VideoState {
+ VideoState() : valid(false), gameWidth(0), gameHeight(0),
#ifdef USE_RGB_COLOR
- bool formatChanged;
+ gameFormat(),
#endif
- };
- TransactionDetails _transactionDetails;
- int _transactionMode;
-
- struct VideoState {
- bool setup;
+ aspectRatioCorrection(false), graphicsMode(GFX_LINEAR) {
+ }
- bool fullscreen;
+ bool valid;
- int mode;
- int scaleFactor;
- bool antialiasing;
+ uint gameWidth, gameHeight;
+#ifdef USE_RGB_COLOR
+ Graphics::PixelFormat gameFormat;
+#endif
bool aspectRatioCorrection;
+ int graphicsMode;
- int screenWidth, screenHeight;
- int overlayWidth, overlayHeight;
- int hardwareWidth, hardwareHeight;
+ bool operator==(const VideoState &right) {
+ return gameWidth == right.gameWidth && gameHeight == right.gameHeight
#ifdef USE_RGB_COLOR
- Graphics::PixelFormat format;
+ && gameFormat == right.gameFormat
#endif
+ && aspectRatioCorrection == right.aspectRatioCorrection
+ && graphicsMode == right.graphicsMode;
+ }
+
+ bool operator!=(const VideoState &right) {
+ return !(*this == right);
+ }
};
- VideoState _videoMode, _oldVideoMode;
/**
- * Sets the OpenGL texture format for the given pixel format. If format is not support will raise an error.
+ * The currently setup video state.
*/
- virtual void getGLPixelFormat(Graphics::PixelFormat pixelFormat, byte &bpp, GLenum &intFormat, GLenum &glFormat, GLenum &type);
+ VideoState _currentState;
- virtual void internUpdateScreen();
- virtual bool loadGFXMode();
- virtual void unloadGFXMode();
+ /**
+ * The old video state used when doing a transaction rollback.
+ */
+ VideoState _oldState;
+protected:
+ enum TransactionMode {
+ kTransactionNone = 0,
+ kTransactionActive = 1,
+ kTransactionRollback = 2
+ };
+
+ TransactionMode getTransactionMode() const { return _transactionMode; }
+
+private:
/**
- * Setup the fullscreen mode state.
+ * The current transaction mode.
*/
- void setFullscreenMode(bool enable);
+ TransactionMode _transactionMode;
/**
- * Query the fullscreen state.
+ * The current screen change ID.
*/
- inline bool getFullscreenMode() const { return _videoMode.fullscreen; }
+ int _screenChangeID;
+protected:
/**
- * Set the scale factor.
+ * Set up the requested video mode. This takes parameters which describe
+ * what resolution the game screen requests (this is possibly aspect ratio
+ * corrected!).
*
- * This can only be used in a GFX transaction.
+ * A sub-class should take these parameters as hints. It might very well
+ * set up a mode which it thinks suites the situation best.
*
- * @param newScale New scale factor.
+ * @parma requestedWidth This is the requested actual game screen width.
+ * @param requestedHeight This is the requested actual game screen height.
+ * @param format This is the requested pixel format of the virtual game screen.
+ * @return true on success, false otherwise
*/
- void setScale(int newScale);
+ virtual bool loadVideoMode(uint requestedWidth, uint requestedHeight, const Graphics::PixelFormat &format) = 0;
/**
- * Query the scale factor.
+ * Save a screenshot of the full display as BMP to the given file. This
+ * uses Common::DumpFile for writing the screenshot.
+ *
+ * @param filename The output filename.
*/
- inline int getScale() const { return _videoMode.scaleFactor; }
+ void saveScreenshot(const Common::String &filename) const;
+
+private:
+ //
+ // OpenGL utilities
+ //
/**
- * Toggle the antialiasing state of the current video mode.
+ * Try to determine the internal parameters for a given pixel format.
*
- * This can only be used in a GFX transaction.
+ * @return true when the format can be used, false otherwise.
+ */
+ bool getGLPixelFormat(const Graphics::PixelFormat &pixelFormat, GLenum &glIntFormat, GLenum &glFormat, GLenum &glType) const;
+
+ //
+ // Actual hardware screen
+ //
+
+ /**
+ * The width of the physical output.
+ */
+ uint _outputScreenWidth;
+
+ /**
+ * The height of the physical output.
+ */
+ uint _outputScreenHeight;
+
+ /**
+ * @return The desired aspect of the game screen.
+ */
+ frac_t getDesiredGameScreenAspect() const;
+
+ /**
+ * Recalculates the area used to display the game screen.
*/
- void toggleAntialiasing();
+ void recalculateDisplayArea();
/**
- * Query the antialiasing state.
+ * The X coordinate of the game screen.
*/
- inline bool getAntialiasingState() const { return _videoMode.antialiasing; }
+ uint _displayX;
- // Drawing coordinates for the current display mode and scale
- int _displayX;
- int _displayY;
- int _displayWidth;
- int _displayHeight;
+ /**
+ * The Y coordinate of the game screen.
+ */
+ uint _displayY;
- virtual const char *getCurrentModeName();
+ /**
+ * The width of the game screen in physical coordinates.
+ */
+ uint _displayWidth;
- virtual void calculateDisplaySize(int &width, int &height);
- virtual void refreshDisplaySize();
+ /**
+ * The height of the game screen in physical coordinates.
+ */
+ uint _displayHeight;
- uint getAspectRatio() const;
+ /**
+ * The default pixel format of the backend.
+ */
+ Graphics::PixelFormat _defaultFormat;
- void setFormatIsBGR(bool isBGR) { _formatBGR = isBGR; }
- bool _formatBGR;
+ /**
+ * The default pixel format with an alpha channel.
+ */
+ Graphics::PixelFormat _defaultFormatAlpha;
//
// Game screen
//
- GLTexture *_gameTexture;
- Graphics::Surface _screenData;
- int _screenChangeCount;
- bool _screenNeedsRedraw;
- Common::Rect _screenDirtyRect;
-#ifdef USE_RGB_COLOR
- Graphics::PixelFormat _screenFormat;
-#endif
- byte *_gamePalette;
+ /**
+ * The virtual game screen.
+ */
+ Texture *_gameScreen;
- virtual void refreshGameScreen();
+ /**
+ * The game palette if in CLUT8 mode.
+ */
+ byte _gamePalette[3 * 256];
- // Shake mode
- int _shakePos;
+ /**
+ * The offset by which the screen is moved vertically.
+ */
+ int _gameScreenShakeOffset;
//
// Overlay
//
- GLTexture *_overlayTexture;
- Graphics::Surface _overlayData;
- Graphics::PixelFormat _overlayFormat;
- bool _overlayVisible;
- bool _overlayNeedsRedraw;
- Common::Rect _overlayDirtyRect;
- virtual void refreshOverlay();
+ /**
+ * The overlay screen.
+ */
+ Texture *_overlay;
+
+ /**
+ * Whether the overlay is visible or not.
+ */
+ bool _overlayVisible;
//
- // Mouse
+ // Cursor
//
- struct MousePos {
- // The mouse position in hardware screen coordinates.
- int16 x, y;
- // The size and hotspot of the original cursor image.
- int16 w, h;
- int16 hotX, hotY;
+ /**
+ * Set up the correct cursor palette.
+ */
+ void updateCursorPalette();
- // The size and hotspot of the scaled cursor, in real coordinates.
- int16 rW, rH;
- int16 rHotX, rHotY;
+ /**
+ * The cursor image.
+ */
+ Texture *_cursor;
- // The size and hotspot of the scaled cursor, in game coordinates.
- int16 vW, vH;
- int16 vHotX, vHotY;
+ /**
+ * X coordinate of the cursor in phyiscal coordinates.
+ */
+ uint _cursorX;
- MousePos() : x(0), y(0), w(0), h(0), hotX(0), hotY(0),
- rW(0), rH(0), rHotX(0), rHotY(0), vW(0), vH(0),
- vHotX(0), vHotY(0) {}
- };
+ /**
+ * Y coordinate of the cursor in physical coordinates.
+ */
+ uint _cursorY;
- GLTexture *_cursorTexture;
- Graphics::Surface _cursorData;
- Graphics::PixelFormat _cursorFormat;
- byte *_cursorPalette;
- bool _cursorPaletteDisabled;
- MousePos _cursorState;
- bool _cursorVisible;
+ /**
+ * The X offset for the cursor hotspot in unscaled coordinates.
+ */
+ uint _cursorHotspotX;
+
+ /**
+ * The Y offset for the cursor hotspot in unscaled coordinates.
+ */
+ uint _cursorHotspotY;
+
+ /**
+ * Recalculate the cursor scaling. Scaling is always done according to
+ * the game screen.
+ */
+ void recalculateCursorScaling();
+
+ /**
+ * The X offset for the cursor hotspot in scaled coordinates.
+ */
+ uint _cursorHotspotXScaled;
+
+ /**
+ * The Y offset for the cursor hotspot in scaled coordinates.
+ */
+ uint _cursorHotspotYScaled;
+
+ /**
+ * The width of the cursor scaled coordinates.
+ */
+ uint _cursorWidthScaled;
+
+ /**
+ * The height of the cursor scaled coordinates.
+ */
+ uint _cursorHeightScaled;
+
+ /**
+ * The key color.
+ */
uint32 _cursorKeyColor;
- bool _cursorDontScale;
- bool _cursorNeedsRedraw;
/**
- * Set up the mouse position for graphics output.
- *
- * @param x X coordinate in native coordinates.
- * @param y Y coordinate in native coordinates.
+ * Whether the cursor is actually visible.
*/
- void setMousePosition(int x, int y) { _cursorState.x = x; _cursorState.y = y; }
+ bool _cursorVisible;
- virtual void refreshCursor();
- virtual void refreshCursorScale();
+ /**
+ * Whether no cursor scaling should be applied.
+ */
+ bool _cursorDontScale;
/**
- * Set up the mouse position for the (event) system.
- *
- * @param x X coordinate in native coordinates.
- * @param y Y coordinate in native coordinates.
+ * Whether the special cursor palette is enabled.
*/
- virtual void setInternalMousePosition(int x, int y) = 0;
+ bool _cursorPaletteEnabled;
/**
- * Adjusts hardware screen coordinates to either overlay or game screen
- * coordinates depending on whether the overlay is visible or not.
- *
- * @param x X coordinate of the mouse position.
- * @param y Y coordinate of the mouse position.
+ * The special cursor palette in case enabled.
*/
- virtual void adjustMousePosition(int16 &x, int16 &y);
+ byte _cursorPalette[3 * 256];
+#ifdef USE_OSD
//
- // Misc
+ // OSD
//
- virtual bool saveScreenshot(const char *filename);
-
-#ifdef USE_OSD
+protected:
/**
* Returns the font used for on screen display
*/
virtual const Graphics::Font *getFontOSD();
+private:
/**
- * Update the OSD texture / surface.
+ * The OSD's contents.
*/
- void updateOSD();
+ Texture *_osd;
/**
- * The OSD contents.
+ * Current opacity level of the OSD.
*/
- Common::Array<Common::String> _osdLines;
-
- GLTexture *_osdTexture;
- Graphics::Surface _osdSurface;
uint8 _osdAlpha;
+
+ /**
+ * When fading the OSD has started.
+ */
uint32 _osdFadeStartTime;
- bool _requireOSDUpdate;
+
+ /**
+ * Mutex to allow displayMessageOnOSD to be used from the audio thread.
+ */
+ Common::Mutex _osdMutex;
+
enum {
kOSDFadeOutDelay = 2 * 1000,
kOSDFadeOutDuration = 500,
@@ -348,4 +474,6 @@ protected:
#endif
};
+} // End of namespace OpenGL
+
#endif
diff --git a/backends/graphics/opengl/glerrorcheck.cpp b/backends/graphics/opengl/opengl-sys.h
index 439593577d..a3524b28d2 100644
--- a/backends/graphics/opengl/glerrorcheck.cpp
+++ b/backends/graphics/opengl/opengl-sys.h
@@ -8,25 +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
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-
+ *
* You should have received a copy of the GNU General Public 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"
+#ifndef BACKENDS_GRAPHICS_OPENGL_OPENGL_H
+#define BACKENDS_GRAPHICS_OPENGL_OPENGL_H
-#if defined(DEBUG) && defined(USE_OPENGL)
+// The purpose of this header is to include the OpenGL headers in an uniform
+// fashion. A notable example for a non standard port is the Tizen port.
-#include "backends/graphics/opengl/glerrorcheck.h"
-#include "common/textconsole.h"
-#include "common/str.h"
+#include "common/scummsys.h"
#ifdef WIN32
#if defined(ARRAYSIZE) && !defined(_WINDOWS_)
@@ -37,31 +37,21 @@
#undef ARRAYSIZE
#endif
-#if defined(USE_GLES)
+// HACK: In case common/util.h has been included already we need to make sure
+// to define ARRAYSIZE again in case of Windows.
+#if !defined(ARRAYSIZE) && defined(COMMON_UTIL_H)
+#define ARRAYSIZE(x) ((int)(sizeof(x) / sizeof(x[0])))
+#endif
+
+#if defined(TIZEN)
+#include <FGraphicsOpengl.h>
+using namespace Tizen::Graphics::Opengl;
+#elif defined(USE_GLES)
#include <GLES/gl.h>
-#elif defined(MACOSX)
-#include <OpenGL/gl.h>
+#elif defined(SDL_BACKEND)
+#include <SDL_opengl.h>
#else
#include <GL/gl.h>
#endif
-static Common::String getGlErrStr(GLenum error) {
- switch (error) {
- case GL_NO_ERROR: return "GL_NO_ERROR";
- case GL_INVALID_ENUM: return "GL_INVALID_ENUM";
- case GL_INVALID_OPERATION: return "GL_INVALID_OPERATION";
- case GL_STACK_OVERFLOW: return "GL_STACK_OVERFLOW";
- case GL_STACK_UNDERFLOW: return "GL_STACK_UNDERFLOW";
- case GL_OUT_OF_MEMORY: return "GL_OUT_OF_MEMORY";
- }
-
- return Common::String::format("(Unknown GL error code 0x%x)", error);
-}
-
-void checkGlError(const char *file, int line) {
- GLenum error = glGetError();
- if (error != GL_NO_ERROR)
- warning("%s:%d: GL error: %s", file, line, getGlErrStr(error).c_str());
-}
-
#endif
diff --git a/backends/graphics/opengl/texture.cpp b/backends/graphics/opengl/texture.cpp
new file mode 100644
index 0000000000..8f17ed7eeb
--- /dev/null
+++ b/backends/graphics/opengl/texture.cpp
@@ -0,0 +1,371 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public 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 "backends/graphics/opengl/texture.h"
+#include "backends/graphics/opengl/extensions.h"
+#include "backends/graphics/opengl/debug.h"
+
+#include "common/rect.h"
+#include "common/textconsole.h"
+
+namespace OpenGL {
+
+static GLuint nextHigher2(GLuint v) {
+ if (v == 0)
+ return 1;
+ v--;
+ v |= v >> 1;
+ v |= v >> 2;
+ v |= v >> 4;
+ v |= v >> 8;
+ v |= v >> 16;
+ return ++v;
+}
+
+GLint Texture::_maxTextureSize = 0;
+
+void Texture::queryTextureInformation() {
+ glGetIntegerv(GL_MAX_TEXTURE_SIZE, &_maxTextureSize);
+ debug(5, "OpenGL maximum texture size: %d", _maxTextureSize);
+}
+
+Texture::Texture(GLenum glIntFormat, GLenum glFormat, GLenum glType, const Graphics::PixelFormat &format)
+ : _glIntFormat(glIntFormat), _glFormat(glFormat), _glType(glType), _format(format), _glFilter(GL_NEAREST),
+ _glTexture(0), _textureData(), _userPixelData(), _allDirty(false) {
+ recreateInternalTexture();
+}
+
+Texture::~Texture() {
+ releaseInternalTexture();
+ _textureData.free();
+}
+
+void Texture::releaseInternalTexture() {
+ GLCALL(glDeleteTextures(1, &_glTexture));
+ _glTexture = 0;
+}
+
+void Texture::recreateInternalTexture() {
+ // Get a new texture name.
+ GLCALL(glGenTextures(1, &_glTexture));
+
+ // Set up all texture parameters.
+ GLCALL(glBindTexture(GL_TEXTURE_2D, _glTexture));
+ GLCALL(glPixelStorei(GL_UNPACK_ALIGNMENT, 1));
+ GLCALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, _glFilter));
+ GLCALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, _glFilter));
+ GLCALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
+ GLCALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
+
+ // In case there is an actual texture setup we reinitialize it.
+ if (_textureData.getPixels()) {
+ // Allocate storage for OpenGL texture.
+ GLCALL(glTexImage2D(GL_TEXTURE_2D, 0, _glIntFormat, _textureData.w,
+ _textureData.h, 0, _glFormat, _glType, NULL));
+
+ // Mark dirts such that it will be completely refreshed the next time.
+ flagDirty();
+ }
+}
+
+void Texture::enableLinearFiltering(bool enable) {
+ if (enable) {
+ _glFilter = GL_LINEAR;
+ } else {
+ _glFilter = GL_NEAREST;
+ }
+
+ GLCALL(glBindTexture(GL_TEXTURE_2D, _glTexture));
+
+ GLCALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, _glFilter));
+ GLCALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, _glFilter));
+}
+
+void Texture::allocate(uint width, uint height) {
+ uint texWidth = width, texHeight = height;
+ if (!g_extNPOTSupported) {
+ texWidth = nextHigher2(texWidth);
+ texHeight = nextHigher2(texHeight);
+ }
+
+ // In case the needed texture dimension changed we will reinitialize the
+ // texture.
+ if (texWidth != _textureData.w || texHeight != _textureData.h) {
+ // Create a buffer for the texture data.
+ _textureData.create(texWidth, texHeight, _format);
+
+ // Set the texture.
+ GLCALL(glBindTexture(GL_TEXTURE_2D, _glTexture));
+
+ // Allocate storage for OpenGL texture.
+ GLCALL(glTexImage2D(GL_TEXTURE_2D, 0, _glIntFormat, _textureData.w,
+ _textureData.h, 0, _glFormat, _glType, NULL));
+ }
+
+ // Create a sub-buffer for raw access.
+ _userPixelData = _textureData.getSubArea(Common::Rect(width, height));
+}
+
+void Texture::copyRectToTexture(uint x, uint y, uint w, uint h, const void *srcPtr, uint srcPitch) {
+ Graphics::Surface *dstSurf = getSurface();
+ assert(x + w <= dstSurf->w);
+ assert(y + h <= dstSurf->h);
+
+ // *sigh* Common::Rect::extend behaves unexpected whenever one of the two
+ // parameters is an empty rect. Thus, we check whether the current dirty
+ // area is valid. In case it is not we simply use the parameters as new
+ // dirty area. Otherwise, we simply call extend.
+ if (_dirtyArea.isEmpty()) {
+ _dirtyArea = Common::Rect(x, y, x + w, y + h);
+ } else {
+ _dirtyArea.extend(Common::Rect(x, y, x + w, y + h));
+ }
+
+ const byte *src = (const byte *)srcPtr;
+ byte *dst = (byte *)dstSurf->getBasePtr(x, y);
+ const uint pitch = dstSurf->pitch;
+ const uint bytesPerPixel = dstSurf->format.bytesPerPixel;
+
+ if (srcPitch == pitch && x == 0 && w == dstSurf->w) {
+ memcpy(dst, src, h * pitch);
+ } else {
+ while (h-- > 0) {
+ memcpy(dst, src, w * bytesPerPixel);
+ dst += pitch;
+ src += srcPitch;
+ }
+ }
+}
+
+void Texture::fill(uint32 color) {
+ Graphics::Surface *dst = getSurface();
+ dst->fillRect(Common::Rect(dst->w, dst->h), color);
+
+ flagDirty();
+}
+
+void Texture::draw(GLuint x, GLuint y, GLuint w, GLuint h) {
+ // Only do any processing when the Texture is initialized.
+ if (!_textureData.getPixels()) {
+ return;
+ }
+
+ // First update any potentional changes.
+ updateTexture();
+
+ // Set the texture.
+ GLCALL(glBindTexture(GL_TEXTURE_2D, _glTexture));
+
+ // Calculate the texture rect that will be drawn.
+ const GLfloat texWidth = (GLfloat)_userPixelData.w / _textureData.w;
+ const GLfloat texHeight = (GLfloat)_userPixelData.h / _textureData.h;
+ const GLfloat texcoords[4*2] = {
+ 0, 0,
+ texWidth, 0,
+ 0, texHeight,
+ texWidth, texHeight
+ };
+ GLCALL(glTexCoordPointer(2, GL_FLOAT, 0, texcoords));
+
+ // Calculate the screen rect where the texture will be drawn.
+ const GLshort vertices[4*2] = {
+ (GLshort)x, (GLshort)y,
+ (GLshort)(x + w), (GLshort)y,
+ (GLshort)x, (GLshort)(y + h),
+ (GLshort)(x + w), (GLshort)(y + h)
+ };
+ GLCALL(glVertexPointer(2, GL_SHORT, 0, vertices));
+
+ // Draw the texture to the screen buffer.
+ GLCALL(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4));
+}
+
+void Texture::updateTexture() {
+ if (!isDirty()) {
+ return;
+ }
+
+ Common::Rect dirtyArea = getDirtyArea();
+
+ // In case we use linear filtering we might need to duplicate the last
+ // pixel row/column to avoid glitches with filtering.
+ if (_glFilter == GL_LINEAR) {
+ if (dirtyArea.right == _userPixelData.w && _userPixelData.w != _textureData.w) {
+ uint height = dirtyArea.height();
+
+ const byte *src = (const byte *)_textureData.getBasePtr(_userPixelData.w - 1, dirtyArea.top);
+ byte *dst = (byte *)_textureData.getBasePtr(_userPixelData.w, dirtyArea.top);
+
+ while (height-- > 0) {
+ memcpy(dst, src, _textureData.format.bytesPerPixel);
+ dst += _textureData.pitch;
+ src += _textureData.pitch;
+ }
+
+ // Extend the dirty area.
+ ++dirtyArea.right;
+ }
+
+ if (dirtyArea.bottom == _userPixelData.h && _userPixelData.h != _textureData.h) {
+ const byte *src = (const byte *)_textureData.getBasePtr(dirtyArea.left, _userPixelData.h - 1);
+ byte *dst = (byte *)_textureData.getBasePtr(dirtyArea.left, _userPixelData.h);
+ memcpy(dst, src, dirtyArea.width() * _textureData.format.bytesPerPixel);
+
+ // Extend the dirty area.
+ ++dirtyArea.bottom;
+ }
+ }
+
+ // Set the texture.
+ GLCALL(glBindTexture(GL_TEXTURE_2D, _glTexture));
+
+ // Update the actual texture.
+ // Although we keep track of the dirty part of the texture buffer we
+ // cannot take advantage of the left/right boundries here because it is
+ // not possible to specify a pitch to glTexSubImage2D. To be precise, with
+ // plain OpenGL we could set GL_UNPACK_ROW_LENGTH to achieve this. However,
+ // OpenGL ES 1.0 does not support GL_UNPACK_ROW_LENGTH. Thus, we are left
+ // with the following options:
+ //
+ // 1) (As we do right now) Simply always update the whole texture lines of
+ // rect changed. This is simplest to implement. In case performance is
+ // really an issue we can think of switching to another method.
+ //
+ // 2) Copy the dirty rect to a temporary buffer and upload that by using
+ // glTexSubImage2D. This is what the Android backend does. It is more
+ // complicated though.
+ //
+ // 3) Use glTexSubImage2D per line changed. This is what the old OpenGL
+ // graphics manager did but it is much slower! Thus, we do not use it.
+ GLCALL(glTexSubImage2D(GL_TEXTURE_2D, 0, 0, dirtyArea.top, _textureData.w, dirtyArea.height(),
+ _glFormat, _glType, _textureData.getBasePtr(0, dirtyArea.top)));
+
+ // We should have handled everything, thus not dirty anymore.
+ clearDirty();
+}
+
+Common::Rect Texture::getDirtyArea() const {
+ if (_allDirty) {
+ return Common::Rect(_userPixelData.w, _userPixelData.h);
+ } else {
+ return _dirtyArea;
+ }
+}
+
+TextureCLUT8::TextureCLUT8(GLenum glIntFormat, GLenum glFormat, GLenum glType, const Graphics::PixelFormat &format)
+ : Texture(glIntFormat, glFormat, glType, format), _clut8Data(), _palette(new byte[256 * format.bytesPerPixel]) {
+ memset(_palette, 0, sizeof(byte) * format.bytesPerPixel);
+}
+
+TextureCLUT8::~TextureCLUT8() {
+ delete[] _palette;
+ _palette = nullptr;
+ _clut8Data.free();
+}
+
+void TextureCLUT8::allocate(uint width, uint height) {
+ Texture::allocate(width, height);
+
+ // We only need to reinitialize our CLUT8 surface when the output size
+ // changed.
+ if (width == _clut8Data.w && height == _clut8Data.h) {
+ return;
+ }
+
+ _clut8Data.create(width, height, Graphics::PixelFormat::createFormatCLUT8());
+}
+
+Graphics::PixelFormat TextureCLUT8::getFormat() const {
+ return Graphics::PixelFormat::createFormatCLUT8();
+}
+
+namespace {
+template<typename ColorType>
+inline void convertPalette(ColorType *dst, const byte *src, uint colors, const Graphics::PixelFormat &format) {
+ while (colors-- > 0) {
+ *dst++ = format.RGBToColor(src[0], src[1], src[2]);
+ src += 3;
+ }
+}
+} // End of anonymous namespace
+
+void TextureCLUT8::setPalette(uint start, uint colors, const byte *palData) {
+ const Graphics::PixelFormat &hardwareFormat = getHardwareFormat();
+
+ if (hardwareFormat.bytesPerPixel == 2) {
+ convertPalette<uint16>((uint16 *)_palette + start, palData, colors, hardwareFormat);
+ } else if (hardwareFormat.bytesPerPixel == 4) {
+ convertPalette<uint32>((uint32 *)_palette + start, palData, colors, hardwareFormat);
+ } else {
+ warning("TextureCLUT8::setPalette: Unsupported pixel depth: %d", hardwareFormat.bytesPerPixel);
+ }
+
+ // A palette changes means we need to refresh the whole surface.
+ flagDirty();
+}
+
+namespace {
+template<typename PixelType>
+inline void doPaletteLookUp(PixelType *dst, const byte *src, uint width, uint height, uint dstPitch, uint srcPitch, const PixelType *palette) {
+ uint srcAdd = srcPitch - width;
+ uint dstAdd = dstPitch - width * sizeof(PixelType);
+
+ while (height-- > 0) {
+ for (uint x = width; x > 0; --x) {
+ *dst++ = palette[*src++];
+ }
+
+ dst = (PixelType *)((byte *)dst + dstAdd);
+ src += srcAdd;
+ }
+}
+} // End of anonymous namespace
+
+void TextureCLUT8::updateTexture() {
+ if (!isDirty()) {
+ return;
+ }
+
+ // Do the palette look up
+ Graphics::Surface *outSurf = Texture::getSurface();
+
+ Common::Rect dirtyArea = getDirtyArea();
+
+ if (outSurf->format.bytesPerPixel == 2) {
+ doPaletteLookUp<uint16>((uint16 *)outSurf->getBasePtr(dirtyArea.left, dirtyArea.top),
+ (const byte *)_clut8Data.getBasePtr(dirtyArea.left, dirtyArea.top),
+ dirtyArea.width(), dirtyArea.height(),
+ outSurf->pitch, _clut8Data.pitch, (const uint16 *)_palette);
+ } else if (outSurf->format.bytesPerPixel == 4) {
+ doPaletteLookUp<uint32>((uint32 *)outSurf->getBasePtr(dirtyArea.left, dirtyArea.top),
+ (const byte *)_clut8Data.getBasePtr(dirtyArea.left, dirtyArea.top),
+ dirtyArea.width(), dirtyArea.height(),
+ outSurf->pitch, _clut8Data.pitch, (const uint32 *)_palette);
+ } else {
+ warning("TextureCLUT8::updateTexture: Unsupported pixel depth: %d", outSurf->format.bytesPerPixel);
+ }
+
+ // Do generic handling of updating the texture.
+ Texture::updateTexture();
+}
+
+} // End of namespace OpenGL
diff --git a/backends/graphics/opengl/texture.h b/backends/graphics/opengl/texture.h
new file mode 100644
index 0000000000..e28d980de4
--- /dev/null
+++ b/backends/graphics/opengl/texture.h
@@ -0,0 +1,175 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public 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_GRAPHICS_OPENGL_TEXTURE_H
+#define BACKENDS_GRAPHICS_OPENGL_TEXTURE_H
+
+#include "backends/graphics/opengl/opengl-sys.h"
+
+#include "graphics/pixelformat.h"
+#include "graphics/surface.h"
+
+#include "common/rect.h"
+
+namespace OpenGL {
+
+/**
+ * An OpenGL texture wrapper. It automatically takes care of all OpenGL
+ * texture handling issues and also provides access to the texture data.
+ */
+class Texture {
+public:
+ /**
+ * Create a new texture with the specific internal format.
+ *
+ * @param glIntFormat The internal format to use.
+ * @param glFormat The input format.
+ * @param glType The input type.
+ * @param format The format used for the texture input.
+ */
+ Texture(GLenum glIntFormat, GLenum glFormat, GLenum glType, const Graphics::PixelFormat &format);
+ virtual ~Texture();
+
+ /**
+ * Destroy the OpenGL texture name.
+ */
+ void releaseInternalTexture();
+
+ /**
+ * Create the OpenGL texture name and flag the whole texture as dirty.
+ */
+ void recreateInternalTexture();
+
+ /**
+ * Enable or disable linear texture filtering.
+ *
+ * @param enable true to enable and false to disable.
+ */
+ void enableLinearFiltering(bool enable);
+
+ /**
+ * Allocate texture space for the desired dimensions. This wraps any
+ * handling of requirements for POT textures.
+ *
+ * @param width The desired logical width.
+ * @param height The desired logical height.
+ */
+ virtual void allocate(uint width, uint height);
+
+ void copyRectToTexture(uint x, uint y, uint w, uint h, const void *src, uint srcPitch);
+
+ void fill(uint32 color);
+
+ void draw(GLuint x, GLuint y, GLuint w, GLuint h);
+
+ void flagDirty() { _allDirty = true; }
+ bool isDirty() const { return _allDirty || !_dirtyArea.isEmpty(); }
+
+ uint getWidth() const { return _userPixelData.w; }
+ uint getHeight() const { return _userPixelData.h; }
+
+ /**
+ * @return The hardware format of the texture data.
+ */
+ const Graphics::PixelFormat &getHardwareFormat() const { return _format; }
+
+ /**
+ * @return The logical format of the texture data.
+ */
+ virtual Graphics::PixelFormat getFormat() const { return _format; }
+
+ virtual Graphics::Surface *getSurface() { return &_userPixelData; }
+ virtual const Graphics::Surface *getSurface() const { return &_userPixelData; }
+
+ /**
+ * @return Whether the texture data is using a palette.
+ */
+ virtual bool hasPalette() const { return false; }
+
+ virtual void setPalette(uint start, uint colors, const byte *palData) {}
+
+ virtual void *getPalette() { return 0; }
+ virtual const void *getPalette() const { return 0; }
+
+ /**
+ * Query texture related OpenGL information from the context. This only
+ * queries the maximum texture size for now.
+ */
+ static void queryTextureInformation();
+
+ /**
+ * @return Return the maximum texture dimensions supported.
+ */
+ static GLint getMaximumTextureSize() { return _maxTextureSize; }
+protected:
+ virtual void updateTexture();
+
+ Common::Rect getDirtyArea() const;
+private:
+ const GLenum _glIntFormat;
+ const GLenum _glFormat;
+ const GLenum _glType;
+ const Graphics::PixelFormat _format;
+
+ GLint _glFilter;
+ GLuint _glTexture;
+
+ Graphics::Surface _textureData;
+ Graphics::Surface _userPixelData;
+
+ bool _allDirty;
+ Common::Rect _dirtyArea;
+ void clearDirty() { _allDirty = false; _dirtyArea = Common::Rect(); }
+
+ static GLint _maxTextureSize;
+};
+
+class TextureCLUT8 : public Texture {
+public:
+ TextureCLUT8(GLenum glIntFormat, GLenum glFormat, GLenum glType, const Graphics::PixelFormat &format);
+ virtual ~TextureCLUT8();
+
+ virtual void allocate(uint width, uint height);
+
+ virtual Graphics::PixelFormat getFormat() const;
+
+ virtual bool hasPalette() const { return true; }
+
+ virtual void setPalette(uint start, uint colors, const byte *palData);
+
+ virtual void *getPalette() { return _palette; }
+ virtual const void *getPalette() const { return _palette; }
+
+ virtual Graphics::Surface *getSurface() { return &_clut8Data; }
+ virtual const Graphics::Surface *getSurface() const { return &_clut8Data; }
+
+protected:
+ virtual void updateTexture();
+
+private:
+ Graphics::Surface _clut8Data;
+ byte *_palette;
+};
+
+} // End of namespace OpenGL
+
+#endif
diff --git a/backends/graphics/openglsdl/openglsdl-graphics.cpp b/backends/graphics/openglsdl/openglsdl-graphics.cpp
index c5605cae87..3f9fc1fbd5 100644
--- a/backends/graphics/openglsdl/openglsdl-graphics.cpp
+++ b/backends/graphics/openglsdl/openglsdl-graphics.cpp
@@ -8,496 +8,351 @@
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
-
+ *
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-
+ *
* You should have received a copy of the GNU General Public 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"
-
-#if defined(SDL_BACKEND) && defined(USE_OPENGL)
-
#include "backends/graphics/openglsdl/openglsdl-graphics.h"
-#include "backends/platform/sdl/sdl.h"
-#include "common/config-manager.h"
+
#include "common/textconsole.h"
+#include "common/config-manager.h"
+#ifdef USE_OSD
#include "common/translation.h"
+#endif
-OpenGLSdlGraphicsManager::OpenGLSdlGraphicsManager(SdlEventSource *eventSource)
- :
- SdlGraphicsManager(eventSource),
- _hwscreen(0),
- _screenResized(false),
- _activeFullscreenMode(-2),
- _lastFullscreenModeWidth(0),
- _lastFullscreenModeHeight(0),
- _desktopWidth(0),
- _desktopHeight(0),
- _ignoreResizeFrames(0) {
-
- // Initialize SDL video subsystem
- if (SDL_InitSubSystem(SDL_INIT_VIDEO) == -1) {
- error("Could not initialize SDL: %s", SDL_GetError());
+OpenGLSdlGraphicsManager::OpenGLSdlGraphicsManager(uint desktopWidth, uint desktopHeight, SdlEventSource *eventSource)
+ : SdlGraphicsManager(eventSource), _lastVideoModeLoad(0), _hwScreen(nullptr), _lastRequestedWidth(0), _lastRequestedHeight(0),
+ _graphicsScale(2), _ignoreLoadVideoMode(false), _gotResize(false), _wantsFullScreen(false), _ignoreResizeEvents(0),
+ _desiredFullscreenWidth(0), _desiredFullscreenHeight(0) {
+ // Setup OpenGL attributes for SDL
+ SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
+ SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
+ SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
+ SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16);
+ SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
+
+ // Retrieve a list of working fullscreen modes
+ const SDL_Rect *const *availableModes = SDL_ListModes(NULL, SDL_OPENGL | SDL_FULLSCREEN);
+ if (availableModes != (void *)-1) {
+ for (;*availableModes; ++availableModes) {
+ const SDL_Rect *mode = *availableModes;
+
+ _fullscreenVideoModes.push_back(VideoMode(mode->w, mode->h));
+ }
+
+ // Sort the modes in ascending order.
+ Common::sort(_fullscreenVideoModes.begin(), _fullscreenVideoModes.end());
}
- // This is also called in initSDL(), but initializing graphics
- // may reset it.
- SDL_EnableUNICODE(1);
-
- // Disable OS cursor
- SDL_ShowCursor(SDL_DISABLE);
-
- // Get desktop resolution
- // TODO: In case the OpenGL manager is created *after* a plain SDL manager
- // has been used, this will return the last setup graphics mode rather
- // than the desktop resolution. We should really look into a way to
- // properly retrieve the desktop resolution.
- const SDL_VideoInfo *videoInfo = SDL_GetVideoInfo();
- if (videoInfo->current_w > 0 && videoInfo->current_h > 0) {
- _desktopWidth = videoInfo->current_w;
- _desktopHeight = videoInfo->current_h;
+ // In case SDL is fine with every mode we will force the desktop mode.
+ // TODO? We could also try to add some default resolutions here.
+ if (_fullscreenVideoModes.empty() && desktopWidth && desktopHeight) {
+ _fullscreenVideoModes.push_back(VideoMode(desktopWidth, desktopHeight));
}
- if (ConfMan.hasKey("last_fullscreen_mode_width") && ConfMan.hasKey("last_fullscreen_mode_height")) {
- _lastFullscreenModeWidth = ConfMan.getInt("last_fullscreen_mode_width");
- _lastFullscreenModeHeight = ConfMan.getInt("last_fullscreen_mode_height");
+ // Get information about display sizes from the previous runs.
+ if (ConfMan.hasKey("last_fullscreen_mode_width", Common::ConfigManager::kApplicationDomain) && ConfMan.hasKey("last_fullscreen_mode_height", Common::ConfigManager::kApplicationDomain)) {
+ _desiredFullscreenWidth = ConfMan.getInt("last_fullscreen_mode_width", Common::ConfigManager::kApplicationDomain);
+ _desiredFullscreenHeight = ConfMan.getInt("last_fullscreen_mode_height", Common::ConfigManager::kApplicationDomain);
+ } else {
+ // Use the desktop resolutions when no previous default has been setup.
+ _desiredFullscreenWidth = desktopWidth;
+ _desiredFullscreenHeight = desktopHeight;
}
}
OpenGLSdlGraphicsManager::~OpenGLSdlGraphicsManager() {
- // Unregister the event observer
- if (g_system->getEventManager()->getEventDispatcher() != NULL)
- g_system->getEventManager()->getEventDispatcher()->unregisterObserver(this);
}
-void OpenGLSdlGraphicsManager::initEventObserver() {
+void OpenGLSdlGraphicsManager::activateManager() {
+ SdlGraphicsManager::activateManager();
+
// Register the graphics manager as a event observer
g_system->getEventManager()->getEventDispatcher()->registerObserver(this, 10, false);
}
+void OpenGLSdlGraphicsManager::deactivateManager() {
+ // Unregister the event observer
+ if (g_system->getEventManager()->getEventDispatcher()) {
+ g_system->getEventManager()->getEventDispatcher()->unregisterObserver(this);
+ }
+
+ SdlGraphicsManager::deactivateManager();
+}
+
bool OpenGLSdlGraphicsManager::hasFeature(OSystem::Feature f) {
- return
- (f == OSystem::kFeatureFullscreenMode) ||
- (f == OSystem::kFeatureIconifyWindow) ||
- OpenGLGraphicsManager::hasFeature(f);
+ switch (f) {
+ case OSystem::kFeatureFullscreenMode:
+ case OSystem::kFeatureIconifyWindow:
+ return true;
+
+ default:
+ return OpenGLGraphicsManager::hasFeature(f);
+ }
}
void OpenGLSdlGraphicsManager::setFeatureState(OSystem::Feature f, bool enable) {
switch (f) {
+ case OSystem::kFeatureFullscreenMode:
+ assert(getTransactionMode() != kTransactionNone);
+ _wantsFullScreen = enable;
+ // When we switch to windowed mode we will ignore resize events. This
+ // avoids bad resizes to the (former) fullscreen resolution.
+ if (!enable) {
+ _ignoreResizeEvents = 10;
+ }
+ break;
+
case OSystem::kFeatureIconifyWindow:
- if (enable)
+ if (enable) {
SDL_WM_IconifyWindow();
+ }
break;
+
default:
OpenGLGraphicsManager::setFeatureState(f, enable);
}
}
-#ifdef USE_RGB_COLOR
-
-Common::List<Graphics::PixelFormat> OpenGLSdlGraphicsManager::getSupportedFormats() const {
- assert(!_supportedFormats.empty());
- return _supportedFormats;
-}
-
-void OpenGLSdlGraphicsManager::detectSupportedFormats() {
-
- // Clear old list
- _supportedFormats.clear();
-
- // Some tables with standard formats that we always list
- // as "supported". If frontend code tries to use one of
- // these, we will perform the necessary format
- // conversion in the background. Of course this incurs a
- // performance hit, but on desktop ports this should not
- // matter. We still push the currently active format to
- // the front, so if frontend code just uses the first
- // available format, it will get one that is "cheap" to
- // use.
- const Graphics::PixelFormat RGBList[] = {
-#if defined(ENABLE_32BIT)
- Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0), // RGBA8888
-#ifndef USE_GLES
- Graphics::PixelFormat(4, 8, 8, 8, 8, 16, 8, 0, 24), // ARGB8888
-#endif
- Graphics::PixelFormat(3, 8, 8, 8, 0, 16, 8, 0, 0), // RGB888
-#endif
- Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0), // RGB565
- Graphics::PixelFormat(2, 5, 5, 5, 1, 11, 6, 1, 0), // RGB5551
- Graphics::PixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0), // RGB555
- Graphics::PixelFormat(2, 4, 4, 4, 4, 12, 8, 4, 0), // RGBA4444
-#ifndef USE_GLES
- Graphics::PixelFormat(2, 4, 4, 4, 4, 8, 4, 0, 12) // ARGB4444
-#endif
- };
-#ifndef USE_GLES
- const Graphics::PixelFormat BGRList[] = {
-#ifdef ENABLE_32BIT
- Graphics::PixelFormat(4, 8, 8, 8, 8, 0, 8, 16, 24), // ABGR8888
- Graphics::PixelFormat(4, 8, 8, 8, 8, 8, 16, 24, 0), // BGRA8888
- Graphics::PixelFormat(3, 8, 8, 8, 0, 0, 8, 16, 0), // BGR888
-#endif
- Graphics::PixelFormat(2, 5, 6, 5, 0, 0, 5, 11, 0), // BGR565
- Graphics::PixelFormat(2, 5, 5, 5, 1, 1, 6, 11, 0), // BGRA5551
- Graphics::PixelFormat(2, 4, 4, 4, 4, 0, 4, 8, 12), // ABGR4444
- Graphics::PixelFormat(2, 4, 4, 4, 4, 4, 8, 12, 0) // BGRA4444
- };
-#endif
-
- Graphics::PixelFormat format = Graphics::PixelFormat::createFormatCLUT8();
- if (_hwscreen) {
- // Get our currently set hardware format
- format = Graphics::PixelFormat(_hwscreen->format->BytesPerPixel,
- 8 - _hwscreen->format->Rloss, 8 - _hwscreen->format->Gloss,
- 8 - _hwscreen->format->Bloss, 8 - _hwscreen->format->Aloss,
- _hwscreen->format->Rshift, _hwscreen->format->Gshift,
- _hwscreen->format->Bshift, _hwscreen->format->Ashift);
-
- // Workaround to SDL not providing an accurate Aloss value on Mac OS X.
- if (_hwscreen->format->Amask == 0)
- format.aLoss = 8;
-
- // Push it first, as the prefered format if available
- for (int i = 0; i < ARRAYSIZE(RGBList); i++) {
- if (RGBList[i] == format) {
- _supportedFormats.push_back(format);
- break;
- }
- }
-#ifndef USE_GLES
- for (int i = 0; i < ARRAYSIZE(BGRList); i++) {
- if (BGRList[i] == format) {
- _supportedFormats.push_back(format);
- break;
- }
+bool OpenGLSdlGraphicsManager::getFeatureState(OSystem::Feature f) {
+ switch (f) {
+ case OSystem::kFeatureFullscreenMode:
+ if (_hwScreen) {
+ return (_hwScreen->flags & SDL_FULLSCREEN) != 0;
+ } else {
+ return _wantsFullScreen;
}
-#endif
- }
- // Push some RGB formats
- for (int i = 0; i < ARRAYSIZE(RGBList); i++) {
- if (_hwscreen && (RGBList[i].bytesPerPixel > format.bytesPerPixel))
- continue;
- if (RGBList[i] != format)
- _supportedFormats.push_back(RGBList[i]);
- }
-#ifndef USE_GLES
- // Push some BGR formats
- for (int i = 0; i < ARRAYSIZE(BGRList); i++) {
- if (_hwscreen && (BGRList[i].bytesPerPixel > format.bytesPerPixel))
- continue;
- if (BGRList[i] != format)
- _supportedFormats.push_back(BGRList[i]);
+ default:
+ return OpenGLGraphicsManager::getFeatureState(f);
}
-#endif
- _supportedFormats.push_back(Graphics::PixelFormat::createFormatCLUT8());
}
-#endif
+bool OpenGLSdlGraphicsManager::setGraphicsMode(int mode) {
+ // HACK: This is stupid but the SurfaceSDL backend defaults to 2x. This
+ // assures that the launcher (which requests 320x200) has a reasonable
+ // size. It also makes small games have a reasonable size (i.e. at least
+ // 640x400). We follow the same logic here until we have a better way to
+ // give hints to our backend for that.
+ _graphicsScale = 2;
-void OpenGLSdlGraphicsManager::setInternalMousePosition(int x, int y) {
- SDL_WarpMouse(x, y);
+ return OpenGLGraphicsManager::setGraphicsMode(mode);
}
-void OpenGLSdlGraphicsManager::updateScreen() {
- if (_ignoreResizeFrames)
- _ignoreResizeFrames -= 1;
+void OpenGLSdlGraphicsManager::resetGraphicsScale() {
+ OpenGLGraphicsManager::resetGraphicsScale();
- OpenGLGraphicsManager::updateScreen();
+ // HACK: See OpenGLSdlGraphicsManager::setGraphicsMode.
+ _graphicsScale = 1;
}
-//
-// Intern
-//
-
-bool OpenGLSdlGraphicsManager::setupFullscreenMode() {
- SDL_Rect const* const*availableModes = SDL_ListModes(NULL, SDL_FULLSCREEN | SDL_OPENGL);
-
- // SDL_ListModes() returns -1 in case any dimension is okay. In that
- // case we'll reuse the current desktop resolution for fullscreen.
- if (availableModes == (void *)-1) {
- _videoMode.hardwareWidth = _desktopWidth;
- _videoMode.hardwareHeight = _desktopHeight;
- _activeFullscreenMode = -2;
- return true;
- }
-
- // If -2, autodetect the fullscreen mode
- // The last used fullscreen mode will be prioritized, if there is no last fullscreen
- // mode, the desktop resolution will be used, and in case the desktop resolution
- // is not available as a fullscreen mode, the one with smallest metric will be selected.
- if (_activeFullscreenMode == -2) {
- // Desktop resolution
- int desktopModeIndex = -1;
-
- // Best metric mode
- const SDL_Rect *bestMode = availableModes[0];
- int bestModeIndex = 0;
- uint bestMetric = (uint)-1;
-
- // Iterate over all available fullscreen modes
- for (int i = 0; const SDL_Rect *mode = availableModes[i]; i++) {
- // Try to setup the last used fullscreen mode
- if (mode->w == _lastFullscreenModeWidth && mode->h == _lastFullscreenModeHeight) {
- _videoMode.hardwareWidth = _lastFullscreenModeWidth;
- _videoMode.hardwareHeight = _lastFullscreenModeHeight;
- _activeFullscreenMode = i;
- return true;
- }
+#ifdef USE_RGB_COLOR
+Common::List<Graphics::PixelFormat> OpenGLSdlGraphicsManager::getSupportedFormats() const {
+ Common::List<Graphics::PixelFormat> formats;
- if (mode->w == _desktopWidth && mode->h == _desktopHeight)
- desktopModeIndex = i;
+ // RGBA8888
+ formats.push_back(Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0));
+ // RGB565
+ formats.push_back(Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0));
+ // RGBA5551
+ formats.push_back(Graphics::PixelFormat(2, 5, 5, 5, 1, 11, 6, 1, 0));
+ // RGBA4444
+ formats.push_back(Graphics::PixelFormat(2, 4, 4, 4, 4, 12, 8, 4, 0));
- if (mode->w < _videoMode.overlayWidth)
- continue;
- if (mode->h < _videoMode.overlayHeight)
- continue;
+#ifndef USE_GLES
+ // ARGB8888, this should not be here, but Sword25 requires it. :-/
+ formats.push_back(Graphics::PixelFormat(4, 8, 8, 8, 8, 16, 8, 0, 24));
- uint metric = mode->w * mode->h - _videoMode.overlayWidth * _videoMode.overlayHeight;
- if (metric < bestMetric) {
- bestMode = mode;
- bestMetric = metric;
- bestModeIndex = i;
- }
- }
+ // RGB555, this is used by SCUMM HE 16 bit games.
+ formats.push_back(Graphics::PixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0));
+#endif
- if (desktopModeIndex >= 0) {
- _videoMode.hardwareWidth = _desktopWidth;
- _videoMode.hardwareHeight = _desktopHeight;
+ formats.push_back(Graphics::PixelFormat::createFormatCLUT8());
- _activeFullscreenMode = desktopModeIndex;
- return true;
- } else if (bestMode) {
- _videoMode.hardwareWidth = bestMode->w;
- _videoMode.hardwareHeight = bestMode->h;
+ return formats;
+}
+#endif
- _activeFullscreenMode = bestModeIndex;
- return true;
- }
- } else {
- // Use last fullscreen mode if looping backwards from the first mode
- if (_activeFullscreenMode == -1) {
- do {
- _activeFullscreenMode++;
- } while(availableModes[_activeFullscreenMode]);
- _activeFullscreenMode--;
- }
+void OpenGLSdlGraphicsManager::updateScreen() {
+ if (_ignoreResizeEvents) {
+ --_ignoreResizeEvents;
+ }
- // Use first fullscreen mode if looping from last mode
- if (!availableModes[_activeFullscreenMode])
- _activeFullscreenMode = 0;
+ OpenGLGraphicsManager::updateScreen();
- // Check if the fullscreen mode is valid
- if (availableModes[_activeFullscreenMode]) {
- _videoMode.hardwareWidth = availableModes[_activeFullscreenMode]->w;
- _videoMode.hardwareHeight = availableModes[_activeFullscreenMode]->h;
- return true;
- }
- }
+ // Swap OpenGL buffers
+ SDL_GL_SwapBuffers();
+}
- // Could not find any suiting fullscreen mode, return false.
- return false;
+void OpenGLSdlGraphicsManager::notifyVideoExpose() {
}
-bool OpenGLSdlGraphicsManager::loadGFXMode() {
- // If the screen was resized, do not change its size
- if (!_screenResized) {
- const int scaleFactor = getScale();
- _videoMode.overlayWidth = _videoMode.hardwareWidth = _videoMode.screenWidth * scaleFactor;
- _videoMode.overlayHeight = _videoMode.hardwareHeight = _videoMode.screenHeight * scaleFactor;
-
- // The only modes where we need to adapt the aspect ratio are 320x200
- // and 640x400. That is since our aspect ratio correction in fact is
- // only used to ensure that the original pixel size aspect for these
- // modes is used.
- // (Non-square pixels on old monitors vs square pixel on new ones).
- if (_videoMode.aspectRatioCorrection) {
- if (_videoMode.screenWidth == 320 && _videoMode.screenHeight == 200)
- _videoMode.overlayHeight = _videoMode.hardwareHeight = 240 * scaleFactor;
- else if (_videoMode.screenWidth == 640 && _videoMode.screenHeight == 400)
- _videoMode.overlayHeight = _videoMode.hardwareHeight = 480 * scaleFactor;
+void OpenGLSdlGraphicsManager::notifyResize(const uint width, const uint height) {
+ 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
+ // switch aspect ratio or similar.
+ _gotResize = true;
+ if (!setupMode(width, height)) {
+ warning("OpenGLSdlGraphicsManager::notifyResize: Resize failed ('%s')", SDL_GetError());
+ g_system->quit();
}
}
+}
- _screenResized = false;
+void OpenGLSdlGraphicsManager::transformMouseCoordinates(Common::Point &point) {
+ adjustMousePosition(point.x, point.y);
+}
- // Setup OpenGL attributes for SDL
- SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
- SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
- SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
- SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16);
- SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
+void OpenGLSdlGraphicsManager::notifyMousePos(Common::Point mouse) {
+ setMousePosition(mouse.x, mouse.y);
+}
- const bool isFullscreen = getFullscreenMode();
+void OpenGLSdlGraphicsManager::setInternalMousePosition(int x, int y) {
+ SDL_WarpMouse(x, y);
+}
- // In case we have an fullscreen mode and we are not in a rollback, detect
- // a proper mode to use. In case we are in a rollback, we already detected
- // a proper mode when setting up that mode, thus there is no need to run
- // the detection again.
- if (isFullscreen && _transactionMode != kTransactionRollback) {
- if (!setupFullscreenMode())
- // Failed setuping a fullscreen mode
- return false;
+bool OpenGLSdlGraphicsManager::loadVideoMode(uint requestedWidth, uint requestedHeight, const Graphics::PixelFormat &format) {
+ // In some cases we might not want to load the requested video mode. This
+ // will assure that the window size is not altered.
+ if (_ignoreLoadVideoMode) {
+ _ignoreLoadVideoMode = false;
+ return true;
}
- _videoMode.overlayWidth = _videoMode.hardwareWidth;
- _videoMode.overlayHeight = _videoMode.hardwareHeight;
+ // This function should never be called from notifyResize thus we know
+ // that the requested size came from somewhere else.
+ _gotResize = false;
- uint32 flags = SDL_OPENGL;
+ // Save the requested dimensions.
+ _lastRequestedWidth = requestedWidth;
+ _lastRequestedHeight = requestedHeight;
- if (isFullscreen)
- flags |= SDL_FULLSCREEN;
- else
- flags |= SDL_RESIZABLE;
-
- // Create our window
- _hwscreen = SDL_SetVideoMode(_videoMode.hardwareWidth, _videoMode.hardwareHeight, 32, flags);
-#ifdef USE_RGB_COLOR
- detectSupportedFormats();
-#endif
+ // Apply the currently saved scale setting.
+ requestedWidth *= _graphicsScale;
+ requestedHeight *= _graphicsScale;
- if (_hwscreen == NULL) {
- // DON'T use error(), as this tries to bring up the debug
- // console, which WON'T WORK now that _hwscreen is hosed.
-
- if (!_oldVideoMode.setup) {
- warning("SDL_SetVideoMode says we can't switch to that mode (%s)", SDL_GetError());
- g_system->quit();
- } else
- // Cancel GFX load, and go back to last mode
- return false;
- }
+ // Set up the mode.
+ return setupMode(requestedWidth, requestedHeight);
+}
- // Check if the screen is BGR format
- setFormatIsBGR(_hwscreen->format->Rshift != 0);
+bool OpenGLSdlGraphicsManager::setupMode(uint width, uint height) {
+ // In case we request a fullscreen mode we will use the mode the user
+ // has chosen last time or the biggest mode available.
+ if (_wantsFullScreen) {
+ if (_desiredFullscreenWidth && _desiredFullscreenHeight) {
+ // In case only a distinct set of modes is available we check
+ // whether the requested mode is actually available.
+ if (!_fullscreenVideoModes.empty()) {
+ VideoModeArray::const_iterator i = Common::find(_fullscreenVideoModes.begin(),
+ _fullscreenVideoModes.end(),
+ VideoMode(_desiredFullscreenWidth, _desiredFullscreenHeight));
+ // It's not available fall back to default.
+ if (i == _fullscreenVideoModes.end()) {
+ _desiredFullscreenWidth = 0;
+ _desiredFullscreenHeight = 0;
+ }
+ }
+ }
- if (isFullscreen) {
- _lastFullscreenModeWidth = _videoMode.hardwareWidth;
- _lastFullscreenModeHeight = _videoMode.hardwareHeight;
- ConfMan.setInt("last_fullscreen_mode_width", _lastFullscreenModeWidth);
- ConfMan.setInt("last_fullscreen_mode_height", _lastFullscreenModeHeight);
- }
+ // In case no desired mode has been set we default to the biggest mode
+ // available or the requested mode in case we don't know any
+ // any fullscreen modes.
+ if (!_desiredFullscreenWidth || !_desiredFullscreenHeight) {
+ if (!_fullscreenVideoModes.empty()) {
+ VideoModeArray::const_iterator i = _fullscreenVideoModes.end();
+ --i;
+
+ _desiredFullscreenWidth = i->width;
+ _desiredFullscreenHeight = i->height;
+ } else {
+ _desiredFullscreenWidth = width;
+ _desiredFullscreenHeight = height;
+ }
+ }
- // Call and return parent implementation of this method
- return OpenGLGraphicsManager::loadGFXMode();
-}
+ // Remember our choice.
+ ConfMan.setInt("last_fullscreen_mode_width", _desiredFullscreenWidth, Common::ConfigManager::kApplicationDomain);
+ ConfMan.setInt("last_fullscreen_mode_height", _desiredFullscreenHeight, Common::ConfigManager::kApplicationDomain);
-void OpenGLSdlGraphicsManager::unloadGFXMode() {
- if (_hwscreen) {
- SDL_FreeSurface(_hwscreen);
- _hwscreen = NULL;
+ // Use our choice.
+ width = _desiredFullscreenWidth;
+ height = _desiredFullscreenHeight;
}
-}
-
-void OpenGLSdlGraphicsManager::internUpdateScreen() {
- // Call to parent implementation of this method
- OpenGLGraphicsManager::internUpdateScreen();
-
- // Swap OpenGL buffers
- SDL_GL_SwapBuffers();
-}
-#ifdef USE_OSD
-void OpenGLSdlGraphicsManager::displayModeChangedMsg() {
- const char *newModeName = getCurrentModeName();
- if (newModeName) {
- const int scaleFactor = getScale();
-
- Common::String osdMessage = Common::String::format(
- "%s: %s\n%d x %d -> %d x %d",
- _("Current display mode"),
- newModeName,
- _videoMode.screenWidth * scaleFactor,
- _videoMode.screenHeight * scaleFactor,
- _hwscreen->w, _hwscreen->h
- );
- displayMessageOnOSD(osdMessage.c_str());
+ // WORKAROUND: Working around infamous SDL bugs when switching
+ // resolutions too fast. This might cause the event system to supply
+ // incorrect mouse position events otherwise.
+ // Reference: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=665779
+ const uint32 curTime = SDL_GetTicks();
+ if (_hwScreen && (curTime < _lastVideoModeLoad || curTime - _lastVideoModeLoad < 100)) {
+ for (int i = 10; i > 0; --i) {
+ SDL_PumpEvents();
+ SDL_Delay(10);
+ }
}
-}
-void OpenGLSdlGraphicsManager::displayScaleChangedMsg() {
- const int scaleFactor = getScale();
- Common::String osdMessage = Common::String::format(
- "%s: x%d\n%d x %d -> %d x %d",
- _("Current scale"),
- scaleFactor,
- _videoMode.screenWidth, _videoMode.screenHeight,
- _videoMode.overlayWidth, _videoMode.overlayHeight
- );
- displayMessageOnOSD(osdMessage.c_str());
-}
-#endif
+ _lastVideoModeLoad = curTime;
-bool OpenGLSdlGraphicsManager::isHotkey(const Common::Event &event) {
- if ((event.kbd.flags & (Common::KBD_CTRL|Common::KBD_ALT)) == (Common::KBD_CTRL|Common::KBD_ALT)) {
- if (event.kbd.keycode == Common::KEYCODE_PLUS || event.kbd.keycode == Common::KEYCODE_MINUS ||
- event.kbd.keycode == Common::KEYCODE_KP_PLUS || event.kbd.keycode == Common::KEYCODE_KP_MINUS ||
- event.kbd.keycode == 'a' || event.kbd.keycode == 'f')
- return true;
- } else if ((event.kbd.flags & (Common::KBD_CTRL|Common::KBD_SHIFT)) == (Common::KBD_CTRL|Common::KBD_SHIFT)) {
- if (event.kbd.keycode == 'a' || event.kbd.keycode == 'f')
- return true;
- } else if ((event.kbd.flags & (Common::KBD_ALT)) == (Common::KBD_ALT) && event.kbd.keycode == 's') {
- return true;
+ uint32 flags = SDL_OPENGL;
+ if (_wantsFullScreen) {
+ flags |= SDL_FULLSCREEN;
+ } else {
+ flags |= SDL_RESIZABLE;
}
- return false;
-}
-void OpenGLSdlGraphicsManager::toggleFullScreen(int loop) {
- beginGFXTransaction();
- const bool isFullscreen = getFullscreenMode();
+ _hwScreen = SDL_SetVideoMode(width, height, 32, flags);
- if (isFullscreen && loop) {
- _activeFullscreenMode += loop;
- setFullscreenMode(true);
- } else {
- _activeFullscreenMode = -2;
- setFullscreenMode(!isFullscreen);
+ if (!_hwScreen) {
+ // We treat fullscreen requests as a "hint" for now. This means in
+ // case it is not available we simply ignore it.
+ if (_wantsFullScreen) {
+ _hwScreen = SDL_SetVideoMode(width, height, 32, SDL_OPENGL | SDL_RESIZABLE);
}
+ }
- // HACK: We need to force a refresh here, since we change the
- // fullscreen mode.
- _transactionDetails.needRefresh = true;
- endGFXTransaction();
-
- // Ignore resize events for the next 10 frames
- _ignoreResizeFrames = 10;
+ if (_hwScreen) {
+ const Graphics::PixelFormat rgba8888 = Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0);
+ notifyContextChange(rgba8888, rgba8888);
+ setActualScreenSize(_hwScreen->w, _hwScreen->h);
+ }
-#ifdef USE_OSD
- Common::String osdMessage;
- if (getFullscreenMode())
- osdMessage = Common::String::format("%s\n%d x %d",
- _("Fullscreen mode"),
- _hwscreen->w, _hwscreen->h
- );
- else
- osdMessage = Common::String::format("%s\n%d x %d",
- _("Windowed mode"),
- _hwscreen->w, _hwscreen->h
- );
- displayMessageOnOSD(osdMessage.c_str());
-#endif
+ return _hwScreen != nullptr;
}
bool OpenGLSdlGraphicsManager::notifyEvent(const Common::Event &event) {
switch (event.type) {
+ case Common::EVENT_KEYUP:
+ return isHotkey(event);
+
case Common::EVENT_KEYDOWN:
if (event.kbd.hasFlags(Common::KBD_ALT)) {
- // Alt-Return and Alt-Enter toggle full screen mode
- if (event.kbd.keycode == Common::KEYCODE_RETURN ||
- event.kbd.keycode == (Common::KeyCode)SDLK_KP_ENTER) {
- toggleFullScreen(0);
+ if ( event.kbd.keycode == Common::KEYCODE_RETURN
+ || event.kbd.keycode == (Common::KeyCode)SDLK_KP_ENTER) {
+ // Alt-Return and Alt-Enter toggle full screen mode
+ beginGFXTransaction();
+ setFeatureState(OSystem::kFeatureFullscreenMode, !getFeatureState(OSystem::kFeatureFullscreenMode));
+ endGFXTransaction();
+
+#ifdef USE_OSD
+ if (getFeatureState(OSystem::kFeatureFullscreenMode)) {
+ displayMessageOnOSD("Fullscreen mode");
+ } else {
+ displayMessageOnOSD("Windowed mode");
+ }
+#endif
return true;
}
- // Alt-S create a screenshot
- if (event.kbd.keycode == 's') {
+ if (event.kbd.keycode == Common::KEYCODE_s) {
+ // Alt-s creates a screenshot
Common::String filename;
for (int n = 0;; n++) {
@@ -509,169 +364,167 @@ bool OpenGLSdlGraphicsManager::notifyEvent(const Common::Event &event) {
break;
SDL_RWclose(file);
}
- if (saveScreenshot(filename.c_str()))
- debug("Saved screenshot '%s'", filename.c_str());
- else
- warning("Could not save screenshot");
- return true;
- }
- }
- if (event.kbd.hasFlags(Common::KBD_CTRL|Common::KBD_ALT)) {
- // Ctrl-Alt-Return and Ctrl-Alt-Enter switch between full screen modes
- if (event.kbd.keycode == Common::KEYCODE_RETURN ||
- event.kbd.keycode == (Common::KeyCode)SDLK_KP_ENTER) {
- toggleFullScreen(1);
+ saveScreenshot(filename.c_str());
+ debug("Saved screenshot '%s'", filename.c_str());
+
return true;
}
+ } else if (event.kbd.hasFlags(Common::KBD_CTRL | Common::KBD_ALT)) {
+ if ( event.kbd.keycode == Common::KEYCODE_PLUS || event.kbd.keycode == Common::KEYCODE_MINUS
+ || event.kbd.keycode == Common::KEYCODE_KP_PLUS || event.kbd.keycode == Common::KEYCODE_KP_MINUS) {
+ // Ctrl+Alt+Plus/Minus Increase/decrease the size
+ const int direction = (event.kbd.keycode == Common::KEYCODE_PLUS || event.kbd.keycode == Common::KEYCODE_KP_PLUS) ? +1 : -1;
+
+ if (getFeatureState(OSystem::kFeatureFullscreenMode)) {
+ // In case we are in fullscreen we will choose the previous
+ // or next mode.
+
+ // In case no modes are available we do nothing.
+ if (_fullscreenVideoModes.empty()) {
+ return true;
+ }
+
+ // Look for the current mode.
+ VideoModeArray::const_iterator i = Common::find(_fullscreenVideoModes.begin(),
+ _fullscreenVideoModes.end(),
+ VideoMode(_desiredFullscreenWidth, _desiredFullscreenHeight));
+ if (i == _fullscreenVideoModes.end()) {
+ return true;
+ }
+
+ // Cycle through the modes in the specified direction.
+ if (direction > 0) {
+ ++i;
+ if (i == _fullscreenVideoModes.end()) {
+ i = _fullscreenVideoModes.begin();
+ }
+ } else {
+ if (i == _fullscreenVideoModes.begin()) {
+ i = _fullscreenVideoModes.end();
+ }
+ --i;
+ }
+
+ _desiredFullscreenWidth = i->width;
+ _desiredFullscreenHeight = i->height;
+
+ // Try to setup the mode.
+ if (!setupMode(_lastRequestedWidth, _lastRequestedHeight)) {
+ warning("OpenGLSdlGraphicsManager::notifyEvent: Fullscreen resize failed ('%s')", SDL_GetError());
+ g_system->quit();
+ }
+ } else {
+ // 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);
+ _graphicsScale = MAX<int>(_graphicsScale + direction, 1);
+
+ // Since we overwrite a user resize here we reset its
+ // flag here. This makes enabling AR smoother because it
+ // will change the window size like in surface SDL.
+ _gotResize = false;
+
+ // Try to setup the mode.
+ if (!setupMode(_lastRequestedWidth * _graphicsScale, _lastRequestedHeight * _graphicsScale)) {
+ warning("OpenGLSdlGraphicsManager::notifyEvent: Window resize failed ('%s')", SDL_GetError());
+ g_system->quit();
+ }
+ }
- // Ctrl-Alt-a switch between display modes
- if (event.kbd.keycode == 'a') {
- beginGFXTransaction();
- setFeatureState(OSystem::kFeatureAspectRatioCorrection, !getFeatureState(OSystem::kFeatureAspectRatioCorrection));
- endGFXTransaction();
#ifdef USE_OSD
- Common::String osdMessage;
- if (getFeatureState(OSystem::kFeatureAspectRatioCorrection))
- osdMessage = Common::String::format("%s\n%d x %d -> %d x %d",
- _("Enabled aspect ratio correction"),
- _videoMode.screenWidth, _videoMode.screenHeight,
- _hwscreen->w, _hwscreen->h);
- else
- osdMessage = Common::String::format("%s\n%d x %d -> %d x %d",
- _("Disabled aspect ratio correction"),
- _videoMode.screenWidth, _videoMode.screenHeight,
- _hwscreen->w, _hwscreen->h);
- displayMessageOnOSD(osdMessage.c_str());
+ const Common::String osdMsg = Common::String::format("Resolution: %dx%d", _hwScreen->w, _hwScreen->h);
+ displayMessageOnOSD(osdMsg.c_str());
#endif
- internUpdateScreen();
+
return true;
- }
+ } else if (event.kbd.keycode == Common::KEYCODE_a) {
+ // In case the user changed the window size manually we will
+ // not change the window size again here.
+ _ignoreLoadVideoMode = _gotResize;
- // Ctrl-Alt-f toggles antialiasing
- if (event.kbd.keycode == 'f') {
+ // Ctrl+Alt+a toggles the aspect ratio correction state.
beginGFXTransaction();
- toggleAntialiasing();
+ setFeatureState(OSystem::kFeatureAspectRatioCorrection, !getFeatureState(OSystem::kFeatureAspectRatioCorrection));
endGFXTransaction();
+ // Make sure we do not ignore the next resize. This
+ // effectively checks whether loadVideoMode has been called.
+ assert(!_ignoreLoadVideoMode);
+
#ifdef USE_OSD
- // TODO: This makes guesses about what internal antialiasing
- // modes we use, we might want to consider a better way of
- // displaying information to the user.
- if (getAntialiasingState())
- displayMessageOnOSD(_("Active filter mode: Linear"));
- else
- displayMessageOnOSD(_("Active filter mode: Nearest"));
+ Common::String osdMsg = "Aspect ratio correction: ";
+ osdMsg += getFeatureState(OSystem::kFeatureAspectRatioCorrection) ? "enabled" : "disabled";
+ displayMessageOnOSD(osdMsg.c_str());
#endif
+
return true;
- }
+ } else if (event.kbd.keycode == Common::KEYCODE_f) {
+ // Ctrl+Alt+f toggles the graphics modes.
+
+ // We are crazy we will allow the OpenGL base class to
+ // introduce new graphics modes like shaders for special
+ // filtering. If some other OpenGL subclass needs this,
+ // we can think of refactoring this.
+ int mode = getGraphicsMode();
+ const OSystem::GraphicsMode *supportedModes = getSupportedGraphicsModes();
+ const OSystem::GraphicsMode *modeDesc = nullptr;
+
+ // Search the current mode.
+ for (; supportedModes->name; ++supportedModes) {
+ if (supportedModes->id == mode) {
+ modeDesc = supportedModes;
+ break;
+ }
+ }
+ assert(modeDesc);
- SDLKey sdlKey = (SDLKey)event.kbd.keycode;
-
- // Ctrl+Alt+Plus/Minus Increase/decrease the scale factor
- if ((sdlKey == SDLK_EQUALS || sdlKey == SDLK_PLUS || sdlKey == SDLK_MINUS ||
- sdlKey == SDLK_KP_PLUS || sdlKey == SDLK_KP_MINUS)) {
- int factor = getScale();
- factor += (sdlKey == SDLK_MINUS || sdlKey == SDLK_KP_MINUS) ? -1 : +1;
- if (0 < factor && factor < 4) {
- // Check if the desktop resolution has been detected
- if (_desktopWidth > 0 && _desktopHeight > 0)
- // If the new scale factor is too big, do not scale
- if (_videoMode.screenWidth * factor > _desktopWidth ||
- _videoMode.screenHeight * factor > _desktopHeight)
- return false;
-
- beginGFXTransaction();
- setScale(factor);
- endGFXTransaction();
-#ifdef USE_OSD
- displayScaleChangedMsg();
-#endif
- return true;
+ // Try to use the next mode in the list.
+ ++modeDesc;
+ if (!modeDesc->name) {
+ modeDesc = getSupportedGraphicsModes();
}
- }
- const bool isNormalNumber = (SDLK_1 <= sdlKey && sdlKey <= SDLK_3);
- const bool isKeypadNumber = (SDLK_KP1 <= sdlKey && sdlKey <= SDLK_KP3);
+ // Never ever try to resize the window when we simply want to
+ // switch the graphics mode. This assures that the window size
+ // does not change.
+ _ignoreLoadVideoMode = true;
+
+ beginGFXTransaction();
+ setGraphicsMode(modeDesc->id);
+ endGFXTransaction();
+
+ // Make sure we do not ignore the next resize. This
+ // effectively checks whether loadVideoMode has been called.
+ assert(!_ignoreLoadVideoMode);
- // Ctrl-Alt-<number key> will change the GFX mode
- if (isNormalNumber || isKeypadNumber) {
- if (sdlKey - (isNormalNumber ? SDLK_1 : SDLK_KP1) <= 3) {
-#ifdef USE_OSD
- int lastMode = _videoMode.mode;
-#endif
- // We need to query the scale and set it up, because
- // setGraphicsMode sets the default scale to 2
- int oldScale = getScale();
- beginGFXTransaction();
- setGraphicsMode(sdlKey - (isNormalNumber ? SDLK_1 : SDLK_KP1));
- setScale(oldScale);
- endGFXTransaction();
#ifdef USE_OSD
- if (lastMode != _videoMode.mode)
- displayModeChangedMsg();
+ const Common::String osdMsg = Common::String::format("Graphics mode: %s", _(modeDesc->description));
+ displayMessageOnOSD(osdMsg.c_str());
#endif
- internUpdateScreen();
- }
- }
- }
- if (event.kbd.hasFlags(Common::KBD_CTRL|Common::KBD_SHIFT)) {
- // Ctrl-Shift-Return and Ctrl-Shift-Enter switch backwards between full screen modes
- if (event.kbd.keycode == Common::KEYCODE_RETURN ||
- event.kbd.keycode == (Common::KeyCode)SDLK_KP_ENTER) {
- toggleFullScreen(-1);
return true;
}
}
- break;
-
- case Common::EVENT_KEYUP:
- return isHotkey(event);
+ // Fall through
default:
- break;
+ return false;
}
-
- return false;
-}
-
-void OpenGLSdlGraphicsManager::notifyVideoExpose() {
}
-void OpenGLSdlGraphicsManager::notifyResize(const uint width, const uint height) {
- // Do not resize if ignoring resize events.
- if (!_ignoreResizeFrames && !getFullscreenMode()) {
- bool scaleChanged = false;
- beginGFXTransaction();
- _videoMode.hardwareWidth = width;
- _videoMode.hardwareHeight = height;
-
- _screenResized = true;
-
- int scale = MIN(_videoMode.hardwareWidth / _videoMode.screenWidth,
- _videoMode.hardwareHeight / _videoMode.screenHeight);
-
- if (getScale() != scale) {
- scaleChanged = true;
- setScale(MAX(MIN(scale, 3), 1));
- }
-
- _transactionDetails.sizeChanged = true;
- endGFXTransaction();
-#ifdef USE_OSD
- if (scaleChanged)
- displayScaleChangedMsg();
-#endif
+bool OpenGLSdlGraphicsManager::isHotkey(const Common::Event &event) {
+ if (event.kbd.hasFlags(Common::KBD_ALT)) {
+ return event.kbd.keycode == Common::KEYCODE_RETURN
+ || event.kbd.keycode == (Common::KeyCode)SDLK_KP_ENTER
+ || event.kbd.keycode == Common::KEYCODE_s;
+ } else if (event.kbd.hasFlags(Common::KBD_CTRL | Common::KBD_ALT)) {
+ return event.kbd.keycode == Common::KEYCODE_PLUS || event.kbd.keycode == Common::KEYCODE_MINUS
+ || event.kbd.keycode == Common::KEYCODE_KP_PLUS || event.kbd.keycode == Common::KEYCODE_KP_MINUS
+ || event.kbd.keycode == Common::KEYCODE_a
+ || event.kbd.keycode == Common::KEYCODE_f;
}
-}
-
-void OpenGLSdlGraphicsManager::transformMouseCoordinates(Common::Point &point) {
- adjustMousePosition(point.x, point.y);
-}
-void OpenGLSdlGraphicsManager::notifyMousePos(Common::Point mouse) {
- setMousePosition(mouse.x, mouse.y);
+ return false;
}
-
-#endif
diff --git a/backends/graphics/openglsdl/openglsdl-graphics.h b/backends/graphics/openglsdl/openglsdl-graphics.h
index 1587183328..9934ca79e2 100644
--- a/backends/graphics/openglsdl/openglsdl-graphics.h
+++ b/backends/graphics/openglsdl/openglsdl-graphics.h
@@ -8,117 +8,109 @@
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
-
+ *
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-
+ *
* You should have received a copy of the GNU General Public 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_GRAPHICS_OPENGLSDL_H
-#define BACKENDS_GRAPHICS_OPENGLSDL_H
+#ifndef BACKENDS_GRAPHICS_OPENGLSDL_OPENGLSDL_GRAPHICS_H
+#define BACKENDS_GRAPHICS_OPENGLSDL_OPENGLSDL_GRAPHICS_H
-#include "backends/platform/sdl/sdl-sys.h"
-#if defined(ARRAYSIZE) && !defined(_WINDOWS_)
-#undef ARRAYSIZE
-#endif
-#include "backends/graphics/sdl/sdl-graphics.h"
#include "backends/graphics/opengl/opengl-graphics.h"
+#include "backends/graphics/sdl/sdl-graphics.h"
+#include "backends/platform/sdl/sdl-sys.h"
+#include "common/array.h"
#include "common/events.h"
-/**
- * SDL OpenGL graphics manager
- */
-class OpenGLSdlGraphicsManager : public OpenGLGraphicsManager, public SdlGraphicsManager, public Common::EventObserver {
+class OpenGLSdlGraphicsManager : public OpenGL::OpenGLGraphicsManager, public SdlGraphicsManager, public Common::EventObserver {
public:
- OpenGLSdlGraphicsManager(SdlEventSource *eventSource);
+ OpenGLSdlGraphicsManager(uint desktopWidth, uint desktopHeight, SdlEventSource *eventSource);
virtual ~OpenGLSdlGraphicsManager();
+ // GraphicsManager API
+ virtual void activateManager();
+ virtual void deactivateManager();
+
virtual bool hasFeature(OSystem::Feature f);
virtual void setFeatureState(OSystem::Feature f, bool enable);
+ virtual bool getFeatureState(OSystem::Feature f);
+
+ virtual bool setGraphicsMode(int mode);
+ virtual void resetGraphicsScale();
#ifdef USE_RGB_COLOR
virtual Common::List<Graphics::PixelFormat> getSupportedFormats() const;
#endif
- virtual void initEventObserver();
- virtual bool notifyEvent(const Common::Event &event);
-
virtual void updateScreen();
- // SdlGraphicsManager interface
+ // EventObserver API
+ virtual bool notifyEvent(const Common::Event &event);
+
+ // SdlGraphicsManager API
virtual void notifyVideoExpose();
virtual void notifyResize(const uint width, const uint height);
virtual void transformMouseCoordinates(Common::Point &point);
virtual void notifyMousePos(Common::Point mouse);
protected:
- virtual void internUpdateScreen();
+ virtual void setInternalMousePosition(int x, int y);
- virtual bool loadGFXMode();
- virtual void unloadGFXMode();
- virtual bool isHotkey(const Common::Event &event);
+ virtual bool loadVideoMode(uint requestedWidth, uint requestedHeight, const Graphics::PixelFormat &format);
+private:
+ bool setupMode(uint width, uint height);
-#ifdef USE_RGB_COLOR
- Common::List<Graphics::PixelFormat> _supportedFormats;
+ uint32 _lastVideoModeLoad;
+ SDL_Surface *_hwScreen;
- /**
- * Update the list of supported pixel formats.
- * This method is invoked by loadGFXMode().
- */
- void detectSupportedFormats();
-#endif
+ uint _lastRequestedWidth;
+ uint _lastRequestedHeight;
+ uint _graphicsScale;
+ bool _ignoreLoadVideoMode;
+ bool _gotResize;
- /**
- * Toggles fullscreen.
- * @loop loop direction for switching fullscreen mode, if 0 toggles it.
- */
- virtual void toggleFullScreen(int loop);
+ bool _wantsFullScreen;
+ uint _ignoreResizeEvents;
- int _activeFullscreenMode;
+ struct VideoMode {
+ VideoMode() : width(0), height(0) {}
+ VideoMode(uint w, uint h) : width(w), height(h) {}
- /**
- * Setup the fullscreen mode.
- * @return false if failed finding a mode, true otherwise.
- */
- virtual bool setupFullscreenMode();
+ bool operator<(const VideoMode &right) const {
+ if (width < right.width) {
+ return true;
+ } else if (width == right.width && height < right.height) {
+ return true;
+ } else {
+ return false;
+ }
+ }
- virtual void setInternalMousePosition(int x, int y);
+ bool operator==(const VideoMode &right) const {
+ return width == right.width && height == right.height;
+ }
- int _lastFullscreenModeWidth;
- int _lastFullscreenModeHeight;
- int _desktopWidth;
- int _desktopHeight;
-
- // Hardware screen
- SDL_Surface *_hwscreen;
-
- // If screen was resized by the user
- bool _screenResized;
-
- // Ignore resize events for the number of updateScreen() calls.
- // Normaly resize events are user generated when resizing the window
- // from its borders, but in some cases a resize event can be generated
- // after a fullscreen change.
- int _ignoreResizeFrames;
-
-#ifdef USE_OSD
- /**
- * Displays a mode change message in OSD
- */
- void displayModeChangedMsg();
-
- /**
- * Displays a scale change message in OSD
- */
- void displayScaleChangedMsg();
-#endif
+ bool operator!=(const VideoMode &right) const {
+ return !(*this == right);
+ }
+
+ uint width, height;
+ };
+ typedef Common::Array<VideoMode> VideoModeArray;
+ VideoModeArray _fullscreenVideoModes;
+
+ uint _desiredFullscreenWidth;
+ uint _desiredFullscreenHeight;
+
+ virtual bool isHotkey(const Common::Event &event);
};
#endif
diff --git a/backends/graphics/sdl/sdl-graphics.cpp b/backends/graphics/sdl/sdl-graphics.cpp
index 2eca4b8aab..40b97b267b 100644
--- a/backends/graphics/sdl/sdl-graphics.cpp
+++ b/backends/graphics/sdl/sdl-graphics.cpp
@@ -26,10 +26,15 @@
SdlGraphicsManager::SdlGraphicsManager(SdlEventSource *source)
: _eventSource(source) {
- _eventSource->setGraphicsManager(this);
}
SdlGraphicsManager::~SdlGraphicsManager() {
- _eventSource->setGraphicsManager(0);
}
+void SdlGraphicsManager::activateManager() {
+ _eventSource->setGraphicsManager(this);
+}
+
+void SdlGraphicsManager::deactivateManager() {
+ _eventSource->setGraphicsManager(0);
+}
diff --git a/backends/graphics/sdl/sdl-graphics.h b/backends/graphics/sdl/sdl-graphics.h
index ea9149fccb..3791961cfa 100644
--- a/backends/graphics/sdl/sdl-graphics.h
+++ b/backends/graphics/sdl/sdl-graphics.h
@@ -23,6 +23,8 @@
#ifndef BACKENDS_GRAPHICS_SDL_SDLGRAPHICS_H
#define BACKENDS_GRAPHICS_SDL_SDLGRAPHICS_H
+#include "backends/graphics/graphics.h"
+
#include "common/rect.h"
class SdlEventSource;
@@ -31,16 +33,26 @@ class SdlEventSource;
* Base class for a SDL based graphics manager.
*
* It features a few extra a few extra features required by SdlEventSource.
- * FIXME/HACK:
- * Note it does not inherit from GraphicsManager to avoid a diamond inheritance
- * in the current OpenGLSdlGraphicsManager.
*/
-class SdlGraphicsManager {
+class SdlGraphicsManager : virtual public GraphicsManager {
public:
SdlGraphicsManager(SdlEventSource *source);
virtual ~SdlGraphicsManager();
/**
+ * Makes this graphics manager active. That means it should be ready to
+ * process inputs now. However, even without being active it should be
+ * able to query the supported modes and other bits.
+ */
+ virtual void activateManager();
+
+ /**
+ * Makes this graphics manager inactive. This should allow another
+ * graphics manager to become active again.
+ */
+ virtual void deactivateManager();
+
+ /**
* Notify the graphics manager that the graphics needs to be redrawn, since
* the application window was modified.
*
diff --git a/backends/graphics/surfacesdl/surfacesdl-graphics.cpp b/backends/graphics/surfacesdl/surfacesdl-graphics.cpp
index 871c6c49b2..b3af08e2e8 100644
--- a/backends/graphics/surfacesdl/surfacesdl-graphics.cpp
+++ b/backends/graphics/surfacesdl/surfacesdl-graphics.cpp
@@ -142,14 +142,6 @@ SurfaceSdlGraphicsManager::SurfaceSdlGraphicsManager(SdlEventSource *sdlEventSou
#endif
_transactionMode(kTransactionNone) {
- if (SDL_InitSubSystem(SDL_INIT_VIDEO) == -1) {
- error("Could not initialize SDL: %s", SDL_GetError());
- }
-
- // This is also called in initSDL(), but initializing graphics
- // may reset it.
- SDL_EnableUNICODE(1);
-
// allocate palette storage
_currentPalette = (SDL_Color *)calloc(sizeof(SDL_Color), 256);
_cursorPalette = (SDL_Color *)calloc(sizeof(SDL_Color), 256);
@@ -165,8 +157,6 @@ SurfaceSdlGraphicsManager::SurfaceSdlGraphicsManager(SdlEventSource *sdlEventSou
_enableFocusRectDebugCode = ConfMan.getBool("use_sdl_debug_focusrect");
#endif
- SDL_ShowCursor(SDL_DISABLE);
-
memset(&_oldVideoMode, 0, sizeof(_oldVideoMode));
memset(&_videoMode, 0, sizeof(_videoMode));
memset(&_transactionDetails, 0, sizeof(_transactionDetails));
@@ -193,10 +183,6 @@ SurfaceSdlGraphicsManager::SurfaceSdlGraphicsManager(SdlEventSource *sdlEventSou
}
SurfaceSdlGraphicsManager::~SurfaceSdlGraphicsManager() {
- // Unregister the event observer
- if (g_system->getEventManager()->getEventDispatcher() != NULL)
- g_system->getEventManager()->getEventDispatcher()->unregisterObserver(this);
-
unloadGFXMode();
if (_mouseSurface)
SDL_FreeSurface(_mouseSurface);
@@ -211,11 +197,22 @@ SurfaceSdlGraphicsManager::~SurfaceSdlGraphicsManager() {
free(_mouseData);
}
-void SurfaceSdlGraphicsManager::initEventObserver() {
+void SurfaceSdlGraphicsManager::activateManager() {
+ SdlGraphicsManager::activateManager();
+
// Register the graphics manager as a event observer
g_system->getEventManager()->getEventDispatcher()->registerObserver(this, 10, false);
}
+void SurfaceSdlGraphicsManager::deactivateManager() {
+ // Unregister the event observer
+ if (g_system->getEventManager()->getEventDispatcher()) {
+ g_system->getEventManager()->getEventDispatcher()->unregisterObserver(this);
+ }
+
+ SdlGraphicsManager::deactivateManager();
+}
+
bool SurfaceSdlGraphicsManager::hasFeature(OSystem::Feature f) {
return
(f == OSystem::kFeatureFullscreenMode) ||
@@ -263,16 +260,16 @@ bool SurfaceSdlGraphicsManager::getFeatureState(OSystem::Feature f) {
}
}
-const OSystem::GraphicsMode *SurfaceSdlGraphicsManager::supportedGraphicsModes() {
- return s_supportedGraphicsModes;
-}
-
const OSystem::GraphicsMode *SurfaceSdlGraphicsManager::getSupportedGraphicsModes() const {
return s_supportedGraphicsModes;
}
int SurfaceSdlGraphicsManager::getDefaultGraphicsMode() const {
+#ifdef USE_SCALERS
return GFX_DOUBLESIZE;
+#else
+ return GFX_NORMAL;
+#endif
}
void SurfaceSdlGraphicsManager::resetGraphicsScale() {
@@ -747,6 +744,8 @@ bool SurfaceSdlGraphicsManager::loadGFXMode() {
if (_screen == NULL)
error("allocating _screen failed");
+ // Avoid having SDL_SRCALPHA set even if we supplied an alpha-channel in the format.
+ SDL_SetAlpha(_screen, 0, 255);
#else
_screen = SDL_CreateRGBSurface(SDL_SWSURFACE, _videoMode.screenWidth, _videoMode.screenHeight, 8, 0, 0, 0, 0);
if (_screen == NULL)
@@ -1081,7 +1080,9 @@ void SurfaceSdlGraphicsManager::internUpdateScreen() {
for (r = _dirtyRectList; r != lastRect; ++r) {
register int dst_y = r->y + _currentShakePos;
register int dst_h = 0;
+#ifdef USE_SCALERS
register int orig_dst_y = 0;
+#endif
register int rx1 = r->x * scale1;
if (dst_y < height) {
@@ -1089,7 +1090,9 @@ void SurfaceSdlGraphicsManager::internUpdateScreen() {
if (dst_h > height - dst_y)
dst_h = height - dst_y;
+#ifdef USE_SCALERS
orig_dst_y = dst_y;
+#endif
dst_y = dst_y * scale1;
if (_videoMode.aspectRatioCorrection && !_overlayVisible)
diff --git a/backends/graphics/surfacesdl/surfacesdl-graphics.h b/backends/graphics/surfacesdl/surfacesdl-graphics.h
index 97de0f9c97..22b7780675 100644
--- a/backends/graphics/surfacesdl/surfacesdl-graphics.h
+++ b/backends/graphics/surfacesdl/surfacesdl-graphics.h
@@ -75,18 +75,18 @@ public:
/**
* SDL graphics manager
*/
-class SurfaceSdlGraphicsManager : public GraphicsManager, public SdlGraphicsManager, public Common::EventObserver {
+class SurfaceSdlGraphicsManager : public SdlGraphicsManager, public Common::EventObserver {
public:
SurfaceSdlGraphicsManager(SdlEventSource *sdlEventSource);
virtual ~SurfaceSdlGraphicsManager();
- virtual void initEventObserver();
+ virtual void activateManager();
+ virtual void deactivateManager();
virtual bool hasFeature(OSystem::Feature f);
virtual void setFeatureState(OSystem::Feature f, bool enable);
virtual bool getFeatureState(OSystem::Feature f);
- static const OSystem::GraphicsMode *supportedGraphicsModes();
virtual const OSystem::GraphicsMode *getSupportedGraphicsModes() const;
virtual int getDefaultGraphicsMode() const;
virtual bool setGraphicsMode(int mode);
diff --git a/backends/module.mk b/backends/module.mk
index 31ac444750..1222d9a363 100644
--- a/backends/module.mk
+++ b/backends/module.mk
@@ -40,14 +40,6 @@ MODULE_OBJS += \
keymapper/remap-dialog.o
endif
-ifdef USE_OPENGL
-MODULE_OBJS += \
- graphics/opengl/glerrorcheck.o \
- graphics/opengl/gltexture.o \
- graphics/opengl/opengl-graphics.o \
- graphics/openglsdl/openglsdl-graphics.o
-endif
-
ifdef ENABLE_VKEYBD
MODULE_OBJS += \
vkeybd/image-map.o \
@@ -57,6 +49,15 @@ MODULE_OBJS += \
vkeybd/virtual-keyboard-parser.o
endif
+# OpenGL specific source files.
+ifdef USE_OPENGL
+MODULE_OBJS += \
+ graphics/opengl/debug.o \
+ graphics/opengl/extensions.o \
+ graphics/opengl/opengl-graphics.o \
+ graphics/opengl/texture.o
+endif
+
# SDL specific source files.
# We cannot just check $BACKEND = sdl, as various other backends
# derive from the SDL backend, and they all need the following files.
@@ -76,6 +77,11 @@ ifndef USE_SDL13
MODULE_OBJS += \
audiocd/sdl/sdl-audiocd.o
endif
+
+ifdef USE_OPENGL
+MODULE_OBJS += \
+ graphics/openglsdl/openglsdl-graphics.o
+endif
endif
ifdef POSIX
diff --git a/backends/platform/android/android.cpp b/backends/platform/android/android.cpp
index ad80ea7f8c..5e3d1d0db6 100644
--- a/backends/platform/android/android.cpp
+++ b/backends/platform/android/android.cpp
@@ -146,7 +146,8 @@ OSystem_Android::OSystem_Android(int audio_sample_rate, int audio_buffer_size) :
_touchpad_scale(66),
_dpad_scale(4),
_fingersDown(0),
- _trackball_scale(2) {
+ _trackball_scale(2),
+ _joystick_scale(10) {
_fsFactory = new POSIXFilesystemFactory();
diff --git a/backends/platform/android/android.h b/backends/platform/android/android.h
index b4813b3bdf..704ce12f60 100644
--- a/backends/platform/android/android.h
+++ b/backends/platform/android/android.h
@@ -231,6 +231,7 @@ private:
int _touchpad_scale;
int _trackball_scale;
int _dpad_scale;
+ int _joystick_scale;
int _fingersDown;
void clipMouse(Common::Point &p);
diff --git a/backends/platform/android/android.mk b/backends/platform/android/android.mk
index f498c671de..915bf8ac60 100644
--- a/backends/platform/android/android.mk
+++ b/backends/platform/android/android.mk
@@ -25,13 +25,19 @@ PATH_RESOURCES = $(PATH_DIST)/res
PORT_DISTFILES = $(PATH_DIST)/README.Android
+# FIXME: OUYA specific.
+# "values-television" not present in vanilla Android.
+# $(PATH_RESOURCES)/../res-ouya/values-television/margins.xml \
+
RESOURCES = \
$(PATH_RESOURCES)/values/strings.xml \
+ $(PATH_RESOURCES)/values/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/scummvm_big.png \
+ $(PATH_RESOURCES)/drawable-xhdpi/ouya_icon.png
PLUGIN_RESOURCES = \
$(PATH_RESOURCES)/values/strings.xml \
diff --git a/backends/platform/android/events.cpp b/backends/platform/android/events.cpp
index db1261e432..5c42db9347 100644
--- a/backends/platform/android/events.cpp
+++ b/backends/platform/android/events.cpp
@@ -64,6 +64,10 @@ enum {
JE_RMB_DOWN = 11,
JE_RMB_UP = 12,
JE_MOUSE_MOVE = 13,
+ JE_GAMEPAD = 14,
+ JE_JOYSTICK = 15,
+ JE_MMB_DOWN = 16,
+ JE_MMB_UP = 17,
JE_QUIT = 0x1000
};
@@ -109,6 +113,25 @@ enum {
JKEYCODE_DPAD_CENTER = 23
};
+// gamepad
+enum {
+ JKEYCODE_BUTTON_A = 96,
+ JKEYCODE_BUTTON_B = 97,
+ JKEYCODE_BUTTON_C = 98,
+ JKEYCODE_BUTTON_X = 99,
+ JKEYCODE_BUTTON_Y = 100,
+ JKEYCODE_BUTTON_Z = 101,
+ JKEYCODE_BUTTON_L1 = 102,
+ JKEYCODE_BUTTON_R1 = 103,
+ JKEYCODE_BUTTON_L2 = 104,
+ JKEYCODE_BUTTON_R2 = 105,
+ JKEYCODE_BUTTON_THUMBL = 106,
+ JKEYCODE_BUTTON_THUMBR = 107,
+ JKEYCODE_BUTTON_START = 108,
+ JKEYCODE_BUTTON_SELECT = 109,
+ JKEYCODE_BUTTON_MODE = 110,
+};
+
// meta modifier
enum {
JMETA_SHIFT = 0x01,
@@ -827,6 +850,94 @@ void OSystem_Android::pushEvent(int type, int arg1, int arg2, int arg3,
return;
+ case JE_GAMEPAD:
+ switch (arg1) {
+ case JACTION_DOWN:
+ e.type = Common::EVENT_KEYDOWN;
+ break;
+ case JACTION_UP:
+ e.type = Common::EVENT_KEYUP;
+ break;
+ default:
+ LOGE("unhandled jaction on gamepad key: %d", arg1);
+ return;
+ }
+
+ switch (arg2) {
+ case JKEYCODE_BUTTON_A:
+ case JKEYCODE_BUTTON_B:
+ switch (arg1) {
+ case JACTION_DOWN:
+ e.type = (arg2 == JKEYCODE_BUTTON_A?
+ Common::EVENT_LBUTTONDOWN :
+ Common::EVENT_RBUTTONDOWN);
+ break;
+ case JACTION_UP:
+ e.type = (arg2 == JKEYCODE_BUTTON_A?
+ Common::EVENT_LBUTTONUP :
+ Common::EVENT_RBUTTONUP);
+ break;
+ }
+
+ e.mouse = getEventManager()->getMousePos();
+
+ break;
+
+ case JKEYCODE_BUTTON_X:
+ e.kbd.keycode = Common::KEYCODE_ESCAPE;
+ e.kbd.ascii = Common::ASCII_ESCAPE;
+ break;
+
+ default:
+ LOGW("unmapped gamepad key: %d", arg2);
+ return;
+ }
+
+ lockMutex(_event_queue_lock);
+ _event_queue.push(e);
+ unlockMutex(_event_queue_lock);
+
+ break;
+
+ case JE_JOYSTICK:
+ e.mouse = getEventManager()->getMousePos();
+
+ switch (arg1) {
+ case JACTION_MULTIPLE:
+ e.type = Common::EVENT_MOUSEMOVE;
+
+ // already multiplied by 100
+ e.mouse.x += arg2 * _joystick_scale / _eventScaleX;
+ e.mouse.y += arg3 * _joystick_scale / _eventScaleY;
+
+ clipMouse(e.mouse);
+
+ break;
+ default:
+ LOGE("unhandled jaction on joystick: %d", arg1);
+ return;
+ }
+
+ lockMutex(_event_queue_lock);
+ _event_queue.push(e);
+ unlockMutex(_event_queue_lock);
+
+ return;
+
+ case JE_MMB_DOWN:
+ e.type = Common::EVENT_MAINMENU;
+
+ lockMutex(_event_queue_lock);
+ _event_queue.push(e);
+ unlockMutex(_event_queue_lock);
+
+ return;
+
+ case JE_MMB_UP:
+ // No action
+
+ return;
+
case JE_QUIT:
e.type = Common::EVENT_QUIT;
diff --git a/backends/platform/android/gfx.cpp b/backends/platform/android/gfx.cpp
index 882dcff9a4..9f6c759c75 100644
--- a/backends/platform/android/gfx.cpp
+++ b/backends/platform/android/gfx.cpp
@@ -94,6 +94,7 @@ Common::List<Graphics::PixelFormat> OSystem_Android::getSupportedFormats() const
Common::List<Graphics::PixelFormat> res;
res.push_back(GLES565Texture::pixelFormat());
res.push_back(GLES5551Texture::pixelFormat());
+ res.push_back(GLES8888Texture::pixelFormat());
res.push_back(GLES4444Texture::pixelFormat());
res.push_back(Graphics::PixelFormat::createFormatCLUT8());
@@ -147,6 +148,8 @@ void OSystem_Android::initTexture(GLESBaseTexture **texture,
*texture = new GLES565Texture();
else if (format_new == GLES5551Texture::pixelFormat())
*texture = new GLES5551Texture();
+ else if (format_new == GLES8888Texture::pixelFormat())
+ *texture = new GLES8888Texture();
else if (format_new == GLES4444Texture::pixelFormat())
*texture = new GLES4444Texture();
else {
@@ -233,7 +236,7 @@ void OSystem_Android::initViewport() {
GLCALL(glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST));
GLCALL(glEnable(GL_BLEND));
- GLCALL(glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA));
+ GLCALL(glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA));
GLCALL(glEnableClientState(GL_VERTEX_ARRAY));
GLCALL(glEnableClientState(GL_TEXTURE_COORD_ARRAY));
@@ -726,7 +729,7 @@ void OSystem_Android::setMouseCursor(const void *buf, uint w, uint h,
_mouse_keycolor = keycolor;
p = _mouse_texture_palette->palette() + _mouse_keycolor * 2;
- WRITE_UINT16(p, READ_UINT16(p) & ~1);
+ WRITE_UINT16(p, 0);
}
if (w == 0 || h == 0)
@@ -779,7 +782,7 @@ void OSystem_Android::setCursorPaletteInternal(const byte *colors,
WRITE_UINT16(p, pf.RGBToColor(colors[0], colors[1], colors[2]));
p = _mouse_texture_palette->palette() + _mouse_keycolor * 2;
- WRITE_UINT16(p, READ_UINT16(p) & ~1);
+ WRITE_UINT16(p, 0);
}
void OSystem_Android::setCursorPalette(const byte *colors,
@@ -821,7 +824,7 @@ void OSystem_Android::disableCursorPalette() {
}
byte *p = _mouse_texture_palette->palette() + _mouse_keycolor * 2;
- WRITE_UINT16(p, READ_UINT16(p) & ~1);
+ WRITE_UINT16(p, 0);
}
}
diff --git a/backends/platform/android/org/scummvm/scummvm/MouseHelper.java b/backends/platform/android/org/scummvm/scummvm/MouseHelper.java
index 999815593f..8990515b84 100644
--- a/backends/platform/android/org/scummvm/scummvm/MouseHelper.java
+++ b/backends/platform/android/org/scummvm/scummvm/MouseHelper.java
@@ -14,6 +14,7 @@ public class MouseHelper {
private long _rmbGuardTime;
private boolean _rmbPressed;
private boolean _lmbPressed;
+ private boolean _mmbPressed;
/**
* Class initialization fails when this throws an exception.
@@ -114,6 +115,23 @@ public class MouseHelper {
_rmbPressed = false;
}
+ boolean mmbDown = (buttonState & MotionEvent.BUTTON_TERTIARY) == MotionEvent.BUTTON_TERTIARY;
+ if (mmbDown) {
+ if (!_mmbPressed) {
+ // middle mouse button was pressed just now
+ _scummvm.pushEvent(ScummVMEvents.JE_MMB_DOWN, (int)e.getX(), (int)e.getY(), e.getButtonState(), 0, 0);
+ }
+
+ _mmbPressed = true;
+ } else {
+ if (_mmbPressed) {
+ // middle mouse button was released just now
+ _scummvm.pushEvent(ScummVMEvents.JE_MMB_UP, (int)e.getX(), (int)e.getY(), e.getButtonState(), 0, 0);
+ }
+
+ _mmbPressed = false;
+ }
+
return true;
}
diff --git a/backends/platform/android/org/scummvm/scummvm/ScummVMActivity.java b/backends/platform/android/org/scummvm/scummvm/ScummVMActivity.java
index 829a948435..5d041dafd2 100644
--- a/backends/platform/android/org/scummvm/scummvm/ScummVMActivity.java
+++ b/backends/platform/android/org/scummvm/scummvm/ScummVMActivity.java
@@ -240,6 +240,14 @@ public class ScummVMActivity extends Activity {
return false;
}
+ @Override
+ public boolean onGenericMotionEvent(final MotionEvent e) {
+ if (_events != null)
+ return _events.onGenericMotionEvent(e);
+
+ return false;
+ }
+
private void showKeyboard(boolean show) {
SurfaceView main_surface = (SurfaceView)findViewById(R.id.main_surface);
InputMethodManager imm = (InputMethodManager)
diff --git a/backends/platform/android/org/scummvm/scummvm/ScummVMEvents.java b/backends/platform/android/org/scummvm/scummvm/ScummVMEvents.java
index 5f51ffac6c..702215341b 100644
--- a/backends/platform/android/org/scummvm/scummvm/ScummVMEvents.java
+++ b/backends/platform/android/org/scummvm/scummvm/ScummVMEvents.java
@@ -9,6 +9,7 @@ import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.GestureDetector;
+import android.view.InputDevice;
import android.view.inputmethod.InputMethodManager;
public class ScummVMEvents implements
@@ -31,6 +32,10 @@ public class ScummVMEvents implements
public static final int JE_RMB_DOWN = 11;
public static final int JE_RMB_UP = 12;
public static final int JE_MOUSE_MOVE = 13;
+ public static final int JE_GAMEPAD = 14;
+ public static final int JE_JOYSTICK = 15;
+ public static final int JE_MMB_DOWN = 16;
+ public static final int JE_MMB_UP = 17;
public static final int JE_QUIT = 0x1000;
final protected Context _context;
@@ -63,6 +68,18 @@ public class ScummVMEvents implements
return true;
}
+ public boolean onGenericMotionEvent(final MotionEvent e) {
+ if((e.getSource() & InputDevice.SOURCE_CLASS_JOYSTICK) != 0) {
+ _scummvm.pushEvent(JE_JOYSTICK, e.getAction(),
+ (int)(e.getAxisValue(MotionEvent.AXIS_X)*100),
+ (int)(e.getAxisValue(MotionEvent.AXIS_Y)*100),
+ 0, 0);
+ return true;
+ }
+
+ return false;
+ }
+
final static int MSG_MENU_LONG_PRESS = 1;
final private Handler keyHandler = new Handler() {
@@ -177,6 +194,25 @@ public class ScummVMEvents implements
(int)(e.getEventTime() - e.getDownTime()),
e.getRepeatCount(), 0);
return true;
+ case KeyEvent.KEYCODE_BUTTON_A:
+ case KeyEvent.KEYCODE_BUTTON_B:
+ case KeyEvent.KEYCODE_BUTTON_C:
+ case KeyEvent.KEYCODE_BUTTON_X:
+ case KeyEvent.KEYCODE_BUTTON_Y:
+ case KeyEvent.KEYCODE_BUTTON_Z:
+ case KeyEvent.KEYCODE_BUTTON_L1:
+ case KeyEvent.KEYCODE_BUTTON_R1:
+ case KeyEvent.KEYCODE_BUTTON_L2:
+ case KeyEvent.KEYCODE_BUTTON_R2:
+ case KeyEvent.KEYCODE_BUTTON_THUMBL:
+ case KeyEvent.KEYCODE_BUTTON_THUMBR:
+ case KeyEvent.KEYCODE_BUTTON_START:
+ case KeyEvent.KEYCODE_BUTTON_SELECT:
+ case KeyEvent.KEYCODE_BUTTON_MODE:
+ _scummvm.pushEvent(JE_GAMEPAD, action, keyCode,
+ (int)(e.getEventTime() - e.getDownTime()),
+ e.getRepeatCount(), 0);
+ return true;
}
_scummvm.pushEvent(JE_KEY, action, keyCode,
diff --git a/backends/platform/android/texture.cpp b/backends/platform/android/texture.cpp
index cc41c0d8a6..87fd2d976c 100644
--- a/backends/platform/android/texture.cpp
+++ b/backends/platform/android/texture.cpp
@@ -259,11 +259,15 @@ void GLESTexture::fillBuffer(uint32 color) {
assert(_surface.getPixels());
if (_pixelFormat.bytesPerPixel == 1 ||
- ((color & 0xff) == ((color >> 8) & 0xff)))
+ (_pixelFormat.bytesPerPixel == 2 &&
+ ((color & 0xff) == ((color >> 8) & 0xff))))
memset(_pixels, color & 0xff, _surface.pitch * _surface.h);
- else
- Common::fill(_pixels, _pixels + _surface.pitch * _surface.h,
+ else if (_pixelFormat.bytesPerPixel == 2)
+ Common::fill((uint16 *)_pixels, (uint16 *)(_pixels + _surface.pitch * _surface.h),
(uint16)color);
+ else
+ Common::fill((uint32 *)_pixels, (uint32 *)(_pixels + _surface.pitch * _surface.h),
+ color);
setDirty();
}
@@ -334,6 +338,13 @@ GLES565Texture::GLES565Texture() :
GLES565Texture::~GLES565Texture() {
}
+GLES8888Texture::GLES8888Texture() :
+ GLESTexture(GL_RGBA, GL_UNSIGNED_BYTE, pixelFormat()) {
+}
+
+GLES8888Texture::~GLES8888Texture() {
+}
+
GLESFakePaletteTexture::GLESFakePaletteTexture(GLenum glFormat, GLenum glType,
Graphics::PixelFormat pixelFormat) :
GLESBaseTexture(glFormat, glType, pixelFormat),
diff --git a/backends/platform/android/texture.h b/backends/platform/android/texture.h
index 4307b5a1bc..67f7343c98 100644
--- a/backends/platform/android/texture.h
+++ b/backends/platform/android/texture.h
@@ -224,6 +224,18 @@ public:
}
};
+// RGBA8888 texture
+class GLES8888Texture : public GLESTexture {
+public:
+ GLES8888Texture();
+ virtual ~GLES8888Texture();
+
+ static inline Graphics::PixelFormat pixelFormat() {
+ // We assume LE since all Android platforms are LE.
+ return Graphics::PixelFormat(4, 8, 8, 8, 8, 0, 8, 16, 24);
+ }
+};
+
class GLESFakePaletteTexture : public GLESBaseTexture {
protected:
GLESFakePaletteTexture(GLenum glFormat, GLenum glType,
diff --git a/backends/platform/dc/dc-fs.cpp b/backends/platform/dc/dc-fs.cpp
index 36f5a1465c..f850c9d26f 100644
--- a/backends/platform/dc/dc-fs.cpp
+++ b/backends/platform/dc/dc-fs.cpp
@@ -27,7 +27,9 @@
#include <ronin/cdfs.h>
#include <stdio.h>
+#define usleep usleep_unistd
#include <unistd.h>
+#undef usleep
/**
* Implementation of the ScummVM file system API based on Ronin.
diff --git a/backends/platform/dc/dc.h b/backends/platform/dc/dc.h
index d62ced02e1..ba60c7740e 100644
--- a/backends/platform/dc/dc.h
+++ b/backends/platform/dc/dc.h
@@ -43,7 +43,9 @@ class Interactive
public:
virtual int key(int k, byte &shiftFlags) = 0;
virtual void mouse(int x, int y) = 0;
+ virtual ~Interactive() = 0;
};
+inline Interactive::~Interactive() { }
#include "softkbd.h"
diff --git a/backends/platform/dc/dcmain.cpp b/backends/platform/dc/dcmain.cpp
index bec1fdae3a..36a22c4b5c 100644
--- a/backends/platform/dc/dcmain.cpp
+++ b/backends/platform/dc/dcmain.cpp
@@ -79,13 +79,14 @@ static bool find_track(int track, int &first_sec, int &last_sec)
if (first < 1 || last > 99 || first > last)
return false;
for (i=first; i<=last; i++)
- if (!(TOC_CTRL(toc->entry[i-1])&4))
+ if (!(TOC_CTRL(toc->entry[i-1])&4)) {
if (track==1) {
first_sec = TOC_LBA(toc->entry[i-1]);
last_sec = TOC_LBA(toc->entry[i]);
return true;
} else
--track;
+ }
return false;
}
@@ -281,7 +282,7 @@ namespace DC_Flash {
if((r = syscall_read_flash(info[0] + (bmb++ << 6), bm, 64))<0)
return r;
}
- if(!(bm[(b>>3)&63] & (0x80>>(b&7))))
+ if(!(bm[(b>>3)&63] & (0x80>>(b&7)))) {
if((r = syscall_read_flash(info[0] + ((b+1) << 6), buf, 64))<0)
return r;
else if((s=*(unsigned short *)(buf+0)) == sec &&
@@ -289,6 +290,7 @@ namespace DC_Flash {
memcpy(dst+(s-sec)*60, buf+2, 60);
got=1;
}
+ }
}
return got;
}
diff --git a/backends/platform/dc/icon.cpp b/backends/platform/dc/icon.cpp
index cf7afc82e0..28edf27f4f 100644
--- a/backends/platform/dc/icon.cpp
+++ b/backends/platform/dc/icon.cpp
@@ -47,8 +47,8 @@ void Icon::create_vmicon(void *buffer)
void Icon::create_texture()
{
- static char tt[16] = { 0, 1, 4, 5, 16, 17, 20, 21,
- 64, 65, 68, 69, 80, 81, 84, 85 };
+ static unsigned char tt[16] = { 0, 1, 4, 5, 16, 17, 20, 21,
+ 64, 65, 68, 69, 80, 81, 84, 85 };
unsigned short *tex = (unsigned short *)ta_txalloc(512);
unsigned short *linebase;
unsigned char *src = bitmap+sizeof(bitmap)-17;
diff --git a/backends/platform/dc/input.cpp b/backends/platform/dc/input.cpp
index 7b21c76efa..5c6adf6c7c 100644
--- a/backends/platform/dc/input.cpp
+++ b/backends/platform/dc/input.cpp
@@ -50,10 +50,10 @@ int handleInput(struct mapledev *pad, int &mouse_x, int &mouse_y,
else if (!(buttons & 512)) newkey = ' ';
else if (!(buttons & 1024)) newkey = numpadmap[(buttons>>4)&15];
- if (!(buttons & 128)) if (inter) newkey = 1001; else mouse_x++;
- if (!(buttons & 64)) if (inter) newkey = 1002; else mouse_x--;
- if (!(buttons & 32)) if (inter) newkey = 1003; else mouse_y++;
- if (!(buttons & 16)) if (inter) newkey = 1004; else mouse_y--;
+ if (!(buttons & 128)) { if (inter) newkey = 1001; else mouse_x++; }
+ if (!(buttons & 64)) { if (inter) newkey = 1002; else mouse_x--; }
+ if (!(buttons & 32)) { if (inter) newkey = 1003; else mouse_y++; }
+ if (!(buttons & 16)) { if (inter) newkey = 1004; else mouse_y--; }
mouse_x += ((int)pad->cond.controller.joyx-128)>>4;
mouse_y += ((int)pad->cond.controller.joyy-128)>>4;
@@ -157,7 +157,7 @@ int handleInput(struct mapledev *pad, int &mouse_x, int &mouse_y,
return -Common::EVENT_RBUTTONUP;
}
- if (mouse_wheel != lastwheel)
+ if (mouse_wheel != lastwheel) {
if (((int8)(mouse_wheel - lastwheel)) > 0) {
lastwheel++;
return -Common::EVENT_WHEELDOWN;
@@ -165,6 +165,7 @@ int handleInput(struct mapledev *pad, int &mouse_x, int &mouse_y,
--lastwheel;
return -Common::EVENT_WHEELUP;
}
+ }
if (newkey && inter && newkey != lastkey) {
int transkey = inter->key(newkey, shiftFlags);
diff --git a/backends/platform/dc/ip.txt.in b/backends/platform/dc/ip.txt.in
index 23424e0950..539d29dd1e 100644
--- a/backends/platform/dc/ip.txt.in
+++ b/backends/platform/dc/ip.txt.in
@@ -7,5 +7,5 @@ Product No : T0000
Version : @VERSION@
Release Date : @DATE@
Boot Filename : SCUMMVM.BIN
-SW Maker Name : The ScummVM team
+SW Maker Name : The ScummVM Team
Game Title : ScummVM
diff --git a/backends/platform/dc/softkbd.h b/backends/platform/dc/softkbd.h
index 8f87d12baa..27826c2744 100644
--- a/backends/platform/dc/softkbd.h
+++ b/backends/platform/dc/softkbd.h
@@ -40,6 +40,7 @@ class SoftKeyboard : public Interactive
public:
SoftKeyboard(const OSystem_Dreamcast *os);
+ virtual ~SoftKeyboard() {}
void draw(float x, float y, int transp = 0);
int key(int k, byte &shiftFlags);
diff --git a/backends/platform/gph/gph-backend.cpp b/backends/platform/gph/gph-backend.cpp
index 485780b472..e51d7d0781 100644
--- a/backends/platform/gph/gph-backend.cpp
+++ b/backends/platform/gph/gph-backend.cpp
@@ -172,7 +172,7 @@ void OSystem_GPH::initSDL() {
// Check if SDL has not been initialized
if (!_initedSDL) {
- uint32 sdlFlags = SDL_INIT_EVENTTHREAD;
+ uint32 sdlFlags = SDL_INIT_EVENTTHREAD | SDL_INIT_VIDEO;
if (ConfMan.hasKey("disable_sdl_parachute"))
sdlFlags |= SDL_INIT_NOPARACHUTE;
diff --git a/backends/platform/null/null.cpp b/backends/platform/null/null.cpp
index 9e05539799..29bf9acacd 100644
--- a/backends/platform/null/null.cpp
+++ b/backends/platform/null/null.cpp
@@ -20,12 +20,23 @@
*
*/
+// We use some stdio.h functionality here thus we need to allow some
+// symbols. Alternatively, we could simply allow everything by defining
+// FORBIDDEN_SYMBOL_ALLOW_ALL
+#define FORBIDDEN_SYMBOL_EXCEPTION_FILE
+#define FORBIDDEN_SYMBOL_EXCEPTION_stdout
+#define FORBIDDEN_SYMBOL_EXCEPTION_stderr
+#define FORBIDDEN_SYMBOL_EXCEPTION_fputs
+
#include "backends/modular-backend.h"
#include "base/main.h"
#if defined(USE_NULL_DRIVER)
#include "backends/saves/default/default-saves.h"
#include "backends/timer/default/default-timer.h"
+#include "backends/events/default/default-events.h"
+#include "backends/mutex/null/null-mutex.h"
+#include "backends/graphics/null/null-graphics.h"
#include "audio/mixer_intern.h"
#include "common/scummsys.h"
@@ -40,13 +51,14 @@
#include "backends/fs/windows/windows-fs-factory.h"
#endif
-class OSystem_NULL : public ModularBackend {
+class OSystem_NULL : public ModularBackend, Common::EventSource {
public:
OSystem_NULL();
virtual ~OSystem_NULL();
virtual void initBackend();
+ virtual Common::EventSource *getDefaultEventSource() { return this; }
virtual bool pollEvent(Common::Event &event);
virtual uint32 getMillis(bool skipRecord = false);
@@ -92,7 +104,7 @@ bool OSystem_NULL::pollEvent(Common::Event &event) {
return false;
}
-uint32 OSystem_NULL::getMillis() {
+uint32 OSystem_NULL::getMillis(bool skipRecord) {
return 0;
}
diff --git a/backends/platform/openpandora/op-backend.cpp b/backends/platform/openpandora/op-backend.cpp
index 354aa24b24..60c3cc7191 100644
--- a/backends/platform/openpandora/op-backend.cpp
+++ b/backends/platform/openpandora/op-backend.cpp
@@ -160,7 +160,7 @@ void OSystem_OP::initSDL() {
// Check if SDL has not been initialized
if (!_initedSDL) {
- uint32 sdlFlags = SDL_INIT_EVENTTHREAD;
+ uint32 sdlFlags = SDL_INIT_EVENTTHREAD | SDL_INIT_VIDEO;
if (ConfMan.hasKey("disable_sdl_parachute"))
sdlFlags |= SDL_INIT_NOPARACHUTE;
diff --git a/backends/platform/sdl/posix/posix.cpp b/backends/platform/sdl/posix/posix.cpp
index 7a8b1e7b70..1752153f29 100644
--- a/backends/platform/sdl/posix/posix.cpp
+++ b/backends/platform/sdl/posix/posix.cpp
@@ -50,7 +50,7 @@ void OSystem_POSIX::init() {
// Initialze File System Factory
_fsFactory = new POSIXFilesystemFactory();
-#if defined(USE_TASKBAR) && defined(USE_TASKBAR_UNITY)
+#if defined(USE_TASKBAR) && defined(USE_UNITY)
// Initialize taskbar manager
_taskbarManager = new UnityTaskbarManager();
#endif
@@ -67,7 +67,7 @@ void OSystem_POSIX::initBackend() {
// Invoke parent implementation of this method
OSystem_SDL::initBackend();
-#if defined(USE_TASKBAR) && defined(USE_TASKBAR_UNITY)
+#if defined(USE_TASKBAR) && defined(USE_UNITY)
// Register the taskbar manager as an event source (this is necessary for the glib event loop to be run)
_eventManager->getEventDispatcher()->registerSource((UnityTaskbarManager *)_taskbarManager, false);
#endif
@@ -80,15 +80,16 @@ bool OSystem_POSIX::hasFeature(Feature f) {
}
Common::String OSystem_POSIX::getDefaultConfigFileName() {
- char configFile[MAXPATHLEN];
+ Common::String configFile;
// On POSIX type systems, by default we store the config file inside
// to the HOME directory of the user.
const char *home = getenv("HOME");
- if (home != NULL && strlen(home) < MAXPATHLEN)
- snprintf(configFile, MAXPATHLEN, "%s/%s", home, _baseConfigName.c_str());
- else
- strcpy(configFile, _baseConfigName.c_str());
+ if (home != NULL && (strlen(home) + 1 + _baseConfigName.size()) < MAXPATHLEN) {
+ configFile = Common::String::format("%s/%s", home, _baseConfigName.c_str());
+ } else {
+ configFile = _baseConfigName;
+ }
return configFile;
}
diff --git a/backends/platform/sdl/sdl.cpp b/backends/platform/sdl/sdl.cpp
index 7ab367d4a4..913ae51f69 100644
--- a/backends/platform/sdl/sdl.cpp
+++ b/backends/platform/sdl/sdl.cpp
@@ -65,10 +65,13 @@
OSystem_SDL::OSystem_SDL()
:
#ifdef USE_OPENGL
- _graphicsModes(0),
+ _desktopWidth(0),
+ _desktopHeight(0),
+ _graphicsModes(),
_graphicsMode(0),
- _sdlModesCount(0),
- _glModesCount(0),
+ _firstGLMode(0),
+ _defaultSDLMode(0),
+ _defaultGLMode(0),
#endif
_inited(false),
_initedSDL(false),
@@ -87,6 +90,9 @@ OSystem_SDL::~OSystem_SDL() {
// Hence, we perform the destruction on our own.
delete _savefileManager;
_savefileManager = 0;
+ if (_graphicsManager) {
+ dynamic_cast<SdlGraphicsManager *>(_graphicsManager)->deactivateManager();
+ }
delete _graphicsManager;
_graphicsManager = 0;
delete _eventManager;
@@ -110,10 +116,6 @@ OSystem_SDL::~OSystem_SDL() {
delete _mutexManager;
_mutexManager = 0;
-#ifdef USE_OPENGL
- delete[] _graphicsModes;
-#endif
-
delete _logger;
_logger = 0;
@@ -124,6 +126,12 @@ void OSystem_SDL::init() {
// Initialize SDL
initSDL();
+ // Enable unicode support if possible
+ SDL_EnableUNICODE(1);
+
+ // Disable OS cursor
+ SDL_ShowCursor(SDL_DISABLE);
+
if (!_logger)
_logger = new Backends::Log::Log(this);
@@ -144,10 +152,6 @@ void OSystem_SDL::init() {
_taskbarManager = new Common::TaskbarManager();
#endif
-#ifdef USE_OPENGL
- // Setup a list with both SDL and OpenGL graphics modes
- setupGraphicsModes();
-#endif
}
void OSystem_SDL::initBackend() {
@@ -159,35 +163,41 @@ void OSystem_SDL::initBackend() {
if (_eventSource == 0)
_eventSource = new SdlEventSource();
- int graphicsManagerType = 0;
+#ifdef USE_OPENGL
+ // Query the desktop resolution. We simply hope nothing tried to change
+ // the resolution so far.
+ const SDL_VideoInfo *videoInfo = SDL_GetVideoInfo();
+ if (videoInfo && videoInfo->current_w > 0 && videoInfo->current_h > 0) {
+ _desktopWidth = videoInfo->current_w;
+ _desktopHeight = videoInfo->current_h;
+ }
+#endif
if (_graphicsManager == 0) {
#ifdef USE_OPENGL
+ // Setup a list with both SDL and OpenGL graphics modes. We only do
+ // this whenever the subclass did not already set up an graphics
+ // manager yet. This is because we don't know the type of the graphics
+ // manager of the subclass, thus we cannot easily switch between the
+ // OpenGL one and the set up one. It also is to be expected that the
+ // subclass does not want any switching of graphics managers anyway.
+ setupGraphicsModes();
+
if (ConfMan.hasKey("gfx_mode")) {
+ // If the gfx_mode is from OpenGL, create the OpenGL graphics manager
Common::String gfxMode(ConfMan.get("gfx_mode"));
- bool use_opengl = false;
- const OSystem::GraphicsMode *mode = OpenGLSdlGraphicsManager::supportedGraphicsModes();
- int i = 0;
- while (mode->name) {
- if (scumm_stricmp(mode->name, gfxMode.c_str()) == 0) {
- _graphicsMode = i + _sdlModesCount;
- use_opengl = true;
+ for (uint i = _firstGLMode; i < _graphicsModeIds.size(); ++i) {
+ if (!scumm_stricmp(_graphicsModes[i].name, gfxMode.c_str())) {
+ _graphicsManager = new OpenGLSdlGraphicsManager(_desktopWidth, _desktopHeight, _eventSource);
+ _graphicsMode = i;
+ break;
}
-
- mode++;
- ++i;
- }
-
- // If the gfx_mode is from OpenGL, create the OpenGL graphics manager
- if (use_opengl) {
- _graphicsManager = new OpenGLSdlGraphicsManager(_eventSource);
- graphicsManagerType = 1;
}
}
#endif
+
if (_graphicsManager == 0) {
_graphicsManager = new SurfaceSdlGraphicsManager(_eventSource);
- graphicsManagerType = 0;
}
}
@@ -230,13 +240,7 @@ void OSystem_SDL::initBackend() {
// so the virtual keyboard can be initialized, but we have to add the
// graphics manager as an event observer after initializing the event
// manager.
- if (graphicsManagerType == 0)
- ((SurfaceSdlGraphicsManager *)_graphicsManager)->initEventObserver();
-#ifdef USE_OPENGL
- else if (graphicsManagerType == 1)
- ((OpenGLSdlGraphicsManager *)_graphicsManager)->initEventObserver();
-#endif
-
+ dynamic_cast<SdlGraphicsManager *>(_graphicsManager)->activateManager();
}
#if defined(USE_TASKBAR)
@@ -257,22 +261,19 @@ void OSystem_SDL::engineDone() {
void OSystem_SDL::initSDL() {
// Check if SDL has not been initialized
if (!_initedSDL) {
- uint32 sdlFlags = 0;
+ // We always initialize the video subsystem because we will need it to
+ // be initialized before the graphics managers to retrieve the desktop
+ // resolution, for example. WebOS also requires this initialization
+ // or otherwise the application won't start.
+ uint32 sdlFlags = SDL_INIT_VIDEO;
+
if (ConfMan.hasKey("disable_sdl_parachute"))
sdlFlags |= SDL_INIT_NOPARACHUTE;
-#ifdef WEBOS
- // WebOS needs this flag or otherwise the application won't start
- sdlFlags |= SDL_INIT_VIDEO;
-#endif
-
// Initialize SDL (SDL Subsystems are initiliazed in the corresponding sdl managers)
if (SDL_Init(sdlFlags) == -1)
error("Could not initialize SDL: %s", SDL_GetError());
- // Enable unicode support if possible
- SDL_EnableUNICODE(1);
-
_initedSDL = true;
}
}
@@ -368,17 +369,6 @@ Common::String OSystem_SDL::getSystemLanguage() const {
const LCID languageIdentifier = GetThreadLocale();
- // GetLocalInfo is only supported starting from Windows 2000, according to this:
- // http://msdn.microsoft.com/en-us/library/dd318101%28VS.85%29.aspx
- // On the other hand the locale constants used, seem to exist on Windows 98 too,
- // check this for that: http://msdn.microsoft.com/en-us/library/dd464799%28v=VS.85%29.aspx
- //
- // I am not exactly sure what is the truth now, it might be very well that this breaks
- // support for systems older than Windows 2000....
- //
- // TODO: Check whether this (or ScummVM at all ;-) works on a system with Windows 98 for
- // example and if it does not and we still want Windows 9x support, we should definitly
- // think of another solution.
if (GetLocaleInfo(languageIdentifier, LOCALE_SISO639LANGNAME, langName, sizeof(langName)) != 0 &&
GetLocaleInfo(languageIdentifier, LOCALE_SISO3166CTRYNAME, ctryName, sizeof(ctryName)) != 0) {
Common::String localeName = langName;
@@ -391,10 +381,15 @@ Common::String OSystem_SDL::getSystemLanguage() const {
}
#else // WIN32
// Activating current locale settings
- const char *locale = setlocale(LC_ALL, "");
+ const Common::String locale = setlocale(LC_ALL, "");
+
+ // Restore default C locale to prevent issues with
+ // portability of sscanf(), atof(), etc.
+ // See bug #3615148
+ setlocale(LC_ALL, "C");
// Detect the language from the locale
- if (!locale) {
+ if (locale.empty()) {
return ModularBackend::getSystemLanguage();
} else {
int length = 0;
@@ -403,14 +398,14 @@ Common::String OSystem_SDL::getSystemLanguage() const {
// ".UTF-8" or the like. We do this, since
// our translation languages are usually
// specified without any charset information.
- for (int i = 0; locale[i]; ++i, ++length) {
+ for (int size = locale.size(); length < size; ++length) {
// TODO: Check whether "@" should really be checked
// here.
- if (locale[i] == '.' || locale[i] == ' ' || locale[i] == '@')
+ if (locale[length] == '.' || locale[length] == ' ' || locale[length] == '@')
break;
}
- return Common::String(locale, length);
+ return Common::String(locale.c_str(), length);
}
#endif // WIN32
#else // USE_DETECTLANG
@@ -535,28 +530,33 @@ Common::TimerManager *OSystem_SDL::getTimerManager() {
#ifdef USE_OPENGL
const OSystem::GraphicsMode *OSystem_SDL::getSupportedGraphicsModes() const {
- return _graphicsModes;
+ if (_graphicsModes.empty()) {
+ return _graphicsManager->getSupportedGraphicsModes();
+ } else {
+ return _graphicsModes.begin();
+ }
}
int OSystem_SDL::getDefaultGraphicsMode() const {
- // Return the default graphics mode from the current graphics manager
- if (_graphicsMode < _sdlModesCount)
+ if (_graphicsModes.empty()) {
return _graphicsManager->getDefaultGraphicsMode();
- else
- return _graphicsManager->getDefaultGraphicsMode() + _sdlModesCount;
+ } else {
+ // Return the default graphics mode from the current graphics manager
+ if (_graphicsMode < _firstGLMode)
+ return _defaultSDLMode;
+ else
+ return _defaultGLMode;
+ }
}
bool OSystem_SDL::setGraphicsMode(int mode) {
- const OSystem::GraphicsMode *srcMode;
- int i;
+ if (_graphicsModes.empty()) {
+ return _graphicsManager->setGraphicsMode(mode);
+ }
- // Check if mode is from SDL or OpenGL
- if (mode < _sdlModesCount) {
- srcMode = SurfaceSdlGraphicsManager::supportedGraphicsModes();
- i = 0;
- } else {
- srcMode = OpenGLSdlGraphicsManager::supportedGraphicsModes();
- i = _sdlModesCount;
+ // Check whether a invalid mode is requested.
+ if (mode < 0 || (uint)mode >= _graphicsModeIds.size()) {
+ return false;
}
// Very hacky way to set up the old graphics manager state, in case we
@@ -575,113 +575,121 @@ bool OSystem_SDL::setGraphicsMode(int mode) {
bool switchedManager = false;
- // Loop through modes
- while (srcMode->name) {
- if (i == mode) {
- // If the new mode and the current mode are not from the same graphics
- // manager, delete and create the new mode graphics manager
- if (_graphicsMode >= _sdlModesCount && mode < _sdlModesCount) {
- debug(1, "switching to plain SDL graphics");
- delete _graphicsManager;
- _graphicsManager = new SurfaceSdlGraphicsManager(_eventSource);
- ((SurfaceSdlGraphicsManager *)_graphicsManager)->initEventObserver();
- _graphicsManager->beginGFXTransaction();
-
- switchedManager = true;
- } else if (_graphicsMode < _sdlModesCount && mode >= _sdlModesCount) {
- debug(1, "switching to OpenGL graphics");
- delete _graphicsManager;
- _graphicsManager = new OpenGLSdlGraphicsManager(_eventSource);
- ((OpenGLSdlGraphicsManager *)_graphicsManager)->initEventObserver();
- _graphicsManager->beginGFXTransaction();
-
- switchedManager = true;
- }
+ // If the new mode and the current mode are not from the same graphics
+ // 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();
+ delete _graphicsManager;
+ _graphicsManager = new SurfaceSdlGraphicsManager(_eventSource);
+
+ switchedManager = true;
+ } else if (_graphicsMode < _firstGLMode && mode >= _firstGLMode) {
+ debug(1, "switching to OpenGL graphics");
+ dynamic_cast<SdlGraphicsManager *>(_graphicsManager)->deactivateManager();
+ delete _graphicsManager;
+ _graphicsManager = new OpenGLSdlGraphicsManager(_desktopWidth, _desktopHeight, _eventSource);
+
+ switchedManager = true;
+ }
- _graphicsMode = mode;
+ _graphicsMode = mode;
- if (switchedManager) {
+ if (switchedManager) {
+ dynamic_cast<SdlGraphicsManager *>(_graphicsManager)->activateManager();
+
+ _graphicsManager->beginGFXTransaction();
#ifdef USE_RGB_COLOR
- _graphicsManager->initSize(screenWidth, screenHeight, &pixelFormat);
+ _graphicsManager->initSize(screenWidth, screenHeight, &pixelFormat);
#else
- _graphicsManager->initSize(screenWidth, screenHeight, 0);
+ _graphicsManager->initSize(screenWidth, screenHeight, 0);
#endif
- _graphicsManager->setFeatureState(kFeatureAspectRatioCorrection, arState);
- _graphicsManager->setFeatureState(kFeatureFullscreenMode, fullscreen);
- _graphicsManager->setFeatureState(kFeatureCursorPalette, cursorPalette);
+ _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
+ // 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.
- return false;
- }
-
- // Next setup the cursor again
- CursorMan.pushCursor(0, 0, 0, 0, 0, 0);
- CursorMan.popCursor();
+ // 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.
+ return false;
+ }
- // Next setup cursor palette if needed
- if (cursorPalette) {
- CursorMan.pushCursorPalette(0, 0, 0);
- CursorMan.popCursorPalette();
- }
+ // Next setup the cursor again
+ CursorMan.pushCursor(0, 0, 0, 0, 0, 0);
+ CursorMan.popCursor();
- _graphicsManager->beginGFXTransaction();
- // Oh my god if this failed the client code might just explode.
- return _graphicsManager->setGraphicsMode(srcMode->id);
- } else {
- return _graphicsManager->setGraphicsMode(srcMode->id);
- }
+ // Next setup cursor palette if needed
+ if (cursorPalette) {
+ CursorMan.pushCursorPalette(0, 0, 0);
+ CursorMan.popCursorPalette();
}
- i++;
- srcMode++;
+ _graphicsManager->beginGFXTransaction();
+ // Oh my god if this failed the client code might just explode.
+ return _graphicsManager->setGraphicsMode(_graphicsModeIds[mode]);
+ } else {
+ return _graphicsManager->setGraphicsMode(_graphicsModeIds[mode]);
}
-
- return false;
}
int OSystem_SDL::getGraphicsMode() const {
- return _graphicsMode;
+ if (_graphicsModes.empty()) {
+ return _graphicsManager->getGraphicsMode();
+ } else {
+ return _graphicsMode;
+ }
}
void OSystem_SDL::setupGraphicsModes() {
- const OSystem::GraphicsMode *sdlGraphicsModes = SurfaceSdlGraphicsManager::supportedGraphicsModes();
- const OSystem::GraphicsMode *openglGraphicsModes = OpenGLSdlGraphicsManager::supportedGraphicsModes();
- _sdlModesCount = 0;
- _glModesCount = 0;
+ _graphicsModes.clear();
+ _graphicsModeIds.clear();
+ _defaultSDLMode = _defaultGLMode = -1;
// Count the number of graphics modes
- const OSystem::GraphicsMode *srcMode = sdlGraphicsModes;
+ const OSystem::GraphicsMode *srcMode;
+ int defaultMode;
+
+ GraphicsManager *manager = new SurfaceSdlGraphicsManager(_eventSource);
+ srcMode = manager->getSupportedGraphicsModes();
+ defaultMode = manager->getDefaultGraphicsMode();
while (srcMode->name) {
- _sdlModesCount++;
+ if (defaultMode == srcMode->id) {
+ _defaultSDLMode = _graphicsModes.size();
+ }
+ _graphicsModes.push_back(*srcMode);
srcMode++;
}
- srcMode = openglGraphicsModes;
+ delete manager;
+ assert(_defaultSDLMode != -1);
+
+ _firstGLMode = _graphicsModes.size();
+ manager = new OpenGLSdlGraphicsManager(_desktopWidth, _desktopHeight, _eventSource);
+ srcMode = manager->getSupportedGraphicsModes();
+ defaultMode = manager->getDefaultGraphicsMode();
while (srcMode->name) {
- _glModesCount++;
+ if (defaultMode == srcMode->id) {
+ _defaultGLMode = _graphicsModes.size();
+ }
+ _graphicsModes.push_back(*srcMode);
srcMode++;
}
-
- // Allocate enough space for merged array of modes
- _graphicsModes = new OSystem::GraphicsMode[_glModesCount + _sdlModesCount + 1];
-
- // Copy SDL graphics modes
- memcpy((void *)_graphicsModes, sdlGraphicsModes, _sdlModesCount * sizeof(OSystem::GraphicsMode));
-
- // Copy OpenGL graphics modes
- memcpy((void *)(_graphicsModes + _sdlModesCount), openglGraphicsModes, _glModesCount * sizeof(OSystem::GraphicsMode));
+ delete manager;
+ manager = nullptr;
+ assert(_defaultGLMode != -1);
// Set a null mode at the end
- memset((void *)(_graphicsModes + _sdlModesCount + _glModesCount), 0, sizeof(OSystem::GraphicsMode));
+ GraphicsMode nullMode;
+ memset(&nullMode, 0, sizeof(nullMode));
+ _graphicsModes.push_back(nullMode);
// Set new internal ids for all modes
int i = 0;
- OSystem::GraphicsMode *mode = _graphicsModes;
+ OSystem::GraphicsMode *mode = _graphicsModes.begin();
while (mode->name) {
+ _graphicsModeIds.push_back(mode->id);
mode->id = i++;
mode++;
}
diff --git a/backends/platform/sdl/sdl.h b/backends/platform/sdl/sdl.h
index 840e73ff09..814cdd7c1b 100644
--- a/backends/platform/sdl/sdl.h
+++ b/backends/platform/sdl/sdl.h
@@ -30,6 +30,8 @@
#include "backends/events/sdl/sdl-events.h"
#include "backends/log/log.h"
+#include "common/array.h"
+
/**
* Base OSystem class for all SDL ports.
*/
@@ -106,15 +108,20 @@ protected:
Backends::Log::Log *_logger;
#ifdef USE_OPENGL
- OSystem::GraphicsMode *_graphicsModes;
+ int _desktopWidth, _desktopHeight;
+
+ typedef Common::Array<GraphicsMode> GraphicsModeArray;
+ GraphicsModeArray _graphicsModes;
+ Common::Array<int> _graphicsModeIds;
int _graphicsMode;
- int _sdlModesCount;
- int _glModesCount;
+ int _firstGLMode;
+ int _defaultSDLMode;
+ int _defaultGLMode;
/**
* Creates the merged graphics modes list
*/
- virtual void setupGraphicsModes();
+ void setupGraphicsModes();
virtual const OSystem::GraphicsMode *getSupportedGraphicsModes() const;
virtual int getDefaultGraphicsMode() const;
diff --git a/backends/platform/symbian/AdaptAllMMPs.pl b/backends/platform/symbian/AdaptAllMMPs.pl
index ffc4e88aff..2f76acf012 100644
--- a/backends/platform/symbian/AdaptAllMMPs.pl
+++ b/backends/platform/symbian/AdaptAllMMPs.pl
@@ -44,6 +44,15 @@ chdir("../../../");
"mmp/scummvm_toltecs.mmp",
"mmp/scummvm_pegasus.mmp",
"mmp/scummvm_wintermute.mmp",
+ # New engines
+ "mmp/scummvm_avalanche.mmp",
+ "mmp/scummvm_dreamweb.mmp",
+ "mmp/scummvm_fullpipe.mmp",
+ "mmp/scummvm_mortevielle.mmp",
+ "mmp/scummvm_neverhood.mmp",
+ "mmp/scummvm_sword25.mmp",
+ "mmp/scummvm_testbed.mmp",
+ "mmp/scummvm_zvision.mmp",
# Target Platform Project Files
"S60/ScummVM_S60.mmp",
"S60v3/ScummVM_S60v3.mmp",
@@ -79,10 +88,14 @@ Preparing to update all the Symbian MMP project files with objects from module.m
# some modules.mk files have #ifndef ENABLE_XXXX blocks:
my @section_empty = (""); # section standard: no #ifdef's in module.mk files
-my @sections_scumm = ("", "ENABLE_SCUMM_7_8", "ENABLE_HE"); # special sections for engine SCUMM
-my @sections_saga = ("", "ENABLE_IHNM", "ENABLE_SAGA2"); # special sections for engine SAGA
-my @sections_kyra = ("", "ENABLE_LOL","ENABLE_EOB"); # special sections for engine KYRA
my @sections_agos = ("", "ENABLE_AGOS2"); # special sections for engine AGOS
+my @section_video = ("", "USE_BINK", "USE_MPEG2"); # special sections for engine VIDEO ###, "USE_THEORADEC"
+my @sections_groovie = ("", "ENABLE_GROOVIE2"); # special sections for engine GROOVIE
+my @sections_kyra = ("", "ENABLE_LOL","ENABLE_EOB"); # special sections for engine KYRA
+my @sections_mohawk = ("", "ENABLE_CSTIME", "ENABLE_MYST", "ENABLE_RIVEN"); # special sections for engine MOHAWK
+my @sections_saga = ("", "ENABLE_IHNM", "ENABLE_SAGA2"); # special sections for engine SAGA
+my @sections_sci = ("", "ENABLE_SCI32"); # special sections for engine SCI
+my @sections_scumm = ("", "ENABLE_SCUMM_7_8", "ENABLE_HE"); # special sections for engine SCUMM
# files excluded from build, case insensitive, will be matched in filename string only
my @excludes_snd = (
@@ -126,13 +139,13 @@ my @excludes_scumm = (
);
-#arseModule(mmpStr, dirStr, ifdefArray, [exclusionsArray])
+#ParseModule(mmpStr, dirStr, ifdefArray, [exclusionsArray])
ParseModule("_base", "base", \@section_empty); # now in ./TRG/ScummVM_TRG.mmp, these never change anyways...
ParseModule("_base", "common", \@section_empty);
ParseModule("_base", "gui", \@section_empty, \@excludes_gui);
ParseModule("_base", "graphics", \@section_empty, \@excludes_graphics);
ParseModule("_base", "audio", \@section_empty, \@excludes_snd);
-ParseModule("_base", "video", \@section_empty);
+ParseModule("_base", "video", \@section_video); #
chdir("engines/");
ParseModule("_scumm", "scumm", \@sections_scumm, \@excludes_scumm );
@@ -156,21 +169,30 @@ ParseModule("_drascula","drascula", \@section_empty);
ParseModule("_made", "made", \@section_empty);
ParseModule("_m4", "m4", \@section_empty);
ParseModule("_tinsel", "tinsel", \@section_empty);
-ParseModule("_groovie", "groovie", \@section_empty);
+ParseModule("_groovie", "groovie", \@sections_groovie);
ParseModule("_tucker", "tucker", \@section_empty);
-ParseModule("_sci", "sci", \@section_empty);
+ParseModule("_sci", "sci", \@sections_sci);
ParseModule("_draci", "draci", \@section_empty);
ParseModule("_teenagent","teenagent", \@section_empty);
-ParseModule("_mohawk" ,"mohawk", \@section_empty);
+ParseModule("_mohawk" ,"mohawk", \@sections_mohawk);
ParseModule("_hugo" ,"hugo", \@section_empty);
ParseModule("_toon" ,"toon", \@section_empty);
ParseModule("_lastexpress","lastexpress", \@section_empty);
ParseModule("_tsage","tsage", \@section_empty);
-ParseModule("_tony","tony", \@section_empty);
+ParseModule("_tony", "tony", \@section_empty);
ParseModule("_toltecs","toltecs", \@section_empty);
ParseModule("_hopkins","hopkins", \@section_empty);
ParseModule("_pegasus","pegasus", \@section_empty);
ParseModule("_wintermute","wintermute", \@section_empty);
+##### new engines
+ParseModule("_avalanche" ,"avalanche", \@section_empty);
+ParseModule("_dreamweb" ,"dreamweb", \@section_empty);
+ParseModule("_fullpipe" ,"fullpipe", \@section_empty);
+ParseModule("_mortevielle" ,"mortevielle", \@section_empty);
+ParseModule("_neverhood" ,"neverhood", \@section_empty);
+ParseModule("_sword25" ,"sword25", \@section_empty);
+ParseModule("_testbed" ,"testbed", \@section_empty);
+ParseModule("_zvision" ,"zvision", \@section_empty);
print "
=======================================================================================
Done. Enjoy :P
diff --git a/backends/platform/symbian/BuildPackageUpload_AllVersions.pl b/backends/platform/symbian/BuildPackageUpload_AllVersions.pl
index 3062068852..560439f4e1 100644
--- a/backends/platform/symbian/BuildPackageUpload_AllVersions.pl
+++ b/backends/platform/symbian/BuildPackageUpload_AllVersions.pl
@@ -1,6 +1,7 @@
use Cwd;
use Switch;
+#use feature "switch";
system("cls");
require "BuildPackageUpload_LocalSettings.pl";
@@ -59,9 +60,13 @@ $ftp_url = "FTP://$FTP_User\@$FTP_Host/$FTP_Dir/";
# these macros are always defined:
$ExtraMacros = "MACRO NONSTANDARD_PORT\n";
-$ExtraMacros .= "MACRO ENABLE_VKEYBD\n";
+$ExtraMacros .= "MACRO ENABLE_VKEYBD\n";
$ExtraMacros .= "MACRO DISABLE_FANCY_THEMES\n";
$ExtraMacros .= "MACRO USE_TRANSLATION\n";
+$ExtraMacros .= "MACRO USE_BINK\n";
+$ExtraMacros .= "MACRO USE_MPEG2\n";
+# $ExtraMacros .= "MACRO \n";
+# candidates are : , USE_TIMIDITY,
# prep nice list of SDKs
#while( ($SDK, $RootDir) = each(%SDK_RootDirs) )
diff --git a/backends/platform/symbian/BuildPackageUpload_LocalSettings.pl b/backends/platform/symbian/BuildPackageUpload_LocalSettings.pl
index ded4ef198f..4ff485b3e3 100644
--- a/backends/platform/symbian/BuildPackageUpload_LocalSettings.pl
+++ b/backends/platform/symbian/BuildPackageUpload_LocalSettings.pl
@@ -2,24 +2,33 @@
##################################################################################################################
@WorkingEngines = qw(
- scumm agos sky queen gob groovie saga drascula
- kyra lure agi touche parallaction cine
- cruise made tinsel tucker sword1 sword2 draci sci teenagent mohawk hugo toon lastexpress tsage cge
- composer toltecs tony wintermute pegasus
+ agos agi cine cge composer cruise draci
+ 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
+ dreamweb fullpipe hopkins mortevielle
+ neverhood testbed avalanche zvision
);
+#### New engines
+#### sword25
@WorkingEngines_1st = qw(
- scumm queen groovie saga drascula
- touche parallaction cine
-? cruise made tucker lastexpress composer wintermute
+ cine composer cruise drascula groovie
+ lastexpress made parallaction queen
+ saga scumm touche tucker wintermute
+ avalanche zvision
);
@WorkingEngines_2nd = qw(
- agos sky gob kyra lure
- agi tinsel sword1 sword2
- draci sci teenagent hugo toon
- tsage cge toltecs tony pegasus
+ agi agos cge draci gob hopkins
+ hugo kyra lure mohawk pegasus sci
+ sky sword1 sword2 teenagent
+ tinsel tsage toltecs tony toon
+ dreamweb fullpipe mortevielle
+ neverhood testbed
);
+#### sword25
@TestingEngines = qw(
@@ -34,20 +43,32 @@
lol
agos2
eob
+ cstime
+ myst
+ riven
+ saga2
+ sci32
+ groovie2
);
#disabled subengines lol saga2 personal nightmare
+ # see configure.engines
%UseableFeatures = (
'zlib' => 'zlib.lib',
'mad' => 'libmad.lib',
'tremor' => 'libtremor.lib',
- 'flac' => 'libflac.lib'
+ 'flac' => 'libflacdec.lib',
+ 'freetype2' => 'freetype.lib',
+ 'faad' => 'libFAAD2.lib',
+ 'mpeg2' => 'libmpeg2.lib'
);
+ # 'mpeg2' => 'libmpeg2.lib'
# these are normally enabled for each variation
#$DefaultFeatures = qw(zlib,mad);
- $DefaultFeatures = qw(zlib,mad,tremor,flac);
+ #$DefaultFeatures = qw(zlib,mad,tremor,);
+ $DefaultFeatures = qw(mad,tremor,faad,flac,freetype2,mpeg2,zlib,);
##################################################################################################################
##
@@ -64,7 +85,8 @@
$HaltOnError = 0;
$SkipExistingPackages = 0;
$ReallyQuiet = 0;
- $DevBase = "C:\\S";
+ $DevBase = "D:\\Symbian";
+ $Compiler = "D:\\Program/ Files\\CodeSourcery\\Sourcery/ G++ Lite";
# specify an optional FTP server to upload to after each Build+Package (can leave empty)
#$FTP_Host = "host.com";
@@ -77,14 +99,14 @@
# Note1: the \epoc32 directory needs to be in these rootdirs
# Note2: these paths do NOT end in a backslash!
# $SDK_RootDirs{'UIQ2'} = "$DevBase\\UIQ_21";
- $SDK_RootDirs{'UIQ3'} = "$DevBase\\UIQ3";
+ # $SDK_RootDirs{'UIQ3'} = "$DevBase\\UIQ3";
# $SDK_RootDirs{'S60v1'} = "$DevBase\\S60v1";
# $SDK_RootDirs{'S60v2'} = "$DevBase\\S60v2";
$SDK_RootDirs{'S60v3'} = "$DevBase\\S60v3";
# $SDK_RootDirs{'S80'} = "$DevBase\\S80";
# $SDK_RootDirs{'S90'} = "$DevBase\\S90";
- $SDK_ToolchainDirs{'S60v3'} = "$DevBase\\arm-symbianelf\\bin";
+ $SDK_ToolchainDirs{'S60v3'} = "$Compiler\\arm-symbianelf\\bin";
$SDK_ToolchainDirs{'UIQ2'} = "$DevBase\\ECompXL\\bin"; # only needed for UIQ2/UIQ3
$SDK_ToolchainDirs{'UIQ3'} = "$DevBase\\ECompXL\\bin"; # only needed for UIQ2/UIQ3
@@ -94,7 +116,7 @@
{
## Standard libraries
$SDK_LibraryDirs{'ALL'}{'zlib.lib'} = "$DevBase\\zlib-1.2.2\\epoc";
- #$SDK_LibraryDirs{'ALL'}{'libmad.lib'} = "$DevBase\\libmad-0.15.1b\\group";
+ $SDK_LibraryDirs{'ALL'}{'libmad.lib'} = "$DevBase\\libmad-0.15.1b\\group";
$SDK_LibraryDirs{'ALL'}{'libtremor.lib'}= "$DevBase\\tremor\\epoc";
## SDL 1.2.12 / AnotherGuest / Symbian version
@@ -186,7 +208,7 @@
# now you can add $VariationSets only built on this PC below this line :)
}
- elsif ($ENV{'COMPUTERNAME'} eq "EMBEDDEV-LAPE") #################################################################
+ elsif ($ENV{'COMPUTERNAME'} eq "EMBEDDEV-VAIO2") #################################################################
{
$Producer = "AnotherGuest";
$RedirectSTDERR = 1;
@@ -206,7 +228,7 @@
$SDK_RootDirs{'S60v3'}= "G:\\S60v3";
#$SDK_RootDirs{'S80'}= "D:\\S80";
#$SDK_RootDirs{'S90'}= "D:\\S90";
- $ECompXL_BinDir= "D:\\ECompXL\\";
+ #$ECompXL_BinDir= "D:\\ECompXL\\";
if (0) # so we can turn them on/off easily
{
# $SDK_LibraryDirs{'ALL'}{'zlib.lib'} = "C:\\S\\zlib-1.2.2\\epoc";
@@ -223,38 +245,42 @@
# now you can add $VariationSets only built on this PC below this line :)
}
- elsif ($ENV{'COMPUTERNAME'} eq "EMBEDDEV_VAIO1") #################################################################
+ elsif ($ENV{'COMPUTERNAME'} eq "PC-FOREVER1111") #################################################################
{
- $Producer = "AnotherGuest";
+ $Producer = "Fedor";
$RedirectSTDERR = 1;
$HaltOnError = 0;
- $SkipExistingPackages = 1;
- $ReallyQuiet = 1;
+ $SkipExistingPackages = 0;
+ $ReallyQuiet = 0;
+ $Compiler = "D:\\Program/ Files\\CodeSourcery\\Sourcery/ G++ Lite";
#$FTP_Host = "host.com";
#$FTP_User = "ag@host.com";
#$FTP_Pass = "password";
#$FTP_Dir = "cvsbuilds";
- #$SDK_RootDirs{'UIQ2'}= "D:\\UIQ2";
- $SDK_RootDirs{'UIQ3'}= "G:\\UIQ3";
- #$SDK_RootDirs{'S60v1'}= "D:\\S60v1";
- #$SDK_RootDirs{'S60v2'}= "D:\\S60v2";
- $SDK_RootDirs{'S60v3'}= "G:\\S60v3";
- #$SDK_RootDirs{'S80'}= "D:\\S80";
- #$SDK_RootDirs{'S90'}= "D:\\S90";
- #$ECompXL_BinDir= "D:\\ECompXL\\";
+ #$SDK_RootDirs{'UIQ2'}= "C:\\UIQ2";
+ #$SDK_RootDirs{'UIQ3'}= "C:\\UIQ3";
+ #$SDK_RootDirs{'S60v1'}= "C:\\S60v1";
+ #$SDK_RootDirs{'S60v2'}= "C:\\S60v2";
+ #$SDK_RootDirs{'S80'}= "C:\\S80";
+ #$SDK_RootDirs{'S90'}= "C:\\S90";
+ #$ECompXL_BinDir= "C:\\ECompXL\\";
+
+ $SDK_RootDirs{'S60v3'}= "D:\\Symbian\\S60_5th_Edition_SDK_v1.0";
+ $SDK_ToolchainDirs{'S60v3'} = "$Compiler\\arm-symbianelf\\bin";
+
+ # these supporting libraries get built first, then all the Variations
+ # Note: the string {'xxx.lib'} is used in checking in build success: so needs to be accurate!
if (0) # so we can turn them on/off easily
{
# $SDK_LibraryDirs{'ALL'}{'zlib.lib'} = "C:\\S\\zlib-1.2.2\\epoc";
-# $SDK_LibraryDirs{'ALL'}{'libmad.lib'} = "C:\\S\\libmad-0.15.1b\\group";
-# $SDK_LibraryDirs{'ALL'}{'libtremor.lib'}= "C:\\tremor\\epoc";
- $SDK_LibraryDirs{'UIQ2'}{'esdl.lib'} = "E:\\WICKED\\ESDL\\epoc\\UIQ";
- $SDK_LibraryDirs{'S60v1'}{'esdl.lib'} = $SDK_LibraryDirs{'S60v2'}{'esdl.lib'} = "E:\\WICKED\\ESDL\\epoc\\S60";
- $SDK_LibraryDirs{'S80'}{'esdl.lib'} = "E:\\WICKED\\ESDL\\epoc\\S80";
- $SDK_LibraryDirs{'S90'}{'esdl.lib'} = "E:\\WICKED\\ESDL\\epoc\\S90";
- $SDK_LibraryDirs{'S60v3'}{'esdl.lib'} = "E:\\WICKED\\ESDL\\epoc\\S60\\S60V3";
- $SDK_LibraryDirs{'UIQ3'}{'esdl.lib'} = "E:\\WICKED\\ESDL\\epoc\\UIQ\\UIQ3";
+ $SDK_LibraryDirs{'ALL'}{'libmad.lib'} = "D:\\Symbian\\Projects\\SDL\\libs\\libmad-0.15.1b\\epoc";
+# $SDK_LibraryDirs{'ALL'}{'libtremor.lib'}= "D:\\Symbian\\Projects\\SDL\\libs\\Tremor\\epoc";
+# $SDK_LibraryDirs{'UIQ2'}{'esdl.lib'} = $SDK_LibraryDirs{'UIQ3'}{'esdl.lib'} = "C:\\S\\ESDL\\epoc\\UIQ";
+# $SDK_LibraryDirs{'S60v1'}{'esdl.lib'} = $SDK_LibraryDirs{'S60v2'}{'esdl.lib'} = $SDK_LibraryDirs{'S60v3'}{'esdl.lib'} = "C:\\S\\ESDL\\epoc\\S60";
+# $SDK_LibraryDirs{'S80'}{'esdl.lib'} = "C:\\S\\ESDL\\epoc\\S80";
+# $SDK_LibraryDirs{'S90'}{'esdl.lib'} = "C:\\S\\ESDL\\epoc\\S90";
}
# now you can add $VariationSets only built on this PC below this line :)
@@ -298,8 +324,8 @@
# the first one includes all SDKs & release-ready engines
$VariationSets{'ALL'}{'all'} = "$DefaultFeatures @WorkingEngines @EnablableSubEngines";
-# $VariationSets{'ALL'}{'1St'} = "$DefaultFeatures @WorkingEngines_1st @EnablableSubEngines";
-# $VariationSets{'ALL'}{'2nd'} = "$DefaultFeatures @WorkingEngines_2nd @EnablableSubEngines";
+ # $VariationSets{'ALL'}{'1St'} = "$DefaultFeatures @WorkingEngines_1st @EnablableSubEngines";
+ # $VariationSets{'ALL'}{'2nd'} = "$DefaultFeatures @WorkingEngines_2nd @EnablableSubEngines";
# now one for each ready-for-release engine
if (0)
{
diff --git a/backends/platform/symbian/README b/backends/platform/symbian/README
index 58cbc7814a..8a44e9399d 100644
--- a/backends/platform/symbian/README
+++ b/backends/platform/symbian/README
@@ -1,8 +1,9 @@
ScummVM - ScummVM ported to EPOC/SymbianOS
- Copyright (C) 2008-2013 ScummVM Team
- Copyright (C) 2003-2008 Lars 'AnotherGuest' Persson
+ Copyright (C) 2008-2014 ScummVM Team
+ Copyright (C) 2013-2013 Fedor Strizhniou aka zanac
+ Copyright (C) 2003-2013 Lars 'AnotherGuest' Persson
Copyright (C) 2002-2008 Jurgen 'SumthinWicked' Braam
Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson
@@ -24,6 +25,15 @@ About ScummVM
Jurgen and Lars have successfully transfered all needed changes into CVS/SVN, with additional helpful tools for Symbian OS
Release History:
+Release version: 1.7.0
+ * Nothing significant in the Symbian port, except SDL improvements (new SDL version used)
+
+Release version: 1.6.0
+ * Nothing significant in the Symbian port, except SDL improvements (new SDL version used)
+
+ Release version: 1.5.0
+ * Nothing significant in the Symbian port, except SDL improvements (new SDL version used)
+
Release version: 1.4.0
* Nothing significant in the Symbian port, except SDL improvements (new SDL version used)
* See main readme for general ScummVM improvements, major update
diff --git a/backends/platform/symbian/S60/ScummVM_S60.mmp.in b/backends/platform/symbian/S60/ScummVM_S60.mmp.in
index 28bd11dec6..ca2ec7f930 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-2013 The ScummVM project
+ * Copyright (C) 2005-2014 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 38d6f19590..2fc39c6838 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-2013 The ScummVM project
+ * Copyright (C) 2005-2014 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/BLD.INF.in b/backends/platform/symbian/S60v3/BLD.INF.in
index 78d130cb08..e21bcc7d01 100644
--- a/backends/platform/symbian/S60v3/BLD.INF.in
+++ b/backends/platform/symbian/S60v3/BLD.INF.in
@@ -8,5 +8,6 @@ PRJ_MMPFILES
//STOP_AUTO_PROJECTS//
gnumakefile icons.mk
+gnumakefile ..\help\build_help.mk
.\ScummVM_A0000658_S60v3.mmp
.\ScummVM_S60v3.mmp
diff --git a/backends/platform/symbian/S60v3/ScummVM_A0000658_S60v3.mmp.in b/backends/platform/symbian/S60v3/ScummVM_A0000658_S60v3.mmp.in
index 99b89efba8..7b9273f2dd 100644
--- a/backends/platform/symbian/S60v3/ScummVM_A0000658_S60v3.mmp.in
+++ b/backends/platform/symbian/S60v3/ScummVM_A0000658_S60v3.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-2014 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 1e0f282bc4..09ff968706 100644
--- a/backends/platform/symbian/S60v3/ScummVM_S60v3.mmp.in
+++ b/backends/platform/symbian/S60v3/ScummVM_S60v3.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-2014 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-CVS-SymbianS60v3.pkg b/backends/platform/symbian/S60v3/scummvm-CVS-SymbianS60v3.pkg
index 4c6b1b05f8..c04b7f6d51 100644
--- a/backends/platform/symbian/S60v3/scummvm-CVS-SymbianS60v3.pkg
+++ b/backends/platform/symbian/S60v3/scummvm-CVS-SymbianS60v3.pkg
@@ -33,7 +33,7 @@
:"ScummVM"
; UID is the app's UID
-#{"ScummVM S60v3"},(0xA0000657),1,60,0
+#{"ScummVM S60v3"},(0xA0000657),1,70,0
;Supports Series 60 v 3.0
[0x101F7961], 0, 0, 0, {"Series60ProductID"}
@@ -57,19 +57,50 @@
"..\..\..\..\README"-"!:\resource\apps\scummvm\README"
"..\..\..\..\NEWS"-"!:\resource\apps\scummvm\NEWS"
+; Scummvm help
+"..\help\ScummVM.hlp"-"!:\resource\help\ScummVM.hlp"
+
; Common datafiles needed for some games
-"..\..\..\..\dists\engine-data\kyra.dat"-"c:\data\scummvm\kyra.dat"
-"..\..\..\..\dists\engine-data\sky.cpt"-"c:\data\scummvm\sky.cpt"
+"..\..\..\..\dists\engine-data\drascula.dat"-"c:\data\scummvm\drascula.dat"
"..\..\..\..\dists\engine-data\hugo.dat"-"c:\data\scummvm\hugo.dat"
+"..\..\..\..\dists\engine-data\kyra.dat"-"c:\data\scummvm\kyra.dat"
"..\..\..\..\dists\engine-data\lure.dat"-"c:\data\scummvm\lure.dat"
-"..\..\..\..\dists\engine-data\drascula.dat"-"c:\data\scummvm\drascula.dat"
+"..\..\..\..\dists\engine-data\mort.dat"-"c:\data\scummvm\mort.dat"
+"..\..\..\..\dists\engine-data\neverhood.dat"-"c:\data\scummvm\neverhood.dat"
+"..\..\..\..\dists\engine-data\queen.tbl"-"c:\data\scummvm\queen.tbl"
+"..\..\..\..\dists\engine-data\sky.cpt"-"c:\data\scummvm\sky.cpt"
"..\..\..\..\dists\engine-data\teenagent.dat"-"c:\data\scummvm\teenagent.dat"
+"..\..\..\..\dists\engine-data\tony.dat"-"c:\data\scummvm\tony.dat"
"..\..\..\..\dists\engine-data\toon.dat"-"c:\data\scummvm\toon.dat"
"..\..\..\..\dists\engine-data\wintermute.zip"-"c:\data\scummvm\wintermute.zip"
-"..\..\..\..\dists\engine-data\tony.dat"-"c:\data\scummvm\tony.dat"
"..\..\..\vkeybd\packs\vkeybd_default.zip"-"c:\data\scummvm\vkeybd_default.zip"
"..\..\..\..\gui\themes\translations.dat"-"c:\data\scummvm\translations.dat"
"..\..\..\..\gui\themes\scummmodern.zip"-"c:\data\scummvm\scummmodern.zip"
+"..\..\..\..\gui\themes\fonts\Arial.bdf"-"c:\data\scummvm\Arial.bdf"
+"..\..\..\..\gui\themes\fonts\Arial12.bdf"-"c:\data\scummvm\Arial12.bdf"
+"..\..\..\..\gui\themes\fonts\ArialBold.bdf"-"c:\data\scummvm\ArialBold.bdf"
+"..\..\..\..\gui\themes\fonts\clR6x12-iso-8859-1.bdf"-"c:\data\scummvm\clR6x12-iso-8859-1.bdf"
+"..\..\..\..\gui\themes\fonts\clR6x12-iso-8859-2.bdf"-"c:\data\scummvm\clR6x12-iso-8859-2.bdf"
+"..\..\..\..\gui\themes\fonts\clR6x12-iso-8859-5.bdf"-"c:\data\scummvm\clR6x12-iso-8859-5.bdf"
+"..\..\..\..\gui\themes\fonts\clR6x12-iso-8859-7.bdf"-"c:\data\scummvm\clR6x12-iso-8859-7.bdf"
+"..\..\..\..\gui\themes\fonts\clR6x12.bdf"-"c:\data\scummvm\clR6x12.bdf"
+"..\..\..\..\gui\themes\fonts\courr12-iso-8859-1.bdf"-"c:\data\scummvm\courr12-iso-8859-1.bdf"
+"..\..\..\..\gui\themes\fonts\fixed5x8-iso-8859-1.bdf"-"c:\data\scummvm\fixed5x8-iso-8859-1.bdf"
+"..\..\..\..\gui\themes\fonts\fixed5x8-iso-8859-5.bdf"-"c:\data\scummvm\fixed5x8-iso-8859-5.bdf"
+"..\..\..\..\gui\themes\fonts\fixed5x8-iso-8859-7.bdf"-"c:\data\scummvm\fixed5x8-iso-8859-7.bdf"
+"..\..\..\..\gui\themes\fonts\fixed5x8.bdf"-"c:\data\scummvm\fixed5x8.bdf"
+"..\..\..\..\gui\themes\fonts\FreeMonoBold.ttf"-"c:\data\scummvm\FreeMonoBold.ttf"
+"..\..\..\..\gui\themes\fonts\FreeSans.ttf"-"c:\data\scummvm\FreeSans.ttf"
+"..\..\..\..\gui\themes\fonts\FreeSansBold.ttf"-"c:\data\scummvm\FreeSansBold.ttf"
+"..\..\..\..\gui\themes\fonts\helvB12-iso-8859-1.bdf"-"c:\data\scummvm\helvB12-iso-8859-1.bdf"
+"..\..\..\..\gui\themes\fonts\helvB12-iso-8859-2.bdf"-"c:\data\scummvm\helvB12-iso-8859-2.bdf"
+"..\..\..\..\gui\themes\fonts\helvB12-iso-8859-5.bdf"-"c:\data\scummvm\helvB12-iso-8859-5.bdf"
+"..\..\..\..\gui\themes\fonts\helvB12.bdf"-"c:\data\scummvm\helvB12.bdf"
+"..\..\..\..\gui\themes\fonts\helvBO12-iso-8859-1.bdf"-"c:\data\scummvm\helvBO12-iso-8859-1.bdf"
+"..\..\..\..\gui\themes\fonts\helvBO12.bdf"-"c:\data\scummvm\helvBO12.bdf"
+"..\..\..\..\gui\themes\fonts\helvR12-iso-8859-1.bdf"-"c:\data\scummvm\helvR12-iso-8859-1.bdf"
+"..\..\..\..\gui\themes\fonts\helvR12.bdf"-"c:\data\scummvm\helvR12.bdf"
+;"..\..\..\..\gui\themes\"-"c:\data\scummvm\"
; Config/log files: 'empty' will automagically be removed on uninstall
""-"c:\data\scummvm\scummvm.ini",FILENULL
diff --git a/backends/platform/symbian/S60v3/scummvm-CVS-SymbianS60v3_split.pkg b/backends/platform/symbian/S60v3/scummvm-CVS-SymbianS60v3_split.pkg
index d3fd0450fa..250076347a 100644
--- a/backends/platform/symbian/S60v3/scummvm-CVS-SymbianS60v3_split.pkg
+++ b/backends/platform/symbian/S60v3/scummvm-CVS-SymbianS60v3_split.pkg
@@ -36,7 +36,7 @@
:"ScummVM"
; UID is the app's UID
-#{"ScummVM S60v3"},(0xA0000657),1,60,0
+#{"ScummVM S60v3"},(0xA0000657),1,70,0
;Supports Series 60 v 3.0
[0x101F7961], 0, 0, 0, {"Series60ProductID"}
@@ -65,19 +65,50 @@
"..\..\..\..\README"-"!:\resource\apps\scummvm\README"
"..\..\..\..\NEWS"-"!:\resource\apps\scummvm\NEWS"
+; Scummvm help
+"..\help\ScummVM.hlp"-"!:\resource\help\ScummVM.hlp"
+
; Common datafiles needed for some games
-"..\..\..\..\dists\engine-data\kyra.dat"-"c:\data\scummvm\kyra.dat"
-"..\..\..\..\dists\engine-data\sky.cpt"-"c:\data\scummvm\sky.cpt"
+"..\..\..\..\dists\engine-data\drascula.dat"-"c:\data\scummvm\drascula.dat"
"..\..\..\..\dists\engine-data\hugo.dat"-"c:\data\scummvm\hugo.dat"
+"..\..\..\..\dists\engine-data\kyra.dat"-"c:\data\scummvm\kyra.dat"
"..\..\..\..\dists\engine-data\lure.dat"-"c:\data\scummvm\lure.dat"
-"..\..\..\..\dists\engine-data\drascula.dat"-"c:\data\scummvm\drascula.dat"
+"..\..\..\..\dists\engine-data\mort.dat"-"c:\data\scummvm\mort.dat"
+"..\..\..\..\dists\engine-data\neverhood.dat"-"c:\data\scummvm\neverhood.dat"
+"..\..\..\..\dists\engine-data\queen.tbl"-"c:\data\scummvm\queen.tbl"
+"..\..\..\..\dists\engine-data\sky.cpt"-"c:\data\scummvm\sky.cpt"
"..\..\..\..\dists\engine-data\teenagent.dat"-"c:\data\scummvm\teenagent.dat"
+"..\..\..\..\dists\engine-data\tony.dat"-"c:\data\scummvm\tony.dat"
"..\..\..\..\dists\engine-data\toon.dat"-"c:\data\scummvm\toon.dat"
-"..\..\..\..\dists\engine-data\wintermute.zip-"c:\data\scummvm\wintermute.zip"
-"..\..\..\..\dists\engine-data\tony.dat-"c:\data\scummvm\tony.dat"
+"..\..\..\..\dists\engine-data\wintermute.zip"-"c:\data\scummvm\wintermute.zip"
"..\..\..\vkeybd\packs\vkeybd_default.zip"-"c:\data\scummvm\vkeybd_default.zip"
"..\..\..\..\gui\themes\translations.dat"-"c:\data\scummvm\translations.dat"
"..\..\..\..\gui\themes\scummmodern.zip"-"c:\data\scummvm\scummmodern.zip"
+"..\..\..\..\gui\themes\fonts\Arial.bdf"-"c:\data\scummvm\Arial.bdf"
+"..\..\..\..\gui\themes\fonts\Arial12.bdf"-"c:\data\scummvm\Arial12.bdf"
+"..\..\..\..\gui\themes\fonts\ArialBold.bdf"-"c:\data\scummvm\ArialBold.bdf"
+"..\..\..\..\gui\themes\fonts\clR6x12-iso-8859-1.bdf"-"c:\data\scummvm\clR6x12-iso-8859-1.bdf"
+"..\..\..\..\gui\themes\fonts\clR6x12-iso-8859-2.bdf"-"c:\data\scummvm\clR6x12-iso-8859-2.bdf"
+"..\..\..\..\gui\themes\fonts\clR6x12-iso-8859-5.bdf"-"c:\data\scummvm\clR6x12-iso-8859-5.bdf"
+"..\..\..\..\gui\themes\fonts\clR6x12-iso-8859-7.bdf"-"c:\data\scummvm\clR6x12-iso-8859-7.bdf"
+"..\..\..\..\gui\themes\fonts\clR6x12.bdf"-"c:\data\scummvm\clR6x12.bdf"
+"..\..\..\..\gui\themes\fonts\courr12-iso-8859-1.bdf"-"c:\data\scummvm\courr12-iso-8859-1.bdf"
+"..\..\..\..\gui\themes\fonts\fixed5x8-iso-8859-1.bdf"-"c:\data\scummvm\fixed5x8-iso-8859-1.bdf"
+"..\..\..\..\gui\themes\fonts\fixed5x8-iso-8859-5.bdf"-"c:\data\scummvm\fixed5x8-iso-8859-5.bdf"
+"..\..\..\..\gui\themes\fonts\fixed5x8-iso-8859-7.bdf"-"c:\data\scummvm\fixed5x8-iso-8859-7.bdf"
+"..\..\..\..\gui\themes\fonts\fixed5x8.bdf"-"c:\data\scummvm\fixed5x8.bdf"
+"..\..\..\..\gui\themes\fonts\FreeMonoBold.ttf"-"c:\data\scummvm\FreeMonoBold.ttf"
+"..\..\..\..\gui\themes\fonts\FreeSans.ttf"-"c:\data\scummvm\FreeSans.ttf"
+"..\..\..\..\gui\themes\fonts\FreeSansBold.ttf"-"c:\data\scummvm\FreeSansBold.ttf"
+"..\..\..\..\gui\themes\fonts\helvB12-iso-8859-1.bdf"-"c:\data\scummvm\helvB12-iso-8859-1.bdf"
+"..\..\..\..\gui\themes\fonts\helvB12-iso-8859-2.bdf"-"c:\data\scummvm\helvB12-iso-8859-2.bdf"
+"..\..\..\..\gui\themes\fonts\helvB12-iso-8859-5.bdf"-"c:\data\scummvm\helvB12-iso-8859-5.bdf"
+"..\..\..\..\gui\themes\fonts\helvB12.bdf"-"c:\data\scummvm\helvB12.bdf"
+"..\..\..\..\gui\themes\fonts\helvBO12-iso-8859-1.bdf"-"c:\data\scummvm\helvBO12-iso-8859-1.bdf"
+"..\..\..\..\gui\themes\fonts\helvBO12.bdf"-"c:\data\scummvm\helvBO12.bdf"
+"..\..\..\..\gui\themes\fonts\helvR12-iso-8859-1.bdf"-"c:\data\scummvm\helvR12-iso-8859-1.bdf"
+"..\..\..\..\gui\themes\fonts\helvR12.bdf"-"c:\data\scummvm\helvR12.bdf"
+;"..\..\..\..\gui\themes\"-"c:\data\scummvm\"
; Config/log files: 'empty' will automagically be removed on uninstall
""-"c:\data\scummvm\scummvm.ini",FILENULL
diff --git a/backends/platform/symbian/S80/ScummVM_S80.mmp.in b/backends/platform/symbian/S80/ScummVM_S80.mmp.in
index d9b9a5c948..34d1979fe5 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-2013 The ScummVM project
+ * Copyright (C) 2005-2014 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 30b1c3f58b..de96963d80 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-2013 The ScummVM project
+ * Copyright (C) 2005-2014 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 790dca14f0..e65397b145 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-2013 The ScummVM project
+ * Copyright (C) 2005-2014 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 cf17f103ef..88a3e4d221 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-2013 The ScummVM project
+ * Copyright (C) 2005-2014 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 bfdd07e898..2e02f1da1d 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-2013 The ScummVM project
+ * Copyright (C) 2005-2014 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/UIQ2/ScummVM_UIQ2.mmp.in b/backends/platform/symbian/UIQ2/ScummVM_UIQ2.mmp.in
index 80ba37d694..68f5bd0cab 100644
--- a/backends/platform/symbian/UIQ2/ScummVM_UIQ2.mmp.in
+++ b/backends/platform/symbian/UIQ2/ScummVM_UIQ2.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-2006 The ScummVM project
+ * Copyright (C) 2005-2006 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 b7f0a17113..11cc767671 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-2013 The ScummVM project
+ * Copyright (C) 2005-2014 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 b7f0a17113..11cc767671 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-2013 The ScummVM project
+ * Copyright (C) 2005-2014 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 fac178ad15..c68e780f11 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-2013 The ScummVM project
+ * Copyright (C) 2005-2014 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 0f1ec7f60f..f554bb3afd 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-2013 The ScummVM project
+ * Copyright (C) 2005-2014 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-CVS-SymbianUIQ3.pkg b/backends/platform/symbian/UIQ3/scummvm-CVS-SymbianUIQ3.pkg
index c62d25dafa..b4f1cfdd5c 100644
--- a/backends/platform/symbian/UIQ3/scummvm-CVS-SymbianUIQ3.pkg
+++ b/backends/platform/symbian/UIQ3/scummvm-CVS-SymbianUIQ3.pkg
@@ -32,7 +32,7 @@
:"ScummVM"
; UID is the app's UID
-#{"ScummVM UIQ3"},(0xA0000657),1,60,0
+#{"ScummVM UIQ3"},(0xA0000657),1,70,0
; ProductID for UIQ 3.0
; Product/platform version UID, Major, Minor, Build, Product ID
diff --git a/backends/platform/symbian/UIQ3/scummvm-CVS-SymbianUIQ3_split.pkg b/backends/platform/symbian/UIQ3/scummvm-CVS-SymbianUIQ3_split.pkg
index a37e0b0533..722e23a1b8 100644
--- a/backends/platform/symbian/UIQ3/scummvm-CVS-SymbianUIQ3_split.pkg
+++ b/backends/platform/symbian/UIQ3/scummvm-CVS-SymbianUIQ3_split.pkg
@@ -35,7 +35,7 @@
:"ScummVM"
; UID is the app's UID
-#{"ScummVM UIQ3"},(0xA0000657),1,60,0
+#{"ScummVM UIQ3"},(0xA0000657),1,70,0
; ProductID for UIQ 3.0
; Product/platform version UID, Major, Minor, Build, Product ID
diff --git a/backends/platform/symbian/UIQ3/scummvm_A0000658_loc.rss b/backends/platform/symbian/UIQ3/scummvm_A0000658_loc.rss
index 47e7c44642..f54bcc24d3 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-2013 The ScummVM project
+ * Copyright (C) 2005-2014 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/Custom.xml b/backends/platform/symbian/help/Custom.xml
new file mode 100644
index 0000000000..8bc518e036
--- /dev/null
+++ b/backends/platform/symbian/help/Custom.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0"?>
+<!DOCTYPE cshcust SYSTEM "/cshlpcmp/dtd/CSHcust.dtd">
+<?xml:stylesheet href="/cshlpcmp/xsl/cshcust.xsl" title="CS-Help customization" type="text/xsl"?>
+<cshcust>
+<parastyle name="body" font="sansserif" size="10"/>
+<parastyle name="tip" font="sansserif" size="10" left="20"></parastyle>
+<parastyle name="note" font="sansserif" size="10" left="20"></parastyle>
+<parastyle name="important" font="sansserif" size="10" left="20"></parastyle>
+<body style="body"/>
+<titlestyle fontstyle="sansserif" size="10"/>
+<listbullet1style bulletchar="8226"/>
+<listbullet2style bulletchar="8226"/>
+<lists leftindent="20"/>
+</cshcust>
+
+
+
+
diff --git a/backends/platform/symbian/help/ScummVM.rtf b/backends/platform/symbian/help/ScummVM.rtf
new file mode 100644
index 0000000000..522fab832c
--- /dev/null
+++ b/backends/platform/symbian/help/ScummVM.rtf
@@ -0,0 +1,266 @@
+{\rtf1\ansi\ansicpg1251\uc1 \deff0\deflang1049\deflangfe1049{\fonttbl{\f0\froman\fcharset204\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f1\fswiss\fcharset204\fprq2{\*\panose 020b0604020202020204}Arial;}
+{\f2\fmodern\fcharset204\fprq1{\*\panose 02070309020205020404}Courier New;}{\f3\froman\fcharset2\fprq2{\*\panose 05050102010706020507}Symbol;}{\f8\froman\fcharset0\fprq2{\*\panose 00000000000000000000}Tms Rmn;}
+{\f14\fnil\fcharset2\fprq2{\*\panose 05000000000000000000}Wingdings;}{\f28\fswiss\fcharset204\fprq2{\*\panose 020b0604020202020204}Arial CYR;}{\f29\fmodern\fcharset204\fprq1{\*\panose 02070309020205020404}Courier New CYR;}
+{\f43\froman\fcharset2\fprq2{\*\panose 05030102010509060703}Webdings;}{\f97\fswiss\fcharset204\fprq2{\*\panose 020b0506020202030204}Arial Narrow;}{\f109\froman\fcharset0\fprq2 Times New Roman;}{\f107\froman\fcharset238\fprq2 Times New Roman CE;}
+{\f110\froman\fcharset161\fprq2 Times New Roman Greek;}{\f111\froman\fcharset162\fprq2 Times New Roman Tur;}{\f112\froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\f113\froman\fcharset178\fprq2 Times New Roman (Arabic);}
+{\f114\froman\fcharset186\fprq2 Times New Roman Baltic;}{\f117\fswiss\fcharset0\fprq2 Arial;}{\f115\fswiss\fcharset238\fprq2 Arial CE;}{\f118\fswiss\fcharset161\fprq2 Arial Greek;}{\f119\fswiss\fcharset162\fprq2 Arial Tur;}
+{\f120\fswiss\fcharset177\fprq2 Arial (Hebrew);}{\f121\fswiss\fcharset178\fprq2 Arial (Arabic);}{\f122\fswiss\fcharset186\fprq2 Arial Baltic;}{\f125\fmodern\fcharset0\fprq1 Courier New;}{\f123\fmodern\fcharset238\fprq1 Courier New CE;}
+{\f126\fmodern\fcharset161\fprq1 Courier New Greek;}{\f127\fmodern\fcharset162\fprq1 Courier New Tur;}{\f128\fmodern\fcharset177\fprq1 Courier New (Hebrew);}{\f129\fmodern\fcharset178\fprq1 Courier New (Arabic);}
+{\f130\fmodern\fcharset186\fprq1 Courier New Baltic;}{\f333\fswiss\fcharset0\fprq2 Arial CYR;}{\f331\fswiss\fcharset238\fprq2 Arial CYR CE;}{\f334\fswiss\fcharset161\fprq2 Arial CYR Greek;}{\f335\fswiss\fcharset162\fprq2 Arial CYR Tur;}
+{\f336\fswiss\fcharset177\fprq2 Arial CYR (Hebrew);}{\f337\fswiss\fcharset178\fprq2 Arial CYR (Arabic);}{\f338\fswiss\fcharset186\fprq2 Arial CYR Baltic;}{\f341\fmodern\fcharset0\fprq1 Courier New CYR;}{\f339\fmodern\fcharset238\fprq1 Courier New CYR CE;}
+{\f342\fmodern\fcharset161\fprq1 Courier New CYR Greek;}{\f343\fmodern\fcharset162\fprq1 Courier New CYR Tur;}{\f344\fmodern\fcharset177\fprq1 Courier New CYR (Hebrew);}{\f345\fmodern\fcharset178\fprq1 Courier New CYR (Arabic);}
+{\f346\fmodern\fcharset186\fprq1 Courier New CYR Baltic;}{\f885\fswiss\fcharset0\fprq2 Arial Narrow;}{\f883\fswiss\fcharset238\fprq2 Arial Narrow CE;}{\f886\fswiss\fcharset161\fprq2 Arial Narrow Greek;}{\f887\fswiss\fcharset162\fprq2 Arial Narrow Tur;}
+{\f890\fswiss\fcharset186\fprq2 Arial Narrow Baltic;}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;
+\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128;\red192\green192\blue192;}{\stylesheet{
+\ql \li0\ri0\sa120\widctlpar\nooverflow\faroman\rin0\lin0\itap0 \f1\fs20\lang2057\langfe1033\cgrid\langnp2057\langfenp1033 \snext0 Normal;}{\s1\ql \li0\ri0\sb360\sa240\keepn\widctlpar\nooverflow\faroman\rin0\lin0\itap0
+\b\f1\fs32\lang2057\langfe1033\kerning28\cgrid\langnp2057\langfenp1033 \sbasedon0 \snext0 heading 1;}{\s2\ql \li0\ri0\sb120\sa120\keepn\widctlpar\brdrt\brdrs\brdrw30\brsp20 \brdrb\brdrs\brdrw30\brsp20 \tqr\tx9072\nooverflow\faroman\rin0\lin0\itap0
+\b\f1\fs24\lang2057\langfe1033\cgrid\langnp2057\langfenp1033 \sbasedon0 \snext0 heading 2;}{\s3\ql \li0\ri0\sb120\sa120\keepn\widctlpar\brdrt\brdrs\brdrw30\brsp20 \tqr\tx9072\nooverflow\faroman\rin0\lin0\itap0
+\b\f1\fs28\lang2057\langfe1033\cgrid\langnp2057\langfenp1033 \sbasedon0 \snext0 heading 3;}{\s4\ql \li0\ri0\sb120\sa120\keepn\widctlpar\brdrt\brdrs\brdrw15\brsp20 \tqr\tx9072\nooverflow\faroman\rin0\lin0\itap0
+\b\f1\fs24\lang2057\langfe1033\cgrid\langnp2057\langfenp1033 \sbasedon0 \snext0 heading 4;}{\s5\ql \li0\ri0\sa120\keepn\widctlpar\nooverflow\faroman\rin0\lin0\itap0 \b\f1\fs20\lang2057\langfe1033\cgrid\langnp2057\langfenp1033 \sbasedon0 \snext0
+heading 5;}{\s6\ql \li0\ri0\sb240\sa60\widctlpar\nooverflow\faroman\rin0\lin0\itap0 \i\f1\fs22\lang2057\langfe1033\cgrid\langnp2057\langfenp1033 \sbasedon0 \snext0 heading 6;}{\s7\ql \li0\ri0\sb240\sa60\widctlpar\nooverflow\faroman\rin0\lin0\itap0
+\f1\fs20\lang2057\langfe1033\cgrid\langnp2057\langfenp1033 \sbasedon0 \snext0 heading 7;}{\s8\ql \li0\ri0\sb240\sa60\widctlpar\nooverflow\faroman\rin0\lin0\itap0 \i\f1\fs20\lang2057\langfe1033\cgrid\langnp2057\langfenp1033 \sbasedon0 \snext0 heading 8;}{
+\s9\ql \li0\ri0\sb240\sa60\widctlpar\nooverflow\faroman\rin0\lin0\itap0 \i\f1\fs18\lang2057\langfe1033\cgrid\langnp2057\langfenp1033 \sbasedon0 \snext0 heading 9;}{\*\cs10 \additive Default Paragraph Font;}{\*\cs15 \additive \b\f1\fs20 \sbasedon10
+App Text;}{\s16\ql \li0\ri0\sb360\sa240\keepn\widctlpar\nooverflow\faroman\rin0\lin0\itap0 \b\f1\fs32\cf9\lang2057\langfe1033\kerning28\cgrid\langnp2057\langfenp1033 \sbasedon0 \snext16 Category UID;}{
+\s17\ql \li0\ri0\sa120\widctlpar\nooverflow\faroman\rin0\lin0\itap0 \i\f1\fs20\lang2057\langfe1033\cgrid\langnp2057\langfenp1033 \sbasedon0 \snext17 Comment;}{\s18\ql \fi-283\li283\ri0\sa120\widctlpar\brdrb\brdrs\brdrw15\brsp20 {\*\pn
+\pnlvlblt\ilvl10\ls2047\pnrnot0\pnf43\pnstart1\pnindent283\pnhang{\pntxtb \'a2}}\nooverflow\faroman\ls2047\ilvl10\rin0\lin283\itap0 \f1\fs20\lang2057\langfe1033\cgrid\langnp2057\langfenp1033 \sbasedon0 \snext18 Context;}{\*\cs19 \additive
+\i\f1\fs20\ulnone\cf0\nosupersub \sbasedon10 Context Comment;}{\s20\ql \li0\ri0\sa120\widctlpar\nooverflow\faroman\rin0\lin0\itap0 \f1\fs20\cf11\lang2057\langfe1033\cgrid\langnp2057\langfenp1033 \sbasedon0 \snext20 Definition Term;}{
+\s21\ql \li0\ri0\sa120\widctlpar\nooverflow\faroman\rin0\lin0\itap0 \f1\fs20\cf11\lang2057\langfe1033\cgrid\langnp2057\langfenp1033 \sbasedon20 \snext21 Definition Definition;}{\*\cs22 \additive \scaps\f97\fs20\cf13 \sbasedon10 Graphic Link;}{
+\s23\ql \fi-283\li283\ri0\sa120\widctlpar{\*\pn \pnlvlblt\ilvl10\ls2047\pnrnot0\pnf14\pnstart1\pnindent283\pnhang{\pntxtb F}}\nooverflow\faroman\ls2047\ilvl10\rin0\lin283\itap0 \f1\fs20\lang2057\langfe1033\cgrid\langnp2057\langfenp1033
+\sbasedon0 \snext23 Tip;}{\s24\ql \fi-283\li283\ri0\sa120\widctlpar{\*\pn \pnlvlblt\ilvl10\ls2047\pnrnot0\pnf14\pnstart1\pnindent283\pnhang{\pntxtb ?}}\nooverflow\faroman\ls2047\ilvl10\rin0\lin283\itap0
+\f1\fs20\lang2057\langfe1033\cgrid\langnp2057\langfenp1033 \sbasedon23 \snext24 Note;}{\s25\ql \fi-283\li283\ri0\sa120\widctlpar{\*\pn \pnlvlblt\ilvl10\ls2047\pnrnot0\pnf43\pnstart1\pnindent283\pnhang{\pntxtb ~}}
+\nooverflow\faroman\ls2047\ilvl10\rin0\lin283\itap0 \f1\fs20\lang2057\langfe1033\cgrid\langnp2057\langfenp1033 \sbasedon24 \snext25 Important;}{\s26\ql \fi-283\li283\ri0\sa120\widctlpar\brdrb\brdrs\brdrw15\brsp20 {\*\pn \pnlvlblt\ilvl10\ls2047\pnrnot0
+\pnf43\pnstart1\pnindent283\pnhang{\pntxtb i}}\nooverflow\faroman\ls2047\ilvl10\rin0\lin283\itap0 \f1\fs20\lang2057\langfe1033\cgrid\langnp2057\langfenp1033 \sbasedon0 \snext26 Index;}{\*\cs27 \additive \b\f2\fs20 \sbasedon10 Key Name;}{
+\s28\ql \fi-284\li284\ri0\sa120\widctlpar{\*\pn \pnlvlbody\ilvl11\ls2047\pnrnot0\pndec\pnstart1\pnindent283\pnhang{\pntxta .}}\nooverflow\faroman\ls2047\ilvl11\rin0\lin284\itap0 \f1\fs20\lang2057\langfe1033\cgrid\langnp2057\langfenp1033
+\sbasedon0 \snext28 List Number;}{\s29\ql \fi-284\li284\ri0\sa120\widctlpar\tx284{\*\pn \pnlvlbody\ilvl0\ls2047\pnrnot0\pndec\pnf8 }\nooverflow\faroman\ls2047\rin0\lin284\itap0 \f1\fs20\lang2057\langfe1033\cgrid\langnp2057\langfenp1033
+\sbasedon28 \snext29 List Manual;}{\s30\ql \fi-284\li568\ri0\sa120\widctlpar{\*\pn \pnlvlbody\ilvl11\ls2047\pnrnot0\pndec\pnstart1\pnindent283\pnhang{\pntxta .}}\nooverflow\faroman\ls2047\ilvl11\rin0\lin568\itap0
+\f1\fs20\lang2057\langfe1033\cgrid\langnp2057\langfenp1033 \sbasedon0 \snext30 List Number 2;}{\s31\ql \fi-284\li568\ri0\sa120\widctlpar\tx284{\*\pn \pnlvlbody\ilvl0\ls2047\pnrnot0\pndec\pnf8 }\nooverflow\faroman\ls2047\rin0\lin568\itap0
+\f1\fs20\lang2057\langfe1033\cgrid\langnp2057\langfenp1033 \sbasedon30 \snext31 List Manual 2;}{\s32\ql \li0\ri0\sa120\widctlpar\nooverflow\faroman\rin0\lin0\itap0 \f1\fs20\cf13\lang2057\langfe1033\cgrid\langnp2057\langfenp1033 \sbasedon0 \snext32
+Synonyms;}{\*\cs33 \additive \super \sbasedon10 endnote reference;}{\s34\ql \fi-284\li284\ri0\sa120\widctlpar\tx284{\*\pn \pnlvlblt\ilvl10\ls2047\pnrnot0\pnf3\pnstart1\pnindent283\pnhang{\pntxtb \'b7}}\nooverflow\faroman\ls2047\ilvl10\rin0\lin284\itap0
+\f1\fs20\lang2057\langfe1033\cgrid\langnp2057\langfenp1033 \sbasedon0 \snext34 \sautoupd List Bullet;}{\s35\ql \fi-284\li568\ri0\sa120\widctlpar{\*\pn \pnlvlblt\ilvl10\ls2047\pnrnot0\pnf3\pnstart1\pnindent283\pnhang{\pntxtb \'b7}}
+\nooverflow\faroman\ls2047\ilvl10\rin0\lin568\itap0 \f1\fs20\lang2057\langfe1033\cgrid\langnp2057\langfenp1033 \sbasedon0 \snext35 \sautoupd List Bullet 2;}{\s36\ql \li0\ri0\sa120\widctlpar\tqc\tx4153\tqr\tx8306\nooverflow\faroman\rin0\lin0\itap0
+\f1\fs20\lang2057\langfe1033\cgrid\langnp2057\langfenp1033 \sbasedon0 \snext36 footer;}{\s37\ql \li284\ri0\sa120\widctlpar\nooverflow\faroman\rin0\lin284\itap0 \f1\fs20\lang2057\langfe1033\cgrid\langnp2057\langfenp1033 \sbasedon0 \snext37 List Continue;}{
+\s38\ql \li566\ri0\sa120\widctlpar\nooverflow\faroman\rin0\lin566\itap0 \f1\fs20\lang2057\langfe1033\cgrid\langnp2057\langfenp1033 \sbasedon0 \snext38 List Continue 2;}}{\*\listtable{\list\listtemplateid-737142542\listsimple{\listlevel\levelnfc0
+\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'02\'00.;}{\levelnumbers\'01;}\chbrdr\brdrnone\brdrcf1 \chshdng0\chcfpat1\chcbpat1 \fi-360\li643\jclisttab\tx643 }{\listname ;}\listid-129}
+{\list\listtemplateid1907811784\listsimple{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'01\u-3913 ?;}{\levelnumbers;}\f3\chbrdr\brdrnone\brdrcf1 \chshdng0\chcfpat1\chcbpat1\fbias0
+\fi-360\li643\jclisttab\tx643 }{\listname ;}\listid-125}{\list\listtemplateid1912741052\listsimple{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'02\'00.;}{\levelnumbers\'01;}\chbrdr
+\brdrnone\brdrcf1 \chshdng0\chcfpat1\chcbpat1 \fi-360\li360\jclisttab\tx360 }{\listname ;}\listid-120}{\list\listtemplateid-51363132\listsimple{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0
+{\leveltext\'01\u-3913 ?;}{\levelnumbers;}\f3\chbrdr\brdrnone\brdrcf1 \chshdng0\chcfpat1\chcbpat1\fbias0 \fi-360\li360\jclisttab\tx360 }{\listname ;}\listid-119}}{\*\listoverridetable{\listoverride\listid-120\listoverridecount0\ls1}
+{\listoverride\listid-129\listoverridecount0\ls2}{\listoverride\listid-119\listoverridecount0\ls3}{\listoverride\listid-125\listoverridecount0\ls4}}{\info{\author Fedor}{\operator Fedor}{\creatim\yr2013\mo11\dy30\hr23\min4}
+{\revtim\yr2013\mo11\dy30\hr23\min24}{\version4}{\edmins20}{\nofpages7}{\nofwords1441}{\nofchars8219}{\*\company DEV}{\nofcharsws10093}{\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\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
+\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 Introduction
+
+\par }\pard\plain \ql \li0\ri0\sa120\widctlpar\nooverflow\faroman\rin0\lin0\itap0 \f1\fs20\lang2057\langfe1033\cgrid\langnp2057\langfenp1033 {\f28
+\par }{\f29
+This help file based on ScummVM forum thread with some elaborations(in Anotherguest section) and text correction. If you wish add some text you may download and modify source document from https://sourceforge.net/projects/scummvms60git/ and then send me t
+o fedor_qd@mail.ru
+\par First guide contain help by Anotherguest, second - VincentJ, third - murgo.
+\par Enjoys, cheers! Always yous, Fedor Strizhniou =)}{\f29\lang1059\langfe1033\langnp1059
+\par }{\f29
+\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 First guide
+
+\par }\pard\plain \s32\ql \li0\ri0\sa120\widctlpar\nooverflow\faroman\rin0\lin0\itap0 \f1\fs20\cf13\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\nooverflow\faroman\rin0\lin0\itap0 \f1\fs20\lang2057\langfe1033\cgrid\langnp2057\langfenp1033 {\f28
+\par
+\par }{\f29 UIQ3 devices: To the top right (holding the phone portrait) you four icons, from the top they are
+\par
+\par * Toggle control mode, in control mode you can change text input , screen orientation and screen scaling
+\par * Mouse button, toggles between left, right and no button when tapping the screen. If no button is selected, 7 & Space works as left mouse button and 9 & Enter works as the right mouse button.
+\par * Esc, tap this to simulate ESC key being pressed. Same functionally on devices with 'C' key.
+\par * Virtual keyboard toggle, toggles the virtual keyboard, if not enabled when selecting '1'/'7' in control mode.
+\par * When Virtual keyboard is enabled you have more onscreen keys available
+\par * Enter key
+\par * Backspace
+\par * Arrow Up/Down to scroll the keys available
+\par * Virtual keyboard, tap letters to simulate keypresses.
+\par
+\par S60 and UIQ3 devices: (Control Key = Green Phone key, to activate/deactivate control mode in SDL)
+\par
+\par * 1 = change Input Mode: Joystick | Keyboard | Cursor
+\par * 2,'p' = change Video Mode: Landscape | Portrait
+\par * 3,'f' = change Orientation Mode for Landscape: 90\'b0 Left | 90\'b0 Right
+\par * 4,'s' = Toggle between stretched and non-stretched modes
+\par * 5 = Toggle between interpolating stretch or not
+\par * 7,'t' = Text/Multitap input
+\par * 8,'c' = Cursor input
+\par * 9,'j' = Joystick input
+\par * 0,'m' = Mouse input
+\par * Up/Down = Alter global volume when not in 1-1 VGA mode. Pan around in VGA 1-1 Mode
+\par * # = On/Off screen keyboard transparency
+\par
+\par S80 devices:
+\par
+\par * Side key 1 = Fire Joystick 1 button (JoyMode)
+\par * Side key 2 = Fire Joystick 2 button (JoyMode) or change Video Mode: Upscaled | Normal (CursorMode)
+\par * Side key 3 = change Input Mode: Joystick | Cursor
+\par
+\par S90 devices: (Control Key = OK, pressed simultaneously with other keys to activate the mode changes in SDL)
+\par
+\par * OK+1 = change Input Mode: Joystick | Cursor
+\par * OK+2 = change Video Mode: Upscaled | Normal
+\par
+\par What are these Joystick, Keyboard and Cursor modes anyway?
+\par }{\f28
+\par }{\f29 Joystick mode sends SDL joystick events to ScummVM which acts as a mouse control in ScummVM. Cursor mod
+e sends keyboard arrows instead, so for example it can be used to navigate through directorylist (one hand use perhaps!?) or save games etc. Keyboard mode is only available for S60 and enables multi-tap to enter text characters in save dialogs. These mode
+s are implemented at the underlying SDL level, so this determines the types 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 Portra
+it 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 center
+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
+\par
+\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 Second guide
+
+\par }\pard\plain \s32\ql \li0\ri0\sa120\widctlpar\nooverflow\faroman\rin0\lin0\itap0 \f1\fs20\cf13\lang2057\langfe1033\cgrid\langnp2057\langfenp1033 {Controls, Virtual keyboard, Shortcuts, ScummVM, Tips, S60, s60
+\par }\pard\plain \ql \li0\ri0\sa120\widctlpar\nooverflow\faroman\rin0\lin0\itap0 \f1\fs20\lang2057\langfe1033\cgrid\langnp2057\langfenp1033 {\f28
+\par
+\par }{\f29 More user-friendly guide for Nokia phones (based on N96 but should apply to most phones)
+\par
+\par Left Soft Key - Left Click
+\par }{\f28
+\par }{\f29 Right Soft Key - Right Click
+\par }{\f28
+\par }{\f29 Navigation buttons - Move pointer on screen
+\par }{\f28
+\par }{\f29 "C" or "Delete Key" - Space Bar (i.e. skip dialogue/cutscene)
+\par }{\f28
+\par }{\f29 * - Bring up Menu (to Save, Load and change the game's options e.g. enable subtitles, speech etc. Varies from game to game)
+\par
+\par The <> is a toggling left right mode. I.e. first click is left, next is right, next is left etc.
+\par
+\par Call Button - Enter/Exit Configuration Mode
+\par }{\f28
+\par }{\f29 Configuration Mode, when activated, shows the word "CTRL" in green in the upper right corner of the screen. It allows to quickly switch between various functions of ScummVM. The following buttons on your keypad are activated when "CTRL" is disp
+layed-
+\par
+\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 whe
+n sending a text message off 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
+\par J - This is the "Joystick/Mouse" mode. Simply put, it allows you to use the navigation buttons to move the pointer around the screen. The left and right mouse buttons are used by the left and right Soft keys.
+\par
+\par The "C" button emulates the space bar, i.e. skip line of dialogue, skip cutscene or pause game (depending on the game, some games simply use the left mouse button to skip dialogue in which case it will pause the game instead)
+\par
+\par 2 - Toggle Landscape and Portrait
+\par Switches the screen output between having the phone held normally (Portrait) or on its side (Landscape). You'll probably never take it off Landscape mode as it offers the better display area.
+\par
+\par 3 - Change Landscape Orientation
+\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 bef
+ore you can move the pointer again. Exiting Configuration Mode does not reset the zoom level.
+\par
+\par 5 & 6 - Unused
+\par
+\par 7 - "Text Input" mode. Shortcut for entering "Text Input" mode directly instead of cycling through the other input types using the "1" key.
+\par
+\par 8 - "Cursor" mode. Shortcut for entering "Cursor" mode directly instead of cycling through the other input types using the "1" key.
+\par
+\par 9 - "Joystick/Mouse" mode. Shortcut for entering "Joystick/Mouse" mode directly instead of cycling through the other input types using the
+\par
+\par "1" key.
+\par
+\par 0 & * - Unused (The "*" Menu is disabled in Configuration Mode")
+\par
+\par Up Navigation Button - Increase ScummVM sound volume. Note that the game itself may have its own independent sound settings (usually found under the * menu)
+\par
+\par Down Navigation Button - Decrease ScummVM sound volume. Note that the game itself may have its own independent sound settings (usually found under the * menu)
+\par
+\par
+\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 Third guide
+
+\par }\pard\plain \s32\ql \li0\ri0\sa120\widctlpar\nooverflow\faroman\rin0\lin0\itap0 \f1\fs20\cf13\lang2057\langfe1033\cgrid\langnp2057\langfenp1033 {Controls, Virtual keyboard, Shortcuts, ScummVM, Tips, S60, s60
+\par }\pard\plain \ql \li0\ri0\sa120\widctlpar\nooverflow\faroman\rin0\lin0\itap0 \f1\fs20\lang2057\langfe1033\cgrid\langnp2057\langfenp1033 {\f28
+\par
+\par }{\f29 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 pre
+ss both keys simultaneously.
+\par
+\par Basic keys:
+\par
+\par Joystick -- Move cursor (in joystick mode) / arrow keys (in keyboard / cursor mode)
+\par Joystick button -- Skip text
+\par Left soft key -- Left mouse button
+\par Right soft key -- Right mouse button (context sensitive actions in Lucas Arts' games, something else in others)
+\par Backspace -- Esc / Skips demos / Removes selected action
+\par * (fn+u) -- Menu
+\par Space -- Pause
+\par Enter -- Enter (usually same as left soft key)
+\par
+\par In main menu:
+\par Shift -- Shift (can be used to mass-add games)
+\par You can press the first letter of the game name to jump there in the games list.
+\par
+\par CTRL-keys:
+\par To use these, first click on green answer key once, so that text CTRL shows up in the northwest corner of the screen, then click the key.
+\par
+\par p / 2 -- Screen orientation
+\par s / 5 -- Screen size
+\par k / 7 -- Input mode: keyboard
+\par c / 8 -- Input mode: cursor
+\par j / 9 -- Input mode: joystick
+\par joystick up -- Volume up
+\par joystick down -- Volume down
+\par 1 -- Toggle input mode
+\par
+\par Game specific:
+\par Most games have some specific keys (the same as in desktop model of ScummVM?). For instance in Day of the Tentacle:
+\par
+\par w -- Walk to
+\par l -- Look at
+\par p -- Pick up
+\par c -- Close
+\par o -- Open
+\par g -- Give
+\par t -- Talk to
+\par s -- Push
+\par y -- Pull
+\par
+\par and in Full Throttle (from the top of my head):
+\par
+\par k -- kick (foot)
+\par t -- talk (mouth)
+\par l -- look (eyes)
+\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 fi
+nding 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
+\par There's good side and bad side to each input mode:
+\par Keyboard (I use this primarily)
+\par
+\par * goes to menu
+\par + you can erase text
+\par + moving is relatively easy
+\par - you can't type in UPPER CASE
+\par - you can't type numbers
+\par - worthless 'current key' -display on left top corner
+\par
+\par Joystick / Cursor:
+\par
+\par + you can access menus
+\par + you can type numbers (just make sure f-letter in left top corner is red before clicking "numbers". It works kinda funnily, but you'll get hang of it.)
+\par - you move mouse cursor which makes walking harder (joystick mode)
+\par - you can't erase text
+\par
+\par There might be some mistakes and some keys missing from the list, feel free to pm me corrections / suggestions.}{\f28
+\par }} \ No newline at end of file
diff --git a/backends/platform/symbian/help/ScummVM.xml b/backends/platform/symbian/help/ScummVM.xml
new file mode 100644
index 0000000000..a1a787012a
--- /dev/null
+++ b/backends/platform/symbian/help/ScummVM.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?xml:stylesheet href="\epoc32\tools\cshlpcmp\xsl\CSHproj.xsl" title="CS Help project" type="text/xsl"?>
+<!DOCTYPE cshproj SYSTEM "\epoc32\tools\cshlpcmp\dtd\CSHproj.dtd">
+
+<cshproj>
+ <helpfileUID>0x100039ce</helpfileUID> <!-- From help file -->
+ <directories>
+ <input></input>
+ <output></output>
+ <working></working>
+ </directories>
+ <files>
+ <source>
+ <file>ScummVM.rtf</file>
+ </source>
+ <destination>ScummVM.hlp</destination>
+ <customization>custom.xml</customization>
+ </files>
+</cshproj>
diff --git a/backends/platform/symbian/help/build_help.mk b/backends/platform/symbian/help/build_help.mk
new file mode 100644
index 0000000000..7a18ad8252
--- /dev/null
+++ b/backends/platform/symbian/help/build_help.mk
@@ -0,0 +1,29 @@
+# ============================================================================
+# Name : help.mk
+# Part of : ScummVM
+#
+# Description: This is file for creating .hlp file
+#
+# ============================================================================
+
+
+makmake :
+ cshlpcmp ScummVM.xml
+
+ifeq (WINS,$(findstring WINS, $(PLATFORM)))
+ copy ScummVM.hlp $(EPOCROOT)epoc32\$(PLATFORM)\c\resource\help
+endif
+
+clean :
+ del ScummVM.hlp
+ del ScummVM.hlp.hrh
+
+bld :
+ cshlpcmp ScummVM.xml
+
+ifeq (WINS,$(findstring WINS, $(PLATFORM)))
+ copy ScummVM.hlp $(EPOCROOT)epoc32\$(PLATFORM)\c\resource\help
+endif
+
+freeze lib cleanlib final resource savespace releasables :
+
diff --git a/backends/platform/symbian/mmp/scummvm_agi.mmp.in b/backends/platform/symbian/mmp/scummvm_agi.mmp.in
index 892ed57732..a3eaa71065 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-2014 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 d3bc84ed51..92b8862794 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-2014 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
new file mode 100644
index 0000000000..1093181a4e
--- /dev/null
+++ b/backends/platform/symbian/mmp/scummvm_avalanche.mmp.in
@@ -0,0 +1,62 @@
+/* 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-2014 The ScummVM Team
+ * Copyright (C) 2013 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_avalanche.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
+
+//START_AUTO_MACROS_SLAVE//
+
+ // empty base file, will be updated by Perl build scripts
+
+//STOP_AUTO_MACROS_SLAVE//
+
+// *** SOURCE files
+
+SOURCEPATH ..\..\..\..\engines\avalanche
+
+//START_AUTO_OBJECTS_AVALANCHE_//
+
+ // empty base file, will be updated by Perl build scripts
+
+//STOP_AUTO_OBJECTS_AVALANCHE_//
+
+// *** Include paths
+
+USERINCLUDE ..\..\..\..\engines
+USERINCLUDE ..\..\..\.. ..\..\..\..\gui ..\..\..\..\audio ..\src
+SYSTEMINCLUDE \epoc32\include\ZLIB // before \epoc32\include because symbian already has older version
+SYSTEMINCLUDE \epoc32\include \epoc32\include\libc ..\src
diff --git a/backends/platform/symbian/mmp/scummvm_base.mmp.in b/backends/platform/symbian/mmp/scummvm_base.mmp.in
index d6dfafd014..358a2ec961 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-2014 The ScummVM Team
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
@@ -50,15 +50,15 @@ ALWAYS_BUILD_AS_ARM
USERINCLUDE ..\..\..\.. ..\..\..\..\gui ..\..\..\..\audio
USERINCLUDE ..\..\..\..\backends\fs ..\src ..\..\..\..\backends\platform\sdl
+USERINCLUDE \epoc32\include\mpeg2dec //\epoc32\include\theora
+SYSTEMINCLUDE \epoc32\include\freetype
+SYSTEMINCLUDE \epoc32\include\mpeg2dec
SYSTEMINCLUDE \epoc32\include\ESDL
SYSTEMINCLUDE \epoc32\include\ZLIB // before \epoc32\include because symbian already has older version
SYSTEMINCLUDE \epoc32\include\libc
SYSTEMINCLUDE \epoc32\include\tremor
SYSTEMINCLUDE \epoc32\include
-SYSTEMINCLUDE \epoc32\include\mw
-SYSTEMINCLUDE \epoc32\include\platform
-SYSTEMINCLUDE \epoc32\include\platform\mw
SYSTEMINCLUDE ..\src // for portdefs.h
// *** SOURCE files
@@ -115,6 +115,9 @@ SOURCEPATH ..\..\..\..\video
//STOP_AUTO_OBJECTS_VIDEO_//
// add a few files manually, since they are not parsed from modules.mk files
+SOURCE bink_decoder.cpp
+SOURCE codecs\mpeg.cpp
+
SOURCEPATH ..\..\..\..
SOURCE backends\events\default\default-events.cpp
SOURCE backends\timer\default\default-timer.cpp
diff --git a/backends/platform/symbian/mmp/scummvm_cge.mmp.in b/backends/platform/symbian/mmp/scummvm_cge.mmp.in
index 66a689efd8..2d93671938 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-2014 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 cb7143b837..a308f92813 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-2014 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 19215f65a6..cfe43b59a2 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-2014 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 c26e93dedc..58aed70f81 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-2014 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 52f862bc6f..ba1759c00b 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-2014 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 9ea02fefe8..c4419dd71e 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-2014 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
new file mode 100644
index 0000000000..a5cc758ff6
--- /dev/null
+++ b/backends/platform/symbian/mmp/scummvm_dreamweb.mmp.in
@@ -0,0 +1,62 @@
+/* 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-2014 The ScummVM Team
+ * Copyright (C) 2013 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_dreamweb.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
+
+//START_AUTO_MACROS_SLAVE//
+
+ // empty base file, will be updated by Perl build scripts
+
+//STOP_AUTO_MACROS_SLAVE//
+
+// *** SOURCE files
+
+SOURCEPATH ..\..\..\..\engines\dreamweb
+
+//START_AUTO_OBJECTS_DREAMWEB_//
+
+ // empty base file, will be updated by Perl build scripts
+
+//STOP_AUTO_OBJECTS_DREAMWEB_//
+
+// *** Include paths
+
+USERINCLUDE ..\..\..\..\engines
+USERINCLUDE ..\..\..\.. ..\..\..\..\gui ..\..\..\..\audio ..\src
+SYSTEMINCLUDE \epoc32\include\ZLIB // before \epoc32\include because symbian already has older version
+SYSTEMINCLUDE \epoc32\include \epoc32\include\libc ..\src
diff --git a/backends/platform/symbian/mmp/scummvm_fullpipe.mmp.in b/backends/platform/symbian/mmp/scummvm_fullpipe.mmp.in
new file mode 100644
index 0000000000..59666b7b74
--- /dev/null
+++ b/backends/platform/symbian/mmp/scummvm_fullpipe.mmp.in
@@ -0,0 +1,62 @@
+/* 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-2014 The ScummVM Team
+ * Copyright (C) 2013 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_fullpipe.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
+
+//START_AUTO_MACROS_SLAVE//
+
+ // empty base file, will be updated by Perl build scripts
+
+//STOP_AUTO_MACROS_SLAVE//
+
+// *** SOURCE files
+
+SOURCEPATH ..\..\..\..\engines\fullpipe
+
+//START_AUTO_OBJECTS_FULLPIPE_//
+
+ // empty base file, will be updated by Perl build scripts
+
+//STOP_AUTO_OBJECTS_FULLPIPE_//
+
+// *** Include paths
+
+USERINCLUDE ..\..\..\..\engines
+USERINCLUDE ..\..\..\.. ..\..\..\..\gui ..\..\..\..\audio ..\src
+SYSTEMINCLUDE \epoc32\include\ZLIB // before \epoc32\include because symbian already has older version
+SYSTEMINCLUDE \epoc32\include \epoc32\include\libc ..\src
diff --git a/backends/platform/symbian/mmp/scummvm_gob.mmp.in b/backends/platform/symbian/mmp/scummvm_gob.mmp.in
index 906d54b487..c2c36626ff 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-2014 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 e7f70bc110..639a794260 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-2014 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 4509026b6c..cfe47d09ba 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-2014 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 13dd7efa1e..fceeb5e5d1 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-2014 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 5772bfaad0..2f8d22595e 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-2014 The ScummVM Team
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
@@ -59,6 +59,13 @@ SOURCEPATH ..\..\..\..\engines\kyra
//STOP_AUTO_OBJECTS_KYRA_ENABLE_LOL//
+
+//START_AUTO_OBJECTS_KYRA_ENABLE_EOB//
+
+ // empty base file, will be updated by Perl build scripts
+
+//STOP_AUTO_OBJECTS_KYRA_ENABLE_EOB//
+
// *** Include paths
USERINCLUDE ..\..\..\..\engines
diff --git a/backends/platform/symbian/mmp/scummvm_lastexpress.mmp.in b/backends/platform/symbian/mmp/scummvm_lastexpress.mmp.in
index b8db95ea0c..fe2ebdfa1b 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-2014 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 84c3eecd5e..f8b42bf337 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-2014 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 e69b40ceb0..05395c1816 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-2014 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 b52d9cc6cb..b0a0e7d34c 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-2014 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_mohawk.mmp.in b/backends/platform/symbian/mmp/scummvm_mohawk.mmp.in
index 5f7bd4e144..005b5f873e 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-2014 The ScummVM Team
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
@@ -53,6 +53,25 @@ SOURCEPATH ..\..\..\..\engines\mohawk
//STOP_AUTO_OBJECTS_MOHAWK_//
+
+//START_AUTO_OBJECTS_MOHAWK_ENABLE_MYST//
+
+ // empty base file, will be updated by Perl build scripts
+
+//STOP_AUTO_OBJECTS_MOHAWK_ENABLE_MYST//
+
+//START_AUTO_OBJECTS_MOHAWK_ENABLE_RIVEN//
+
+ // empty base file, will be updated by Perl build scripts
+
+//STOP_AUTO_OBJECTS_MOHAWK_ENABLE_RIVEN//
+
+//START_AUTO_OBJECTS_MOHAWK_ENABLE_CSTIME//
+
+ // empty base file, will be updated by Perl build scripts
+
+//STOP_AUTO_OBJECTS_MOHAWK_ENABLE_CSTIME//
+
// *** Include paths
USERINCLUDE ..\..\..\..\engines
diff --git a/backends/platform/symbian/mmp/scummvm_mortevielle.mmp.in b/backends/platform/symbian/mmp/scummvm_mortevielle.mmp.in
new file mode 100644
index 0000000000..90af4cb835
--- /dev/null
+++ b/backends/platform/symbian/mmp/scummvm_mortevielle.mmp.in
@@ -0,0 +1,62 @@
+/* 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-2014 The ScummVM Team
+ * Copyright (C) 2013 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_mortevielle.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
+
+//START_AUTO_MACROS_SLAVE//
+
+ // empty base file, will be updated by Perl build scripts
+
+//STOP_AUTO_MACROS_SLAVE//
+
+// *** SOURCE files
+
+SOURCEPATH ..\..\..\..\engines\mortevielle
+
+//START_AUTO_OBJECTS_MORTEVIELLE_//
+
+ // empty base file, will be updated by Perl build scripts
+
+//STOP_AUTO_OBJECTS_MORTEVIELLE_//
+
+// *** Include paths
+
+USERINCLUDE ..\..\..\..\engines
+USERINCLUDE ..\..\..\.. ..\..\..\..\gui ..\..\..\..\audio ..\src
+SYSTEMINCLUDE \epoc32\include\ZLIB // before \epoc32\include because symbian already has older version
+SYSTEMINCLUDE \epoc32\include \epoc32\include\libc ..\src
diff --git a/backends/platform/symbian/mmp/scummvm_neverhood.mmp.in b/backends/platform/symbian/mmp/scummvm_neverhood.mmp.in
new file mode 100644
index 0000000000..b65f0f6ab6
--- /dev/null
+++ b/backends/platform/symbian/mmp/scummvm_neverhood.mmp.in
@@ -0,0 +1,61 @@
+/* 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-2014 The ScummVM Team
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public 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_neverhood.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
+
+//START_AUTO_MACROS_SLAVE//
+
+ // empty base file, will be updated by Perl build scripts
+
+//STOP_AUTO_MACROS_SLAVE//
+
+// *** SOURCE files
+
+SOURCEPATH ..\..\..\..\engines\neverhood
+
+//START_AUTO_OBJECTS_NEVERHOOD_//
+
+ // empty base file, will be updated by Perl build scripts
+
+//STOP_AUTO_OBJECTS_NEVERHOOD_//
+
+// *** Include paths
+
+USERINCLUDE ..\..\..\..\engines
+USERINCLUDE ..\..\..\.. ..\..\..\..\gui ..\..\..\..\audio ..\src
+SYSTEMINCLUDE \epoc32\include\ZLIB // before \epoc32\include because symbian already has older version
+SYSTEMINCLUDE \epoc32\include \epoc32\include\libc ..\src
diff --git a/backends/platform/symbian/mmp/scummvm_parallaction.mmp.in b/backends/platform/symbian/mmp/scummvm_parallaction.mmp.in
index f8ee389577..92d916224e 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-2014 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 fefc63e936..66863f2d74 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-2014 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_queen.mmp.in b/backends/platform/symbian/mmp/scummvm_queen.mmp.in
index f507f482f9..3d8cfc1949 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-2014 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 cd158556dc..9ca633972b 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-2014 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 5749c66e10..109b277667 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-2014 The ScummVM Team
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
@@ -53,6 +53,14 @@ SOURCEPATH ..\..\..\..\engines\sci
//STOP_AUTO_OBJECTS_SCI_//
+
+//START_AUTO_OBJECTS_SCI_ENABLE_SCI32//
+
+ // empty base file, will be updated by Perl build scripts
+
+//STOP_AUTO_OBJECTS_SCI_ENABLE_SCI32//
+
+
// *** Include paths
USERINCLUDE ..\..\..\..\engines
diff --git a/backends/platform/symbian/mmp/scummvm_scumm.mmp.in b/backends/platform/symbian/mmp/scummvm_scumm.mmp.in
index c07725e002..cc008766a8 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-2014 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 b5048106dc..0ab35dffd7 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-2014 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 578839e8c4..3b709fe1de 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-2014 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 23a055c99c..ec5ccaefc9 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-2014 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
new file mode 100644
index 0000000000..62907f9245
--- /dev/null
+++ b/backends/platform/symbian/mmp/scummvm_sword25.mmp.in
@@ -0,0 +1,63 @@
+/* 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-2014 The ScummVM Team
+ * Copyright (C) 2013 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_sword25.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
+
+//START_AUTO_MACROS_SLAVE//
+
+ // empty base file, will be updated by Perl build scripts
+
+//STOP_AUTO_MACROS_SLAVE//
+
+// *** SOURCE files
+
+SOURCEPATH ..\..\..\..\engines\sword25
+
+//START_AUTO_OBJECTS_SWORD25_//
+
+ // empty base file, will be updated by Perl build scripts
+
+//STOP_AUTO_OBJECTS_SWORD25_//
+
+// *** Include paths
+
+USERINCLUDE ..\..\..\..\engines
+USERINCLUDE ..\..\..\.. ..\..\..\..\gui ..\..\..\..\audio ..\src
+USERINCLUDE ..\..\..\..\engines\sword25\util\lua ..\..\..\..\engines\sword25\util\pluto
+SYSTEMINCLUDE \epoc32\include\ZLIB // before \epoc32\include because symbian already has older version
+SYSTEMINCLUDE \epoc32\include \epoc32\include\libc ..\src
diff --git a/backends/platform/symbian/mmp/scummvm_teenagent.mmp.in b/backends/platform/symbian/mmp/scummvm_teenagent.mmp.in
index 58bfa4c337..73a86b9913 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-2014 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
new file mode 100644
index 0000000000..07d1df625d
--- /dev/null
+++ b/backends/platform/symbian/mmp/scummvm_testbed.mmp.in
@@ -0,0 +1,62 @@
+/* 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-2014 The ScummVM Team
+ * Copyright (C) 2013 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_testbed.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
+
+//START_AUTO_MACROS_SLAVE//
+
+ // empty base file, will be updated by Perl build scripts
+
+//STOP_AUTO_MACROS_SLAVE//
+
+// *** SOURCE files
+
+SOURCEPATH ..\..\..\..\engines\testbed
+
+//START_AUTO_OBJECTS_TESTBED_//
+
+ // empty base file, will be updated by Perl build scripts
+
+//STOP_AUTO_OBJECTS_TESTBED_//
+
+// *** Include paths
+
+USERINCLUDE ..\..\..\..\engines
+USERINCLUDE ..\..\..\.. ..\..\..\..\gui ..\..\..\..\audio ..\src
+SYSTEMINCLUDE \epoc32\include\ZLIB // before \epoc32\include because symbian already has older version
+SYSTEMINCLUDE \epoc32\include \epoc32\include\libc ..\src
diff --git a/backends/platform/symbian/mmp/scummvm_tinsel.mmp.in b/backends/platform/symbian/mmp/scummvm_tinsel.mmp.in
index 4cdd0bd774..6436aaaa9b 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-2014 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 9f9d1c1dda..8685f80f71 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-2014 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 d80d82a9c5..01d4712cbb 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-2014 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 00f84d2bec..2cddddd777 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-2014 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 e59dd0cd00..24ca777c70 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-2014 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 cd4aa158dc..d017be593b 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-2014 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 0ff8eb9920..f30bbfc469 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-2014 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_wintermute.mmp.in b/backends/platform/symbian/mmp/scummvm_wintermute.mmp.in
index ebe762fe36..5d26f36df5 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-2014 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
new file mode 100644
index 0000000000..a007f45f5b
--- /dev/null
+++ b/backends/platform/symbian/mmp/scummvm_zvision.mmp.in
@@ -0,0 +1,62 @@
+/* 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-2014 The ScummVM Team
+ * Copyright (C) 2013 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_zvision.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
+
+//START_AUTO_MACROS_SLAVE//
+
+ // empty base file, will be updated by Perl build scripts
+
+//STOP_AUTO_MACROS_SLAVE//
+
+// *** SOURCE files
+
+SOURCEPATH ..\..\..\..\engines\zvision
+
+//START_AUTO_OBJECTS_ZVISION_//
+
+ // empty base file, will be updated by Perl build scripts
+
+//STOP_AUTO_OBJECTS_ZVISION_//
+
+// *** Include paths
+
+USERINCLUDE ..\..\..\..\engines
+USERINCLUDE ..\..\..\.. ..\..\..\..\gui ..\..\..\..\audio ..\src
+SYSTEMINCLUDE \epoc32\include\ZLIB // before \epoc32\include because symbian already has older version
+SYSTEMINCLUDE \epoc32\include \epoc32\include\libc ..\src
diff --git a/backends/platform/symbian/res/ScummVmAif.rss b/backends/platform/symbian/res/ScummVmAif.rss
index fab2cadbb8..2dbf436a8f 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-2013 The ScummVM project
+ * Copyright (C) 2005-2014 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 7e667f1cf3..6a0ab24ff0 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-2013 The ScummVM project
+ * Copyright (C) 2005-2014 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 3325d72249..562fef54c6 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-2013 The ScummVM project
+ * Copyright (C) 2005-2014 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 c43a9da118..316e4d08f6 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-2013 The ScummVM project
+ * Copyright (C) 2005-2014 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 b1bd976f9e..ead85a933e 100644
--- a/backends/platform/symbian/src/SymbianOS.cpp
+++ b/backends/platform/symbian/src/SymbianOS.cpp
@@ -197,3 +197,8 @@ void* scumm_bsearch(const void *key, const void *base, size_t nmemb, size_t size
return NULL;
}
+
+int remove(const char *path)
+{
+ return unlink(path);
+}
diff --git a/backends/platform/symbian/src/portdefs.h b/backends/platform/symbian/src/portdefs.h
index 1f9128a54f..f69a90e009 100644
--- a/backends/platform/symbian/src/portdefs.h
+++ b/backends/platform/symbian/src/portdefs.h
@@ -60,6 +60,8 @@ typedef signed long int int32;
#define SMALL_SCREEN_DEVICE
#define DISABLE_COMMAND_LINE
+#define USE_RGB_COLOR
+int remove(const char *path);
#if defined(USE_TREMOR) && !defined(USE_VORBIS)
#define USE_VORBIS // make sure this one is defined together with USE_TREMOR!
diff --git a/backends/platform/tizen/graphics.cpp b/backends/platform/tizen/graphics.cpp
index 2cafb9f781..390796dc0e 100644
--- a/backends/platform/tizen/graphics.cpp
+++ b/backends/platform/tizen/graphics.cpp
@@ -37,7 +37,6 @@ TizenGraphicsManager::TizenGraphicsManager(TizenAppForm *appForm) :
_eglContext(EGL_NO_CONTEXT),
_initState(true) {
assert(appForm != NULL);
- _videoMode.fullscreen = true;
}
TizenGraphicsManager::~TizenGraphicsManager() {
@@ -51,17 +50,34 @@ TizenGraphicsManager::~TizenGraphicsManager() {
}
}
+result TizenGraphicsManager::Construct() {
+ // Initialize our OpenGL ES context.
+ loadEgl();
+
+ // Notify the OpenGL code about our context.
+
+ // We default to RGB565 and RGBA5551 which is closest to the actual output
+ // mode we setup.
+ notifyContextChange(Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0), Graphics::PixelFormat(2, 5, 5, 5, 1, 11, 6, 1, 0));
+
+ // Tell our size.
+ int x, y, width, height;
+ _appForm->GetBounds(x, y, width, height);
+ AppLog("screen size: %dx%d", width, height);
+ setActualScreenSize(width, height);
+ return E_SUCCESS;
+}
+
const Graphics::Font *TizenGraphicsManager::getFontOSD() {
return FontMan.getFontByUsage(Graphics::FontManager::kBigGUIFont);
}
bool TizenGraphicsManager::moveMouse(int16 &x, int16 &y) {
- int16 currentX = _cursorState.x;
- int16 currentY = _cursorState.y;
+ int16 currentX, currentY;
+ getMousePosition(currentX, currentY);
// save the current hardware coordinates
- _cursorState.x = x;
- _cursorState.y = y;
+ setMousePosition(x, y);
// return x/y as game coordinates
adjustMousePosition(x, y);
@@ -85,15 +101,17 @@ Common::List<Graphics::PixelFormat> TizenGraphicsManager::getSupportedFormats()
}
bool TizenGraphicsManager::hasFeature(OSystem::Feature f) {
- bool result = (f == OSystem::kFeatureFullscreenMode ||
- f == OSystem::kFeatureVirtualKeyboard ||
+ bool result =
+ (f == OSystem::kFeatureVirtualKeyboard ||
OpenGLGraphicsManager::hasFeature(f));
return result;
}
void TizenGraphicsManager::setFeatureState(OSystem::Feature f, bool enable) {
- if (f == OSystem::kFeatureVirtualKeyboard && enable) {
- _appForm->showKeypad();
+ if (f == OSystem::kFeatureVirtualKeyboard) {
+ if (enable) {
+ _appForm->showKeypad();
+ }
} else {
OpenGLGraphicsManager::setFeatureState(f, enable);
}
@@ -106,8 +124,9 @@ void TizenGraphicsManager::setReady() {
}
void TizenGraphicsManager::updateScreen() {
- if (_transactionMode == kTransactionNone) {
- internUpdateScreen();
+ if (!_initState) {
+ OpenGLGraphicsManager::updateScreen();
+ eglSwapBuffers(_eglDisplay, _eglSurface);
}
}
@@ -133,10 +152,6 @@ bool TizenGraphicsManager::loadEgl() {
eglBindAPI(EGL_OPENGL_ES_API);
- if (_eglDisplay) {
- unloadGFXMode();
- }
-
_eglDisplay = eglGetDisplay((EGLNativeDisplayType) EGL_DEFAULT_DISPLAY);
if (EGL_NO_DISPLAY == _eglDisplay) {
systemError("eglGetDisplay() failed");
@@ -178,65 +193,12 @@ bool TizenGraphicsManager::loadEgl() {
systemError("eglMakeCurrent() failed");
return false;
}
- if (!_initState) {
- _appForm->GetVisualElement()->SetShowState(true);
- }
logLeaving();
return true;
}
-bool TizenGraphicsManager::loadGFXMode() {
- logEntered();
-
- if (!loadEgl()) {
- unloadGFXMode();
- return false;
- }
-
- int x, y, width, height;
- _appForm->GetBounds(x, y, width, height);
- _videoMode.overlayWidth = _videoMode.hardwareWidth = width;
- _videoMode.overlayHeight = _videoMode.hardwareHeight = height;
- _videoMode.scaleFactor = 4; // for proportional sized cursor in the launcher
-
- AppLog("screen size: %dx%d", _videoMode.hardwareWidth, _videoMode.hardwareHeight);
- return OpenGLGraphicsManager::loadGFXMode();
-}
-
-void TizenGraphicsManager::loadTextures() {
- logEntered();
- OpenGLGraphicsManager::loadTextures();
-}
-
-void TizenGraphicsManager::internUpdateScreen() {
- if (!_initState) {
- OpenGLGraphicsManager::internUpdateScreen();
- eglSwapBuffers(_eglDisplay, _eglSurface);
- }
-}
-
-void TizenGraphicsManager::unloadGFXMode() {
- logEntered();
- _appForm->GetVisualElement()->SetShowState(false);
-
- if (_eglDisplay != EGL_NO_DISPLAY) {
- eglMakeCurrent(_eglDisplay, NULL, NULL, NULL);
-
- if (_eglContext != EGL_NO_CONTEXT) {
- eglDestroyContext(_eglDisplay, _eglContext);
- _eglContext = EGL_NO_CONTEXT;
- }
-
- if (_eglSurface != EGL_NO_SURFACE) {
- eglDestroySurface(_eglDisplay, _eglSurface);
- _eglSurface = EGL_NO_SURFACE;
- }
-
- eglTerminate(_eglDisplay);
- _eglDisplay = EGL_NO_DISPLAY;
- }
-
- _eglConfig = NULL;
- OpenGLGraphicsManager::unloadGFXMode();
- logLeaving();
+bool TizenGraphicsManager::loadVideoMode(uint requestedWidth, uint requestedHeight, const Graphics::PixelFormat &format) {
+ // We get this whenever a new resolution is requested. Since Tizen is
+ // using a fixed output size we do nothing like that here.
+ return true;
}
diff --git a/backends/platform/tizen/graphics.h b/backends/platform/tizen/graphics.h
index 27e5a6aaeb..29ba86a3c4 100644
--- a/backends/platform/tizen/graphics.h
+++ b/backends/platform/tizen/graphics.h
@@ -39,28 +39,31 @@ using namespace Tizen::Graphics;
using namespace Tizen::Graphics::Opengl;
using namespace Tizen::App;
-class TizenGraphicsManager : public OpenGLGraphicsManager {
+class TizenGraphicsManager : public OpenGL::OpenGLGraphicsManager {
public:
TizenGraphicsManager(TizenAppForm *appForm);
virtual ~TizenGraphicsManager();
+ result Construct();
+
Common::List<Graphics::PixelFormat> getSupportedFormats() const;
bool hasFeature(OSystem::Feature f);
- void updateScreen();
void setFeatureState(OSystem::Feature f, bool enable);
+ void updateScreen();
+
void setReady();
bool isReady() { return !_initState; }
- const Graphics::Font *getFontOSD();
+
bool moveMouse(int16 &x, int16 &y);
-private:
- void internUpdateScreen();
- bool loadGFXMode();
- void loadTextures();
- void unloadGFXMode();
+protected:
void setInternalMousePosition(int x, int y) {}
- void showSplash();
+ bool loadVideoMode(uint requestedWidth, uint requestedHeight, const Graphics::PixelFormat &format);
+
+ const Graphics::Font *getFontOSD();
+
+private:
bool loadEgl();
TizenAppForm *_appForm;
EGLDisplay _eglDisplay;
diff --git a/backends/platform/tizen/system.cpp b/backends/platform/tizen/system.cpp
index 3448dc1421..f7ebc46719 100644
--- a/backends/platform/tizen/system.cpp
+++ b/backends/platform/tizen/system.cpp
@@ -267,7 +267,7 @@ result TizenSystem::initModules() {
}
_graphicsManager = (GraphicsManager *)new TizenGraphicsManager(_appForm);
- if (!_graphicsManager) {
+ if (!_graphicsManager || graphicsManager->Construct() != E_SUCCESS) {
return E_OUT_OF_MEMORY;
}
diff --git a/backends/platform/wii/main.cpp b/backends/platform/wii/main.cpp
index affe053b6a..ec6231522e 100644
--- a/backends/platform/wii/main.cpp
+++ b/backends/platform/wii/main.cpp
@@ -225,7 +225,8 @@ int main(int argc, char *argv[]) {
printf("shutdown\n");
SYS_UnregisterResetFunc(&resetinfo);
- fatUnmountDefault();
+ fatUnmount("usb:/");
+ fatUnmount("sd:/");
if (res)
show_console(res);
diff --git a/backends/platform/wii/osystem_events.cpp b/backends/platform/wii/osystem_events.cpp
index 3ba66aed89..aa63c8aa22 100644
--- a/backends/platform/wii/osystem_events.cpp
+++ b/backends/platform/wii/osystem_events.cpp
@@ -188,7 +188,7 @@ void OSystem_Wii::initEvents() {
_padAcceleration = 9 - ConfMan.getInt("wii_pad_acceleration");
#ifdef USE_WII_KBD
- _kbd_active = KEYBOARD_Init() >= 0;
+ _kbd_active = KEYBOARD_Init(NULL) >= 0;
#endif
}
diff --git a/backends/platform/wii/wii.mk b/backends/platform/wii/wii.mk
index 7d2db68b4e..99ef46338c 100644
--- a/backends/platform/wii/wii.mk
+++ b/backends/platform/wii/wii.mk
@@ -17,10 +17,10 @@ geckoupload: $(WII_EXE_STRIPPED)
$(DEVKITPPC)/bin/geckoupload $<
wiigdb:
- $(DEVKITPPC)/bin/powerpc-gekko-gdb -n $(EXECUTABLE)
+ $(DEVKITPPC)/bin/powerpc-eabi-gdb -n $(EXECUTABLE)
wiidebug:
- $(DEVKITPPC)/bin/powerpc-gekko-gdb -n $(EXECUTABLE) -x $(srcdir)/backends/platform/wii/gdb.txt
+ $(DEVKITPPC)/bin/powerpc-eabi-gdb -n $(EXECUTABLE) -x $(srcdir)/backends/platform/wii/gdb.txt
# target to create a Wii snapshot
wiidist: all
diff --git a/backends/platform/wince/CEActionsPocket.cpp b/backends/platform/wince/CEActionsPocket.cpp
index 5980a41caa..493a5e688c 100644
--- a/backends/platform/wince/CEActionsPocket.cpp
+++ b/backends/platform/wince/CEActionsPocket.cpp
@@ -236,7 +236,7 @@ CEActionsPocket::~CEActionsPocket() {
bool CEActionsPocket::perform(GUI::ActionType action, bool pushed) {
static bool keydialogrunning = false, quitdialog = false;
- _graphicsMan = ((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager());
+ _graphicsMan = dynamic_cast<WINCESdlGraphicsManager *>(((OSystem_SDL *)g_system)->getGraphicsManager());
if (!pushed) {
switch (action) {
diff --git a/backends/platform/wince/CEActionsSmartphone.cpp b/backends/platform/wince/CEActionsSmartphone.cpp
index 2cce288323..d2bc449dfc 100644
--- a/backends/platform/wince/CEActionsSmartphone.cpp
+++ b/backends/platform/wince/CEActionsSmartphone.cpp
@@ -202,7 +202,7 @@ CEActionsSmartphone::~CEActionsSmartphone() {
bool CEActionsSmartphone::perform(GUI::ActionType action, bool pushed) {
static bool keydialogrunning = false, quitdialog = false;
- _graphicsMan = ((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager());
+ _graphicsMan = dynamic_cast<WINCESdlGraphicsManager *>(((OSystem_SDL *)g_system)->getGraphicsManager());
if (!pushed) {
switch (action) {
diff --git a/backends/platform/wince/CELauncherDialog.cpp b/backends/platform/wince/CELauncherDialog.cpp
index dd6076e0af..3908294682 100644
--- a/backends/platform/wince/CELauncherDialog.cpp
+++ b/backends/platform/wince/CELauncherDialog.cpp
@@ -65,12 +65,12 @@ public:
};
CELauncherDialog::CELauncherDialog() : GUI::LauncherDialog() {
- ((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->reset_panel();
+ dynamic_cast<WINCESdlGraphicsManager *>(((OSystem_SDL *)g_system)->getGraphicsManager())->reset_panel();
}
void CELauncherDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 data) {
if ((cmd == 'STRT') || (cmd == kListItemActivatedCmd) || (cmd == kListItemDoubleClickedCmd)) {
- ((WINCESdlGraphicsManager *)((OSystem_SDL *)g_system)->getGraphicsManager())->init_panel();
+ dynamic_cast<WINCESdlGraphicsManager *>(((OSystem_SDL *)g_system)->getGraphicsManager())->init_panel();
}
LauncherDialog::handleCommand(sender, cmd, data);
if (cmd == 'ABOU') {
diff --git a/backends/platform/wince/wince-sdl.cpp b/backends/platform/wince/wince-sdl.cpp
index 3897731db4..1c9c178460 100644
--- a/backends/platform/wince/wince-sdl.cpp
+++ b/backends/platform/wince/wince-sdl.cpp
@@ -422,7 +422,7 @@ void OSystem_WINCE3::initBackend() {
if (_graphicsManager == 0)
_graphicsManager = new WINCESdlGraphicsManager(_eventSource);
- ((WINCESdlEventSource *)_eventSource)->init((WINCESdlGraphicsManager *)_graphicsManager);
+ ((WINCESdlEventSource *)_eventSource)->init(dynamic_cast<WINCESdlGraphicsManager *>(_graphicsManager));
// Call parent implementation of this method
OSystem_SDL::initBackend();
@@ -486,15 +486,16 @@ void OSystem_WINCE3::swap_sound_master() {
//WINCESdlGraphicsManager _graphicsManager
- if (((WINCESdlGraphicsManager *)_graphicsManager)->_toolbarHandler.activeName() == NAME_MAIN_PANEL)
- ((WINCESdlGraphicsManager *)_graphicsManager)->_toolbarHandler.forceRedraw(); // redraw sound icon
+ WINCESdlGraphicsManager *graphicsManager = dynamic_cast<WINCESdlGraphicsManager *>(_graphicsManager);
+ if (graphicsManager->_toolbarHandler.activeName() == NAME_MAIN_PANEL)
+ graphicsManager->_toolbarHandler.forceRedraw(); // redraw sound icon
}
void OSystem_WINCE3::engineInit() {
check_mappings(); // called here to initialize virtual keys handling
- ((WINCESdlGraphicsManager *)_graphicsManager)->update_game_settings();
+ dynamic_cast<WINCESdlGraphicsManager *>(_graphicsManager)->update_game_settings();
// finalize mixer init
_mixerManager->init();
}
@@ -563,7 +564,7 @@ void OSystem_WINCE3::setGraphicsModeIntern() {
void OSystem_WINCE3::initSDL() {
// Check if SDL has not been initialized
if (!_initedSDL) {
- uint32 sdlFlags = SDL_INIT_EVENTTHREAD;
+ uint32 sdlFlags = SDL_INIT_EVENTTHREAD | SDL_INIT_VIDEO;
if (ConfMan.hasKey("disable_sdl_parachute"))
sdlFlags |= SDL_INIT_NOPARACHUTE;
@@ -576,9 +577,6 @@ void OSystem_WINCE3::initSDL() {
if (SDL_Init(sdlFlags) == -1)
error("Could not initialize SDL: %s", SDL_GetError());
- // Enable unicode support if possible
- SDL_EnableUNICODE(1);
-
_initedSDL = true;
}
}
diff --git a/backends/taskbar/unity/unity-taskbar.cpp b/backends/taskbar/unity/unity-taskbar.cpp
index f36e2bf628..1b82e58c8a 100644
--- a/backends/taskbar/unity/unity-taskbar.cpp
+++ b/backends/taskbar/unity/unity-taskbar.cpp
@@ -24,7 +24,7 @@
#define FORBIDDEN_SYMBOL_EXCEPTION_time_h
#include "common/scummsys.h"
-#if defined(POSIX) && defined(USE_TASKBAR) && defined(USE_TASKBAR_UNITY)
+#if defined(POSIX) && defined(USE_TASKBAR) && defined(USE_UNITY)
#include "backends/taskbar/unity/unity-taskbar.h"
diff --git a/backends/taskbar/unity/unity-taskbar.h b/backends/taskbar/unity/unity-taskbar.h
index d1d9430bcd..d818ed9ff1 100644
--- a/backends/taskbar/unity/unity-taskbar.h
+++ b/backends/taskbar/unity/unity-taskbar.h
@@ -23,7 +23,7 @@
#ifndef BACKEND_UNITY_TASKBAR_H
#define BACKEND_UNITY_TASKBAR_H
-#if defined(POSIX) && defined(USE_TASKBAR) && defined(USE_TASKBAR_UNITY)
+#if defined(POSIX) && defined(USE_TASKBAR) && defined(USE_UNITY)
#include "common/events.h"
#include "common/str.h"
diff --git a/base/main.cpp b/base/main.cpp
index 103d743bbc..abf75b7e7e 100644
--- a/base/main.cpp
+++ b/base/main.cpp
@@ -134,6 +134,19 @@ static Common::Error runGame(const EnginePlugin *plugin, OSystem &system, const
Common::Error err = Common::kNoError;
Engine *engine = 0;
+#if defined(SDL_BACKEND) && defined(USE_OPENGL) && defined(USE_RGB_COLOR)
+ // HACK: We set up the requested graphics mode setting here to allow the
+ // backend to switch from Surface SDL to OpenGL if necessary. This is
+ // needed because otherwise the g_system->getSupportedFormats might return
+ // bad values.
+ g_system->beginGFXTransaction();
+ g_system->setGraphicsMode(ConfMan.get("gfx_mode").c_str());
+ if (g_system->endGFXTransaction() != OSystem::kTransactionSuccess) {
+ warning("Switching graphics mode to '%s' failed", ConfMan.get("gfx_mode").c_str());
+ return Common::kUnknownError;
+ }
+#endif
+
// Verify that the game path refers to an actual directory
if (!(dir.exists() && dir.isDirectory()))
err = Common::kPathNotDirectory;
@@ -184,7 +197,7 @@ static Common::Error runGame(const EnginePlugin *plugin, OSystem &system, const
//
// Add the game path to the directory search list
- SearchMan.addDirectory(dir.getPath(), dir, 0, 4);
+ engine->initializePath(dir);
// Add extrapath (if any) to the directory search list
if (ConfMan.hasKey("extrapath")) {
diff --git a/base/plugins.cpp b/base/plugins.cpp
index b8cd097683..a232bb1427 100644
--- a/base/plugins.cpp
+++ b/base/plugins.cpp
@@ -295,7 +295,7 @@ bool PluginManagerUncached::loadPluginFromGameId(const Common::String &gameId) {
if (domain->contains(gameId)) {
Common::String filename = (*domain)[gameId];
- if (loadPluginByFileName(filename)) {
+ if (loadPluginByFileName(filename)) {
return true;
}
}
diff --git a/base/plugins.h b/base/plugins.h
index 4409c9eaea..e0673ce636 100644
--- a/base/plugins.h
+++ b/base/plugins.h
@@ -169,7 +169,7 @@ protected:
PluginType _type;
public:
- Plugin() : _pluginObject(0) {}
+ Plugin() : _pluginObject(0), _type(PLUGIN_TYPE_MAX) {}
virtual ~Plugin() {
//if (isLoaded())
//unloadPlugin();
diff --git a/common/c++11-compat.h b/common/c++11-compat.h
index 50d79bd79e..f963ba9ac8 100644
--- a/common/c++11-compat.h
+++ b/common/c++11-compat.h
@@ -31,7 +31,9 @@
// Custom nullptr replacement. This is not type safe as the real C++11 nullptr
// though.
//
+#if !defined(nullptr) // XCode 5.0.1 has __cplusplus=199711 but defines this
#define nullptr 0
+#endif
//
// Replacement for the override keyword. This allows compilation of code
diff --git a/common/ini-file.cpp b/common/ini-file.cpp
index be5247dcfb..9de0b38e93 100644
--- a/common/ini-file.cpp
+++ b/common/ini-file.cpp
@@ -53,7 +53,7 @@ bool INIFile::loadFromFile(const String &filename) {
return false;
}
-bool INIFile::loadFromSaveFile(const char *filename) {
+bool INIFile::loadFromSaveFile(const String &filename) {
assert(g_system);
SaveFileManager *saveFileMan = g_system->getSavefileManager();
SeekableReadStream *loadFile;
@@ -181,7 +181,7 @@ bool INIFile::saveToFile(const String &filename) {
return false;
}
-bool INIFile::saveToSaveFile(const char *filename) {
+bool INIFile::saveToSaveFile(const String &filename) {
assert(g_system);
SaveFileManager *saveFileMan = g_system->getSavefileManager();
WriteStream *saveFile;
diff --git a/common/ini-file.h b/common/ini-file.h
index 1d94ce7bdc..a1505fe468 100644
--- a/common/ini-file.h
+++ b/common/ini-file.h
@@ -94,10 +94,10 @@ public:
void clear();
bool loadFromFile(const String &filename);
- bool loadFromSaveFile(const char *filename);
+ bool loadFromSaveFile(const String &filename);
bool loadFromStream(SeekableReadStream &stream);
bool saveToFile(const String &filename);
- bool saveToSaveFile(const char *filename);
+ bool saveToSaveFile(const String &filename);
bool saveToStream(WriteStream &stream);
bool hasSection(const String &section) const;
diff --git a/common/language.cpp b/common/language.cpp
index 898adf8d0e..6704a52373 100644
--- a/common/language.cpp
+++ b/common/language.cpp
@@ -28,6 +28,7 @@ namespace Common {
const LanguageDescription g_languages[] = {
{ "zh-cn", "zh_CN", "Chinese (China)", ZH_CNA },
{ "zh", "zh_TW", "Chinese (Taiwan)", ZH_TWN },
+ { "hr", "hr_HR", "Croatian", HR_HRV },
{ "cz", "cs_CZ", "Czech", CZ_CZE },
{ "nl", "nl_NL", "Dutch", NL_NLD },
{ "en", "en", "English", EN_ANY }, // Generic English (when only one game version exist)
@@ -38,11 +39,11 @@ const LanguageDescription g_languages[] = {
{ "gr", "el_GR", "Greek", GR_GRE },
{ "he", "he_IL", "Hebrew", HE_ISR },
{ "hb", "he_IL", "Hebrew", HE_ISR }, // Deprecated
- { "hr", "hr_HR", "Croatian", HR_HRV },
{ "hu", "hu_HU", "Hungarian", HU_HUN },
{ "it", "it_IT", "Italian", IT_ITA },
{ "jp", "ja_JP", "Japanese", JA_JPN },
{ "kr", "ko_KR", "Korean", KO_KOR },
+ { "lv", "lv_LV", "Latvian", LV_LAT },
{ "nb", "nb_NO", "Norwegian Bokm\xE5l", NB_NOR }, // TODO Someone should verify the unix locale
{ "pl", "pl_PL", "Polish", PL_POL },
{ "br", "pt_BR", "Portuguese", PT_BRA },
diff --git a/common/language.h b/common/language.h
index 03b9ebaf8e..f18815509b 100644
--- a/common/language.h
+++ b/common/language.h
@@ -34,6 +34,7 @@ class String;
enum Language {
ZH_CNA,
ZH_TWN,
+ HR_HRV,
CZ_CZE,
NL_NLD,
EN_ANY, // Generic English (when only one game version exist)
@@ -43,11 +44,11 @@ enum Language {
DE_DEU,
GR_GRE,
HE_ISR,
- HR_HRV,
HU_HUN,
IT_ITA,
JA_JPN,
KO_KOR,
+ LV_LAT,
NB_NOR,
PL_POL,
PT_BRA,
diff --git a/common/module.mk b/common/module.mk
index 1b34d151d0..67c498df00 100644
--- a/common/module.mk
+++ b/common/module.mk
@@ -35,6 +35,7 @@ MODULE_OBJS := \
translation.o \
unarj.o \
unzip.o \
+ ustr.o \
util.o \
winexe.o \
winexe_ne.o \
diff --git a/common/quicktime.cpp b/common/quicktime.cpp
index a3efc2b443..6ab5a42b89 100644
--- a/common/quicktime.cpp
+++ b/common/quicktime.cpp
@@ -368,9 +368,6 @@ int QuickTimeParser::readMVHD(Atom atom) {
int QuickTimeParser::readTRAK(Atom atom) {
Track *track = new Track();
- if (!track)
- return -1;
-
track->codecType = CODEC_TYPE_MOV_OTHER;
track->startTime = 0; // XXX: check
_tracks.push_back(track);
diff --git a/common/recorderfile.cpp b/common/recorderfile.cpp
index d08bc599f1..7c438cbf69 100644
--- a/common/recorderfile.cpp
+++ b/common/recorderfile.cpp
@@ -45,6 +45,8 @@ PlaybackFile::PlaybackFile() : _tmpRecordFile(_tmpBuffer, kRecordBuffSize), _tmp
_recordCount = 0;
_eventsSize = 0;
memset(_tmpBuffer, 1, kRecordBuffSize);
+
+ _playbackParseState = kFileStateCheckFormat;
}
PlaybackFile::~PlaybackFile() {
diff --git a/common/scummsys.h b/common/scummsys.h
index 3e9d5ef063..48dffc53a6 100644
--- a/common/scummsys.h
+++ b/common/scummsys.h
@@ -23,6 +23,10 @@
#ifndef COMMON_SCUMMSYS_H
#define COMMON_SCUMMSYS_H
+#ifndef __has_feature // Optional of course.
+ #define __has_feature(x) 0 // Compatibility with non-clang compilers.
+#endif
+
// This is a convenience macro to test whether the compiler used is a GCC
// version, which is at least major.minor.
#define GCC_ATLEAST(major, minor) (defined(__GNUC__) && (__GNUC__ > (major) || (__GNUC__ == (major) && __GNUC_MINOR__ >= (minor))))
@@ -401,6 +405,8 @@
typedef unsigned int uint32;
typedef signed int int32;
typedef unsigned int uint;
+ typedef signed long long int64;
+ typedef unsigned long long uint64;
#endif
diff --git a/common/str.h b/common/str.h
index 6b4475e1c4..ea2db1d1d6 100644
--- a/common/str.h
+++ b/common/str.h
@@ -234,6 +234,13 @@ public:
static String vformat(const char *fmt, va_list args);
public:
+ typedef char value_type;
+ /**
+ * Unsigned version of the underlying type. This can be used to cast
+ * individual string characters to bigger integer types without sign
+ * extension happening.
+ */
+ typedef unsigned char unsigned_type;
typedef char * iterator;
typedef const char * const_iterator;
diff --git a/common/unarj.cpp b/common/unarj.cpp
index fe3c17a2ac..e8aed7cbd1 100644
--- a/common/unarj.cpp
+++ b/common/unarj.cpp
@@ -95,6 +95,12 @@ class ArjDecoder {
public:
ArjDecoder(const ArjHeader *hdr) {
_compsize = hdr->compSize;
+ _compressed = 0;
+ _outstream = 0;
+ _bitbuf = 0;
+ _bytebuf = 0;
+ _bitcount = 0;
+ _blocksize = 0;
}
~ArjDecoder() {
@@ -112,7 +118,6 @@ public:
uint16 _bitbuf;
uint16 _bytebuf;
int32 _compsize;
- byte _subbitbuf;
int _bitcount;
void init_getbits();
@@ -132,9 +137,6 @@ public:
private:
byte _ntext[ARJ_FDICSIZ];
- int16 _getlen;
- int16 _getbuf;
-
uint16 _left[2 * ARJ_NC - 1];
uint16 _right[2 * ARJ_NC - 1];
byte _c_len[ARJ_NC];
@@ -656,7 +658,6 @@ void ArjDecoder::decode_f(int32 origsize) {
init_getbits();
ncount = 0;
- _getlen = _getbuf = 0;
r = 0;
while (ncount < (uint32)origsize) {
diff --git a/common/ustr.cpp b/common/ustr.cpp
new file mode 100644
index 0000000000..fbc831cb56
--- /dev/null
+++ b/common/ustr.cpp
@@ -0,0 +1,329 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "common/ustr.h"
+#include "common/memorypool.h"
+#include "common/util.h"
+
+namespace Common {
+
+extern MemoryPool *g_refCountPool;
+
+static uint32 computeCapacity(uint32 len) {
+ // By default, for the capacity we use the next multiple of 32
+ return ((len + 32 - 1) & ~0x1F);
+}
+
+U32String::U32String(const value_type *str) : _size(0), _str(_storage) {
+ if (str == 0) {
+ _storage[0] = 0;
+ _size = 0;
+ } else {
+ uint32 len = 0;
+ const value_type *s = str;
+ while (*s++) {
+ ++len;
+ }
+ initWithCStr(str, len);
+ }
+}
+
+U32String::U32String(const value_type *str, uint32 len) : _size(0), _str(_storage) {
+ initWithCStr(str, len);
+}
+
+U32String::U32String(const value_type *beginP, const value_type *endP) : _size(0), _str(_storage) {
+ assert(endP >= beginP);
+ initWithCStr(beginP, endP - beginP);
+}
+
+U32String::U32String(const U32String &str)
+ : _size(str._size) {
+ if (str.isStorageIntern()) {
+ // String in internal storage: just copy it
+ memcpy(_storage, str._storage, _builtinCapacity * sizeof(value_type));
+ _str = _storage;
+ } else {
+ // String in external storage: use refcount mechanism
+ str.incRefCount();
+ _extern._refCount = str._extern._refCount;
+ _extern._capacity = str._extern._capacity;
+ _str = str._str;
+ }
+ assert(_str != 0);
+}
+
+U32String::~U32String() {
+ decRefCount(_extern._refCount);
+}
+
+U32String &U32String::operator=(const U32String &str) {
+ if (&str == this)
+ return *this;
+
+ if (str.isStorageIntern()) {
+ decRefCount(_extern._refCount);
+ _size = str._size;
+ _str = _storage;
+ memcpy(_str, str._str, (_size + 1) * sizeof(value_type));
+ } else {
+ str.incRefCount();
+ decRefCount(_extern._refCount);
+
+ _extern._refCount = str._extern._refCount;
+ _extern._capacity = str._extern._capacity;
+ _size = str._size;
+ _str = str._str;
+ }
+
+ return *this;
+}
+
+U32String &U32String::operator+=(const U32String &str) {
+ if (&str == this) {
+ return operator+=(U32String(str));
+ }
+
+ int len = str._size;
+ if (len > 0) {
+ ensureCapacity(_size + len, true);
+
+ memcpy(_str + _size, str._str, (len + 1) * sizeof(value_type));
+ _size += len;
+ }
+ return *this;
+}
+
+U32String &U32String::operator+=(value_type c) {
+ ensureCapacity(_size + 1, true);
+
+ _str[_size++] = c;
+ _str[_size] = 0;
+
+ return *this;
+}
+
+bool U32String::equals(const U32String &x) const {
+ if (this == &x || _str == x._str) {
+ return true;
+ }
+
+ if (x.size() != _size) {
+ return false;
+ }
+
+ return !memcmp(_str, x._str, _size * sizeof(value_type));
+}
+
+bool U32String::contains(value_type x) const {
+ for (uint32 i = 0; i < _size; ++i) {
+ if (_str[i] == x) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+void U32String::deleteChar(uint32 p) {
+ assert(p < _size);
+
+ makeUnique();
+ while (p++ < _size)
+ _str[p - 1] = _str[p];
+ _size--;
+}
+
+void U32String::clear() {
+ decRefCount(_extern._refCount);
+
+ _size = 0;
+ _str = _storage;
+ _storage[0] = 0;
+}
+
+void U32String::toLowercase() {
+ makeUnique();
+ for (uint32 i = 0; i < _size; ++i) {
+ if (_str[i] < 128) {
+ _str[i] = tolower(_str[i]);
+ }
+ }
+}
+
+void U32String::toUppercase() {
+ makeUnique();
+ for (uint32 i = 0; i < _size; ++i) {
+ if (_str[i] < 128) {
+ _str[i] = toupper(_str[i]);
+ }
+ }
+}
+
+uint32 U32String::find(const U32String &str, uint32 pos) const {
+ if (pos >= _size) {
+ return npos;
+ }
+
+ const value_type *strP = str.c_str();
+
+ for (const_iterator cur = begin() + pos; *cur; ++cur) {
+ uint i = 0;
+ while (true) {
+ if (!strP[i]) {
+ return cur - begin();
+ }
+
+ if (cur[i] != strP[i]) {
+ break;
+ }
+
+ ++i;
+ }
+ }
+
+ return npos;
+}
+
+void U32String::makeUnique() {
+ ensureCapacity(_size, true);
+}
+
+void U32String::ensureCapacity(uint32 new_size, bool keep_old) {
+ bool isShared;
+ uint32 curCapacity, newCapacity;
+ value_type *newStorage;
+ int *oldRefCount = _extern._refCount;
+
+ if (isStorageIntern()) {
+ isShared = false;
+ curCapacity = _builtinCapacity;
+ } else {
+ isShared = (oldRefCount && *oldRefCount > 1);
+ curCapacity = _extern._capacity;
+ }
+
+ // Special case: If there is enough space, and we do not share
+ // the storage, then there is nothing to do.
+ if (!isShared && new_size < curCapacity)
+ return;
+
+ if (isShared && new_size < _builtinCapacity) {
+ // We share the storage, but there is enough internal storage: Use that.
+ newStorage = _storage;
+ newCapacity = _builtinCapacity;
+ } else {
+ // We need to allocate storage on the heap!
+
+ // Compute a suitable new capacity limit
+ // If the current capacity is sufficient we use the same capacity
+ if (new_size < curCapacity)
+ newCapacity = curCapacity;
+ else
+ newCapacity = MAX(curCapacity * 2, computeCapacity(new_size+1));
+
+ // Allocate new storage
+ newStorage = new value_type[newCapacity];
+ assert(newStorage);
+ }
+
+ // Copy old data if needed, elsewise reset the new storage.
+ if (keep_old) {
+ assert(_size < newCapacity);
+ memcpy(newStorage, _str, (_size + 1) * sizeof(value_type));
+ } else {
+ _size = 0;
+ newStorage[0] = 0;
+ }
+
+ // Release hold on the old storage ...
+ decRefCount(oldRefCount);
+
+ // ... in favor of the new storage
+ _str = newStorage;
+
+ if (!isStorageIntern()) {
+ // Set the ref count & capacity if we use an external storage.
+ // It is important to do this *after* copying any old content,
+ // else we would override data that has not yet been copied!
+ _extern._refCount = 0;
+ _extern._capacity = newCapacity;
+ }
+}
+
+void U32String::incRefCount() const {
+ assert(!isStorageIntern());
+ if (_extern._refCount == 0) {
+ if (g_refCountPool == 0) {
+ g_refCountPool = new MemoryPool(sizeof(int));
+ assert(g_refCountPool);
+ }
+
+ _extern._refCount = (int *)g_refCountPool->allocChunk();
+ *_extern._refCount = 2;
+ } else {
+ ++(*_extern._refCount);
+ }
+}
+
+void U32String::decRefCount(int *oldRefCount) {
+ if (isStorageIntern())
+ return;
+
+ if (oldRefCount) {
+ --(*oldRefCount);
+ }
+ if (!oldRefCount || *oldRefCount <= 0) {
+ // The ref count reached zero, so we free the string storage
+ // and the ref count storage.
+ if (oldRefCount) {
+ assert(g_refCountPool);
+ g_refCountPool->freeChunk(oldRefCount);
+ }
+ delete[] _str;
+
+ // Even though _str points to a freed memory block now,
+ // we do not change its value, because any code that calls
+ // decRefCount will have to do this afterwards anyway.
+ }
+}
+
+void U32String::initWithCStr(const value_type *str, uint32 len) {
+ assert(str);
+
+ _storage[0] = 0;
+
+ _size = len;
+
+ if (len >= _builtinCapacity) {
+ // Not enough internal storage, so allocate more
+ _extern._capacity = computeCapacity(len+1);
+ _extern._refCount = 0;
+ _str = new value_type[_extern._capacity];
+ assert(_str != 0);
+ }
+
+ // Copy the string into the storage area
+ memmove(_str, str, len * sizeof(value_type));
+ _str[len] = 0;
+}
+
+} // End of namespace Common
diff --git a/common/ustr.h b/common/ustr.h
new file mode 100644
index 0000000000..ab9dac70de
--- /dev/null
+++ b/common/ustr.h
@@ -0,0 +1,194 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef COMMON_USTR_H
+#define COMMON_USTR_H
+
+#include "common/scummsys.h"
+
+namespace Common {
+
+/**
+ * Very simple string class for UTF-32 strings in ScummVM. The main intention
+ * behind this class is to feature a simple way of displaying UTF-32 strings
+ * through the Graphics::Font API.
+ *
+ * Please note that operations like equals, deleteCharacter, toUppercase, etc.
+ * are only very simplified convenience operations. They might not fully work
+ * as you would expect for a proper UTF-32 string class.
+ *
+ * The presence of \0 characters in the string will cause undefined
+ * behavior in some operations.
+ */
+class U32String {
+public:
+ static const uint32 npos = 0xFFFFFFFF;
+
+ typedef uint32 value_type;
+ typedef uint32 unsigned_type;
+private:
+ /**
+ * The size of the internal storage. Increasing this means less heap
+ * allocations are needed, at the cost of more stack memory usage,
+ * and of course lots of wasted memory.
+ */
+ static const uint32 _builtinCapacity = 32;
+
+ /**
+ * Length of the string.
+ */
+ uint32 _size;
+
+ /**
+ * Pointer to the actual string storage. Either points to _storage,
+ * or to a block allocated on the heap via malloc.
+ */
+ value_type *_str;
+
+
+ union {
+ /**
+ * Internal string storage.
+ */
+ value_type _storage[_builtinCapacity];
+ /**
+ * External string storage data -- the refcounter, and the
+ * capacity of the string _str points to.
+ */
+ struct {
+ mutable int *_refCount;
+ uint32 _capacity;
+ } _extern;
+ };
+
+ inline bool isStorageIntern() const {
+ return _str == _storage;
+ }
+
+public:
+ /** Construct a new empty string. */
+ U32String() : _size(0), _str(_storage) { _storage[0] = 0; }
+
+ /** Construct a new string from the given NULL-terminated C string. */
+ explicit U32String(const value_type *str);
+
+ /** Construct a new string containing exactly len characters read from address str. */
+ U32String(const value_type *str, uint32 len);
+
+ /** Construct a new string containing the characters between beginP (including) and endP (excluding). */
+ U32String(const value_type *beginP, const value_type *endP);
+
+ /** Construct a copy of the given string. */
+ U32String(const U32String &str);
+
+ ~U32String();
+
+ U32String &operator=(const U32String &str);
+ U32String &operator+=(const U32String &str);
+ U32String &operator+=(value_type c);
+
+ /**
+ * Equivalence comparison operator.
+ * @see equals
+ */
+ bool operator==(const U32String &x) const { return equals(x); }
+
+ /**
+ * Compares whether two U32String are the same based on memory comparison.
+ * This does *not* do comparison based on canonical equivalence.
+ */
+ bool equals(const U32String &x) const;
+
+ bool contains(value_type x) const;
+
+ inline const value_type *c_str() const { return _str; }
+ inline uint32 size() const { return _size; }
+
+ inline bool empty() const { return (_size == 0); }
+
+ value_type operator[](int idx) const {
+ assert(_str && idx >= 0 && idx < (int)_size);
+ return _str[idx];
+ }
+
+ /**
+ * Removes the value at position p from the string.
+ * Using this on decomposed characters will not remove the whole
+ * character!
+ */
+ void deleteChar(uint32 p);
+
+ /** Clears the string, making it empty. */
+ void clear();
+
+ /**
+ * Convert all characters in the string to lowercase.
+ *
+ * Be aware that this only affects the case of ASCII characters. All
+ * other characters will not be touched at all.
+ */
+ void toLowercase();
+
+ /**
+ * Convert all characters in the string to uppercase.
+ *
+ * Be aware that this only affects the case of ASCII characters. All
+ * other characters will not be touched at all.
+ */
+ void toUppercase();
+
+ uint32 find(const U32String &str, uint32 pos = 0) const;
+
+ typedef value_type * iterator;
+ typedef const value_type * const_iterator;
+
+ iterator begin() {
+ // Since the user could potentially
+ // change the string via the returned
+ // iterator we have to assure we are
+ // pointing to a unique storage.
+ makeUnique();
+
+ return _str;
+ }
+
+ iterator end() {
+ return begin() + size();
+ }
+
+ const_iterator begin() const {
+ return _str;
+ }
+
+ const_iterator end() const {
+ return begin() + size();
+ }
+private:
+ void makeUnique();
+ void ensureCapacity(uint32 new_size, bool keep_old);
+ void incRefCount() const;
+ void decRefCount(int *oldRefCount);
+ void initWithCStr(const value_type *str, uint32 len);
+};
+
+} // End of namespace Common
+
+#endif
diff --git a/common/winexe_ne.cpp b/common/winexe_ne.cpp
index c3698d5fce..8ab7e707bb 100644
--- a/common/winexe_ne.cpp
+++ b/common/winexe_ne.cpp
@@ -187,7 +187,7 @@ uint32 NEResources::getResourceTableOffset() {
static const char *s_resTypeNames[] = {
"", "cursor", "bitmap", "icon", "menu", "dialog", "string",
"font_dir", "font", "accelerator", "rc_data", "msg_table",
- "group_cursor", "group_icon", "", "", "version", "dlg_include",
+ "group_cursor", "", "group_icon", "", "version", "dlg_include",
"", "plug_play", "vxd", "ani_cursor", "ani_icon", "html",
"manifest"
};
diff --git a/common/winexe_ne.h b/common/winexe_ne.h
index f00941412f..3f50b5cc54 100644
--- a/common/winexe_ne.h
+++ b/common/winexe_ne.h
@@ -46,7 +46,7 @@ enum NEResourceType {
kNERCData = 0x0A,
kNEMessageTable = 0x0B,
kNEGroupCursor = 0x0C,
- kNEGroupIcon = 0x0D,
+ kNEGroupIcon = 0x0E,
kNEVersion = 0x10,
kNEDlgInclude = 0x11,
kNEPlugPlay = 0x13,
diff --git a/common/zlib.cpp b/common/zlib.cpp
index 920338e57e..f1a298a9f1 100644
--- a/common/zlib.cpp
+++ b/common/zlib.cpp
@@ -27,6 +27,7 @@
#include "common/ptr.h"
#include "common/util.h"
#include "common/stream.h"
+#include "common/textconsole.h"
#if defined(USE_ZLIB)
#ifdef __SYMBIAN32__
@@ -158,10 +159,11 @@ protected:
uint32 _pos;
uint32 _origSize;
bool _eos;
+ bool _shownBackwardSeekingWarning;
public:
- GZipReadStream(SeekableReadStream *w, uint32 knownSize = 0) : _wrapped(w), _stream() {
+ GZipReadStream(SeekableReadStream *w, uint32 knownSize = 0) : _wrapped(w), _stream(), _shownBackwardSeekingWarning(false) {
assert(w != 0);
// Verify file header is correct
@@ -241,13 +243,17 @@ public:
}
bool seek(int32 offset, int whence = SEEK_SET) {
int32 newPos = 0;
- assert(whence != SEEK_END); // SEEK_END not supported
switch (whence) {
case SEEK_SET:
newPos = offset;
break;
case SEEK_CUR:
newPos = _pos + offset;
+ break;
+ case SEEK_END:
+ // NOTE: This can be an expensive operation (see below).
+ newPos = size() + offset;
+ break;
}
assert(newPos >= 0);
@@ -256,9 +262,15 @@ public:
// To search backward, we have to restart the whole decompression
// from the start of the file. A rather wasteful operation, best
// to avoid it. :/
-#if DEBUG
- warning("Backward seeking in GZipReadStream detected");
-#endif
+
+ if (!_shownBackwardSeekingWarning) {
+ // We only throw this warning once per stream, to avoid
+ // getting the console swarmed with warnings when consecutive
+ // seeks are made.
+ warning("Backward seeking in GZipReadStream detected");
+ _shownBackwardSeekingWarning = true;
+ }
+
_pos = 0;
_wrapped->seek(0, SEEK_SET);
_zlibErr = inflateReset(&_stream);
diff --git a/configure b/configure
index 9761544652..a2022c113a 100755
--- a/configure
+++ b/configure
@@ -97,7 +97,9 @@ add_feature() {
_srcdir=`dirname $0`
# Read list of engines
-. $_srcdir/engines/configure.engines
+for i in $_srcdir/engines/*/configure.engine; do
+ . "$i"
+done
#
# Default settings
@@ -124,7 +126,7 @@ _opengl=auto
_opengles=auto
_readline=auto
_freetype2=auto
-_taskbar=yes
+_taskbar=auto
_updates=no
_libunity=auto
# Default option behavior yes/no
@@ -864,6 +866,7 @@ Special configuration feature:
motomagx for MotoMAGX
n64 for Nintendo 64
openpandora for OpenPandora
+ ouya for OUYA
ps2 for PlayStation 2
ps3 for PlayStation 3
psp for PlayStation Portable
@@ -1268,7 +1271,7 @@ get_system_exe_extension $guessed_host
NATIVEEXEEXT=$_exeext
case $_host in
-android | android-v7a)
+android | android-v7a | ouya)
_host_os=android
_host_cpu=arm
_host_alias=arm-linux-androideabi
@@ -1302,7 +1305,7 @@ ds)
gamecube)
_host_os=gamecube
_host_cpu=ppc
- _host_alias=powerpc-gekko
+ _host_alias=powerpc-eabi
;;
gp2x)
_host_os=gph-linux
@@ -1425,7 +1428,7 @@ webos)
wii)
_host_os=wii
_host_cpu=ppc
- _host_alias=powerpc-gekko
+ _host_alias=powerpc-eabi
;;
wince)
_host_os=wince
@@ -2043,12 +2046,21 @@ case $_host_os in
CXXFLAGS="$CXXFLAGS -march=armv5te"
CXXFLAGS="$CXXFLAGS -mtune=xscale"
CXXFLAGS="$CXXFLAGS -msoft-float"
+ ABI="armeabi"
;;
android-v7a)
CXXFLAGS="$CXXFLAGS -march=armv7-a"
CXXFLAGS="$CXXFLAGS -mfloat-abi=softfp"
CXXFLAGS="$CXXFLAGS -mfpu=vfp"
LDFLAGS="$LDFLAGS -Wl,--fix-cortex-a8"
+ ABI="armeabi-v7a"
+ ;;
+ ouya)
+ CXXFLAGS="$CXXFLAGS -march=armv7-a"
+ CXXFLAGS="$CXXFLAGS -mtune=cortex-a9"
+ CXXFLAGS="$CXXFLAGS -mfloat-abi=softfp"
+ CXXFLAGS="$CXXFLAGS -mfpu=neon"
+ ABI="armeabi-v7a"
;;
esac
CXXFLAGS="$CXXFLAGS --sysroot=$ANDROID_NDK/platforms/android-4/arch-arm"
@@ -2074,6 +2086,8 @@ case $_host_os in
CXXFLAGS="$CXXFLAGS -Wno-psabi"
LDFLAGS="$LDFLAGS --sysroot=$ANDROID_NDK/platforms/android-4/arch-arm"
LDFLAGS="$LDFLAGS -mthumb-interwork"
+ LDFLAGS="$LDFLAGS -L$ANDROID_NDK/sources/cxx-stl/gnu-libstdc++/`$CXX -dumpversion`/libs/$ABI/"
+ LIBS="$LIBS -lsupc++"
add_line_to_config_mk "ANDROID_SDK = $ANDROID_SDK"
_seq_midi=no
;;
@@ -2338,7 +2352,7 @@ if test -n "$_host"; then
# Cross-compiling mode - add your target here if needed
echo "Cross-compiling to $_host"
case "$_host" in
- android | android-v7a)
+ android | android-v7a | ouya)
# we link a .so as default
LDFLAGS="$LDFLAGS -shared"
LDFLAGS="$LDFLAGS -Wl,-Bsymbolic,--no-undefined"
@@ -2414,6 +2428,8 @@ if test -n "$_host"; then
CXXFLAGS="$CXXFLAGS -fschedule-insns2"
CXXFLAGS="$CXXFLAGS -fomit-frame-pointer"
CXXFLAGS="$CXXFLAGS -fdelete-null-pointer-checks"
+ # no-delayed-branch is a workaround for GCC bug #42841 - "SH: Assembler complains pcrel too far."
+ CXXFLAGS="$CXXFLAGS -fno-delayed-branch"
_backend="dc"
_build_scalers=no
_mad=yes
@@ -2674,7 +2690,6 @@ if test -n "$_host"; then
_backend="tizen"
_port_mk="backends/platform/tizen/tizen.mk"
_arm_asm=yes
- _taskbar=no
_build_scalers=no
_seq_midi=no
_mt32emu=no
@@ -3410,10 +3425,10 @@ int main(void) {
return 0;
}
EOF
- cc_check $PNG_CFLAGS $PNG_LIBS -lpng && _png=yes
+ cc_check $PNG_CFLAGS $PNG_LIBS -lpng -lz && _png=yes
fi
if test "$_png" = yes ; then
- LIBS="$LIBS $PNG_LIBS -lpng"
+ LIBS="$LIBS $PNG_LIBS -lpng -lz"
INCLUDES="$INCLUDES $PNG_CFLAGS"
fi
define_in_config_if_yes "$_png" 'USE_PNG'
@@ -3658,6 +3673,25 @@ fi
if test "$_readline" = yes ; then
LIBS="$LIBS $READLINE_LIBS $_READLINE_LIBS"
INCLUDES="$INCLUDES $READLINE_CFLAGS"
+
+ #
+ # Check the type of rl_completion_entry_function.
+ # It can be int(*)(const char *, int) or char *(*)(const char *, int).
+ #
+ cat > $TMPC << EOF
+#include <stdio.h>
+#include <readline/readline.h>
+#include <readline/history.h>
+
+int readline_completionFunction(const char *, int);
+
+int main(void) {
+ char *x = readline("");
+ rl_completion_entry_function = &readline_completionFunction;
+}
+EOF
+ cc_check -c && add_line_to_config_h '#define USE_READLINE_INT_COMPLETION'
+
fi
define_in_config_h_if_yes "$_readline" 'USE_READLINE'
@@ -3696,7 +3730,7 @@ if test "$_libunity" = yes ; then
LIBS="$LIBS $LIBUNITY_LIBS"
INCLUDES="$INCLUDES $LIBUNITY_CFLAGS"
fi
-define_in_config_h_if_yes "$_libunity" 'USE_TASKBAR_UNITY'
+define_in_config_h_if_yes "$_libunity" 'USE_UNITY'
fi
echo "$_libunity"
@@ -3958,24 +3992,27 @@ fi
# Check whether to build taskbar integration support
#
echo_n "Building taskbar integration support... "
-define_in_config_if_yes $_taskbar 'USE_TASKBAR'
-if test "$_taskbar" = yes; then
+if test "$_taskbar" = "no"; then
+ echo "no"
+else
case $_host_os in
mingw*)
LIBS="$LIBS -lole32 -luuid"
echo "win32"
+ _taskbar=yes
;;
*)
if test "$_libunity" = yes; then
echo "unity"
+ _taskbar=yes
else
- echo "$_taskbar"
+ echo "no"
+ _taskbar=no
fi
;;
esac
-else
- echo "$_taskbar"
fi
+define_in_config_if_yes $_taskbar 'USE_TASKBAR'
#
# Check whether to build Bink video support
@@ -4190,8 +4227,18 @@ for engine in $_engines; do
fi
done
-# Prepare the information to be shown
+# Sort engines to place our headline engine at start...
+# No technical reason, just historical convention
+headline_engine=scumm
+_sorted_engines="${headline_engine}"
for engine in $_engines; do
+ if test "${engine}" != "${headline_engine}" ; then
+ _sorted_engines="${_sorted_engines} ${engine}"
+ fi
+done
+
+# Prepare the information to be shown
+for engine in $_sorted_engines; do
if test "`get_engine_sub $engine`" = "no" ; then
# It's a main engine
prepare_engine_build_strings $engine
@@ -4373,3 +4420,59 @@ include \$(srcdir)/Makefile
EOF
fi
+
+# Ensure engines folder exists prior to trying to generate
+# files into it (used for out-of-tree-builds)
+mkdir -p engines
+
+echo "Creating engines/engines.mk"
+cat > engines/engines.mk << EOF
+# This file is automatically generated by configure
+# DO NOT EDIT MANUALLY
+# This file is being included by "Makefile.common"
+EOF
+
+for engine in $_sorted_engines; do
+ j=`echo $engine | tr '[:lower:]' '[:upper:]'`
+ if test "`get_engine_sub $engine`" = "no" ; then
+ # main engine
+ cat >> engines/engines.mk << EOF
+
+ifdef ENABLE_$j
+DEFINES += -DENABLE_$j=\$(ENABLE_$j)
+MODULES += engines/$engine
+EOF
+
+ for subeng in `get_engine_subengines $engine` ; do
+ k=`echo $subeng | tr '[:lower:]' '[:upper:]'`
+ cat >> engines/engines.mk << EOF
+
+ifdef ENABLE_$k
+DEFINES += -DENABLE_$k
+endif
+EOF
+ done
+
+ cat >> engines/engines.mk << EOF
+endif
+EOF
+ fi
+done
+
+echo "Creating engines/plugins_table.h"
+cat > engines/plugins_table.h << EOF
+/* This file is automatically generated by configure */
+/* DO NOT EDIT MANUALLY */
+// This file is being included by "base/plugins.cpp"
+EOF
+
+for engine in $_sorted_engines; do
+ if test "`get_engine_sub $engine`" = "no" ; then
+ j=`echo $engine | tr '[:lower:]' '[:upper:]'`
+ cat >> engines/plugins_table.h << EOF
+#if PLUGIN_ENABLED_STATIC($j)
+LINK_PLUGIN($j)
+#endif
+EOF
+ fi
+done
diff --git a/devtools/convbdf.cpp b/devtools/convbdf.cpp
index c8b1fb7d6d..69728eb9fd 100644
--- a/devtools/convbdf.cpp
+++ b/devtools/convbdf.cpp
@@ -20,6 +20,10 @@
*
*/
+#ifndef __has_feature // Optional of course.
+ #define __has_feature(x) 0 // Compatibility with non-clang compilers.
+#endif
+
#include <fstream>
#include <string>
#include <stdio.h>
diff --git a/devtools/create_mortdat/create_mortdat.cpp b/devtools/create_mortdat/create_mortdat.cpp
index 5a491eea2f..693e277b91 100644
--- a/devtools/create_mortdat/create_mortdat.cpp
+++ b/devtools/create_mortdat/create_mortdat.cpp
@@ -33,10 +33,6 @@
#undef main
#endif // main
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
#include "common/endian.h"
#include "create_mortdat.h"
#include "enginetext.h"
@@ -214,7 +210,7 @@ void writeMenuData(const char *menuData, int languageId) {
outputFile.writeByte(languageId);
// Write each 8-characters block as a byte (one bit per character)
// ' ' -> 0, anything else -> 1
- byte value;
+ byte value = 0;
int valueCpt = 0;
const char* str = menuData;
while (*str != 0) {
diff --git a/devtools/create_neverhood/create_neverhood.cpp b/devtools/create_neverhood/create_neverhood.cpp
index 446ee5ec3b..a37ff99ca9 100644
--- a/devtools/create_neverhood/create_neverhood.cpp
+++ b/devtools/create_neverhood/create_neverhood.cpp
@@ -30,8 +30,8 @@
#undef main
#endif // main
-#include <vector>
#include "create_neverhood.h"
+#include <vector>
#include "md5.h"
#include "tables.h"
diff --git a/devtools/create_project/codeblocks.cpp b/devtools/create_project/codeblocks.cpp
index ec003df2d5..442a2b0025 100644
--- a/devtools/create_project/codeblocks.cpp
+++ b/devtools/create_project/codeblocks.cpp
@@ -120,6 +120,7 @@ void CodeBlocksProvider::createProjectFile(const std::string &name, const std::s
"\t\t\t\t\t<Add directory=\"..\\..\\engines\" />\n"
"\t\t\t\t\t<Add directory=\"..\\..\\common\" />\n"
"\t\t\t\t\t<Add directory=\"..\\..\" />\n"
+ "\t\t\t\t\t<Add directory=\".\\\" />\n"
"\t\t\t\t</Compiler>\n";
//////////////////////////////////////////////////////////////////////////
diff --git a/devtools/create_project/config.h b/devtools/create_project/config.h
index 1a66edff93..63bf3dee26 100644
--- a/devtools/create_project/config.h
+++ b/devtools/create_project/config.h
@@ -27,11 +27,12 @@
#define PROJECT_NAME "scummvm" // Used for folders, icons, resources and project/solution name
#define LIBS_DEFINE "SCUMMVM_LIBS" // Name of the include environment variable
#define REVISION_DEFINE "SCUMMVM_INTERNAL_REVISION"
+#define FIRST_ENGINE "scumm" // Name of the engine which should be sorted as first element
#define ENABLE_LANGUAGE_EXTENSIONS "" // Comma separated list of projects that need language extensions
#define DISABLE_EDIT_AND_CONTINUE "tinsel,tony,scummvm" // Comma separated list of projects that need Edit&Continue to be disabled for co-routine support (the main project is automatically added)
//#define ADDITIONAL_LIBRARY "" // Add a single library to the list of externally linked libraries
-#define NEEDS_RTTI 0 // Enable RTTI globally
+#define NEEDS_RTTI 1 // Enable RTTI globally
#endif // TOOLS_CREATE_PROJECT_CONFIG_H
diff --git a/devtools/create_project/create_project.cpp b/devtools/create_project/create_project.cpp
index e013377241..9d7ed532cb 100644
--- a/devtools/create_project/create_project.cpp
+++ b/devtools/create_project/create_project.cpp
@@ -43,6 +43,7 @@
#include <stack>
#include <algorithm>
#include <iomanip>
+#include <iterator>
#include <cstring>
#include <cstdlib>
@@ -59,6 +60,7 @@
#include <sys/param.h>
#include <sys/stat.h>
#include <dirent.h>
+#include <errno.h>
#endif
namespace {
@@ -81,22 +83,6 @@ std::string unifyPath(const std::string &path);
* @param exe Name of the executable.
*/
void displayHelp(const char *exe);
-
-/**
- * Structure for describing an FSNode. This is a very minimalistic
- * description, which includes everything we need.
- * It only contains the name of the node and whether it is a directory
- * or not.
- */
-struct FSNode {
- FSNode() : name(), isDirectory(false) {}
- FSNode(const std::string &n, bool iD) : name(n), isDirectory(iD) {}
-
- std::string name; ///< Name of the file system node
- bool isDirectory; ///< Whether it is a directory or not
-};
-
-typedef std::list<FSNode> FileList;
} // End of anonymous namespace
enum ProjectType {
@@ -128,7 +114,7 @@ int main(int argc, char *argv[]) {
setup.filePrefix = setup.srcDir;
setup.outputDir = '.';
- setup.engines = parseConfigure(setup.srcDir);
+ setup.engines = parseEngines(setup.srcDir);
if (setup.engines.empty()) {
std::cout << "WARNING: No engines found in configure file or configure file missing in \"" << setup.srcDir << "\"\n";
@@ -672,47 +658,70 @@ void displayHelp(const char *exe) {
}
/**
- * Try to parse a given line and create an engine definition
- * out of the result.
+ * Parse the configure.engine file of a given engine directory and return a
+ * list of all defined engines.
*
- * This may take *any* input line, when the line is not used
- * to define an engine the result of the function will be "false".
+ * @param engineDir The directory of the engine.
+ * @return The list of all defined engines.
+ */
+EngineDescList parseEngineConfigure(const std::string &engineDir);
+
+/**
+ * Compares two FSNode entries in a strict-weak fashion based on the name.
*
- * Note that the contents of "engine" are undefined, when this
- * function returns "false".
+ * @param left The first operand.
+ * @param right The second operand.
+ * @return "true" when the name of the left operand is strictly smaller than
+ * the name of the second operand. "false" otherwise.
+ */
+bool compareFSNode(const CreateProjectTool::FSNode &left, const CreateProjectTool::FSNode &right);
+
+#ifdef FIRST_ENGINE
+/**
+ * Compares two FSNode entries in a strict-weak fashion based on engine name
+ * order.
*
- * @param line Text input line.
- * @param engine Reference to an object, where the engine information
- * is to be stored in.
- * @return "true", when parsing succeeded, "false" otherwise.
+ * @param left The first operand.
+ * @param right The second operand.
+ * @return "true" when the name of the left operand is strictly smaller than
+ * the name of the second operand. "false" otherwise.
*/
-bool parseEngine(const std::string &line, EngineDesc &engine);
+bool compareEngineNames(const CreateProjectTool::FSNode &left, const CreateProjectTool::FSNode &right);
+#endif
} // End of anonymous namespace
-EngineDescList parseConfigure(const std::string &srcDir) {
- std::string configureFile = srcDir + "/engines/configure.engines";
+EngineDescList parseEngines(const std::string &srcDir) {
+ using CreateProjectTool::FileList;
+ using CreateProjectTool::listDirectory;
- std::ifstream configure(configureFile.c_str());
- if (!configure)
- return EngineDescList();
+ EngineDescList engineList;
- std::string line;
- EngineDescList engines;
+ FileList engineFiles = listDirectory(srcDir + "/engines/");
- for (;;) {
- std::getline(configure, line);
- if (configure.eof())
- break;
+#ifdef FIRST_ENGINE
+ // In case we want to sort an engine to the front of the list we will
+ // use some manual sorting predicate which assures that.
+ engineFiles.sort(&compareEngineNames);
+#else
+ // Otherwise, we simply sort the file list alphabetically this allows
+ // for a nicer order in --list-engines output, for example.
+ engineFiles.sort(&compareFSNode);
+#endif
- if (configure.fail())
- error("Failed while reading from " + configureFile);
+ for (FileList::const_iterator i = engineFiles.begin(), end = engineFiles.end(); i != end; ++i) {
+ // Each engine requires its own sub directory thus we will skip all
+ // non directory file nodes here.
+ if (!i->isDirectory) {
+ continue;
+ }
- EngineDesc desc;
- if (parseEngine(line, desc))
- engines.push_back(desc);
+ // Retrieve all engines defined in this sub directory and add them to
+ // the list of all engines.
+ EngineDescList list = parseEngineConfigure(srcDir + "/engines/" + i->name);
+ engineList.splice(engineList.end(), list);
}
- return engines;
+ return engineList;
}
bool isSubEngine(const std::string &name, const EngineDescList &engines) {
@@ -777,6 +786,21 @@ StringList getEngineDefines(const EngineDescList &engines) {
}
namespace {
+/**
+ * Try to parse a given line and create an engine definition
+ * out of the result.
+ *
+ * This may take *any* input line, when the line is not used
+ * to define an engine the result of the function will be "false".
+ *
+ * Note that the contents of "engine" are undefined, when this
+ * function returns "false".
+ *
+ * @param line Text input line.
+ * @param engine Reference to an object, where the engine information
+ * is to be stored in.
+ * @return "true", when parsing succeeded, "false" otherwise.
+ */
bool parseEngine(const std::string &line, EngineDesc &engine) {
// Format:
// add_engine engine_name "Readable Description" enable_default ["SubEngineList"]
@@ -799,6 +823,48 @@ bool parseEngine(const std::string &line, EngineDesc &engine) {
return true;
}
+
+EngineDescList parseEngineConfigure(const std::string &engineDir) {
+ std::string configureFile = engineDir + "/configure.engine";
+
+ std::ifstream configure(configureFile.c_str());
+ if (!configure)
+ return EngineDescList();
+
+ std::string line;
+ EngineDescList engines;
+
+ for (;;) {
+ std::getline(configure, line);
+ if (configure.eof())
+ break;
+
+ if (configure.fail())
+ error("Failed while reading from " + configureFile);
+
+ EngineDesc desc;
+ if (parseEngine(line, desc))
+ engines.push_back(desc);
+ }
+
+ return engines;
+}
+
+bool compareFSNode(const CreateProjectTool::FSNode &left, const CreateProjectTool::FSNode &right) {
+ return left.name < right.name;
+}
+
+#ifdef FIRST_ENGINE
+bool compareEngineNames(const CreateProjectTool::FSNode &left, const CreateProjectTool::FSNode &right) {
+ if (left.name == FIRST_ENGINE) {
+ return right.name != FIRST_ENGINE;
+ } else if (right.name == FIRST_ENGINE) {
+ return false;
+ } else {
+ return compareFSNode(left, right);
+ }
+}
+#endif
} // End of anonymous namespace
TokenList tokenize(const std::string &input, char separator) {
@@ -1048,13 +1114,6 @@ bool compareNodes(const FileNode *l, const FileNode *r) {
}
}
-/**
- * Returns a list of all files and directories in the specified
- * path.
- *
- * @param dir Directory which should be listed.
- * @return List of all children.
- */
FileList listDirectory(const std::string &dir) {
FileList result;
#ifdef USE_WIN32_API
@@ -1095,6 +1154,32 @@ FileList listDirectory(const std::string &dir) {
return result;
}
+void createDirectory(const std::string &dir) {
+#if defined(_WIN32) || defined(WIN32)
+ if (!CreateDirectory(dir.c_str(), NULL)) {
+ if (GetLastError() != ERROR_ALREADY_EXISTS) {
+ error("Could not create folder \"" + dir + "\"");
+ }
+ }
+#else
+ if (mkdir(dir.c_str(), 0777) == -1) {
+ if (errno == EEXIST) {
+ // Try to open as a folder (might be a file / symbolic link)
+ DIR *dirp = opendir(dir.c_str());
+ if (dirp == NULL) {
+ error("Could not create folder \"" + dir + "\"");
+ } else {
+ // The folder exists, just close the stream and return
+ closedir(dirp);
+ }
+ } else {
+ error("Could not create folder \"" + dir + "\"");
+ }
+ }
+#endif
+
+}
+
/**
* Scans the specified directory against files, which should be included
* in the project files. It will not include files present in the exclude list.
@@ -1242,6 +1327,12 @@ void ProjectProvider::createProject(BuildSetup &setup) {
// Create other misc. build files
createOtherBuildFiles(setup);
+
+ // In case we create the main ScummVM project files we will need to
+ // generate engines/plugins_table.h too.
+ if (!setup.tests && !setup.devTools) {
+ createEnginePluginsTable(setup);
+ }
}
ProjectProvider::UUIDMap ProjectProvider::createUUIDMap(const BuildSetup &setup) const {
@@ -1569,6 +1660,37 @@ void ProjectProvider::createModuleList(const std::string &moduleDir, const Strin
error("Malformed file " + moduleMkFile);
}
+void ProjectProvider::createEnginePluginsTable(const BuildSetup &setup) {
+ // First we need to create the "engines" directory.
+ createDirectory(setup.outputDir + "/engines");
+
+ // Then, we can generate the actual "plugins_table.h" file.
+ const std::string enginePluginsTableFile = setup.outputDir + "/engines/plugins_table.h";
+ std::ofstream enginePluginsTable(enginePluginsTableFile.c_str());
+ if (!enginePluginsTable) {
+ error("Could not open \"" + enginePluginsTableFile + "\" for writing");
+ }
+
+ enginePluginsTable << "/* This file is automatically generated by create_project */\n"
+ << "/* DO NOT EDIT MANUALLY */\n"
+ << "// This file is being included by \"base/plugins.cpp\"\n";
+
+ for (EngineDescList::const_iterator i = setup.engines.begin(), end = setup.engines.end(); i != end; ++i) {
+ // We ignore all sub engines here because they require no special
+ // handling.
+ if (isSubEngine(i->name, setup.engines)) {
+ continue;
+ }
+
+ // Make the engine name all uppercase.
+ std::string engineName;
+ std::transform(i->name.begin(), i->name.end(), std::back_inserter(engineName), toupper);
+
+ enginePluginsTable << "#if PLUGIN_ENABLED_STATIC(" << engineName << ")\n"
+ << "LINK_PLUGIN(" << engineName << ")\n"
+ << "#endif\n";
+ }
+}
} // End of anonymous namespace
void error(const std::string &message) {
diff --git a/devtools/create_project/create_project.h b/devtools/create_project/create_project.h
index 5325bf6d1b..459342a67d 100644
--- a/devtools/create_project/create_project.h
+++ b/devtools/create_project/create_project.h
@@ -23,6 +23,10 @@
#ifndef TOOLS_CREATE_PROJECT_H
#define TOOLS_CREATE_PROJECT_H
+#ifndef __has_feature // Optional of course.
+ #define __has_feature(x) 0 // Compatibility with non-clang compilers.
+#endif
+
#include <map>
#include <list>
#include <string>
@@ -98,16 +102,17 @@ struct EngineDesc {
typedef std::list<EngineDesc> EngineDescList;
/**
- * This function parses the project configure file and creates a list
- * of available engines.
+ * This function parses the project directory and creates a list of
+ * available engines.
*
* It will also automatically setup the default build state (enabled
- * or disabled) to the state specified in the "configure" file.
+ * or disabled) to the state specified in the individual configure.engine
+ * files.
*
* @param srcDir Path to the root of the project source.
* @return List of available engines.
*/
-EngineDescList parseConfigure(const std::string &srcDir);
+EngineDescList parseEngines(const std::string &srcDir);
/**
* Checks whether the specified engine is a sub engine. To determine this
@@ -259,6 +264,22 @@ void NORETURN_PRE error(const std::string &message) NORETURN_POST;
namespace CreateProjectTool {
/**
+ * Structure for describing an FSNode. This is a very minimalistic
+ * description, which includes everything we need.
+ * It only contains the name of the node and whether it is a directory
+ * or not.
+ */
+struct FSNode {
+ FSNode() : name(), isDirectory(false) {}
+ FSNode(const std::string &n, bool iD) : name(n), isDirectory(iD) {}
+
+ std::string name; ///< Name of the file system node
+ bool isDirectory; ///< Whether it is a directory or not
+};
+
+typedef std::list<FSNode> FileList;
+
+/**
* Gets a proper sequence of \t characters for the given
* indentation level.
*
@@ -311,6 +332,22 @@ bool producesObjectFile(const std::string &fileName);
std::string toString(int num);
/**
+ * Returns a list of all files and directories in the specified
+ * path.
+ *
+ * @param dir Directory which should be listed.
+ * @return List of all children.
+ */
+FileList listDirectory(const std::string &dir);
+
+/**
+ * Create a directory at the given path.
+ *
+ * @param dir The path to create.
+ */
+void createDirectory(const std::string &dir);
+
+/**
* Structure representing a file tree. This contains two
* members: name and children. "name" holds the name of
* the node. "children" does contain all the node's children.
@@ -470,6 +507,15 @@ protected:
* @return A new UUID as string.
*/
std::string createUUID() const;
+
+private:
+ /**
+ * This creates the engines/plugins_table.h file required for building
+ * ScummVM.
+ *
+ * @param setup Description of the desired build.
+ */
+ void createEnginePluginsTable(const BuildSetup &setup);
};
} // End of CreateProjectTool namespace
diff --git a/devtools/create_project/msbuild.cpp b/devtools/create_project/msbuild.cpp
index 0d68b2e9c9..018a04370f 100644
--- a/devtools/create_project/msbuild.cpp
+++ b/devtools/create_project/msbuild.cpp
@@ -360,7 +360,7 @@ void MSBuildProvider::outputGlobalPropFile(const BuildSetup &setup, std::ofstrea
"\t\t<ClCompile>\n"
"\t\t\t<DisableLanguageExtensions>true</DisableLanguageExtensions>\n"
"\t\t\t<DisableSpecificWarnings>" << warnings << ";%(DisableSpecificWarnings)</DisableSpecificWarnings>\n"
- "\t\t\t<AdditionalIncludeDirectories>$(" << LIBS_DEFINE << ")\\include;" << prefix << ";" << prefix << "\\engines;" << (setup.tests ? prefix + "\\test\\cxxtest;" : "") << "$(TargetDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n"
+ "\t\t\t<AdditionalIncludeDirectories>$(" << LIBS_DEFINE << ")\\include;.;" << prefix << ";" << prefix << "\\engines;" << (setup.tests ? prefix + "\\test\\cxxtest;" : "") << "$(TargetDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n"
"\t\t\t<PreprocessorDefinitions>" << definesList << "%(PreprocessorDefinitions)</PreprocessorDefinitions>\n"
"\t\t\t<ExceptionHandling>" << ((setup.devTools || setup.tests) ? "Sync" : "") << "</ExceptionHandling>\n";
@@ -434,8 +434,11 @@ void MSBuildProvider::createBuildProp(const BuildSetup &setup, bool isRelease, b
"\t\t\t<DebugInformationFormat>" << (isWin32 ? "EditAndContinue" : "ProgramDatabase") << "</DebugInformationFormat>\n" // For x64 format Edit and continue is not supported, thus we default to Program Database
"\t\t\t<EnablePREfast>" << (configuration == "Analysis" ? "true" : "false") << "</EnablePREfast>\n";
- if (configuration == "LLVM")
- properties << "\t\t\t<AdditionalOptions>-Wno-microsoft -Wno-long-long -Wno-multichar -Wno-unknown-pragmas -Wno-reorder -Wpointer-arith -Wcast-qual -Wshadow -Wnon-virtual-dtor -Wwrite-strings -Wno-conversion -Wno-shorten-64-to-32 -Wno-sign-compare -Wno-four-char-constants -Wno-nested-anon-types %(AdditionalOptions)</AdditionalOptions>\n";
+ if (configuration == "LLVM") {
+ // FIXME The LLVM cl wrapper does not seem to work properly with the $(TargetDir) path so we hard-code the build folder until the issue is resolved
+ properties << "\t\t\t<AdditionalIncludeDirectories>" << configuration << outputBitness <<";%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n"
+ "\t\t\t<AdditionalOptions>-Wno-microsoft -Wno-long-long -Wno-multichar -Wno-unknown-pragmas -Wno-reorder -Wpointer-arith -Wcast-qual -Wshadow -Wnon-virtual-dtor -Wwrite-strings -Wno-conversion -Wno-shorten-64-to-32 -Wno-sign-compare -Wno-four-char-constants -Wno-nested-anon-types -Qunused-arguments %(AdditionalOptions)</AdditionalOptions>\n";
+ }
properties << "\t\t</ClCompile>\n"
"\t\t<Link>\n"
@@ -521,6 +524,7 @@ void MSBuildProvider::writeFileListToProject(const FileNode &dir, std::ofstream
outputNasmCommand(projectFile, "Debug", (isDuplicate ? (*entry).prefix : ""));
outputNasmCommand(projectFile, "Analysis", (isDuplicate ? (*entry).prefix : ""));
outputNasmCommand(projectFile, "Release", (isDuplicate ? (*entry).prefix : ""));
+ outputNasmCommand(projectFile, "LLVM", (isDuplicate ? (*entry).prefix : ""));
projectFile << "\t\t</CustomBuild>\n";
}
diff --git a/devtools/create_project/scripts/install-natvis.bat b/devtools/create_project/scripts/install-natvis.bat
new file mode 100644
index 0000000000..62186df7bf
--- /dev/null
+++ b/devtools/create_project/scripts/install-natvis.bat
@@ -0,0 +1,41 @@
+@echo off
+echo Installing Visual Studio debugger integration...
+
+REM On 2000 & XP, the folder is "My Documents" but VS 2012 is not supported on those OSes
+SET DOCUMENTS="%USERPROFILE%\Documents"
+set FOUND=0
+
+REM Set current folder
+cd /d %~dp0
+
+:INSTALL_VS11
+SET FOLDER="%DOCUMENTS%\Visual Studio 2012"
+IF EXIST %FOLDER% (
+ echo Visual Studio 2012
+ copy scummvm.natvis %FOLDER%\Visualizers
+ IF NOT %ERRORLEVEL% == 0 GOTO FAILED
+ SET FOUND=1
+)
+
+:INSTALL_VS12
+SET FOLDER="%DOCUMENTS%\Visual Studio 2013"
+IF EXIST %FOLDER% (
+ echo Visual Studio 2013
+ copy scummvm.natvis %FOLDER%\Visualizers
+ IF NOT %ERRORLEVEL% == 0 GOTO FAILED
+ SET FOUND=1
+)
+
+IF %FOUND% == 1 goto SUCCESS
+echo Failed to find Visual Studio user folder.
+
+:SUCCESS
+echo.
+echo Done!
+goto END
+
+:FAILED
+echo Failed to install visualization file
+
+:END
+pause
diff --git a/devtools/create_project/scripts/scummvm.natvis b/devtools/create_project/scripts/scummvm.natvis
new file mode 100644
index 0000000000..995668690e
--- /dev/null
+++ b/devtools/create_project/scripts/scummvm.natvis
@@ -0,0 +1,91 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+ Debug visualizers for a few common ScummVM types for Visual Studio 2012 and up.
+
+ To use, copy this file into Documents\Visual Studio 20xx\Visualizers.
+
+ Known issues:
+
+ * Lists appear to be infinite (the same elements repeat over and over again).
+ Unfortunately, Lists don't store length information, and it's not possible to
+ detect whether a Node is the last one by the Node itself.
+
+ * In HashMaps, missing and dummy nodes are shown along with the useful ones.
+-->
+
+<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
+ <UIVisualizer ServiceId="{A452AFEA-3DF6-46BB-9177-C0B08F318025}" Id="1" MenuName="Add to Image Watch"/>
+
+ <Type Name="Graphics::Surface">
+ <UIVisualizer ServiceId="{A452AFEA-3DF6-46BB-9177-C0B08F318025}" Id="1" />
+ </Type>
+
+ <Type Name="Graphics::Surface">
+ <Expand>
+ <Synthetic Name="[type]">
+ <DisplayString>UINT8</DisplayString>
+ </Synthetic>
+ <Item Name="[channels]" Condition="format.bytesPerPixel==1">1</Item>
+ <Item Name="[channels]" Condition="format.bytesPerPixel==2">2</Item>
+ <Synthetic Name="[channels]" Condition="format.bytesPerPixel==4">
+ <DisplayString>RGBA</DisplayString>
+ </Synthetic>
+ <Item Name="[width]">w</Item>
+ <Item Name="[height]">h</Item>
+ <Item Name="[stride]">pitch</Item>
+ <Item Name="[data]">pixels</Item>
+ </Expand>
+ </Type>
+
+ <Type Name="Common::Array&lt;*&gt;">
+ <DisplayString>{{size = {_size}}}</DisplayString>
+ <Expand>
+ <Item Name="[size]">_size</Item>
+ <Item Name="[capacity]">_capacity</Item>
+ <ArrayItems>
+ <Size>_size</Size>
+ <ValuePointer>_storage</ValuePointer>
+ </ArrayItems>
+ </Expand>
+ </Type>
+
+ <Type Name="Common::HashMap&lt;*,*,*,*&gt;">
+ <DisplayString>{{ size = {_size} }}</DisplayString>
+ <Expand>
+ <Item Name="[size]">_size</Item>
+ <Item Name="[capacity]">_mask + 1</Item>
+ <Item Name="[deleted]">_deleted</Item>
+ <IndexListItems>
+ <Size>_mask + 1</Size>
+ <ValueNode Condition="_storage[$i] &amp;&amp; _storage[$i] != (Common::HashMap&lt;$T1,$T2,$T3,$T4&gt;::Node *)1">*_storage[$i]</ValueNode>
+ </IndexListItems>
+ </Expand>
+ </Type>
+
+ <Type Name="Common::List&lt;*&gt;">
+ <DisplayString Condition="&amp;_anchor == _anchor._next">{{ empty }}</DisplayString>
+ <DisplayString Condition="&amp;_anchor != _anchor._next">{{ non-empty }}</DisplayString>
+ <Expand>
+ <LinkedListItems Condition="&amp;_anchor != _anchor._next">
+ <HeadPointer>_anchor._next</HeadPointer>
+ <NextPointer>_next</NextPointer>
+ <ValueNode>((Common::ListInternal::Node&lt;$T1&gt;*)this)->_data</ValueNode>
+ </LinkedListItems>
+ </Expand>
+ </Type>
+
+ <Type Name="Common::String">
+ <DisplayString>{_str,[_size]}</DisplayString>
+ <StringView>_str,[_size]</StringView>
+ <Expand>
+ <Item Name="[size]">_size</Item>
+ <Item Condition="_str != _storage" Name="[capacity]">_extern._capacity</Item>
+ <Item Condition="_str != _storage" Name="[refCount]">*_extern._refCount</Item>
+ <ArrayItems>
+ <Size>_size</Size>
+ <ValuePointer>_str</ValuePointer>
+ </ArrayItems>
+ </Expand>
+ </Type>
+</AutoVisualizer>
diff --git a/devtools/create_project/visualstudio.cpp b/devtools/create_project/visualstudio.cpp
index 438e0772f9..84bc674f9a 100644
--- a/devtools/create_project/visualstudio.cpp
+++ b/devtools/create_project/visualstudio.cpp
@@ -232,7 +232,7 @@ void VisualStudioProvider::outputGlobalPropFile(const BuildSetup &setup, std::of
"\t\tName=\"VCCLCompilerTool\"\n"
"\t\tDisableLanguageExtensions=\"" << (setup.devTools ? "false" : "true") << "\"\n"
"\t\tDisableSpecificWarnings=\"" << warnings << "\"\n"
- "\t\tAdditionalIncludeDirectories=\"" << prefix << ";" << prefix << "\\engines;$(" << LIBS_DEFINE << ")\\include;" << (setup.tests ? prefix + "\\test\\cxxtest;" : "") << "$(TargetDir)\"\n"
+ "\t\tAdditionalIncludeDirectories=\".\\;" << prefix << ";" << prefix << "\\engines;$(" << LIBS_DEFINE << ")\\include;" << (setup.tests ? prefix + "\\test\\cxxtest;" : "") << "$(TargetDir)\"\n"
"\t\tPreprocessorDefinitions=\"" << definesList << "\"\n"
"\t\tExceptionHandling=\"" << ((setup.devTools || setup.tests) ? "1" : "0") << "\"\n";
diff --git a/devtools/create_project/xcode.cpp b/devtools/create_project/xcode.cpp
index a9b8e7a752..d95bf3e9ee 100644
--- a/devtools/create_project/xcode.cpp
+++ b/devtools/create_project/xcode.cpp
@@ -26,15 +26,6 @@
#include <fstream>
#include <algorithm>
-#if defined(_WIN32) || defined(WIN32)
-#include <windows.h>
-#else
-#include <sys/param.h>
-#include <sys/stat.h>
-#include <dirent.h>
-#include <errno.h>
-#endif
-
namespace CreateProjectTool {
#define DEBUG_XCODE_HASH 0
@@ -88,27 +79,7 @@ XCodeProvider::XCodeProvider(StringList &global_warnings, std::map<std::string,
void XCodeProvider::createWorkspace(const BuildSetup &setup) {
// Create project folder
std::string workspace = setup.outputDir + '/' + PROJECT_NAME ".xcodeproj";
-
-#if defined(_WIN32) || defined(WIN32)
- if (!CreateDirectory(workspace.c_str(), NULL))
- if (GetLastError() != ERROR_ALREADY_EXISTS)
- error("Could not create folder \"" + setup.outputDir + '/' + PROJECT_NAME ".xcodeproj\"");
-#else
- if (mkdir(workspace.c_str(), 0777) == -1) {
- if (errno == EEXIST) {
- // Try to open as a folder (might be a file / symbolic link)
- DIR *dirp = opendir(workspace.c_str());
- if (dirp == NULL) {
- error("Could not create folder \"" + setup.outputDir + '/' + PROJECT_NAME ".xcodeproj\"");
- } else {
- // The folder exists, just close the stream and return
- closedir(dirp);
- }
- } else {
- error("Could not create folder \"" + setup.outputDir + '/' + PROJECT_NAME ".xcodeproj\"");
- }
- }
-#endif
+ createDirectory(workspace);
// Setup global objects
setupDefines(setup);
diff --git a/devtools/create_translations/create_translations.cpp b/devtools/create_translations/create_translations.cpp
index a153632c47..a8b04a7a52 100644
--- a/devtools/create_translations/create_translations.cpp
+++ b/devtools/create_translations/create_translations.cpp
@@ -22,6 +22,8 @@
* The generated files is used by ScummVM to propose translation of its GUI.
*/
+#include "create_translations.h"
+
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -34,7 +36,6 @@
#undef main
#endif // main
-#include "create_translations.h"
#include "po_parser.h"
#include "cp_parser.h"
diff --git a/devtools/create_translations/create_translations.h b/devtools/create_translations/create_translations.h
index 9ccbd39b2b..1df01e6333 100644
--- a/devtools/create_translations/create_translations.h
+++ b/devtools/create_translations/create_translations.h
@@ -28,4 +28,8 @@ typedef unsigned short uint16;
typedef unsigned int uint32;
typedef signed short int16;
+#ifndef __has_feature // Optional of course.
+ #define __has_feature(x) 0 // Compatibility with non-clang compilers.
+#endif
+
#endif /* CREATE_TRANSLATIONS_H */
diff --git a/devtools/credits.pl b/devtools/credits.pl
index 45018a5633..53f0d11307 100755
--- a/devtools/credits.pl
+++ b/devtools/credits.pl
@@ -48,7 +48,7 @@ if ($mode eq "") {
$Text::Wrap::unexpand = 0;
if ($mode eq "TEXT") {
$Text::Wrap::columns = 78;
- $max_name_width = 23; # The maximal width of a name.
+ $max_name_width = 28; # The maximal width of a name.
} elsif ($mode eq "CPP") {
$Text::Wrap::columns = 48; # Approx.
}
@@ -60,6 +60,7 @@ sub html_entities_to_ascii {
# For now we hardcode these mappings
# &aacute; -> a
# &eacute; -> e
+ # &iacute; -> i
# &igrave; -> i
# &oacute; -> o
# &oslash; -> o
@@ -72,8 +73,10 @@ sub html_entities_to_ascii {
# &#322; -> l
# &#347; -> s
# &Scaron; -> S
+ # &ntilde; -> n
$text =~ s/&aacute;/a/g;
$text =~ s/&eacute;/e/g;
+ $text =~ s/&iacute;/i/g;
$text =~ s/&igrave;/i/g;
$text =~ s/&oacute;/o/g;
$text =~ s/&oslash;/o/g;
@@ -81,6 +84,7 @@ sub html_entities_to_ascii {
$text =~ s/&#347;/s/g;
$text =~ s/&Scaron;/S/g;
$text =~ s/&aring;/aa/g;
+ $text =~ s/&ntilde;/n/g;
$text =~ s/&auml;/a/g;
$text =~ s/&euml;/e/g;
@@ -101,6 +105,7 @@ sub html_entities_to_cpp {
# The numerical values are octal!
$text =~ s/&aacute;/\\341/g;
$text =~ s/&eacute;/\\351/g;
+ $text =~ s/&iacute;/\\355/g;
$text =~ s/&igrave;/\\354/g;
$text =~ s/&oacute;/\\363/g;
$text =~ s/&oslash;/\\370/g;
@@ -108,6 +113,7 @@ sub html_entities_to_cpp {
$text =~ s/&#347;/s/g;
$text =~ s/&Scaron;/S/g;
$text =~ s/&aring;/\\345/g;
+ $text =~ s/&ntilde;/\\361/g;
$text =~ s/&auml;/\\344/g;
$text =~ s/&euml;/\\353/g;
@@ -126,6 +132,7 @@ sub html_entities_to_rtf {
$text =~ s/&aacute;/\\'87/g;
$text =~ s/&eacute;/\\'8e/g;
+ $text =~ s/&iacute;/\\'92/g;
$text =~ s/&igrave;/\\'93/g;
$text =~ s/&oacute;/\\'97/g;
$text =~ s/&oslash;/\\'bf/g;
@@ -135,6 +142,8 @@ sub html_entities_to_rtf {
$text =~ s/&Scaron;/\\uc0\\u540 /g;
# Back to hex numbers
+ $text =~ s/&ntilde;/\\'96/g;
+
$text =~ s/&auml;/\\'8a/g;
$text =~ s/&euml;/\\'eb/g;
$text =~ s/&ouml;/\\'9a/g;
@@ -151,12 +160,14 @@ sub html_entities_to_tex {
$text =~ s/&aacute;/\\'a/g;
$text =~ s/&eacute;/\\'e/g;
+ $text =~ s/&iacute;/\\'i/g;
$text =~ s/&igrave;/\\`\\i/g;
$text =~ s/&oacute;/\\'o/g;
$text =~ s/&oslash;/{\\o}/g;
$text =~ s/&aring;/\\aa /g;
$text =~ s/&#322;/{\\l}/g;
$text =~ s/&Scaron;/{\\v S}/g;
+ $text =~ s/&ntilde;/\\Ëœn/g;
$text =~ s/&auml;/\\"a/g;
$text =~ s/&ouml;/\\"o/g;
@@ -541,6 +552,11 @@ begin_credits("Credits");
add_person("Oliver Kiehl", "olki", "(retired)");
add_person("Ludvig Strigeus", "ludde", "(retired)");
end_section();
+
+ begin_section("Avalanche");
+ add_person("Peter Bozs&oacute;", "uruk", "");
+ add_person("Arnaud Boutonn&eacute;", "Strangerke", "");
+ end_section();
begin_section("CGE");
add_person("Arnaud Boutonn&eacute;", "Strangerke", "");
@@ -754,6 +770,10 @@ begin_credits("Credits");
begin_section("Wintermute");
add_person("Einar Johan T. S&oslash;m&aring;en", "somaen", "");
end_section();
+
+ begin_section("ZVision");
+ add_person("Adrian Astley", "RichieSams", "");
+ end_section();
end_section();
@@ -975,7 +995,7 @@ begin_credits("Credits");
end_section();
end_section();
- begin_section("Translations");
+ begin_section("GUI Translations");
begin_persons();
add_person("Thierry Crozat", "criezy", "Translation Lead");
end_persons();
@@ -1040,6 +1060,20 @@ begin_credits("Credits");
add_person("Lubomyr Lisen", "", "");
end_section();
end_section();
+ begin_section("Game Translations");
+ begin_section("CGE");
+ add_person("Dan Serban", "nutron", "Soltys English translation");
+ 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("Drascula");
+ add_person("Thierry Crozat", "criezy", "Improve French translation");
+ end_section();
+ begin_section("Mortevielle");
+ add_person("Hugo Labrande", "", "Improve English translation");
+ add_person("Thierry Crozat", "criezy", "Improve English translation");
+ end_section();
+ end_section();
begin_section("Websites (design)");
begin_persons();
@@ -1063,6 +1097,7 @@ begin_credits("Credits");
add_person("Janne Huttunen", "", "V3 actor mask support, Dig/FT SMUSH audio");
add_person("Kov&aacute;cs Endre J&aacute;nos", "", "Several fixes for Simon1");
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("Claudio Matsuoka", "", "Daily Linux builds");
add_person("Thomas Mayer", "", "PSP port contributions");
@@ -1154,6 +1189,7 @@ begin_credits("Credits");
add_person("Jimmi Th&oslash;gersen", "", "For ScummRev, and much obscure code/documentation");
add_person("", "Tristan", "For additional work on the original MT-32 emulator");
add_person("James Woodcock", "", "Soundtrack enhancements");
+ add_person("Anton Yartsev", "Zidane", "For the original re-implementation of the ZVision engine");
end_persons();
add_paragraph(
diff --git a/devtools/extract_mort/extract_mort.cpp b/devtools/extract_mort/extract_mort.cpp
index 4346f1f4bf..a52458f9b2 100644
--- a/devtools/extract_mort/extract_mort.cpp
+++ b/devtools/extract_mort/extract_mort.cpp
@@ -104,9 +104,9 @@ public:
return ftell(f);
}
uint32 size() {
- int position = ftell(f);
+ uint32 position = ftell(f);
fseek (f, 0, SEEK_END);
- int end = ftell (f);
+ uint32 end = ftell(f);
fseek (f, position, SEEK_SET);
return end;
diff --git a/devtools/scumm-md5.txt b/devtools/scumm-md5.txt
index 0dbcbf4792..a52bbaecf8 100644
--- a/devtools/scumm-md5.txt
+++ b/devtools/scumm-md5.txt
@@ -598,6 +598,7 @@ catalog Humongous Interactive Catalog
a56e8d9d4281c53c3f63c9bd22a59e21 10978342 en All HE CUP Preview George Kormendi
74da3494fbe1a7d20213b0afe0954755 10841544 fr All HE CUP Preview - George Kormendi
4c4820518e16e1a0e3616a3b021a04f3 10927456 de All HE CUP Preview - Kirben
+ 288fb75b24389733c29fa107fe8d44e8 10795148 us All HE CUP Preview - Kirben
airport Let's Explore the Airport with Buzzy
d6334a5a9b61afe18c368540fdf522ca -1 en Mac - - - Joachim Eberhard
diff --git a/dists/android/AndroidManifest.xml b/dists/android/AndroidManifest.xml
index 320ed16a6e..16d1ee578b 100644
--- a/dists/android/AndroidManifest.xml
+++ b/dists/android/AndroidManifest.xml
@@ -36,6 +36,7 @@
<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>
diff --git a/dists/android/AndroidManifest.xml.in b/dists/android/AndroidManifest.xml.in
index 8f7887eaf5..bf45ffcc0e 100644
--- a/dists/android/AndroidManifest.xml.in
+++ b/dists/android/AndroidManifest.xml.in
@@ -36,6 +36,7 @@
<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>
diff --git a/dists/android/res-ouya/values-television/margins.xml b/dists/android/res-ouya/values-television/margins.xml
new file mode 100644
index 0000000000..df586eea34
--- /dev/null
+++ b/dists/android/res-ouya/values-television/margins.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <dimen name="verticalMargin">45px</dimen>
+ <dimen name="horizontalMargin">80px</dimen>
+</resources>
diff --git a/dists/android/res/drawable-xhdpi/ouya_icon.png b/dists/android/res/drawable-xhdpi/ouya_icon.png
new file mode 100644
index 0000000000..42f9a2a8ce
--- /dev/null
+++ b/dists/android/res/drawable-xhdpi/ouya_icon.png
Binary files differ
diff --git a/dists/android/res/layout/main.xml b/dists/android/res/layout/main.xml
index 8b0d515d62..31aa345cc7 100644
--- a/dists/android/res/layout/main.xml
+++ b/dists/android/res/layout/main.xml
@@ -9,4 +9,8 @@
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/values/margins.xml b/dists/android/res/values/margins.xml
new file mode 100644
index 0000000000..a865687b3a
--- /dev/null
+++ b/dists/android/res/values/margins.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <dimen name="verticalMargin">0px</dimen>
+ <dimen name="horizontalMargin">0px</dimen>
+</resources>
diff --git a/dists/debian/copyright b/dists/debian/copyright
index 1cccd01a07..1317fc6cee 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-2013 The ScummVM Project
+ScummVM is Copyright © 2002-2014 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/engine-data/README b/dists/engine-data/README
index 9bbb006d17..e87f04c65b 100644
--- a/dists/engine-data/README
+++ b/dists/engine-data/README
@@ -21,6 +21,9 @@ File created partially by extracting font data from the French executable. It
also contains the French and German translation, as well as a custom-made
English translation.
+neverhood.dat:
+TODO
+
queen.tbl:
'queen.tbl' contains a list of filenames, filesizes and offsets for the
individual files saved in QUEEN.1. This data was originally included in the
@@ -38,4 +41,4 @@ tony.dat:
This file contains the font table used by the different versions of the game.
toon.dat:
-'toon.dat' contains all the strings hardcoded in the original executables.
+This file contains all the strings hardcoded in the original executables.
diff --git a/dists/macosx/Info.plist b/dists/macosx/Info.plist
index b9a4eff1b8..63813c06de 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.7.0git, Copyright 2001-2013 The ScummVM team</string>
+ <string>1.7.0git, Copyright 2001-2014 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-2013 The ScummVM team</string>
+ <string>Copyright 2001-2014 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 b810b7ea5a..9ef1584440 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-2013 The ScummVM team</string>
+ <string>@VERSION@, Copyright 2001-2014 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-2013 The ScummVM team</string>
+ <string>Copyright 2001-2014 The ScummVM Team</string>
<key>SUFeedURL</key>
<string>http://www.scummvm.org/appcasts/macosx/release.xml</string>
<key>SUPublicDSAKeyFile</key>
diff --git a/dists/msvc11/readme.txt b/dists/msvc11/readme.txt
index fa91a8cc12..45faac0663 100644
--- a/dists/msvc11/readme.txt
+++ b/dists/msvc11/readme.txt
@@ -3,4 +3,7 @@ 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_msvc11.bat file for a default build. You can run
-create_project.exe with no parameters to check the possible command-line options
+create_project.exe with no parameters to check the possible command-line options.
+
+To enable debug visualization for common types, see the comment in
+/devtools/create_project/scripts/scummvm.natvis.
diff --git a/dists/msvc12/readme.txt b/dists/msvc12/readme.txt
index 760f9ff601..2d91c72140 100644
--- a/dists/msvc12/readme.txt
+++ b/dists/msvc12/readme.txt
@@ -3,4 +3,7 @@ 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_msvc12.bat file for a default build. You can run
-create_project.exe with no parameters to check the possible command-line options
+create_project.exe with no parameters to check the possible command-line options.
+
+To enable debug visualization for common types, see the comment in
+/devtools/create_project/scripts/scummvm.natvis.
diff --git a/dists/scummvm.rc b/dists/scummvm.rc
index 037db3ef62..f0609c1a79 100644
--- a/dists/scummvm.rc
+++ b/dists/scummvm.rc
@@ -81,7 +81,7 @@ BEGIN
VALUE "FileDescription", "http://www.scummvm.org/\0"
VALUE "FileVersion", "1.7.0git\0"
VALUE "InternalName", "scummvm\0"
- VALUE "LegalCopyright", "Copyright © 2001-2013 The ScummVM Team\0"
+ VALUE "LegalCopyright", "Copyright © 2001-2014 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 c18c18ef63..401c0abb0d 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-2013 The ScummVM Team\0"
+ VALUE "LegalCopyright", "Copyright © 2001-2014 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.iss b/dists/win32/ScummVM.iss
index fa0f760f59..5afb407177 100644
--- a/dists/win32/ScummVM.iss
+++ b/dists/win32/ScummVM.iss
@@ -1,5 +1,5 @@
[Setup]
-AppCopyright=2013
+AppCopyright=2014
AppName=ScummVM
AppVerName=ScummVM Git
AppPublisher=The ScummVM Team
diff --git a/dists/win32/migration.bat b/dists/win32/migration.bat
index b4b00c02cc..e1b27a1fb3 100644
--- a/dists/win32/migration.bat
+++ b/dists/win32/migration.bat
@@ -4,7 +4,7 @@
:: This script will copy any saved games located in the
:: old default location, to the new default location.
::
-:: (c) 2012-2013 ScummVM Team
+:: (c) 2012-2014 ScummVM Team
::
@echo off
diff --git a/dists/win32/scummvm.nsi b/dists/win32/scummvm.nsi
index 5357be9fe4..602b9fd6c3 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-2013 The ScummVM Team"
+!define COPYRIGHT "Copyright © 2001-2014 The ScummVM Team"
#########################################################################################
# Installer configuration
diff --git a/dists/win32/scummvm.nsi.in b/dists/win32/scummvm.nsi.in
index 9f8bd1dad2..b8ddc74a86 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-2013 The ScummVM Team"
+!define COPYRIGHT "Copyright © 2001-2014 The ScummVM Team"
#########################################################################################
# Installer configuration
diff --git a/engines/agi/configure.engine b/engines/agi/configure.engine
new file mode 100644
index 0000000000..fad659f86d
--- /dev/null
+++ b/engines/agi/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 agi "AGI" yes
diff --git a/engines/agi/detection_tables.h b/engines/agi/detection_tables.h
index f1bb079ffc..a7a3920df8 100644
--- a/engines/agi/detection_tables.h
+++ b/engines/agi/detection_tables.h
@@ -849,6 +849,7 @@ static const AGIGameDescription gameDescriptions[] = {
FANMADE("Tonight The Shrieking Corpses Bleed (Demo v0.11)", "bcc57a7c8d563fa0c333107ae1c0a6e6"),
FANMADE("Tonight The Shrieking Corpses Bleed (v1.01)", "36b38f621b38e8d104aa0807302dc8c9"),
FANMADE("Turks' Quest - Heir to the Planet", "3d19254b737c8b218e5bc4580542b79a"),
+ FANMADE("Ultimate AGI Fangame (Demo)", "2d14d6fa2a2136d681e46e06821905bf"),
FANMADE("URI Quest (v0.173 Feb 27)", "3986eefcf546dafc45f920ae91a697c3"),
FANMADE("URI Quest (v0.173 Jan 29)", "494150940d34130605a4f2e67ee40b12"),
{
diff --git a/engines/agi/loader_v1.cpp b/engines/agi/loader_v1.cpp
index 33e956af41..3b862ed91f 100644
--- a/engines/agi/loader_v1.cpp
+++ b/engines/agi/loader_v1.cpp
@@ -202,7 +202,7 @@ int AgiLoader_v1::loadResource(int t, int n) {
uint8 *data = NULL;
debugC(3, kDebugLevelResources, "(t = %d, n = %d)", t, n);
- if (n > MAX_DIRS)
+ if (n >= MAX_DIRS)
return errBadResource;
switch (t) {
diff --git a/engines/agi/loader_v2.cpp b/engines/agi/loader_v2.cpp
index ee69bb5b27..458927a3bc 100644
--- a/engines/agi/loader_v2.cpp
+++ b/engines/agi/loader_v2.cpp
@@ -178,7 +178,7 @@ int AgiLoader_v2::loadResource(int t, int n) {
uint8 *data = NULL;
debugC(3, kDebugLevelResources, "(t = %d, n = %d)", t, n);
- if (n > MAX_DIRS)
+ if (n >= MAX_DIRS)
return errBadResource;
switch (t) {
diff --git a/engines/agi/loader_v3.cpp b/engines/agi/loader_v3.cpp
index 250d8e7615..1dd00dc18e 100644
--- a/engines/agi/loader_v3.cpp
+++ b/engines/agi/loader_v3.cpp
@@ -257,7 +257,7 @@ int AgiLoader_v3::loadResource(int t, int n) {
int ec = errOK;
uint8 *data = NULL;
- if (n > MAX_DIRS)
+ if (n >= MAX_DIRS)
return errBadResource;
switch (t) {
diff --git a/engines/agi/opcodes.cpp b/engines/agi/opcodes.cpp
index 807ab2dc2c..d893e44c12 100644
--- a/engines/agi/opcodes.cpp
+++ b/engines/agi/opcodes.cpp
@@ -367,6 +367,18 @@ void AgiEngine::setupOpcodes() {
logicNamesTest = insV2Test;
logicNamesCmd = insV2;
+
+ // Alter opcode parameters for specific games
+ // TODO: This could be either turned into a game feature, or a version
+ // specific check, instead of a game version check
+
+ // The Apple IIGS versions of MH1 and Goldrush both have a parameter for
+ // show.mouse and hide.mouse. Fixes bugs #3577754 and #3426946.
+ if ((getGameID() == GID_MH1 || getGameID() == GID_GOLDRUSH) &&
+ getPlatform() == Common::kPlatformApple2GS) {
+ logicNamesCmd[176].args = "n"; // hide.mouse
+ logicNamesCmd[178].args = "n"; // show.mouse
+ }
} else {
for (int i = 0; i < ARRAYSIZE(insV1Test); ++i)
_agiCondCommands[i] = insV1Test[i].func;
@@ -376,18 +388,6 @@ void AgiEngine::setupOpcodes() {
logicNamesTest = insV1Test;
logicNamesCmd = insV1;
}
-
- // Alter opcode parameters for specific games
- // TODO: This could be either turned into a game feature, or a version
- // specific check, instead of a game version check
-
- // The Apple IIGS versions of MH1 and Goldrush both have a parameter for
- // show.mouse and hide.mouse. Fixes bugs #3577754 and #3426946.
- if ((getGameID() == GID_MH1 || getGameID() == GID_GOLDRUSH) &&
- getPlatform() == Common::kPlatformApple2GS) {
- logicNamesCmd[176].args = "n"; // hide.mouse
- logicNamesCmd[178].args = "n"; // show.mouse
- }
}
}
diff --git a/engines/agi/preagi_mickey.cpp b/engines/agi/preagi_mickey.cpp
index ed4882fcab..d0f6540651 100644
--- a/engines/agi/preagi_mickey.cpp
+++ b/engines/agi/preagi_mickey.cpp
@@ -850,7 +850,7 @@ void MickeyEngine::drawRoomAnimation() {
}
void MickeyEngine::drawRoom() {
- uint8 buffer[256];
+ uint8 buffer[512];
int pBuf = 0;
int nObjs;
diff --git a/engines/agi/words.cpp b/engines/agi/words.cpp
index 9c5b3d349a..f423995de8 100644
--- a/engines/agi/words.cpp
+++ b/engines/agi/words.cpp
@@ -93,14 +93,25 @@ int AgiEngine::loadWords(const char *fname) {
} while (!(c & 0x80) && k < (int)sizeof(str) - 1);
str[k] = 0;
- // And store it in our internal dictionary
- AgiWord *w = new AgiWord;
- w->word = myStrndup(str, k);
- w->id = fp.readUint16BE();
- _game.words[i].push_back(w);
+ // WORKAROUND:
+ // The SQ0 fan game stores words starting with numbers (like '7up')
+ // in its dictionary under the 'a' entry. We skip these.
+ // See bug #3615061
+ if (str[0] == 'a' + i) {
+ // And store it in our internal dictionary
+ AgiWord *w = new AgiWord;
+ w->word = myStrndup(str, k);
+ w->id = fp.readUint16BE();
+ _game.words[i].push_back(w);
+ }
+
+ k = fp.readByte();
// Are there more words with an already known prefix?
- if (!(k = fp.readByte()))
+ // WORKAROUND: We only break after already seeing words with the
+ // right prefix, for the SQ0 words starting with digits filed under
+ // 'a'. See above comment and bug #3615061.
+ if (k == 0 && str[0] >= 'a' + i)
break;
}
}
diff --git a/engines/agos/agos.h b/engines/agos/agos.h
index 87a1228c6a..0b8e585f57 100644
--- a/engines/agos/agos.h
+++ b/engines/agos/agos.h
@@ -25,7 +25,6 @@
#include "engines/engine.h"
-#include "common/archive.h"
#include "common/array.h"
#include "common/error.h"
#include "common/keyboard.h"
@@ -187,27 +186,6 @@ class Debugger;
# define _OPCODE(ver, x) { &ver::x, "" }
#endif
-class ArchiveMan : public Common::SearchSet {
-public:
- ArchiveMan();
-
- void enableFallback(bool val) { _fallBack = val; }
-
-#ifdef ENABLE_AGOS2
- void registerArchive(const Common::String &filename, int priority);
-#endif
-
- virtual bool hasFile(const Common::String &name) const;
- virtual int listMatchingMembers(Common::ArchiveMemberList &list, const Common::String &pattern) const;
- virtual int listMembers(Common::ArchiveMemberList &list) const;
-
- virtual const Common::ArchiveMemberPtr getMember(const Common::String &name) const;
- virtual Common::SeekableReadStream *createReadStreamForMember(const Common::String &filename) const;
-
-private:
- bool _fallBack;
-};
-
class AGOSEngine : public Engine {
protected:
friend class Debugger;
@@ -622,8 +600,6 @@ public:
AGOSEngine(OSystem *system, const AGOSGameDescription *gd);
virtual ~AGOSEngine();
- ArchiveMan _archives;
-
byte *_curSfxFile;
uint32 _curSfxFileSize;
uint16 _sampleEnd, _sampleWait;
diff --git a/engines/agos/animation.cpp b/engines/agos/animation.cpp
index 40c9d1d049..d438de049a 100644
--- a/engines/agos/animation.cpp
+++ b/engines/agos/animation.cpp
@@ -251,8 +251,8 @@ bool MoviePlayerDXA::load() {
}
Common::String videoName = Common::String::format("%s.dxa", baseName);
- Common::SeekableReadStream *videoStream = _vm->_archives.createReadStreamForMember(videoName);
- if (!videoStream)
+ Common::File *videoStream = new Common::File();
+ if (!videoStream->open(videoName))
error("Failed to load video file %s", videoName.c_str());
if (!loadStream(videoStream))
error("Failed to load video stream from file %s", videoName.c_str());
@@ -421,8 +421,8 @@ MoviePlayerSMK::MoviePlayerSMK(AGOSEngine_Feeble *vm, const char *name)
bool MoviePlayerSMK::load() {
Common::String videoName = Common::String::format("%s.smk", baseName);
- Common::SeekableReadStream *videoStream = _vm->_archives.createReadStreamForMember(videoName);
- if (!videoStream)
+ Common::File *videoStream = new Common::File();
+ if (!videoStream->open(videoName))
error("Failed to load video file %s", videoName.c_str());
if (!loadStream(videoStream))
error("Failed to load video stream from file %s", videoName.c_str());
@@ -532,25 +532,25 @@ MoviePlayer *makeMoviePlayer(AGOSEngine_Feeble *vm, const char *name) {
memcpy(shortName, baseName, 6);
sprintf(filename, "%s~1.dxa", shortName);
- if (vm->_archives.hasFile(filename)) {
+ if (Common::File::exists(filename)) {
memset(baseName, 0, sizeof(baseName));
memcpy(baseName, filename, 8);
}
sprintf(filename, "%s~1.smk", shortName);
- if (vm->_archives.hasFile(filename)) {
+ if (Common::File::exists(filename)) {
memset(baseName, 0, sizeof(baseName));
memcpy(baseName, filename, 8);
}
}
sprintf(filename, "%s.dxa", baseName);
- if (vm->_archives.hasFile(filename)) {
+ if (Common::File::exists(filename)) {
return new MoviePlayerDXA(vm, baseName);
}
sprintf(filename, "%s.smk", baseName);
- if (vm->_archives.hasFile(filename)) {
+ if (Common::File::exists(filename)) {
return new MoviePlayerSMK(vm, baseName);
}
diff --git a/engines/agos/configure.engine b/engines/agos/configure.engine
new file mode 100644
index 0000000000..3ae1fb16f2
--- /dev/null
+++ b/engines/agos/configure.engine
@@ -0,0 +1,4 @@
+# This file is included from the main "configure" script
+# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps]
+add_engine agos "AGOS" yes "agos2" "AGOS 1 games"
+add_engine agos2 "AGOS 2 games" yes
diff --git a/engines/agos/detection.cpp b/engines/agos/detection.cpp
index a5a42a86ad..b6d3c2f020 100644
--- a/engines/agos/detection.cpp
+++ b/engines/agos/detection.cpp
@@ -28,6 +28,7 @@
#include "common/savefile.h"
#include "common/system.h"
#include "common/textconsole.h"
+#include "common/installshield_cab.h"
#include "agos/intern.h"
#include "agos/agos.h"
@@ -269,8 +270,12 @@ void AGOSEngine::loadArchives() {
if (getFeatures() & GF_PACKED) {
for (ag = _gameDescription->desc.filesDescriptions; ag->fileName; ag++) {
- if (!_archives.hasArchive(ag->fileName))
- _archives.registerArchive(ag->fileName, ag->fileType);
+ if (!SearchMan.hasArchive(ag->fileName)) {
+ Common::SeekableReadStream *stream = SearchMan.createReadStreamForMember(ag->fileName);
+
+ if (stream)
+ SearchMan.add(ag->fileName, Common::makeInstallShieldArchive(stream, DisposeAfterUse::YES), ag->fileType);
+ }
}
}
}
diff --git a/engines/agos/detection_tables.h b/engines/agos/detection_tables.h
index 70757865f5..329af75d0c 100644
--- a/engines/agos/detection_tables.h
+++ b/engines/agos/detection_tables.h
@@ -1091,6 +1091,30 @@ static const AGOSGameDescription gameDescriptions[] = {
GF_32COLOR | GF_CRUNCHED | GF_CRUNCHED_GAMEPC | GF_OLD_BUNDLE | GF_PLANAR
},
+ // Simon the Sorcerer 1 - German Amiga OCS Floppy
+ {
+ {
+ "simon1",
+ "OCS Floppy",
+
+ {
+ { "gameamiga", GAME_BASEFILE, "634c82b7a0b760214fd71add328c7a00", 39493},
+ { "icon.pkd", GAME_ICONFILE, "565ef7a98dcc21ef526a2bb10b6f42ed", 18979},
+ { "stripped.txt", GAME_STRFILE, "f5fc67db3b8c5283cda51c43b98a74f8", 243},
+ { "tbllist", GAME_TBLFILE, "f9d5bf2ce09f82289c791c3ca26e1e4b", 696},
+ { NULL, 0, NULL, 0}
+ },
+ Common::DE_DEU,
+ Common::kPlatformAmiga,
+ ADGF_NO_FLAGS,
+ GUIO2(GUIO_NOSPEECH, GUIO_NOMIDI)
+ },
+
+ GType_SIMON1,
+ GID_SIMON1,
+ GF_32COLOR | GF_CRUNCHED | GF_OLD_BUNDLE | GF_PLANAR
+ },
+
// Simon the Sorcerer 1 - English Amiga AGA Floppy
{
{
diff --git a/engines/agos/icons.cpp b/engines/agos/icons.cpp
index 6d4192da2a..5647fece7e 100644
--- a/engines/agos/icons.cpp
+++ b/engines/agos/icons.cpp
@@ -1089,15 +1089,15 @@ bool AGOSEngine_PN::ifObjectInInv(uint16 a) {
}
bool AGOSEngine_PN::testContainer(uint16 a) {
- return bitextract(_quickptr[1] + a * _quickshort[1], 0) != 0;
+ return bitextract(_quickptr[1] + a * _quickshort[1], 0) != 0;
}
bool AGOSEngine_PN::testObvious(uint16 a) {
- return bitextract(_quickptr[1] + a * _quickshort[1], 4) != 0;
+ return bitextract(_quickptr[1] + a * _quickshort[1], 4) != 0;
}
bool AGOSEngine_PN::testSeen(uint16 a) {
- return bitextract(_quickptr[1] + a * _quickshort[1], 3) != 0;
+ return bitextract(_quickptr[1] + a * _quickshort[1], 3) != 0;
}
void AGOSEngine_PN::printIcon(HitArea *ha, uint8 i, uint8 r) {
diff --git a/engines/agos/res.cpp b/engines/agos/res.cpp
index cf1d062d96..1c79a073e8 100644
--- a/engines/agos/res.cpp
+++ b/engines/agos/res.cpp
@@ -24,7 +24,6 @@
#include "common/archive.h"
-#include "common/installshield_cab.h"
#include "common/file.h"
#include "common/memstream.h"
#include "common/textconsole.h"
@@ -38,52 +37,6 @@
namespace AGOS {
-ArchiveMan::ArchiveMan() {
- _fallBack = true;
-}
-
-#ifdef ENABLE_AGOS2
-void ArchiveMan::registerArchive(const Common::String &filename, int priority) {
- Common::SeekableReadStream *stream = SearchMan.createReadStreamForMember(filename);
-
- if (stream)
- add(filename, makeInstallShieldArchive(stream, DisposeAfterUse::YES), priority);
-}
-#endif
-
-bool ArchiveMan::hasFile(const Common::String &name) const {
- if (_fallBack && SearchMan.hasFile(name))
- return true;
-
- return Common::SearchSet::hasFile(name);
-}
-
-int ArchiveMan::listMatchingMembers(Common::ArchiveMemberList &list, const Common::String &pattern) const {
- const int matches = _fallBack ? SearchMan.listMatchingMembers(list, pattern) : 0;
- return matches + Common::SearchSet::listMatchingMembers(list, pattern);
-}
-
-int ArchiveMan::listMembers(Common::ArchiveMemberList &list) const {
- const int matches = _fallBack ? SearchMan.listMembers(list) : 0;
- return matches + Common::SearchSet::listMembers(list);
-}
-
-const Common::ArchiveMemberPtr ArchiveMan::getMember(const Common::String &name) const {
- Common::ArchiveMemberPtr ptr = _fallBack ? SearchMan.getMember(name) : Common::ArchiveMemberPtr();
- if (ptr)
- return ptr;
-
- return Common::SearchSet::getMember(name);
-}
-
-Common::SeekableReadStream *ArchiveMan::createReadStreamForMember(const Common::String &filename) const {
- if (_fallBack && SearchMan.hasFile(filename)) {
- return SearchMan.createReadStreamForMember(filename);
- }
-
- return Common::SearchSet::createReadStreamForMember(filename);
-}
-
#ifdef ENABLE_AGOS2
uint16 AGOSEngine_Feeble::to16Wrapper(uint value) {
return TO_LE_16(value);
@@ -198,39 +151,35 @@ int AGOSEngine::allocGamePcVars(Common::SeekableReadStream *in) {
}
void AGOSEngine_PN::loadGamePcFile() {
- Common::SeekableReadStream *in;
-
if (getFileName(GAME_BASEFILE) != NULL) {
+ Common::File in;
// Read dataBase
- in = _archives.createReadStreamForMember(getFileName(GAME_BASEFILE));
- if (!in) {
+ if (!in.open(getFileName(GAME_BASEFILE))) {
error("loadGamePcFile: Can't load database file '%s'", getFileName(GAME_BASEFILE));
}
- _dataBaseSize = in->size();
+ _dataBaseSize = in.size();
_dataBase = (byte *)malloc(_dataBaseSize);
if (_dataBase == NULL)
error("loadGamePcFile: Out of memory for dataBase");
- in->read(_dataBase, _dataBaseSize);
- delete in;
+ in.read(_dataBase, _dataBaseSize);
if (_dataBase[31] != 0)
error("Later version of system requested");
}
if (getFileName(GAME_TEXTFILE) != NULL) {
+ Common::File in;
// Read textBase
- in = _archives.createReadStreamForMember(getFileName(GAME_TEXTFILE));
- if (!in) {
+ if (!in.open(getFileName(GAME_TEXTFILE))) {
error("loadGamePcFile: Can't load textbase file '%s'", getFileName(GAME_TEXTFILE));
}
- _textBaseSize = in->size();
+ _textBaseSize = in.size();
_textBase = (byte *)malloc(_textBaseSize);
if (_textBase == NULL)
error("loadGamePcFile: Out of memory for textBase");
- in->read(_textBase, _textBaseSize);
- delete in;
+ in.read(_textBase, _textBaseSize);
if (_textBase[getlong(30L)] != 128)
error("Unknown compression format");
@@ -238,20 +187,19 @@ void AGOSEngine_PN::loadGamePcFile() {
}
void AGOSEngine::loadGamePcFile() {
- Common::SeekableReadStream *in;
int fileSize;
if (getFileName(GAME_BASEFILE) != NULL) {
/* Read main gamexx file */
- in = _archives.createReadStreamForMember(getFileName(GAME_BASEFILE));
- if (!in) {
+ Common::File in;
+ if (!in.open(getFileName(GAME_BASEFILE))) {
error("loadGamePcFile: Can't load gamexx file '%s'", getFileName(GAME_BASEFILE));
}
if (getFeatures() & GF_CRUNCHED_GAMEPC) {
- uint srcSize = in->size();
+ uint srcSize = in.size();
byte *srcBuf = (byte *)malloc(srcSize);
- in->read(srcBuf, srcSize);
+ in.read(srcBuf, srcSize);
uint dstSize = READ_BE_UINT32(srcBuf + srcSize - 4);
byte *dstBuf = (byte *)malloc(dstSize);
@@ -262,25 +210,23 @@ void AGOSEngine::loadGamePcFile() {
readGamePcFile(&stream);
free(dstBuf);
} else {
- readGamePcFile(in);
+ readGamePcFile(&in);
}
- delete in;
}
if (getFileName(GAME_TBLFILE) != NULL) {
/* Read list of TABLE resources */
- in = _archives.createReadStreamForMember(getFileName(GAME_TBLFILE));
- if (!in) {
+ Common::File in;
+ if (!in.open(getFileName(GAME_TBLFILE))) {
error("loadGamePcFile: Can't load table resources file '%s'", getFileName(GAME_TBLFILE));
}
- fileSize = in->size();
+ fileSize = in.size();
_tblList = (byte *)malloc(fileSize);
if (_tblList == NULL)
error("loadGamePcFile: Out of memory for strip table list");
- in->read(_tblList, fileSize);
- delete in;
+ in.read(_tblList, fileSize);
/* Remember the current state */
_subroutineListOrg = _subroutineList;
@@ -290,71 +236,67 @@ void AGOSEngine::loadGamePcFile() {
if (getFileName(GAME_STRFILE) != NULL) {
/* Read list of TEXT resources */
- in = _archives.createReadStreamForMember(getFileName(GAME_STRFILE));
- if (!in)
+ Common::File in;
+ if (!in.open(getFileName(GAME_STRFILE)))
error("loadGamePcFile: Can't load text resources file '%s'", getFileName(GAME_STRFILE));
- fileSize = in->size();
+ fileSize = in.size();
_strippedTxtMem = (byte *)malloc(fileSize);
if (_strippedTxtMem == NULL)
error("loadGamePcFile: Out of memory for strip text list");
- in->read(_strippedTxtMem, fileSize);
- delete in;
+ in.read(_strippedTxtMem, fileSize);
}
if (getFileName(GAME_STATFILE) != NULL) {
/* Read list of ROOM STATE resources */
- in = _archives.createReadStreamForMember(getFileName(GAME_STATFILE));
- if (!in) {
+ Common::File in;
+ if (!in.open(getFileName(GAME_STATFILE))) {
error("loadGamePcFile: Can't load state resources file '%s'", getFileName(GAME_STATFILE));
}
- _numRoomStates = in->size() / 8;
+ _numRoomStates = in.size() / 8;
_roomStates = (RoomState *)calloc(_numRoomStates, sizeof(RoomState));
if (_roomStates == NULL)
error("loadGamePcFile: Out of memory for room state list");
for (uint s = 0; s < _numRoomStates; s++) {
- uint16 num = in->readUint16BE() - (_itemArrayInited - 2);
+ uint16 num = in.readUint16BE() - (_itemArrayInited - 2);
- _roomStates[num].state = in->readUint16BE();
- _roomStates[num].classFlags = in->readUint16BE();
- _roomStates[num].roomExitStates = in->readUint16BE();
+ _roomStates[num].state = in.readUint16BE();
+ _roomStates[num].classFlags = in.readUint16BE();
+ _roomStates[num].roomExitStates = in.readUint16BE();
}
- delete in;
}
if (getFileName(GAME_RMSLFILE) != NULL) {
/* Read list of ROOM ITEMS resources */
- in = _archives.createReadStreamForMember(getFileName(GAME_RMSLFILE));
- if (!in) {
+ Common::File in;
+ if (!in.open(getFileName(GAME_RMSLFILE))) {
error("loadGamePcFile: Can't load room resources file '%s'", getFileName(GAME_RMSLFILE));
}
- fileSize = in->size();
+ fileSize = in.size();
_roomsList = (byte *)malloc(fileSize);
if (_roomsList == NULL)
error("loadGamePcFile: Out of memory for room items list");
- in->read(_roomsList, fileSize);
- delete in;
+ in.read(_roomsList, fileSize);
}
if (getFileName(GAME_XTBLFILE) != NULL) {
/* Read list of XTABLE resources */
- in = _archives.createReadStreamForMember(getFileName(GAME_XTBLFILE));
- if (!in) {
+ Common::File in;
+ if (!in.open(getFileName(GAME_XTBLFILE))) {
error("loadGamePcFile: Can't load xtable resources file '%s'", getFileName(GAME_XTBLFILE));
}
- fileSize = in->size();
+ fileSize = in.size();
_xtblList = (byte *)malloc(fileSize);
if (_xtblList == NULL)
error("loadGamePcFile: Out of memory for strip xtable list");
- in->read(_xtblList, fileSize);
- delete in;
+ in.read(_xtblList, fileSize);
/* Remember the current state */
_xsubroutineListOrg = _subroutineList;
@@ -828,7 +770,7 @@ void AGOSEngine::loadVGABeardFile(uint16 id) {
uint32 offs, size;
if (getFeatures() & GF_OLD_BUNDLE) {
- Common::SeekableReadStream *in;
+ Common::File in;
char filename[15];
if (id == 23)
id = 112;
@@ -844,22 +786,20 @@ void AGOSEngine::loadVGABeardFile(uint16 id) {
sprintf(filename, "0%d.VGA", id);
}
- in = _archives.createReadStreamForMember(filename);
- if (!in)
+ if (!in.open(filename))
error("loadSimonVGAFile: Can't load %s", filename);
- size = in->size();
+ size = in.size();
if (getFeatures() & GF_CRUNCHED) {
byte *srcBuffer = (byte *)malloc(size);
- if (in->read(srcBuffer, size) != size)
+ if (in.read(srcBuffer, size) != size)
error("loadSimonVGAFile: Read failed");
decrunchFile(srcBuffer, _vgaBufferPointers[11].vgaFile2, size);
free(srcBuffer);
} else {
- if (in->read(_vgaBufferPointers[11].vgaFile2, size) != size)
+ if (in.read(_vgaBufferPointers[11].vgaFile2, size) != size)
error("loadSimonVGAFile: Read failed");
}
- delete in;
} else {
offs = _gameOffsetsPtr[id];
@@ -869,7 +809,7 @@ void AGOSEngine::loadVGABeardFile(uint16 id) {
}
void AGOSEngine::loadVGAVideoFile(uint16 id, uint8 type, bool useError) {
- Common::SeekableReadStream *in;
+ Common::File in;
char filename[15];
byte *dst;
uint32 file, offs, srcSize, dstSize;
@@ -922,8 +862,7 @@ void AGOSEngine::loadVGAVideoFile(uint16 id, uint8 type, bool useError) {
}
}
- in = _archives.createReadStreamForMember(filename);
- if (!in) {
+ if (!in.open(filename)) {
if (useError)
error("loadVGAVideoFile: Can't load %s", filename);
@@ -931,11 +870,11 @@ void AGOSEngine::loadVGAVideoFile(uint16 id, uint8 type, bool useError) {
return;
}
- dstSize = srcSize = in->size();
+ dstSize = srcSize = in.size();
if (getGameType() == GType_PN && getPlatform() == Common::kPlatformDOS && id == 17 && type == 2) {
// The A2.out file isn't compressed in PC version of Personal Nightmare
dst = allocBlock(dstSize + extraBuffer);
- if (in->read(dst, dstSize) != dstSize)
+ if (in.read(dst, dstSize) != dstSize)
error("loadVGAVideoFile: Read failed");
} else if (getGameType() == GType_PN && (getFeatures() & GF_CRUNCHED)) {
Common::Stack<uint32> data;
@@ -943,7 +882,7 @@ void AGOSEngine::loadVGAVideoFile(uint16 id, uint8 type, bool useError) {
int dataOutSize = 0;
for (uint i = 0; i < srcSize / 4; ++i) {
- uint32 dataVal = in->readUint32BE();
+ uint32 dataVal = in.readUint32BE();
// Correct incorrect byte, in corrupt 72.out file, included in some PC versions.
if (dataVal == 168042714)
data.push(168050906);
@@ -957,7 +896,7 @@ void AGOSEngine::loadVGAVideoFile(uint16 id, uint8 type, bool useError) {
delete[] dataOut;
} else if (getFeatures() & GF_CRUNCHED) {
byte *srcBuffer = (byte *)malloc(srcSize);
- if (in->read(srcBuffer, srcSize) != srcSize)
+ if (in.read(srcBuffer, srcSize) != srcSize)
error("loadVGAVideoFile: Read failed");
dstSize = READ_BE_UINT32(srcBuffer + srcSize - 4);
@@ -966,10 +905,9 @@ void AGOSEngine::loadVGAVideoFile(uint16 id, uint8 type, bool useError) {
free(srcBuffer);
} else {
dst = allocBlock(dstSize + extraBuffer);
- if (in->read(dst, dstSize) != dstSize)
+ if (in.read(dst, dstSize) != dstSize)
error("loadVGAVideoFile: Read failed");
}
- delete in;
} else {
id = id * 2 + (type - 1);
offs = _gameOffsetsPtr[id];
diff --git a/engines/agos/res_snd.cpp b/engines/agos/res_snd.cpp
index 2777d4f269..86d24e0b07 100644
--- a/engines/agos/res_snd.cpp
+++ b/engines/agos/res_snd.cpp
@@ -450,17 +450,14 @@ static const char *const dimpSoundList[32] = {
void AGOSEngine::loadSoundFile(const char* filename) {
- Common::SeekableReadStream *in;
-
- in = _archives.createReadStreamForMember(filename);
- if (!in)
+ Common::File in;
+ if (!in.open(filename))
error("loadSound: Can't load %s", filename);
- uint32 dstSize = in->size();
+ uint32 dstSize = in.size();
byte *dst = (byte *)malloc(dstSize);
- if (in->read(dst, dstSize) != dstSize)
+ if (in.read(dst, dstSize) != dstSize)
error("loadSound: Read failed");
- delete in;
_sound->playSfxData(dst, 0, 0, 0);
}
@@ -469,21 +466,19 @@ void AGOSEngine::loadSound(uint16 sound, int16 pan, int16 vol, uint16 type) {
byte *dst;
if (getGameId() == GID_DIMP) {
- Common::SeekableReadStream *in;
+ Common::File in;
char filename[15];
assert(sound >= 1 && sound <= 32);
sprintf(filename, "%s.wav", dimpSoundList[sound - 1]);
- in = _archives.createReadStreamForMember(filename);
- if (!in)
+ if (!in.open(filename))
error("loadSound: Can't load %s", filename);
- uint32 dstSize = in->size();
+ uint32 dstSize = in.size();
dst = (byte *)malloc(dstSize);
- if (in->read(dst, dstSize) != dstSize)
+ if (in.read(dst, dstSize) != dstSize)
error("loadSound: Read failed");
- delete in;
} else if (getFeatures() & GF_ZLIBCOMP) {
char filename[15];
diff --git a/engines/agos/saveload.cpp b/engines/agos/saveload.cpp
index 8eb7f066b3..8b133971de 100644
--- a/engines/agos/saveload.cpp
+++ b/engines/agos/saveload.cpp
@@ -1031,7 +1031,12 @@ bool AGOSEngine::loadGame(const Common::String &filename, bool restartMode) {
if (restartMode) {
// Load restart state
- f = _archives.createReadStreamForMember(filename);
+ Common::File *file = new Common::File();
+ if (!file->open(filename)) {
+ delete file;
+ file = nullptr;
+ }
+ f = file;
} else {
f = _saveFileMan->openForLoading(filename);
}
@@ -1205,7 +1210,12 @@ bool AGOSEngine_Elvira2::loadGame(const Common::String &filename, bool restartMo
if (restartMode) {
// Load restart state
- f = _archives.createReadStreamForMember(filename);
+ Common::File *file = new Common::File();
+ if (!file->open(filename)) {
+ delete file;
+ file = nullptr;
+ }
+ f = file;
} else {
f = _saveFileMan->openForLoading(filename);
}
diff --git a/engines/agos/subroutine.cpp b/engines/agos/subroutine.cpp
index f5aad2dcc8..7a84a20808 100644
--- a/engines/agos/subroutine.cpp
+++ b/engines/agos/subroutine.cpp
@@ -266,8 +266,8 @@ Common::SeekableReadStream *AGOSEngine::openTablesFile(const char *filename) {
}
Common::SeekableReadStream *AGOSEngine::openTablesFile_simon1(const char *filename) {
- Common::SeekableReadStream *in = _archives.createReadStreamForMember(filename);
- if (!in)
+ Common::File *in = new Common::File();
+ if (!in->open(filename))
error("openTablesFile: Can't open '%s'", filename);
return in;
}
diff --git a/engines/avalanche/animation.cpp b/engines/avalanche/animation.cpp
new file mode 100644
index 0000000000..639abe99b3
--- /dev/null
+++ b/engines/avalanche/animation.cpp
@@ -0,0 +1,1562 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public 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 based on the original source code of Lord Avalot d'Argent version 1.3.
+ * Copyright (c) 1994-1995 Mike, Mark and Thomas Thurman.
+ */
+
+/* TRIP5 Trippancy V - the sprite animation subsystem */
+
+#include "avalanche/avalanche.h"
+#include "avalanche/animation.h"
+
+namespace Avalanche {
+
+// Art gallery at 2,1; notice about this at 2,2.
+const int32 Animation::kCatacombMap[8][8] = {
+ // Geida's room
+ // 1 2 3 4 5 6 7 8
+ {0x204, 0x200, 0xd0f0, 0xf0ff, 0xff, 0xd20f, 0xd200, 0x200},
+ {0x50f1, 0x20ff, 0x2ff, 0xff, 0xe0ff, 0x20ff, 0x200f, 0x7210},
+ {0xe3f0, 0xe10f, 0x72f0, 0xff, 0xe0ff, 0xff, 0xff, 0x800f},
+ {0x2201, 0x2030, 0x800f, 0x220, 0x20f, 0x30, 0xff, 0x23f}, // >> Oubliette
+ {0x5024, 0xf3, 0xff, 0x200f, 0x22f0, 0x20f, 0x200, 0x7260},
+ {0xf0, 0x2ff, 0xe2ff, 0xff, 0x200f, 0x50f0, 0x72ff, 0x201f},
+ {0xf6, 0x220f, 0x22f0, 0x30f, 0xf0, 0x20f, 0x8200, 0x2f0}, // <<< In here
+ {0x34, 0x200f, 0x51f0, 0x201f, 0xf1, 0x50ff, 0x902f, 0x2062}
+};
+
+AnimationType::AnimationType(Animation *anim) {
+ _anim = anim;
+
+ _xLength = 0;
+ _yLength = 0;
+ for (int i = 0; i < 24; i++) {
+ _mani[i] = nullptr;
+ _sil[i] = nullptr;
+ }
+ _frameNum = 0;
+ _seq = 0;
+ _characterId = 0;
+ _count = 0;
+ _facingDir = kDirNone;
+ _stepNum = 0;
+ _x = 0;
+ _y = 0;
+ _moveX = 0;
+ _moveY = 0;
+ _quick = false;
+ _visible = false;
+ _homing = false;
+ _doCheck = false;
+ _homingX = 0;
+ _homingY = 0;
+ _speedX = 0;
+ _speedY = 0;
+ _vanishIfStill = false;
+ _callEachStepFl = false;
+ _eachStepProc = Animation::kProcNone;
+ _fgBubbleCol = kColorWhite;
+ _bgBubbleCol = kColorBlack;
+ _id = 177;
+}
+
+/**
+ * Loads & sets up the sprite.
+ */
+void AnimationType::init(byte spritenum, bool doCheck) {
+ const int32 idshould = -1317732048;
+
+ if (spritenum == 177)
+ return; // Already running!
+
+ Common::File inf;
+ Common::String filename = Common::String::format("sprite%d.avd", spritenum);
+ if (!inf.open(filename))
+ error("AVALANCHE: Trip: File not found: %s", filename.c_str());
+
+ inf.seek(177);
+
+ int32 id = inf.readSint32LE();
+ if (id != idshould) {
+ inf.close();
+ return;
+ }
+
+ // Replace variable named 'soa' in the original code.
+ inf.skip(2);
+ // Skip real name Size (1 byte) then fixed sized zone containing name (12 bytes)
+ inf.skip(1 + 12);
+ // Skip real comment size (1 byte) then fixed sized zone containing comment (16 bytes)
+ inf.skip(1 + 16);
+
+ _frameNum = inf.readByte();
+ _xLength = inf.readByte();
+ _yLength = inf.readByte();
+ _seq = inf.readByte();
+ uint16 size = inf.readUint16LE();
+ assert (size > 6);
+ _fgBubbleCol = (Color)inf.readByte();
+ _bgBubbleCol = (Color)inf.readByte();
+ _characterId = inf.readByte();
+
+ byte xWidth = _xLength / 8;
+ if ((_xLength % 8) > 0)
+ xWidth++;
+ for (int i = 0; i < _frameNum; i++) {
+ _sil[i] = new SilType[11 * (_yLength + 1)];
+ _mani[i] = new ManiType[size - 6];
+ for (int j = 0; j <= _yLength; j++)
+ inf.read((*_sil[i])[j], xWidth);
+ inf.read(*_mani[i], size - 6);
+ }
+
+ _x = 0;
+ _y = 0;
+ _quick = true;
+ _visible = false;
+ _speedX = kWalk;
+ _speedY = 1;
+ _homing = false;
+ _moveX = 0;
+ _moveY = 0;
+ _stepNum = 0;
+ _doCheck = doCheck;
+ _count = 0;
+ _id = spritenum;
+ _vanishIfStill = false;
+ _callEachStepFl = false;
+
+ inf.close();
+}
+
+/**
+ * Just sets 'quick' to false.
+ * @remarks Originally called 'original'
+ */
+void AnimationType::reset() {
+ _quick = false;
+ _id = 177;
+}
+
+/**
+ * Drops sprite onto screen.
+ * @remarks Originally called 'andexor'
+ */
+void AnimationType::draw() {
+ if (_vanishIfStill && (_moveX == 0) && (_moveY == 0))
+ return;
+
+ byte picnum = _facingDir * _seq + _stepNum;
+
+ _anim->_vm->_graphics->drawSprite(this, picnum, _x, _y);
+}
+
+/**
+ * Turns character round.
+ */
+void AnimationType::turn(Direction whichway) {
+ if (whichway == 8)
+ _facingDir = kDirUp;
+ else
+ _facingDir = whichway;
+}
+
+/**
+ * Switches it on.
+ */
+void AnimationType::appear(int16 wx, int16 wy, Direction wf) {
+ _x = (wx / 8) * 8;
+ _y = wy;
+ _oldX[_anim->_vm->_cp] = wx;
+ _oldY[_anim->_vm->_cp] = wy;
+ turn(wf);
+ _visible = true;
+ _moveX = 0;
+ _moveY = 0;
+}
+
+/**
+ * Check collision
+ * @remarks Originally called 'collision_check'
+ */
+bool AnimationType::checkCollision() {
+ for (int i = 0; i < _anim->kSpriteNumbMax; i++) {
+ AnimationType *spr = _anim->_sprites[i];
+ if (spr->_quick && (spr->_id != _id) && (_x + _xLength > spr->_x) && (_x < spr->_x + spr->_xLength) && (spr->_y == _y))
+ return true;
+ }
+
+ return false;
+}
+
+/**
+ * Prepares for draw(), etc.
+ */
+void AnimationType::walk() {
+ if (!_anim->_vm->_doingSpriteRun) {
+ _oldX[_anim->_vm->_cp] = _x;
+ _oldY[_anim->_vm->_cp] = _y;
+ if (_homing)
+ homeStep();
+ _x += _moveX;
+ _y += _moveY;
+ }
+
+ if (_doCheck) {
+ if (checkCollision()) {
+ bounce();
+ return;
+ }
+
+ byte magicColor = _anim->checkFeet(_x, _x + _xLength, _oldY[_anim->_vm->_cp], _y, _yLength) - 1;
+ // -1 is because the modified array indexes of magics[] compared to Pascal .
+
+ if ((magicColor != 255) & !_anim->_vm->_doingSpriteRun) {
+ MagicType *magic = &_anim->_vm->_magics[magicColor];
+ switch (magic->_operation) {
+ case kMagicExclaim:
+ bounce();
+ _anim->_mustExclaim = true;
+ _anim->_sayWhat = magic->_data;
+ break;
+ case kMagicBounce:
+ bounce();
+ break;
+ case kMagicTransport:
+ _anim->_vm->flipRoom((Room)(magic->_data >> 8), magic->_data & 0xff);
+ break;
+ case kMagicUnfinished: {
+ bounce();
+ Common::String tmpStr = Common::String::format("%c%cSorry.%cThis place is not available yet!",
+ kControlBell, kControlCenter, kControlRoman);
+ _anim->_vm->_dialogs->displayText(tmpStr);
+ }
+ break;
+ case kMagicSpecial:
+ _anim->callSpecial(magic->_data);
+ break;
+ case kMagicOpenDoor:
+ _anim->_vm->openDoor((Room)(magic->_data >> 8), magic->_data & 0xff, magicColor);
+ break;
+ }
+ }
+ }
+
+ if (!_anim->_vm->_doingSpriteRun) {
+ _count++;
+ if (((_moveX != 0) || (_moveY != 0)) && (_count > 1)) {
+ _stepNum++;
+ if (_stepNum == _seq)
+ _stepNum = 0;
+ _count = 0;
+ }
+ }
+}
+
+/**
+ * Bounces off walls
+ */
+void AnimationType::bounce() {
+ _x = _oldX[_anim->_vm->_cp];
+ _y = _oldY[_anim->_vm->_cp];
+ if (_doCheck)
+ _anim->stopWalking();
+ else
+ stopWalk();
+ _anim->_vm->drawDirection();
+}
+
+int8 AnimationType::getSign(int16 val) {
+ if (val > 0)
+ return 1;
+ else if (val < 0)
+ return -1;
+ else
+ return 0;
+}
+
+/**
+ * Home in on a point.
+ */
+void AnimationType::walkTo(byte pedNum) {
+ PedType *curPed = &_anim->_vm->_peds[pedNum];
+
+ setSpeed(getSign(curPed->_x - _x) * 4, getSign(curPed->_y - _y));
+ _homingX = curPed->_x - _xLength / 2;
+ _homingY = curPed->_y - _yLength;
+ _homing = true;
+}
+
+void AnimationType::stopHoming() {
+ _homing = false;
+}
+
+/**
+ * Calculates ix & iy for one homing step.
+ */
+void AnimationType::homeStep() {
+ int16 temp;
+
+ if ((_homingX == _x) && (_homingY == _y)) {
+ // touching the target
+ stopWalk();
+ return;
+ }
+ _moveX = 0;
+ _moveY = 0;
+ if (_homingY != _y) {
+ temp = _homingY - _y;
+ if (temp > 4)
+ _moveY = 4;
+ else if (temp < -4)
+ _moveY = -4;
+ else
+ _moveY = temp;
+ }
+ if (_homingX != _x) {
+ temp = _homingX - _x;
+ if (temp > 4)
+ _moveX = 4;
+ else if (temp < -4)
+ _moveX = -4;
+ else
+ _moveX = temp;
+ }
+}
+
+/**
+ * Sets ix & iy, non-homing, etc.
+ */
+void AnimationType::setSpeed(int8 xx, int8 yy) {
+ _moveX = xx;
+ _moveY = yy;
+ if ((_moveX == 0) && (_moveY == 0))
+ return; // no movement
+ if (_moveX == 0) {
+ // No horz movement
+ if (_moveY < 0)
+ turn(kDirUp);
+ else
+ turn(kDirDown);
+ } else {
+ if (_moveX < 0)
+ turn(kDirLeft);
+ else
+ turn(kDirRight);
+ }
+}
+
+/**
+ * Stops the sprite from moving.
+ */
+void AnimationType::stopWalk() {
+ _moveX = 0;
+ _moveY = 0;
+ _homing = false;
+}
+
+/**
+ * Sets up talk vars.
+ */
+void AnimationType::chatter() {
+ _anim->_vm->_dialogs->setTalkPos(_x + _xLength / 2, _y);
+ _anim->_vm->_graphics->setDialogColor(_bgBubbleCol, _fgBubbleCol);
+}
+
+void AnimationType::remove() {
+ for (int i = 0; i < _frameNum; i++) {
+ delete[] _mani[i];
+ delete[] _sil[i];
+ }
+
+ _quick = false;
+ _id = 177;
+}
+
+Animation::Animation(AvalancheEngine *vm) {
+ _vm = vm;
+ _mustExclaim = false;
+
+ for (int16 i = 0; i < kSpriteNumbMax; i++) {
+ _sprites[i] = new AnimationType(this);
+ }
+
+ _direction = kDirNone;
+ _oldDirection = kDirNone;
+ _arrowTriggered = false;
+ _geidaSpin = 0;
+ _geidaTime = 0;
+ _sayWhat = 0;
+}
+
+Animation::~Animation() {
+ for (int16 i = 0; i < kSpriteNumbMax; i++) {
+ AnimationType *curSpr = _sprites[i];
+
+ if (curSpr->_quick)
+ curSpr->remove();
+ delete(curSpr);
+ }
+}
+
+/**
+ * Resets Animation variables.
+ * @remarks Originally called 'loadtrip'
+ */
+void Animation::resetAnims() {
+ setDirection(kDirStopped);
+ for (int16 i = 0; i < kSpriteNumbMax; i++)
+ _sprites[i]->reset();
+}
+
+byte Animation::checkFeet(int16 x1, int16 x2, int16 oy, int16 y, byte yl) {
+ if (!_vm->_alive)
+ return 0;
+
+ if (x1 < 0)
+ x1 = 0;
+ if (x2 > 639)
+ x2 = 639;
+
+ int16 minY = MIN(oy, y) + yl;
+ int16 maxY = MAX(oy, y) + yl;
+
+ return _vm->_graphics->getAlsoColor(x1, minY, x2, maxY);
+}
+
+byte Animation::geidaPed(byte ped) {
+ switch (ped) {
+ case 1:
+ return 6;
+ case 2:
+ case 6:
+ return 7;
+ case 3:
+ case 5:
+ return 8;
+ case 4:
+ return 9;
+ default:
+ error("geidaPed(): Unhandled ped value %d", ped);
+ }
+}
+
+/**
+ * When you enter a new position in the catacombs, this procedure should be
+ * called. It changes the 'also' codes so that they may match the picture
+ * on the screen.
+ */
+void Animation::catacombMove(byte ped) {
+ // XY_uint16 is _catacombX+_catacombY*256. Thus, every room in the
+ // catacombs has a different number for it.
+ uint16 xy = _vm->_catacombX + _vm->_catacombY * 256;
+ _geidaSpin = 0;
+
+ switch (xy) {
+ case 1801: // Exit catacombs
+ _vm->flipRoom(kRoomLustiesRoom, 4);
+ _vm->_dialogs->displayText("Phew! Nice to be out of there!");
+ return;
+ case 1033:{ // Oubliette
+ _vm->flipRoom(kRoomOubliette, 1);
+ Common::String tmpStr = Common::String::format("Oh, NO!%c1%c", kControlRegister, kControlSpeechBubble);
+ _vm->_dialogs->displayText(tmpStr);
+ }
+ return;
+ case 4:
+ _vm->flipRoom(kRoomGeidas, 1);
+ return;
+ case 2307:
+ _vm->flipRoom(kRoomLusties, 5);
+ _vm->_dialogs->displayText("Oh no... here we go again...");
+ _vm->_userMovesAvvy = false;
+ _sprites[0]->_moveY = 1;
+ _sprites[0]->_moveX = 0;
+ return;
+ }
+
+ if (!_vm->_enterCatacombsFromLustiesRoom)
+ _vm->loadRoom(29);
+ int32 here = kCatacombMap[_vm->_catacombY - 1][_vm->_catacombX - 1];
+
+ switch (here & 0xf) { // West.
+ case 0: // no connection (wall)
+ _vm->_magics[1]._operation = kMagicBounce; // Sloping wall.
+ _vm->_magics[2]._operation = kMagicNothing; // Straight wall.
+ _vm->_portals[4]._operation = kMagicNothing; // Door.
+ _vm->_background->draw(-1, -1, 27);
+ break;
+ case 0x1: // no connection (wall + shield),
+ _vm->_magics[1]._operation = kMagicBounce; // Sloping wall.
+ _vm->_magics[2]._operation = kMagicNothing; // Straight wall.
+ _vm->_portals[4]._operation = kMagicNothing; // Door.
+ _vm->_background->draw(-1, -1, 27); // Wall, plus...
+ _vm->_background->draw(-1, -1, 28); // ...shield.
+ break;
+ case 0x2: // wall with door
+ _vm->_magics[1]._operation = kMagicBounce; // Sloping wall.
+ _vm->_magics[2]._operation = kMagicNothing; // Straight wall.
+ _vm->_portals[4]._operation = kMagicSpecial; // Door.
+ _vm->_background->draw(-1, -1, 27); // Wall, plus...
+ _vm->_background->draw(-1, -1, 29); // ...door.
+ break;
+ case 0x3: // wall with door and shield
+ _vm->_magics[1]._operation = kMagicBounce; // Sloping wall.
+ _vm->_magics[2]._operation = kMagicNothing; // Straight wall.
+ _vm->_portals[4]._operation = kMagicSpecial; // Door.
+ _vm->_background->draw(-1, -1, 27); // Wall, plus...
+ _vm->_background->draw(-1, -1, 29); // ...door, and...
+ _vm->_background->draw(-1, -1, 28); // ...shield.
+ break;
+ case 0x4: // no connection (wall + window),
+ _vm->_magics[1]._operation = kMagicBounce; // Sloping wall.
+ _vm->_magics[2]._operation = kMagicNothing; // Straight wall.
+ _vm->_portals[4]._operation = kMagicNothing; // Door.
+ _vm->_background->draw(-1, -1, 27); // Wall, plus...
+ _vm->_background->draw(-1, -1, 4); // ...window.
+ break;
+ case 0x5: // wall with door and window
+ _vm->_magics[1]._operation = kMagicBounce; // Sloping wall.
+ _vm->_magics[2]._operation = kMagicNothing; // Straight wall.
+ _vm->_portals[4]._operation = kMagicSpecial; // Door.
+ _vm->_background->draw(-1, -1, 27); // Wall, plus...
+ _vm->_background->draw(-1, -1, 29); // ...door, and...
+ _vm->_background->draw(-1, -1, 4); // ...window.
+ break;
+ case 0x6: // no connection (wall + torches),
+ _vm->_magics[1]._operation = kMagicBounce; // Sloping wall.
+ _vm->_magics[2]._operation = kMagicNothing; // Straight wall.
+ _vm->_portals[4]._operation = kMagicNothing; // No door.
+ _vm->_background->draw(-1, -1, 27); // Wall, plus...
+ _vm->_background->draw(-1, -1, 6); // ...torches.
+ break;
+ case 0x7: // wall with door and torches
+ _vm->_magics[1]._operation = kMagicBounce; // Sloping wall.
+ _vm->_magics[2]._operation = kMagicNothing; // Straight wall.
+ _vm->_portals[4]._operation = kMagicSpecial; // Door.
+ _vm->_background->draw(-1, -1, 27); // Wall, plus...
+ _vm->_background->draw(-1, -1, 29); // ...door, and...
+ _vm->_background->draw(-1, -1, 6); // ...torches.
+ break;
+ case 0xf: // straight-through corridor.
+ _vm->_magics[1]._operation = kMagicNothing; // Sloping wall.
+ _vm->_magics[2]._operation = kMagicSpecial; // Straight wall.
+ break;
+ }
+
+ /* ---- */
+
+ switch ((here & 0xf0) >> 4) { // East
+ case 0: // no connection (wall)
+ _vm->_magics[4]._operation = kMagicBounce; // Sloping wall.
+ _vm->_magics[5]._operation = kMagicNothing; // Straight wall.
+ _vm->_portals[6]._operation = kMagicNothing; // Door.
+ _vm->_background->draw(-1, -1, 18);
+ break;
+ case 0x1: // no connection (wall + window),
+ _vm->_magics[4]._operation = kMagicBounce; // Sloping wall.
+ _vm->_magics[5]._operation = kMagicNothing; // Straight wall.
+ _vm->_portals[6]._operation = kMagicNothing; // Door.
+ _vm->_background->draw(-1, -1, 18); // Wall, plus...
+ _vm->_background->draw(-1, -1, 19); // ...window.
+ break;
+ case 0x2: // wall with door
+ _vm->_magics[4]._operation = kMagicBounce; // Sloping wall.
+ _vm->_magics[5]._operation = kMagicNothing; // Straight wall.
+ _vm->_portals[6]._operation = kMagicSpecial; // Door.
+ _vm->_background->draw(-1, -1, 18); // Wall, plus...
+ _vm->_background->draw(-1, -1, 20); // ...door.
+ break;
+ case 0x3: // wall with door and window
+ _vm->_magics[4]._operation = kMagicBounce; // Sloping wall.
+ _vm->_magics[5]._operation = kMagicNothing; // Straight wall.
+ _vm->_portals[6]._operation = kMagicSpecial; // Door.
+ _vm->_background->draw(-1, -1, 18); // Wall, plus...
+ _vm->_background->draw(-1, -1, 19); // ...door, and...
+ _vm->_background->draw(-1, -1, 20); // ...window.
+ break;
+ case 0x6: // no connection (wall + torches),
+ _vm->_magics[4]._operation = kMagicBounce; // Sloping wall.
+ _vm->_magics[5]._operation = kMagicNothing; // Straight wall.
+ _vm->_portals[6]._operation = kMagicNothing; // No door.
+ _vm->_background->draw(-1, -1, 18); // Wall, plus...
+ _vm->_background->draw(-1, -1, 17); // ...torches.
+ break;
+ case 0x7: // wall with door and torches
+ _vm->_magics[4]._operation = kMagicBounce; // Sloping wall.
+ _vm->_magics[5]._operation = kMagicNothing; // Straight wall.
+ _vm->_portals[6]._operation = kMagicSpecial; // Door.
+ _vm->_background->draw(-1, -1, 18); // Wall, plus...
+ _vm->_background->draw(-1, -1, 20); // ...door, and...
+ _vm->_background->draw(-1, -1, 17); // ...torches.
+ break;
+ case 0xf: // straight-through corridor.
+ _vm->_magics[4]._operation = kMagicNothing; // Sloping wall.
+ _vm->_magics[5]._operation = kMagicSpecial; // Straight wall.
+ _vm->_portals[6]._operation = kMagicNothing; // Door.
+ break;
+ }
+
+ switch ((here & 0xf00) >> 8) { // South
+ case 0: // No connection.
+ _vm->_magics[6]._operation = kMagicBounce;
+ _vm->_magics[11]._operation = kMagicBounce;
+ _vm->_magics[12]._operation = kMagicBounce;
+ break;
+ case 0x1:
+ _vm->_background->draw(-1, -1, 21);
+
+ if ((xy == 2051) && _vm->_geidaFollows)
+ _vm->_magics[12]._operation = kMagicExclaim;
+ else
+ _vm->_magics[12]._operation = kMagicSpecial; // Right exit south.
+
+ _vm->_magics[6]._operation = kMagicBounce;
+ _vm->_magics[11]._operation = kMagicBounce;
+ break;
+ case 0x2:
+ _vm->_background->draw(-1, -1, 22);
+ _vm->_magics[6]._operation = kMagicSpecial; // Middle exit south.
+ _vm->_magics[11]._operation = kMagicBounce;
+ _vm->_magics[12]._operation = kMagicBounce;
+ break;
+ case 0x3:
+ _vm->_background->draw(-1, -1, 23);
+ _vm->_magics[11]._operation = kMagicSpecial; // Left exit south.
+ _vm->_magics[6]._operation = kMagicBounce;
+ _vm->_magics[12]._operation = kMagicBounce;
+ break;
+ }
+
+ switch ((here & 0xf000) >> 12) { // North
+ case 0: // No connection
+ _vm->_magics[0]._operation = kMagicBounce;
+ _vm->_portals[3]._operation = kMagicNothing; // Door.
+ break;
+ // LEFT handles:
+#if 0
+ case 0x1:
+ _vm->_celer->show_one(-1, -1, 4);
+ _vm->magics[1].op = _vm->bounces; // { Left exit north. } { Change magic number! }
+ _vm->portals[12].op = _vm->special; // { Door. }
+ break;
+#endif
+ case 0x2:
+ _vm->_background->draw(-1, -1, 3);
+ _vm->_magics[0]._operation = kMagicBounce; // Middle exit north.
+ _vm->_portals[3]._operation = kMagicSpecial; // Door.
+ break;
+#if 0
+ case 0x3:
+ _vm->_celer->show_one(-1, -1, 4);
+ _vm->magics[1].op = _vm->bounces; // { Right exit north. } { Change magic number! }
+ _vm->portals[12].op = _vm->special; // { Door. }
+ break;
+ // RIGHT handles:
+ case 0x4:
+ _vm->_celer->show_one(-1, -1, 3);
+ _vm->magics[1].op = _vm->bounces; // { Left exit north. } { Change magic number! }
+ _vm->portals[12].op = _vm->special; // { Door. }
+ break;
+#endif
+ case 0x5:
+ _vm->_background->draw(-1, -1, 2);
+ _vm->_magics[0]._operation = kMagicBounce; // Middle exit north.
+ _vm->_portals[3]._operation = kMagicSpecial; // Door.
+ break;
+#if 0
+ case 0x6:
+ _vm->_celer->show_one(-1, -1, 3);
+ _vm->magics[1].op = _vm->bounces; // { Right exit north. }
+ _vm->portals[12].op = _vm->special; // { Door. }
+ break;
+#endif
+ // ARCHWAYS:
+ case 0x7:
+ case 0x8:
+ case 0x9:
+ _vm->_background->draw(-1, -1, 5);
+
+ if (((here & 0xf000) >> 12) > 0x7)
+ _vm->_background->draw(-1, -1, 30);
+ if (((here & 0xf000) >> 12) == 0x9)
+ _vm->_background->draw(-1, -1, 31);
+
+ _vm->_magics[0]._operation = kMagicSpecial; // Middle arch north.
+ _vm->_portals[3]._operation = kMagicNothing; // Door.
+ break;
+ // DECORATIONS:
+ case 0xd: // No connection + WINDOW
+ _vm->_magics[0]._operation = kMagicBounce;
+ _vm->_portals[3]._operation = kMagicNothing; // Door.
+ _vm->_background->draw(-1, -1, 13);
+ break;
+ case 0xe: // No connection + TORCH
+ _vm->_magics[0]._operation = kMagicBounce;
+ _vm->_portals[3]._operation = kMagicNothing; // Door.
+ _vm->_background->draw(-1, -1, 7);
+ break;
+ // Recessed door:
+ case 0xf:
+ _vm->_magics[0]._operation = kMagicNothing; // Door to Geida's room.
+ _vm->_background->draw(-1, -1, 0);
+ _vm->_portals[3]._operation = kMagicSpecial; // Door.
+ break;
+ }
+
+ switch (xy) {
+ case 514:
+ _vm->_background->draw(-1, -1, 16);
+ break; // [2,2] : "Art Gallery" sign over door.
+ case 264:
+ _vm->_background->draw(-1, -1, 8);
+ break; // [8,1] : "The Wrong Way!" sign.
+ case 1797:
+ _vm->_background->draw(-1, -1, 1);
+ break; // [5,7] : "Ite Mingite" sign.
+ case 258:
+ for (int i = 0; i <= 2; i++) { // [2,1] : Art gallery - pictures
+ _vm->_background->draw(130 + i * 120, 70, 14);
+ _vm->_background->draw(184 + i * 120, 78, 15);
+ }
+ break;
+ case 1287:
+ for (int i = 10; i <= 13; i++)
+ _vm->_background->draw(-1, -1, i - 1);
+ break; // [7,5] : 4 candles.
+ case 776:
+ _vm->_background->draw(-1, -1, 9);
+ break; // [8,3] : 1 candle.
+ case 2049:
+ _vm->_background->draw(-1, -1, 10);
+ break; // [1,8] : another candle.
+ case 257:
+ _vm->_background->draw(-1, -1, 11);
+ _vm->_background->draw(-1, -1, 12);
+ break; // [1,1] : the other two.
+ }
+
+ if (_vm->_geidaFollows && (ped > 0)) {
+ AnimationType *spr1 = _sprites[1];
+
+ if (!spr1->_quick) // If we don't already have her...
+ spr1->init(5, true); // ...Load Geida.
+ appearPed(1, geidaPed(ped));
+ spr1->_callEachStepFl = true;
+ spr1->_eachStepProc = kProcGeida;
+ }
+}
+
+/**
+ * This proc gets called whenever you touch a line defined as _vm->special.
+ */
+void Animation::dawnDelay() {
+ _vm->_timer->addTimer(2, Timer::kProcDawnDelay, Timer::kReasonDawndelay);
+}
+
+void Animation::callSpecial(uint16 which) {
+ switch (which) {
+ case 1: // _vm->special 1: Room 22: top of stairs.
+ _vm->_background->draw(-1, -1, 0);
+ _vm->_brummieStairs = 1;
+ _vm->_magics[9]._operation = kMagicNothing;
+ _vm->_timer->addTimer(10, Timer::kProcStairs, Timer::kReasonBrummieStairs);
+ stopWalking();
+ _vm->_userMovesAvvy = false;
+ break;
+ case 2: // _vm->special 2: Room 22: bottom of stairs.
+ _vm->_brummieStairs = 3;
+ _vm->_magics[10]._operation = kMagicNothing;
+ _vm->_magics[11]._operation = kMagicExclaim;
+ _vm->_magics[11]._data = 5;
+ _vm->_magics[3]._operation = kMagicBounce; // Now works as planned!
+ stopWalking();
+ _vm->_dialogs->displayScrollChain('Q', 26);
+ _vm->_userMovesAvvy = true;
+ break;
+ case 3: // _vm->special 3: Room 71: triggers dart.
+ _sprites[0]->bounce(); // Must include that.
+
+ if (!_arrowTriggered) {
+ _arrowTriggered = true;
+
+ AnimationType *spr1 = _sprites[1];
+ appearPed(1, 3); // The dart starts at ped 4, and...
+ spr1->walkTo(4); // flies to ped 5 (- 1 for pascal to C conversion).
+ spr1->_facingDir = kDirUp; // Only face.
+ // Should call some kind of Eachstep procedure which will deallocate
+ // the sprite when it hits the wall, and replace it with the chunk
+ // graphic of the arrow buried in the plaster. */
+
+ // OK!
+ spr1->_callEachStepFl = true;
+ spr1->_eachStepProc = kProcArrow;
+ }
+ break;
+ case 4: // This is the ghost room link.
+ _vm->fadeOut();
+ _sprites[0]->turn(kDirRight); // you'll see this after we get back from bootstrap
+ _vm->_timer->addTimer(1, Timer::kProcGhostRoomPhew, Timer::kReasonGhostRoomPhew);
+ //_vm->_enid->backToBootstrap(3); TODO: Replace it with proper ScummVM-friendly function(s)! Do not remove until then!
+ break;
+ case 5:
+ if (_vm->_friarWillTieYouUp) {
+ // _vm->special 5: Room 42: touched tree, and get tied up.
+ _vm->_magics[4]._operation = kMagicBounce; // Boundary effect is now working again.
+ _vm->_dialogs->displayScrollChain('Q', 35);
+ _sprites[0]->remove();
+
+ AnimationType *spr1 = _sprites[1];
+ _vm->_background->draw(-1, -1, 1);
+ _vm->_dialogs->displayScrollChain('Q', 36);
+ _vm->_tiedUp = true;
+ _vm->_friarWillTieYouUp = false;
+ spr1->walkTo(2);
+ spr1->_vanishIfStill = true;
+ spr1->_doCheck = true; // One of them must have Check_Me switched on.
+ _vm->setRoom(kPeopleFriarTuck, kRoomDummy); // Not here, then.
+ _vm->_timer->addTimer(364, Timer::kProcHangAround, Timer::kReasonHangingAround);
+ }
+ break;
+ case 6: {
+ // _vm->special 6: fall down oubliette.
+ AnimationType *avvy = _sprites[0];
+ _vm->_userMovesAvvy = false;
+ avvy->_moveX = 3;
+ avvy->_moveY = 0;
+ avvy->_facingDir = kDirRight;
+ _vm->_timer->addTimer(1, Timer::kProcFallDownOubliette, Timer::kReasonFallingDownOubliette);
+ }
+ break;
+ case 7: // _vm->special 7: stop falling down oubliette.
+ _sprites[0]->_visible = false;
+ _vm->_magics[9]._operation = kMagicNothing;
+ stopWalking();
+ _vm->_timer->loseTimer(Timer::kReasonFallingDownOubliette);
+ //_vm->mblit(12, 80, 38, 160, 3, 0);
+ //_vm->mblit(12, 80, 38, 160, 3, 1);
+ _vm->_dialogs->displayText("Oh dear, you seem to be down the bottom of an oubliette.");
+ _vm->_timer->addTimer(200, Timer::kProcMeetAvaroid, Timer::kReasonMeetingAvaroid);
+ break;
+ case 8: // _vm->special 8: leave du Lustie's room.
+ if (_vm->_geidaFollows && !_vm->_lustieIsAsleep) {
+ AnimationType *spr1 = _sprites[1];
+ _vm->_dialogs->displayScrollChain('Q', 63);
+ spr1->turn(kDirDown);
+ spr1->stopWalk();
+ spr1->_callEachStepFl = false; // Geida
+ _vm->gameOver();
+ }
+ break;
+ case 9: {
+ // _vm->special 9: lose Geida to Robin Hood...
+ if (!_vm->_geidaFollows)
+ return; // DOESN'T COUNT: no Geida.
+ AnimationType *spr1 = _sprites[1];
+ spr1->_callEachStepFl = false; // She no longer follows Avvy around.
+ spr1->walkTo(3); // She walks to somewhere...
+ _sprites[0]->remove(); // Lose Avvy.
+ _vm->_userMovesAvvy = false;
+ _vm->_timer->addTimer(40, Timer::kProcRobinHoodAndGeida, Timer::kReasonRobinHoodAndGeida);
+ }
+ break;
+ case 10: // _vm->special 10: transfer north in catacombs.
+ if ((_vm->_catacombX == 4) && (_vm->_catacombY == 1)) {
+ // Into Geida's room.
+ if (_vm->_objects[kObjectKey - 1])
+ _vm->_dialogs->displayScrollChain('Q', 62);
+ else {
+ _vm->_dialogs->displayScrollChain('Q', 61);
+ return;
+ }
+ }
+ _vm->fadeOut();
+ _vm->_catacombY--;
+ catacombMove(4);
+ if (_vm->_room != kRoomCatacombs)
+ return;
+ switch ((kCatacombMap[_vm->_catacombY - 1][_vm->_catacombX - 1] & 0xf00) >> 8) {
+ case 0x1:
+ appearPed(0, 11);
+ break;
+ case 0x3:
+ appearPed(0, 10);
+ break;
+ default:
+ appearPed(0, 3);
+ }
+ dawnDelay();
+ break;
+ case 11: // _vm->special 11: transfer east in catacombs.
+ _vm->fadeOut();
+ _vm->_catacombX++;
+ catacombMove(1);
+ if (_vm->_room != kRoomCatacombs)
+ return;
+ appearPed(0, 0);
+ dawnDelay();
+ break;
+ case 12: // _vm->special 12: transfer south in catacombs.
+ _vm->fadeOut();
+ _vm->_catacombY++;
+ catacombMove(2);
+ if (_vm->_room != kRoomCatacombs)
+ return;
+ appearPed(0, 1);
+ dawnDelay();
+ break;
+ case 13: // _vm->special 13: transfer west in catacombs.
+ _vm->fadeOut();
+ _vm->_catacombX--;
+ catacombMove(3);
+ if (_vm->_room != kRoomCatacombs)
+ return;
+ appearPed(0, 2);
+ dawnDelay();
+ break;
+ }
+}
+
+void Animation::updateSpeed() {
+ AnimationType *avvy = _sprites[0];
+ // Given that you've just changed the speed in _speedX, this adjusts _moveX.
+ avvy->_moveX = (avvy->_moveX / 3) * avvy->_speedX;
+ _vm->_graphics->drawSpeedBar(avvy->_speedX);
+}
+
+void Animation::setMoveSpeed(byte t, Direction dir) {
+ AnimationType *spr = _sprites[t];
+ switch (dir) {
+ case kDirUp:
+ spr->setSpeed(0, -spr->_speedY);
+ break;
+ case kDirDown:
+ spr->setSpeed(0, spr->_speedY);
+ break;
+ case kDirLeft:
+ spr->setSpeed(-spr->_speedX, 0);
+ break;
+ case kDirRight:
+ spr->setSpeed(spr->_speedX, 0);
+ break;
+ case kDirUpLeft:
+ spr->setSpeed(-spr->_speedX, -spr->_speedY);
+ break;
+ case kDirUpRight:
+ spr->setSpeed(spr->_speedX, -spr->_speedY);
+ break;
+ case kDirDownLeft:
+ spr->setSpeed(-spr->_speedX, spr->_speedY);
+ break;
+ case kDirDownRight:
+ spr->setSpeed(spr->_speedX, spr->_speedY);
+ break;
+ default:
+ break;
+ }
+}
+
+void Animation::appearPed(byte sprNum, byte pedNum) {
+ AnimationType *curSpr = _sprites[sprNum];
+ PedType *curPed = &_vm->_peds[pedNum];
+ curSpr->appear(curPed->_x - curSpr->_xLength / 2, curPed->_y - curSpr->_yLength, curPed->_direction);
+ setMoveSpeed(sprNum, curPed->_direction);
+}
+
+/**
+ * @remarks Originally called 'follow_avvy_y'
+ */
+void Animation::followAvalotY(byte tripnum) {
+ if (_sprites[0]->_facingDir == kDirLeft)
+ return;
+
+ AnimationType *tripSpr = _sprites[tripnum];
+ AnimationType *spr1 = _sprites[1];
+
+ if (tripSpr->_homing)
+ tripSpr->_homingY = spr1->_y;
+ else {
+ if (tripSpr->_y < spr1->_y)
+ tripSpr->_y++;
+ else if (tripSpr->_y > spr1->_y)
+ tripSpr->_y--;
+ else
+ return;
+
+ if (tripSpr->_moveX == 0) {
+ tripSpr->_stepNum++;
+ if (tripSpr->_stepNum == tripSpr->_seq)
+ tripSpr->_stepNum = 0;
+ tripSpr->_count = 0;
+ }
+ }
+}
+
+void Animation::backAndForth(byte tripnum) {
+ AnimationType *tripSpr = _sprites[tripnum];
+
+ if (!tripSpr->_homing) {
+ if (tripSpr->_facingDir == kDirRight)
+ tripSpr->walkTo(3);
+ else
+ tripSpr->walkTo(4);
+ }
+}
+
+void Animation::faceAvvy(byte tripnum) {
+ AnimationType *tripSpr = _sprites[tripnum];
+
+ if (!tripSpr->_homing) {
+ if (_sprites[0]->_x >= tripSpr->_x)
+ tripSpr->_facingDir = kDirRight;
+ else
+ tripSpr->_facingDir = kDirLeft;
+ }
+}
+
+void Animation::arrowProcs(byte tripnum) {
+ AnimationType *tripSpr = _sprites[tripnum];
+ AnimationType *avvy = _sprites[tripnum];
+
+ if (tripSpr->_homing) {
+ // Arrow is still in flight.
+ // We must check whether or not the arrow has collided tr[tripnum] Avvy's head.
+ // This is so if: a) the bottom of the arrow is below Avvy's head,
+ // b) the left of the arrow is left of the right of Avvy's head, and
+ // c) the right of the arrow is right of the left of Avvy's head.
+ if ((tripSpr->_y + tripSpr->_yLength >= avvy->_y) // A
+ && (tripSpr->_x <= avvy->_x + avvy->_xLength) // B
+ && (tripSpr->_x + tripSpr->_xLength >= avvy->_x)) { // C
+ // OK, it's hit him... what now?
+
+ _sprites[1]->_callEachStepFl = false; // prevent recursion.
+ _vm->_dialogs->displayScrollChain('Q', 47); // Complaint!
+ tripSpr->remove(); // Deallocate the arrow.
+
+ _vm->gameOver();
+
+ _vm->_userMovesAvvy = false; // Stop the user from moving him.
+ _vm->_timer->addTimer(55, Timer::kProcNaughtyDuke, Timer::kReasonNaughtyDuke);
+ }
+ } else { // Arrow has hit the wall!
+ tripSpr->remove(); // Deallocate the arrow.
+ _vm->_background->draw(-1, -1, 2); // Show pic of arrow stuck into the door.
+ _vm->_arrowInTheDoor = true; // So that we can pick it up.
+ }
+}
+
+void Animation::grabAvvy(byte tripnum) { // For Friar Tuck, in Nottingham.
+ AnimationType *tripSpr = _sprites[tripnum];
+ AnimationType *avvy = _sprites[0];
+
+ int16 tox = avvy->_x + 17;
+ int16 toy = avvy->_y - 1;
+ if ((tripSpr->_x == tox) && (tripSpr->_y == toy)) {
+ tripSpr->_callEachStepFl = false;
+ tripSpr->_facingDir = kDirLeft;
+ tripSpr->stopWalk();
+ // ... whatever ...
+ } else {
+ // Still some way to go.
+ if (tripSpr->_x < tox) {
+ tripSpr->_x += 5;
+ if (tripSpr->_x > tox)
+ tripSpr->_x = tox;
+ }
+ if (tripSpr->_y < toy)
+ tripSpr->_y++;
+ tripSpr->_stepNum++;
+ if (tripSpr->_stepNum == tripSpr->_seq)
+ tripSpr->_stepNum = 0;
+ }
+}
+
+void Animation::takeAStep(byte &tripnum) {
+ AnimationType *tripSpr = _sprites[tripnum];
+
+ if (tripSpr->_moveX == 0) {
+ tripSpr->_stepNum++;
+ if (tripSpr->_stepNum == tripSpr->_seq)
+ tripSpr->_stepNum = 0;
+ tripSpr->_count = 0;
+ }
+}
+
+void Animation::spin(Direction dir, byte &tripnum) {
+ AnimationType *tripSpr = _sprites[tripnum];
+
+ if (tripSpr->_facingDir == dir)
+ return;
+
+ tripSpr->_facingDir = dir;
+ if (tripSpr->_id == 2)
+ return; // Not for Spludwick
+
+ _geidaSpin++;
+ _geidaTime = 20;
+ if (_geidaSpin == 5) {
+ _vm->_dialogs->displayText("Steady on, Avvy, you'll make the poor girl dizzy!");
+ _geidaSpin = 0;
+ _geidaTime = 0; // knock out records
+ }
+}
+
+void Animation::geidaProcs(byte tripnum) {
+ AnimationType *tripSpr = _sprites[tripnum];
+ AnimationType *avvy = _sprites[0];
+
+ if (_geidaTime > 0) {
+ _geidaTime--;
+ if (_geidaTime == 0)
+ _geidaSpin = 0;
+ }
+
+ if (tripSpr->_y < (avvy->_y - 2)) {
+ // Geida is further from the screen than Avvy.
+ spin(kDirDown, tripnum);
+ tripSpr->_moveY = 1;
+ tripSpr->_moveX = 0;
+ takeAStep(tripnum);
+ return;
+ } else if (tripSpr->_y > (avvy->_y + 2)) {
+ // Avvy is further from the screen than Geida.
+ spin(kDirUp, tripnum);
+ tripSpr->_moveY = -1;
+ tripSpr->_moveX = 0;
+ takeAStep(tripnum);
+ return;
+ }
+
+ tripSpr->_moveY = 0;
+ // These 12-s are not in the original, I added them to make the following method more "smooth".
+ // Now the NPC which is following Avvy won't block his way and will walk next to him properly.
+ if (tripSpr->_x < avvy->_x - avvy->_speedX * 8 - 12) {
+ tripSpr->_moveX = avvy->_speedX;
+ spin(kDirRight, tripnum);
+ takeAStep(tripnum);
+ } else if (tripSpr->_x > avvy->_x + avvy->_speedX * 8 + 12) {
+ tripSpr->_moveX = -avvy->_speedX;
+ spin(kDirLeft, tripnum);
+ takeAStep(tripnum);
+ } else
+ tripSpr->_moveX = 0;
+}
+
+/**
+ * @remarks Originally called 'call_andexors'
+ */
+void Animation::drawSprites() {
+ int8 order[5];
+ byte temp;
+ bool ok;
+
+ for (int i = 0; i < 5; i++)
+ order[i] = -1;
+
+ for (int16 i = 0; i < kSpriteNumbMax; i++) {
+ AnimationType *curSpr = _sprites[i];
+ if (curSpr->_quick && curSpr->_visible)
+ order[i] = i;
+ }
+
+ do {
+ ok = true;
+ for (int i = 0; i < 4; i++) {
+ if ((order[i] != -1) && (order[i + 1] != -1) && (_sprites[order[i]]->_y > _sprites[order[i + 1]]->_y)) {
+ // Swap them!
+ temp = order[i];
+ order[i] = order[i + 1];
+ order[i + 1] = temp;
+ ok = false;
+ }
+ }
+ } while (!ok);
+
+ _vm->_graphics->refreshBackground();
+
+ for (int i = 0; i < 5; i++) {
+ if (order[i] > -1)
+ _sprites[order[i]]->draw();
+ }
+}
+
+/**
+ * Animation links
+ * @remarks Originally called 'trippancy_link'
+ */
+void Animation::animLink() {
+ if (_vm->_menu->isActive() || _vm->_seeScroll)
+ return;
+ for (int16 i = 0; i < kSpriteNumbMax; i++) {
+ AnimationType *curSpr = _sprites[i];
+ if (curSpr->_quick && curSpr->_visible)
+ curSpr->walk();
+ }
+
+ drawSprites();
+
+ for (int16 i = 0; i < kSpriteNumbMax; i++) {
+ AnimationType *curSpr = _sprites[i];
+ if (curSpr->_quick && curSpr->_callEachStepFl) {
+ switch (curSpr->_eachStepProc) {
+ case kProcFollowAvvyY :
+ followAvalotY(i);
+ break;
+ case kProcBackAndForth :
+ backAndForth(i);
+ break;
+ case kProcFaceAvvy :
+ faceAvvy(i);
+ break;
+ case kProcArrow :
+ arrowProcs(i);
+ break;
+ // PROCSpludwick_procs : spludwick_procs(fv);
+ case kProcGrabAvvy :
+ grabAvvy(i);
+ break;
+ case kProcGeida :
+ geidaProcs(i);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ if (_mustExclaim) {
+ _mustExclaim = false;
+ _vm->_dialogs->displayScrollChain('X', _sayWhat);
+ }
+}
+
+void Animation::stopWalking() {
+ AnimationType *avvy = _sprites[0];
+
+ avvy->stopWalk();
+ _direction = kDirStopped;
+ if (_vm->_alive)
+ avvy->_stepNum = 1;
+}
+
+/**
+ * Hide in the cupboard
+ * @remarks Originally called 'hide_in_the_cupboard'
+ */
+void Animation::hideInCupboard() {
+ if (_vm->_avvysInTheCupboard) {
+ if (_vm->_parser->_wearing == kObjectDummy) {
+ Common::String tmpStr = Common::String::format("%cAVVY!%cGet dressed first!", kControlItalic, kControlRoman);
+ _vm->_dialogs->displayText(tmpStr);
+ } else {
+ _sprites[0]->_visible = true;
+ _vm->_userMovesAvvy = true;
+ appearPed(0, 2); // Walk out of the cupboard.
+ _vm->_dialogs->displayText("You leave the cupboard. Nice to be out of there!");
+ _vm->_avvysInTheCupboard = false;
+ _vm->_sequence->startCupboardSeq();
+ }
+ } else {
+ // Not hiding in the cupboard
+ _sprites[0]->_visible = false;
+ _vm->_userMovesAvvy = false;
+ Common::String tmpStr = Common::String::format("You walk into the room...%cIt seems to be an empty, " \
+ "but dusty, cupboard. Hmmmm... you leave the door slightly open to avoid suffocation.", kControlParagraph);
+ _vm->_dialogs->displayText(tmpStr);
+ _vm->_avvysInTheCupboard = true;
+ _vm->_background->draw(-1, -1, 7);
+ }
+}
+
+/**
+ * Returns true if you're within field "which".
+ */
+bool Animation::inField(byte which) {
+ AnimationType *avvy = _sprites[0];
+
+ FieldType *curField = &_vm->_fields[which];
+ int16 yy = avvy->_y + avvy->_yLength;
+
+ return (avvy->_x >= curField->_x1) && (avvy->_x <= curField->_x2) && (yy >= curField->_y1) && (yy <= curField->_y2);
+}
+
+/**
+ * Returns True if you're near a door.
+ */
+bool Animation::nearDoor() {
+ if (_vm->_fieldNum < 8)
+ // there ARE no doors here!
+ return false;
+
+ AnimationType *avvy = _sprites[0];
+
+ int16 ux = avvy->_x;
+ int16 uy = avvy->_y + avvy->_yLength;
+
+ for (int i = 8; i < _vm->_fieldNum; i++) {
+ FieldType *curField = &_vm->_fields[i];
+ if ((ux >= curField->_x1) && (ux <= curField->_x2) && (uy >= curField->_y1) && (uy <= curField->_y2))
+ return true;
+ }
+
+ return false;
+}
+
+/**
+ * @remarks Originally called 'tripkey'
+ */
+void Animation::handleMoveKey(const Common::Event &event) {
+ if (!_vm->_userMovesAvvy)
+ return;
+
+ if (_vm->_menu->_activeMenuItem._activeNow)
+ _vm->_parser->tryDropdown();
+ else {
+ switch (event.kbd.keycode) {
+ case Common::KEYCODE_UP:
+ if (_direction != kDirUp) {
+ _direction = kDirUp;
+ setMoveSpeed(0, _direction);
+ } else
+ stopWalking();
+ break;
+ case Common::KEYCODE_DOWN:
+ if (_direction != kDirDown) {
+ _direction = kDirDown;
+ setMoveSpeed(0, _direction);
+ } else
+ stopWalking();
+ break;
+ case Common::KEYCODE_LEFT:
+ if (_direction != kDirLeft) {
+ _direction = kDirLeft;
+ setMoveSpeed(0, _direction);
+ } else
+ stopWalking();
+ break;
+ case Common::KEYCODE_RIGHT:
+ if (_direction != kDirRight) {
+ _direction = kDirRight;
+ setMoveSpeed(0, _direction);
+ } else
+ stopWalking();
+ break;
+ case Common::KEYCODE_PAGEUP:
+ if (_direction != kDirUpRight) {
+ _direction = kDirUpRight;
+ setMoveSpeed(0, _direction);
+ } else
+ stopWalking();
+ break;
+ case Common::KEYCODE_PAGEDOWN:
+ if (_direction != kDirDownRight) {
+ _direction = kDirDownRight;
+ setMoveSpeed(0, _direction);
+ } else
+ stopWalking();
+ break;
+ case Common::KEYCODE_END:
+ if (_direction != kDirDownLeft) {
+ _direction = kDirDownLeft;
+ setMoveSpeed(0, _direction);
+ } else
+ stopWalking();
+ break;
+ case Common::KEYCODE_HOME:
+ if (_direction != kDirUpLeft) {
+ _direction = kDirUpLeft;
+ setMoveSpeed(0, _direction);
+ } else
+ stopWalking();
+ break;
+ case Common::KEYCODE_KP5:
+ stopWalking();
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+/**
+* Draws a part of the lightning bolt for thunder().
+* @remarks Originally called 'zl'
+*/
+void Animation::drawLightning(int16 x1, int16 y1, int16 x2, int16 y2) {
+ _vm->_graphics->drawLine(x1, y1 - 1, x2, y2 - 1, 1, 3, kColorBlue);
+ _vm->_graphics->drawLine(x1, y1, x2, y2, 1, 1, kColorLightcyan);
+}
+
+/**
+* Plays the actual thunder animation when Avvy (the player) swears too much.
+* @remarks Originally called 'zonk'
+*/
+void Animation::thunder() {
+ _vm->_graphics->setBackgroundColor(kColorYellow);
+
+ _vm->_graphics->saveScreen();
+
+ int x = _vm->_animation->_sprites[0]->_x + _vm->_animation->_sprites[0]->_xLength / 2;
+ int y = _vm->_animation->_sprites[0]->_y;
+
+ for (int i = 0; i < 256; i++) {
+ _vm->_sound->playNote(270 - i, 1);
+
+ drawLightning(640, 0, 0, y / 4);
+ drawLightning(0, y / 4, 640, y / 2);
+ drawLightning(640, y / 2, x, y);
+ _vm->_graphics->refreshScreen();
+
+ _vm->_sound->playNote(2700 - 10 * i, 5);
+ _vm->_system->delayMillis(5);
+ _vm->_sound->playNote(270 - i, 1);
+
+ _vm->_graphics->restoreScreen();
+ _vm->_sound->playNote(2700 - 10 * i, 5);
+ _vm->_system->delayMillis(5);
+ }
+
+ _vm->_graphics->restoreScreen();
+ _vm->_graphics->removeBackup();
+
+ _vm->_graphics->setBackgroundColor(kColorBlack);
+}
+
+/**
+* Makes the screen wobble.
+*/
+void Animation::wobble() {
+ _vm->_graphics->saveScreen();
+
+ for (int i = 0; i < 26; i++) {
+ _vm->_graphics->shiftScreen();
+ _vm->_graphics->refreshScreen();
+ _vm->_system->delayMillis(i * 7);
+
+ _vm->_graphics->restoreScreen();
+ _vm->_system->delayMillis(i * 7);
+ }
+
+ _vm->_graphics->restoreScreen();
+ _vm->_graphics->removeBackup();
+}
+
+void Animation::setDirection(Direction dir) {
+ _direction = dir;
+}
+
+void Animation::setOldDirection(Direction dir) {
+ _oldDirection = dir;
+}
+
+Direction Animation::getDirection() {
+ return _direction;
+}
+
+Direction Animation::getOldDirection() {
+ return _oldDirection;
+}
+
+void Animation::setAvvyClothes(int id) {
+ AnimationType *spr = _sprites[0];
+ if (spr->_id == id)
+ return;
+
+ int16 x = spr->_x;
+ int16 y = spr->_y;
+ spr->remove();
+ spr->init(id, true);
+ spr->appear(x, y, kDirLeft);
+ spr->_visible = false;
+}
+
+int Animation::getAvvyClothes() {
+ return _sprites[0]->_id;
+}
+
+void Animation::resetVariables() {
+ setDirection(kDirUp);
+ _geidaSpin = 0;
+ _geidaTime = 0;
+ _arrowTriggered = false;
+}
+
+void Animation::synchronize(Common::Serializer &sz) {
+ sz.syncAsByte(_direction);
+ sz.syncAsByte(_geidaSpin);
+ sz.syncAsByte(_geidaTime);
+
+ byte spriteNum = 0;
+ if (sz.isSaving()) {
+ for (int i = 0; i < kSpriteNumbMax; i++) {
+ if (_sprites[i]->_quick)
+ spriteNum++;
+ }
+ }
+ sz.syncAsByte(spriteNum);
+
+ if (sz.isLoading()) {
+ for (int i = 0; i < kSpriteNumbMax; i++) { // Deallocate sprites.
+ AnimationType *spr = _sprites[i];
+ if (spr->_quick)
+ spr->remove();
+ }
+ }
+
+ for (int i = 0; i < spriteNum; i++) {
+ AnimationType *spr = _sprites[i];
+ sz.syncAsByte(spr->_id);
+ sz.syncAsByte(spr->_doCheck);
+
+ if (sz.isLoading()) {
+ spr->_quick = true;
+ spr->init(spr->_id, spr->_doCheck);
+ }
+
+ sz.syncAsByte(spr->_moveX);
+ sz.syncAsByte(spr->_moveY);
+ sz.syncAsByte(spr->_facingDir);
+ sz.syncAsByte(spr->_stepNum);
+ sz.syncAsByte(spr->_visible);
+ sz.syncAsByte(spr->_homing);
+ sz.syncAsByte(spr->_count);
+ sz.syncAsByte(spr->_speedX);
+ sz.syncAsByte(spr->_speedY);
+ sz.syncAsByte(spr->_frameNum);
+ sz.syncAsSint16LE(spr->_homingX);
+ sz.syncAsSint16LE(spr->_homingY);
+ sz.syncAsByte(spr->_callEachStepFl);
+ sz.syncAsByte(spr->_eachStepProc);
+ sz.syncAsByte(spr->_vanishIfStill);
+ sz.syncAsSint16LE(spr->_x);
+ sz.syncAsSint16LE(spr->_y);
+
+ if (sz.isLoading() && spr->_visible)
+ spr->appear(spr->_x, spr->_y, spr->_facingDir);
+ }
+
+ sz.syncAsByte(_arrowTriggered);
+}
+
+} // End of namespace Avalanche.
diff --git a/engines/avalanche/animation.h b/engines/avalanche/animation.h
new file mode 100644
index 0000000000..aa4e6482a4
--- /dev/null
+++ b/engines/avalanche/animation.h
@@ -0,0 +1,177 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public 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 based on the original source code of Lord Avalot d'Argent version 1.3.
+ * Copyright (c) 1994-1995 Mike, Mark and Thomas Thurman.
+ */
+
+/* Original name: TRIP5 / Trippancy V - the sprite animation subsystem */
+
+#ifndef AVALANCHE_ANIMATION_H
+#define AVALANCHE_ANIMATION_H
+
+namespace Avalanche {
+class AvalancheEngine;
+class Animation;
+
+enum Direction {
+ kDirUp = 0, kDirRight, kDirDown, kDirLeft,
+ kDirUpRight, kDirDownRight, kDirDownLeft, kDirUpLeft,
+ kDirStopped, kDirNone = 177
+};
+
+class AnimationType {
+public:
+ byte _id;
+
+ byte _xLength, _yLength;
+ ManiType *_mani[24];
+ SilType *_sil[24];
+ byte _frameNum; // Number of pictures.
+ byte _seq; // How many in one stride.
+ byte _characterId; // The number according to Acci. (1=Avvy, etc.)
+ byte _count; // Counts before changing step.
+
+ Direction _facingDir;
+ byte _stepNum;
+ int16 _x, _y; // Current xy coords.
+ int8 _moveX, _moveY; // Amount to move sprite by, each step.
+ bool _quick, _visible, _homing, _doCheck;
+ int16 _homingX, _homingY; // Homing x & y coords.
+ byte _speedX, _speedY;
+ bool _vanishIfStill;
+ bool _callEachStepFl;
+ byte _eachStepProc;
+
+ AnimationType(Animation *anim);
+
+ void init(byte spritenum, bool doCheck);
+ void reset();
+ void draw();
+ void turn(Direction whichway);
+ void appear(int16 wx, int16 wy, Direction wf);
+ void bounce();
+ void walk();
+ void walkTo(byte pednum);
+ void stopHoming();
+ void setSpeed(int8 xx, int8 yy);
+ void stopWalk();
+ void chatter();
+ void remove();
+
+private:
+ Animation *_anim;
+
+ int16 _oldX[2], _oldY[2]; // Last xy coords.
+ Color _fgBubbleCol, _bgBubbleCol; // Foreground & background bubble colors.
+
+ bool checkCollision();
+ int8 getSign(int16 val);
+ void homeStep();
+};
+
+class Animation {
+public:
+ friend class AnimationType;
+
+ static const byte kSpriteNumbMax = 5; // current max no. of sprites
+
+ enum Proc {
+ kProcNone = 0,
+ kProcFollowAvvyY,
+ kProcBackAndForth,
+ kProcFaceAvvy,
+ kProcArrow,
+ kProcSpludwick, // Unused
+ kProcGrabAvvy,
+ kProcGeida // Spludwick uses it as well for homing! TODO: Unify it with kProcSpludwick.
+ };
+
+ AnimationType *_sprites[kSpriteNumbMax];
+
+ Animation(AvalancheEngine *vm);
+ ~Animation();
+
+ void animLink();
+ void resetAnims();
+ void callSpecial(uint16 which);
+ void catacombMove(byte ped);
+ void stopWalking();
+ void setMoveSpeed(byte t, Direction dir);
+ void appearPed(byte sprNum, byte pedNum);
+ bool inField(byte which);
+ bool nearDoor();
+ void updateSpeed();
+ void handleMoveKey(const Common::Event &event);
+ void hideInCupboard();
+
+ // These 2 functions are responsible for playing the thunder animation when the player swears too much.
+ void drawLightning(int16 x1, int16 y1, int16 x2, int16 y2);
+ void thunder();
+
+ void wobble();
+
+ void setDirection(Direction dir);
+ void setOldDirection(Direction dir);
+ Direction getDirection();
+ Direction getOldDirection();
+
+ void setAvvyClothes(int id);
+ int getAvvyClothes();
+
+ void resetVariables();
+ void synchronize(Common::Serializer &sz);
+private:
+ Direction _direction; // The direction Avvy is currently facing.
+ Direction _oldDirection;
+ static const int32 kCatacombMap[8][8];
+ bool _arrowTriggered; // And has the arrow been triggered?
+ bool _mustExclaim;
+ byte _geidaSpin, _geidaTime; // For the making "Geida dizzy" joke.
+ uint16 _sayWhat;
+
+ AvalancheEngine *_vm;
+
+ byte checkFeet(int16 x1, int16 x2, int16 oy, int16 y, byte yl);
+ byte geidaPed(byte ped);
+ void dawnDelay();
+
+ void grabAvvy(byte tripnum);
+ void arrowProcs(byte tripnum);
+
+ // Different movements for NPCs:
+ void followAvalotY(byte tripnum);
+ void backAndForth(byte tripnum);
+ void faceAvvy(byte tripnum);
+
+ // Movements for Homing NPCs: Spludwick and Geida.
+ void spin(Direction dir, byte &tripnum);
+ void takeAStep(byte &tripnum);
+ void geidaProcs(byte tripnum);
+
+ void drawSprites();
+};
+
+} // End of namespace Avalanche.
+
+#endif // AVALANCHE_ANIMATION_H
diff --git a/engines/avalanche/avalanche.cpp b/engines/avalanche/avalanche.cpp
new file mode 100644
index 0000000000..a7e7be0ad3
--- /dev/null
+++ b/engines/avalanche/avalanche.cpp
@@ -0,0 +1,540 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public 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 based on the original source code of Lord Avalot d'Argent version 1.3.
+ * Copyright (c) 1994-1995 Mike, Mark and Thomas Thurman.
+ */
+
+#include "avalanche/avalanche.h"
+
+#include "common/random.h"
+#include "common/savefile.h"
+#include "graphics/thumbnail.h"
+
+namespace Avalanche {
+
+AvalancheEngine::AvalancheEngine(OSystem *syst, const AvalancheGameDescription *gd) : Engine(syst), _gameDescription(gd), _fxHidden(false), _interrogation(0) {
+ _system = syst;
+ _console = new AvalancheConsole(this);
+
+ _rnd = new Common::RandomSource("avalanche");
+ TimeDate time;
+ _system->getTimeAndDate(time);
+ _rnd->setSeed(time.tm_sec + time.tm_min + time.tm_hour);
+ _showDebugLines = false;
+
+ _clock = nullptr;
+ _graphics = nullptr;
+ _parser = nullptr;
+ _pingo = nullptr;
+ _dialogs = nullptr;
+ _background = nullptr;
+ _sequence = nullptr;
+ _timer = nullptr;
+ _animation = nullptr;
+ _menu = nullptr;
+ _closing = nullptr;
+ _sound = nullptr;
+ _nim = nullptr;
+
+ _platform = gd->desc.platform;
+ initVariables();
+}
+
+AvalancheEngine::~AvalancheEngine() {
+ delete _console;
+ delete _rnd;
+
+ delete _graphics;
+ delete _parser;
+
+ delete _clock;
+ delete _pingo;
+ delete _dialogs;
+ delete _background;
+ delete _sequence;
+ delete _timer;
+ delete _animation;
+ delete _menu;
+ delete _closing;
+ delete _sound;
+ delete _nim;
+
+ for (int i = 0; i < 31; i++) {
+ for (int j = 0; j < 2; j++) {
+ if (_also[i][j] != nullptr) {
+ delete _also[i][j];
+ _also[i][j] = nullptr;
+ }
+ }
+ }
+}
+
+void AvalancheEngine::initVariables() {
+ for (int i = 0; i < 31; i++) {
+ _also[i][0] = nullptr;
+ _also[i][1] = nullptr;
+ }
+
+ memset(_fxPal, 0, 16 * 16 * 3);
+
+ for (int i = 0; i < 15; i++) {
+ _peds[i]._direction = kDirNone;
+ _peds[i]._x = 0;
+ _peds[i]._y = 0;
+ _magics[i]._operation = kMagicNothing;
+ _magics[i]._data = 0;
+ }
+
+ for (int i = 0; i < 7; i++) {
+ _portals[i]._operation = kMagicNothing;
+ _portals[i]._data = 0;
+ }
+
+ for (int i = 0; i < 30; i++) {
+ _fields[i]._x1 = 0;
+ _fields[i]._y1 = 0;
+ _fields[i]._x2 = 0;
+ _fields[i]._y2 = 0;
+ }
+
+ _fieldNum = 0;
+ _cp = 0;
+ _ledStatus = 177;
+ _alive = false;
+ _subjectNum = 0;
+ _him = kPeoplePardon;
+ _her = kPeoplePardon;
+ _it = Parser::kPardon;
+ _roomCycles = 0;
+ _doingSpriteRun = false;
+ _isLoaded = false;
+ _soundFx = true;
+ _holdTheDawn = false;
+
+ _lineNum = 0;
+ for (int i = 0; i < 50; i++)
+ _lines[i]._color = kColorWhite;
+ _dropsOk = false;
+ _cheat = false;
+ _letMeOut = false;
+ _thinks = 2;
+ _thinkThing = true;
+ _seeScroll = false;
+ _currentMouse = 177;
+ _holdLeftMouse = false;
+
+ resetVariables();
+}
+
+Common::ErrorCode AvalancheEngine::initialize() {
+ _graphics = new GraphicManager(this);
+ _parser = new Parser(this);
+
+ _clock = new Clock(this);
+ _pingo = new Pingo(this);
+ _dialogs = new Dialogs(this);
+ _background = new Background(this);
+ _sequence = new Sequence(this);
+ _timer = new Timer(this);
+ _animation = new Animation(this);
+ _menu = new Menu(this);
+ _closing = new Closing(this);
+ _sound = new SoundHandler(this);
+ _nim = new Nim(this);
+
+ _graphics->init();
+ _dialogs->init();
+ init();
+ _parser->init();
+
+ return Common::kNoError;
+}
+
+GUI::Debugger *AvalancheEngine::getDebugger() {
+ return _console;
+}
+
+Common::Platform AvalancheEngine::getPlatform() const {
+ return _platform;
+}
+
+bool AvalancheEngine::hasFeature(EngineFeature f) const {
+ return (f == kSupportsSavingDuringRuntime) || (f == kSupportsLoadingDuringRuntime);
+}
+
+const char *AvalancheEngine::getCopyrightString() const {
+ return "Copyright (c) 1994-1995 Mike, Mark and Thomas Thurman.";
+}
+
+void AvalancheEngine::synchronize(Common::Serializer &sz) {
+ _animation->synchronize(sz);
+ _parser->synchronize(sz);
+ _nim->synchronize(sz);
+ _sequence->synchronize(sz);
+ _background->synchronize(sz);
+
+ sz.syncAsByte(_carryNum);
+ for (int i = 0; i < kObjectNum; i++)
+ sz.syncAsByte(_objects[i]);
+ sz.syncAsSint16LE(_dnascore);
+ sz.syncAsSint32LE(_money);
+ sz.syncAsByte(_room);
+ if (sz.isSaving())
+ _saveNum++;
+ sz.syncAsByte(_saveNum);
+ sz.syncBytes(_roomCount, 100);
+ sz.syncAsByte(_wonNim);
+ sz.syncAsByte(_wineState);
+ sz.syncAsByte(_cwytalotGone);
+ sz.syncAsByte(_passwordNum);
+ sz.syncAsByte(_aylesIsAwake);
+ sz.syncAsByte(_drawbridgeOpen);
+ sz.syncAsByte(_avariciusTalk);
+ sz.syncAsByte(_rottenOnion);
+ sz.syncAsByte(_onionInVinegar);
+ sz.syncAsByte(_givenToSpludwick);
+ sz.syncAsByte(_brummieStairs);
+ sz.syncAsByte(_cardiffQuestionNum);
+ sz.syncAsByte(_passedCwytalotInHerts);
+ sz.syncAsByte(_avvyIsAwake);
+ sz.syncAsByte(_avvyInBed);
+ sz.syncAsByte(_userMovesAvvy);
+ sz.syncAsByte(_npcFacing);
+ sz.syncAsByte(_givenBadgeToIby);
+ sz.syncAsByte(_friarWillTieYouUp);
+ sz.syncAsByte(_tiedUp);
+ sz.syncAsByte(_boxContent);
+ sz.syncAsByte(_talkedToCrapulus);
+ sz.syncAsByte(_jacquesState);
+ sz.syncAsByte(_bellsAreRinging);
+ sz.syncAsByte(_standingOnDais);
+ sz.syncAsByte(_takenPen);
+ sz.syncAsByte(_arrowInTheDoor);
+
+ if (sz.isSaving()) {
+ uint16 like2drinkSize = _favoriteDrink.size();
+ sz.syncAsUint16LE(like2drinkSize);
+ for (uint16 i = 0; i < like2drinkSize; i++) {
+ char actChr = _favoriteDrink[i];
+ sz.syncAsByte(actChr);
+ }
+
+ uint16 favoriteSongSize = _favoriteSong.size();
+ sz.syncAsUint16LE(favoriteSongSize);
+ for (uint16 i = 0; i < favoriteSongSize; i++) {
+ char actChr = _favoriteSong[i];
+ sz.syncAsByte(actChr);
+ }
+
+ uint16 worst_place_on_earthSize = _worstPlaceOnEarth.size();
+ sz.syncAsUint16LE(worst_place_on_earthSize);
+ for (uint16 i = 0; i < worst_place_on_earthSize; i++) {
+ char actChr = _worstPlaceOnEarth[i];
+ sz.syncAsByte(actChr);
+ }
+
+ uint16 spare_eveningSize = _spareEvening.size();
+ sz.syncAsUint16LE(spare_eveningSize);
+ for (uint16 i = 0; i < spare_eveningSize; i++) {
+ char actChr = _spareEvening[i];
+ sz.syncAsByte(actChr);
+ }
+ } else {
+ if (!_favoriteDrink.empty())
+ _favoriteDrink.clear();
+ uint16 like2drinkSize = 0;
+ char actChr = ' ';
+ sz.syncAsUint16LE(like2drinkSize);
+ for (uint16 i = 0; i < like2drinkSize; i++) {
+ sz.syncAsByte(actChr);
+ _favoriteDrink += actChr;
+ }
+
+ if (!_favoriteSong.empty())
+ _favoriteSong.clear();
+ uint16 favourite_songSize = 0;
+ sz.syncAsUint16LE(favourite_songSize);
+ for (uint16 i = 0; i < favourite_songSize; i++) {
+ sz.syncAsByte(actChr);
+ _favoriteSong += actChr;
+ }
+
+ if (!_worstPlaceOnEarth.empty())
+ _worstPlaceOnEarth.clear();
+ uint16 worst_place_on_earthSize = 0;
+ sz.syncAsUint16LE(worst_place_on_earthSize);
+ for (uint16 i = 0; i < worst_place_on_earthSize; i++) {
+ sz.syncAsByte(actChr);
+ _worstPlaceOnEarth += actChr;
+ }
+
+ if (!_spareEvening.empty())
+ _spareEvening.clear();
+ uint16 spare_eveningSize = 0;
+ sz.syncAsUint16LE(spare_eveningSize);
+ for (uint16 i = 0; i < spare_eveningSize; i++) {
+ sz.syncAsByte(actChr);
+ _spareEvening += actChr;
+ }
+ }
+
+ sz.syncAsSint32LE(_totalTime);
+ sz.syncAsByte(_jumpStatus);
+ sz.syncAsByte(_mushroomGrowing);
+ sz.syncAsByte(_spludwickAtHome);
+ sz.syncAsByte(_lastRoom);
+ sz.syncAsByte(_lastRoomNotMap);
+ sz.syncAsByte(_crapulusWillTell);
+ sz.syncAsByte(_enterCatacombsFromLustiesRoom);
+ sz.syncAsByte(_teetotal);
+ sz.syncAsByte(_malagauche);
+ sz.syncAsByte(_drinking);
+ sz.syncAsByte(_enteredLustiesRoomAsMonk);
+ sz.syncAsByte(_catacombX);
+ sz.syncAsByte(_catacombY);
+ sz.syncAsByte(_avvysInTheCupboard);
+ sz.syncAsByte(_geidaFollows);
+ sz.syncAsByte(_givenPotionToGeida);
+ sz.syncAsByte(_lustieIsAsleep);
+ sz.syncAsByte(_beenTiedUp);
+ sz.syncAsByte(_sittingInPub);
+ sz.syncAsByte(_spurgeTalkCount);
+ sz.syncAsByte(_metAvaroid);
+ sz.syncAsByte(_takenMushroom);
+ sz.syncAsByte(_givenPenToAyles);
+ sz.syncAsByte(_askedDogfoodAboutNim);
+
+ for (int i = 0; i < 7; i++) {
+ sz.syncAsSint32LE(_timer->_times[i]._timeLeft);
+ sz.syncAsByte(_timer->_times[i]._action);
+ sz.syncAsByte(_timer->_times[i]._reason);
+ }
+
+}
+
+bool AvalancheEngine::canSaveGameStateCurrently() { // TODO: Refine these!!!
+ return (!_seeScroll && _alive);
+}
+
+Common::Error AvalancheEngine::saveGameState(int slot, const Common::String &desc) {
+ return (saveGame(slot, desc) ? Common::kNoError : Common::kWritingFailed);
+}
+
+bool AvalancheEngine::saveGame(const int16 slot, const Common::String &desc) {
+ Common::String fileName = getSaveFileName(slot);
+ Common::OutSaveFile *f = g_system->getSavefileManager()->openForSaving(fileName);
+ if (!f) {
+ warning("Can't create file '%s', game not saved.", fileName.c_str());
+ return false;
+ }
+
+ f->writeUint32LE(MKTAG('A', 'V', 'A', 'L'));
+
+ // Write version. We can't restore from obsolete versions.
+ f->writeByte(kSavegameVersion);
+
+ f->writeUint32LE(desc.size());
+ f->write(desc.c_str(), desc.size());
+ Graphics::saveThumbnail(*f);
+
+ TimeDate t;
+ _system->getTimeAndDate(t);
+ f->writeSint16LE(t.tm_mday);
+ f->writeSint16LE(t.tm_mon);
+ f->writeSint16LE(t.tm_year);
+
+ _totalTime += getTimeInSeconds() - _startTime;
+
+ Common::Serializer sz(NULL, f);
+ synchronize(sz);
+ f->finalize();
+ delete f;
+
+ return true;
+}
+
+Common::String AvalancheEngine::getSaveFileName(const int slot) {
+ return Common::String::format("%s.%03d", _targetName.c_str(), slot);
+}
+
+bool AvalancheEngine::canLoadGameStateCurrently() { // TODO: Refine these!!!
+ return (!_seeScroll);
+}
+
+Common::Error AvalancheEngine::loadGameState(int slot) {
+ return (loadGame(slot) ? Common::kNoError : Common::kReadingFailed);
+}
+
+bool AvalancheEngine::loadGame(const int16 slot) {
+ Common::String fileName = getSaveFileName(slot);
+ Common::InSaveFile *f = g_system->getSavefileManager()->openForLoading(fileName);
+ if (!f)
+ return false;
+
+ uint32 signature = f->readUint32LE();
+ if (signature != MKTAG('A', 'V', 'A', 'L'))
+ return false;
+
+ // Check version. We can't restore from obsolete versions.
+ byte saveVersion = f->readByte();
+ if (saveVersion > kSavegameVersion) {
+ warning("Savegame of incompatible version!");
+ delete f;
+ return false;
+ }
+
+ // Read the description.
+ uint32 descSize = f->readUint32LE();
+ Common::String description;
+ for (uint32 i = 0; i < descSize; i++) {
+ char actChar = f->readByte();
+ description += actChar;
+ }
+
+ description.toUppercase();
+ Graphics::skipThumbnail(*f);
+
+ // Read the time the game was saved.
+ TimeDate t;
+ t.tm_mday = f->readSint16LE();
+ t.tm_mon = f->readSint16LE();
+ t.tm_year = f->readSint16LE();
+
+ resetAllVariables();
+
+ Common::Serializer sz(f, NULL);
+ synchronize(sz);
+ delete f;
+
+ _isLoaded = true;
+
+ _seeScroll = true; // This prevents display of the new sprites before the new picture is loaded.
+
+ if (_holdTheDawn) {
+ _holdTheDawn = false;
+ fadeIn();
+ }
+
+ _background->release();
+ minorRedraw();
+ _menu->setup();
+ setRoom(kPeopleAvalot, _room);
+ _alive = true;
+ refreshObjectList();
+ _animation->updateSpeed();
+ drawDirection();
+ _animation->animLink();
+ _background->update();
+
+ Common::String tmpStr = Common::String::format("%cLoaded: %c%s.ASG%c%c%c%s%c%csaved on %s.",
+ kControlItalic, kControlRoman, description.c_str(), kControlCenter, kControlNewLine,
+ kControlNewLine, _roomnName.c_str(), kControlNewLine, kControlNewLine,
+ expandDate(t.tm_mday, t.tm_mon, t.tm_year).c_str());
+ _dialogs->displayText(tmpStr);
+
+ AnimationType *avvy = _animation->_sprites[0];
+ if (avvy->_quick && avvy->_visible)
+ _animation->setMoveSpeed(0, _animation->getDirection()); // We push Avvy in the right direction is he was moving.
+
+ return true;
+}
+
+Common::String AvalancheEngine::expandDate(int d, int m, int y) {
+ static const char months[12][10] = {
+ "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"
+ };
+
+ Common::String month = Common::String(months[m]);
+ Common::String day = intToStr(d);
+
+ if (((1 <= d) && (d <= 9)) || ((21 <= d) && (d <= 31)))
+ switch (d % 10) {
+ case 1:
+ day += "st";
+ break;
+ case 2:
+ day += "nd";
+ break;
+ case 3:
+ day += "rd";
+ break;
+ default:
+ day += "th";
+ }
+
+ return day + ' ' + month + ' ' + intToStr(y + 1900);
+}
+
+uint32 AvalancheEngine::getTimeInSeconds() {
+ TimeDate time;
+ _system->getTimeAndDate(time);
+ return time.tm_hour * 3600 + time.tm_min * 60 + time.tm_sec;
+}
+
+void AvalancheEngine::updateEvents() {
+ Common::Event event;
+
+ while (_eventMan->pollEvent(event)) {
+ switch (event.type) {
+ case Common::EVENT_LBUTTONDOWN:
+ _holdLeftMouse = true; // Used in checkclick() and Menu::menu_link().
+ break;
+ case Common::EVENT_LBUTTONUP:
+ _holdLeftMouse = false; // Same as above.
+ break;
+ case Common::EVENT_KEYDOWN:
+ if ((event.kbd.keycode == Common::KEYCODE_d) && (event.kbd.flags & Common::KBD_CTRL)) {
+ // Attach to the debugger
+ _console->attach();
+ _console->onFrame();
+ } else
+ handleKeyDown(event);
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+bool AvalancheEngine::getEvent(Common::Event &event) {
+ return _eventMan->pollEvent(event);
+}
+
+Common::Point AvalancheEngine::getMousePos() {
+ return _eventMan->getMousePos();
+}
+
+Common::Error AvalancheEngine::run() {
+ Common::ErrorCode err = initialize();
+ if (err != Common::kNoError)
+ return err;
+
+ do {
+ runAvalot();
+ } while (!_letMeOut && !shouldQuit());
+
+ return Common::kNoError;
+}
+
+} // End of namespace Avalanche
diff --git a/engines/avalanche/avalanche.h b/engines/avalanche/avalanche.h
new file mode 100644
index 0000000000..fe13fa8d9e
--- /dev/null
+++ b/engines/avalanche/avalanche.h
@@ -0,0 +1,312 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public 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 based on the original source code of Lord Avalot d'Argent version 1.3.
+ * Copyright (c) 1994-1995 Mike, Mark and Thomas Thurman.
+ */
+
+#ifndef AVALANCHE_AVALANCHE_H
+#define AVALANCHE_AVALANCHE_H
+
+#include "avalanche/console.h"
+#include "avalanche/graphics.h"
+#include "avalanche/parser.h"
+#include "avalanche/avalot.h"
+#include "avalanche/pingo.h"
+#include "avalanche/dialogs.h"
+#include "avalanche/background.h"
+#include "avalanche/sequence.h"
+#include "avalanche/timer.h"
+#include "avalanche/animation.h"
+#include "avalanche/menu.h"
+#include "avalanche/closing.h"
+#include "avalanche/sound.h"
+#include "avalanche/nim.h"
+#include "avalanche/clock.h"
+
+#include "common/serializer.h"
+
+#include "engines/engine.h"
+#include "engines/advancedDetector.h"
+
+#include "graphics/cursorman.h"
+
+namespace Common {
+class RandomSource;
+}
+
+namespace Avalanche {
+
+struct AvalancheGameDescription {
+ ADGameDescription desc;
+};
+
+static const int kSavegameVersion = 2;
+
+enum Pitch {
+ kPitchInvalid,
+ kPitchLower,
+ kPitchSame,
+ kPitchHigher
+};
+
+class AvalancheEngine : public Engine {
+public:
+ byte _saveNum; // number of times this game has been saved
+
+ Clock *_clock;
+ GraphicManager *_graphics;
+ Parser *_parser;
+ Pingo *_pingo;
+ Dialogs *_dialogs;
+ Background *_background;
+ Sequence *_sequence;
+ Timer *_timer;
+ Animation *_animation;
+ Menu *_menu;
+ Closing *_closing;
+ SoundHandler *_sound;
+ Nim *_nim;
+
+ OSystem *_system;
+
+ AvalancheEngine(OSystem *syst, const AvalancheGameDescription *gd);
+ ~AvalancheEngine();
+
+ Common::ErrorCode initialize();
+ GUI::Debugger *getDebugger();
+
+ Common::RandomSource *_rnd;
+
+ const AvalancheGameDescription *_gameDescription;
+ uint32 getFeatures() const;
+ const char *getGameId() const;
+ Common::Platform getPlatform() const;
+ bool hasFeature(EngineFeature f) const;
+ const char *getCopyrightString() const;
+
+ void synchronize(Common::Serializer &sz);
+ virtual bool canSaveGameStateCurrently();
+ Common::Error saveGameState(int slot, const Common::String &desc);
+ bool saveGame(const int16 slot, const Common::String &desc);
+ Common::String getSaveFileName(const int slot);
+ virtual bool canLoadGameStateCurrently();
+ Common::Error loadGameState(int slot);
+ bool loadGame(const int16 slot);
+ Common::String expandDate(int d, int m, int y);
+ uint32 getTimeInSeconds();
+
+ void updateEvents();
+ bool getEvent(Common::Event &event); // A wrapper around _eventMan->pollEvent(), so we can use it in Scrolls::normscroll() for example.
+ Common::Point getMousePos();
+
+protected:
+ // Engine APIs
+ Common::Error run();
+
+private:
+ AvalancheConsole *_console;
+ Common::Platform _platform;
+
+public:
+ // For Thinkabout:
+ static const bool kThing = true;
+ static const bool kPerson = false;
+
+ static const char kSpludwicksOrder[3];
+
+ static const uint16 kNotes[12];
+
+ bool _holdLeftMouse;
+
+ // If this is greater than zero, the next line you type is stored in the DNA in a position dictated by the value.
+ // If a scroll comes up, or you leave the room, it's automatically set to zero.
+ byte _interrogation;
+
+ // Former DNA structure
+ byte _carryNum; // How many objects you're carrying...
+ bool _objects[kObjectNum]; // ...and which ones they are.
+ int16 _dnascore; // your score, of course
+ int32 _money; // your current amount of dosh
+ Room _room; // your current room
+ bool _wonNim; // Have you *won* Nim? (That's harder.)
+ byte _wineState; // 0=good (Notts), 1=passable(Argent) ... 3=vinegar.
+ bool _cwytalotGone; // Has Cwytalot rushed off to Jerusalem yet?
+ byte _passwordNum; // Number of the passw for this game.
+ bool _aylesIsAwake; // pretty obvious!
+ byte _drawbridgeOpen; // Between 0 (shut) and 4 (open).
+ byte _avariciusTalk; // How much Avaricius has said to you.
+ bool _rottenOnion; // And has it rotted?
+ bool _onionInVinegar; // Is the onion in the vinegar?
+ byte _givenToSpludwick; // 0 = nothing given, 1 = onion...
+ byte _brummieStairs; // Progression through the stairs trick.
+ byte _cardiffQuestionNum; // Things you get asked in Cardiff.
+ bool _avvyIsAwake; // Well? Is Avvy awake? (Screen 1 only.)
+ bool _avvyInBed; // True if Avvy's in bed, but awake.
+ bool _userMovesAvvy; // If this is false, the user has no control over Avvy's movements.
+ byte _npcFacing; // If there's an NPC in the current room which turns it's head according to Avvy's movement (keep looking at him), this variable tells which way it's facing at the moment.
+ bool _givenBadgeToIby; // Have you given the badge to Iby yet?
+ bool _friarWillTieYouUp; // If you're going to get tied up.
+ bool _tiedUp; // You ARE tied up!
+ byte _boxContent; // 0 = money (sixpence), 254 = empty, any other number implies the contents of the box.
+ bool _talkedToCrapulus; // Pretty self-explanatory.
+ byte _jacquesState; // 0=asleep, 1=awake, 2=gets up, 3=gone.
+ bool _bellsAreRinging; // Is Jacques ringing the bells?
+ bool _standingOnDais; // In room 71, inside Cardiff Castle.
+ bool _takenPen; // Have you taken the pen (in Cardiff?)
+ bool _arrowInTheDoor; // Did the arrow hit the wall?
+ Common::String _favoriteDrink, _favoriteSong, _worstPlaceOnEarth, _spareEvening; // Personalisation str's
+ uint32 _startTime; // When did you start playing this session?
+ uint32 _totalTime; // Your total time playing this game, in seconds. Updated only at saving and loading.
+ byte _jumpStatus; // Fixes how high you're jumping.
+ bool _mushroomGrowing; // Is the mushroom growing in 42?
+ bool _crapulusWillTell; // Will Crapulus tell you about Spludwick being away?
+ bool _enterCatacombsFromLustiesRoom;
+ bool _teetotal; // Are we touching any more drinks?
+ byte _malagauche; // Position of Malagauche. See Celer for more info.
+ char _drinking; // What's he getting you?
+ bool _enteredLustiesRoomAsMonk;
+ byte _catacombX, _catacombY; // XY coords in the catacombs.
+ bool _avvysInTheCupboard; // On screen 22.
+ bool _geidaFollows; // Is Geida following you?
+ bool _givenPotionToGeida; // Does Geida have the potion?
+ bool _lustieIsAsleep; // Is BDL asleep?
+ bool _beenTiedUp; // In r__Robins.
+ bool _sittingInPub; // Are you sitting down in the pub?
+ byte _spurgeTalkCount; // Count for talking to Spurge.
+ bool _metAvaroid;
+ bool _takenMushroom, _givenPenToAyles, _askedDogfoodAboutNim;
+ // End of former DNA Structure
+
+ bool _showDebugLines;
+ byte _lineNum; // Number of lines.
+ LineType _lines[50]; // For Also.
+ bool _dropsOk;
+ bool _cheat; // CHECKME: Currently unused
+ bool _letMeOut;
+ byte _thinks;
+ bool _thinkThing;
+ bool _seeScroll; // TODO: maybe this means we're interacting with the toolbar / a scroll?
+ char _objectList[10];
+ // Called .free() for them in ~Gyro().
+
+ byte _currentMouse; // current mouse-void
+ Common::String *_also[31][2];
+ PedType _peds[15];
+ MagicType _magics[15];
+ MagicType _portals[7];
+ FieldType _fields[30];
+ byte _fieldNum;
+ Common::String _listen;
+ byte _cp, _ledStatus;
+ FontType _font;
+ bool _alive;
+ byte _subjectNum; // The same thing.
+ People _him, _her;
+ byte _it;
+ uint32 _roomCycles; // Set to 0 when you enter a room, added to in every loop. Cycles since you've been in this room.
+
+ bool _doingSpriteRun; // Only set to True if we're doing a sprite_run at this moment. This stops the trippancy system from moving any of the sprites.
+ bool _soundFx;
+
+ bool _isLoaded; // Is it a loaded gamestate?
+
+ void callVerb(VerbCode id);
+ void loadRoom(byte num);
+ void thinkAbout(byte object, bool type); // Hey!!! Get it and put it!!!
+ void incScore(byte num); // Add on no. of points
+ void fxToggle();
+ void refreshObjectList();
+ void errorLed();
+ void fadeOut();
+ void fadeIn();
+ void drawDirection(); // Draws the little icon at the left end of the text input field.
+ void gameOver();
+ uint16 bearing(byte whichPed); // Returns the bearing from ped 'whichped' to Avvy, in degrees.
+
+ // There are two kinds of redraw: Major and Minor. Minor is what happens when you load a game, etc. Major redraws EVERYTHING.
+ void minorRedraw();
+ void majorRedraw();
+
+ void spriteRun();
+
+ Common::String intToStr(int32 num);
+ void newGame(); // This sets up the DNA for a completely new game.
+ bool getFlag(char x);
+ bool decreaseMoney(uint16 amount); // Called pennycheck in the original.
+
+ Common::String getName(People whose);
+ Common::String getItem(byte which); // Called get_better in the original.
+ Common::String f5Does(); // This procedure determines what f5 does.
+
+ void openDoor(Room whither, byte ped, byte magicnum); // Handles slidey-open doors.
+ void flipRoom(Room room, byte ped);
+
+ void setRoom(People persId, Room roomId);
+ Room getRoom(People persId);
+private:
+ static const int16 kMaxSprites = 2; // Current max no. of sprites.
+ static Room _whereIs[29];
+
+ // Will be used in dusk() and dawn().
+ bool _fxHidden;
+ byte _fxPal[16][16][3];
+
+ bool _spludwickAtHome; // Is Spludwick at home?
+ bool _passedCwytalotInHerts; // Have you passed Cwytalot in Herts?
+ bool _holdTheDawn; // If this is true, calling Dawn will do nothing. It's used, for example, at the start, to stop Load from dawning.
+ byte _lastRoom;
+ byte _lastRoomNotMap;
+ byte _roomCount[100]; // Add one to each every time you enter a room
+ Common::String _mouseText;
+ Common::String _flags;
+ Common::String _roomnName; // Name of actual room
+ int8 _scoreToDisplay[3];
+
+ Common::String readAlsoStringFromFile(Common::File &file);
+ void runAvalot();
+ void init();
+ void initVariables();
+ void setup();
+ void scram(Common::String &str);
+ void unScramble();
+ void handleKeyDown(Common::Event &event); // To replace Basher::keyboard_link() and Basher::typein().
+ void enterNewTown();
+ void findPeople(byte room);
+ void putGeidaAt(byte whichPed, byte ped);
+ void guideAvvy(Common::Point cursorPos);
+ void enterRoom(Room room, byte ped);
+ void exitRoom(byte x);
+ void drawToolbar();
+ void drawScore();
+ void useCompass(const Common::Point &cursorPos); // Click on the compass on the toolbar to control Avvy's movement.
+ void checkClick();
+ void fixFlashers();
+ void loadAlso(byte num);
+ void resetAllVariables();
+ void resetVariables();
+};
+
+} // End of namespace Avalanche
+
+#endif // AVALANCHE_AVALANCHE_H
diff --git a/engines/avalanche/avalot.cpp b/engines/avalanche/avalot.cpp
new file mode 100644
index 0000000000..6648e8d961
--- /dev/null
+++ b/engines/avalanche/avalot.cpp
@@ -0,0 +1,1664 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public 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 based on the original source code of Lord Avalot d'Argent version 1.3.
+ * Copyright (c) 1994-1995 Mike: Mark and Thomas Thurman.
+ */
+
+/* AVALOT The kernel of the program. */
+
+#include "avalanche/avalanche.h"
+
+#include "common/random.h"
+#include "common/system.h"
+#include "common/config-manager.h"
+#include "graphics/palette.h"
+
+namespace Avalanche {
+
+// vv Stairs trap.
+
+/* Explanation: $NSEW.
+ Nibble N: North.
+ 0 = no connection,
+ 2 = (left,) middle(, right) door with left-hand handle,
+ 5 = (left,) middle(, right) door with right-hand handle,
+ 7 = arch,
+ 8 = arch and 1 north of it,
+ 9 = arch and 2 north of it,
+ D = no connection + WINDOW,
+ E = no connection + TORCH,
+ F = recessed door (to Geida's room.)
+
+ Nibble S: South.
+ 0 = no connection,
+ 1,2,3 = left, middle, right door.
+
+ Nibble E: East.
+ 0 = no connection (wall),
+ 1 = no connection (wall + window),
+ 2 = wall with door,
+ 3 = wall with door and window,
+ 6 = wall with candles,
+ 7 = wall with door and candles,
+ F = straight-through corridor.
+
+ Nibble W: West.
+ 0 = no connection (wall),
+ 1 = no connection (wall + shield),
+ 2 = wall with door,
+ 3 = wall with door and shield,
+ 4 = no connection (window),
+ 5 = wall with door and window,
+ 6 = wall with candles,
+ 7 = wall with door and candles,
+ F = straight-through corridor. */
+
+const char AvalancheEngine::kSpludwicksOrder[3] = {kObjectOnion, kObjectInk, kObjectMushroom};
+const uint16 AvalancheEngine::kNotes[12] = {196, 220, 247, 262, 294, 330, 350, 392, 440, 494, 523, 587};
+
+Room AvalancheEngine::_whereIs[29] = {
+ // The Lads
+ kRoomYours, // Avvy
+ kRoomSpludwicks, // Spludwick
+ kRoomOutsideYours, // Crapulus
+ kRoomDucks, // Duck - r__DucksRoom's not defined yet.
+ kRoomArgentPub, // Malagauche
+ kRoomRobins, // Friar Tuck.
+ kRoomDummy, // Robin Hood - can't meet him at the start.
+ kRoomBrummieRoad, // Cwytalot
+ kRoomLustiesRoom, // Baron du Lustie.
+ kRoomOutsideCardiffCastle, // The Duke of Cardiff.
+ kRoomArgentPub, // Dogfood
+ kRoomOutsideDucks, // Trader
+ kRoomArgentPub, // Ibythneth
+ kRoomAylesOffice, // Ayles
+ kRoomNottsPub, // Port
+ kRoomNottsPub, // Spurge
+ kRoomMusicRoom, // Jacques
+ kRoomNowhere,
+ kRoomNowhere,
+ kRoomNowhere,
+ kRoomNowhere,
+ kRoomNowhere,
+ kRoomNowhere,
+ kRoomNowhere,
+ kRoomNowhere,
+ // The Lasses
+ kRoomYours, // Arkata
+ kRoomGeidas, // Geida
+ kRoomDummy, // nobody allocated here!
+ kRoomWiseWomans // The Wise Woman.
+};
+
+
+
+void AvalancheEngine::handleKeyDown(Common::Event &event) {
+ _sound->click();
+
+ if ((Common::KEYCODE_F1 <= event.kbd.keycode) && (event.kbd.keycode <= Common::KEYCODE_F15))
+ _parser->handleFunctionKey(event);
+ else if ((32 <= event.kbd.ascii) && (event.kbd.ascii <= 128) && (event.kbd.ascii != 47))
+ _parser->handleInputText(event);
+ else
+ switch (event.kbd.keycode) { // We can control Avvy with the numpad as well.
+ case Common::KEYCODE_KP8:
+ event.kbd.keycode = Common::KEYCODE_UP;
+ break;
+ case Common::KEYCODE_KP2:
+ event.kbd.keycode = Common::KEYCODE_DOWN;
+ break;
+ case Common::KEYCODE_KP6:
+ event.kbd.keycode = Common::KEYCODE_RIGHT;
+ break;
+ case Common::KEYCODE_KP4:
+ event.kbd.keycode = Common::KEYCODE_LEFT;
+ break;
+ case Common::KEYCODE_KP9:
+ event.kbd.keycode = Common::KEYCODE_PAGEUP;
+ break;
+ case Common::KEYCODE_KP3:
+ event.kbd.keycode = Common::KEYCODE_PAGEDOWN;
+ break;
+ case Common::KEYCODE_KP7:
+ event.kbd.keycode = Common::KEYCODE_HOME;
+ break;
+ case Common::KEYCODE_KP1:
+ event.kbd.keycode = Common::KEYCODE_END;
+ break;
+ default:
+ break;
+ }
+
+ switch (event.kbd.keycode) {
+ case Common::KEYCODE_UP:
+ case Common::KEYCODE_DOWN:
+ case Common::KEYCODE_RIGHT:
+ case Common::KEYCODE_LEFT:
+ case Common::KEYCODE_PAGEUP:
+ case Common::KEYCODE_PAGEDOWN:
+ case Common::KEYCODE_HOME:
+ case Common::KEYCODE_END:
+ case Common::KEYCODE_KP5:
+ if (_alive && _avvyIsAwake) {
+ _animation->handleMoveKey(event); // Fallthroughs are intended.
+ drawDirection();
+ return;
+ }
+ case Common::KEYCODE_BACKSPACE:
+ _parser->handleBackspace();
+ break;
+ case Common::KEYCODE_RETURN:
+ _parser->handleReturn();
+ break;
+ default:
+ break;
+ }
+
+ drawDirection();
+}
+
+void AvalancheEngine::setup() {
+ init();
+
+ _dialogs->reset();
+ fadeOut();
+ _graphics->loadDigits();
+
+ _parser->_inputTextPos = 0;
+ _parser->_quote = true;
+
+ _animation->resetAnims();
+
+ drawToolbar();
+ _dialogs->setReadyLight(2);
+
+ fadeIn();
+ _parser->_cursorState = false;
+ _parser->cursorOn();
+ _animation->_sprites[0]->_speedX = kWalk;
+ _animation->updateSpeed();
+
+ _menu->init();
+
+ int16 loadSlot = ConfMan.instance().getInt("save_slot");
+ if (loadSlot >= 0) {
+ _thinks = 2; // You always have money.
+ thinkAbout(kObjectMoney, kThing);
+
+ loadGame(loadSlot);
+ } else {
+ newGame();
+
+ _soundFx = !_soundFx;
+ fxToggle();
+ thinkAbout(kObjectMoney, kThing);
+
+ _dialogs->displayScrollChain('Q', 83); // Info on the game, etc.
+ }
+}
+
+void AvalancheEngine::runAvalot() {
+ setup();
+
+ do {
+ uint32 beginLoop = _system->getMillis();
+
+ updateEvents(); // The event handler.
+
+ _clock->update();
+ _menu->update();
+ _background->update();
+ _animation->animLink();
+ checkClick();
+ _timer->updateTimer();
+
+ _graphics->drawDebugLines();
+ _graphics->refreshScreen();
+
+ uint32 delay = _system->getMillis() - beginLoop;
+ if (delay <= 55)
+ _system->delayMillis(55 - delay); // Replaces slowdown(); 55 comes from 18.2 Hz (B Flight).
+ } while (!_letMeOut && !shouldQuit());
+
+ warning("STUB: run()");
+
+ _closing->exitGame();
+}
+
+void AvalancheEngine::init() {
+ for (int i = 0; i < 31; i++) {
+ for (int j = 0; j < 2; j++)
+ _also[i][j] = nullptr;
+ }
+
+ _letMeOut = false;
+ _currentMouse = 177;
+ _dropsOk = true;
+ _mouseText = "";
+ _cheat = false;
+ _cp = 0;
+ _ledStatus = 177;
+ for (int i = 0; i < 3; i++)
+ _scoreToDisplay[i] = -1; // Impossible digits.
+ _holdTheDawn = false;
+
+ _graphics->loadMouse(kCurWait);
+ CursorMan.showMouse(true);
+}
+
+/**
+ * Call a given Verb
+ * @remarks Originally called 'callverb'
+ */
+void AvalancheEngine::callVerb(VerbCode id) {
+ if (id == _parser->kPardon) {
+ Common::String tmpStr = Common::String::format("The f5 key lets you do a particular action in certain " \
+ "situations. However, at the moment there is nothing assigned to it. You may press alt-A to see " \
+ "what the current setting of this key is.");
+ _dialogs->displayText(tmpStr);
+ } else
+ _parser->doVerb(id);
+}
+
+/**
+ * Check is it's possible to give something to Spludwick
+ * @remarks Originally called 'nextstring'
+ */
+Common::String AvalancheEngine::readAlsoStringFromFile(Common::File &file) {
+ Common::String str;
+ byte length = file.readByte();
+ for (int i = 0; i < length; i++)
+ str += file.readByte();
+ return str;
+}
+
+void AvalancheEngine::scram(Common::String &str) {
+ for (uint i = 0; i < str.size(); i++)
+ str.setChar(str[i] ^ 177, i);
+}
+
+void AvalancheEngine::unScramble() {
+ for (int i = 0; i < 31; i++) {
+ for (int j = 0; j < 2; j++) {
+ if (_also[i][j] != nullptr)
+ scram(*_also[i][j]);
+ }
+ }
+ scram(_listen);
+ scram(_flags);
+}
+
+void AvalancheEngine::loadAlso(byte num) {
+ for (int i = 0; i < 31; i++) {
+ for (int j = 0; j < 2; j++) {
+ if (_also[i][j] != nullptr) {
+ delete _also[i][j];
+ _also[i][j] = nullptr;
+ }
+ }
+ }
+ Common::String filename;
+ filename = Common::String::format("also%d.avd", num);
+ Common::File file;
+ if (!file.open(filename))
+ error("AVALANCHE: File not found: %s", filename.c_str());
+
+ file.seek(128);
+
+ byte alsoNum = file.readByte();
+ Common::String tmpStr;
+ for (int i = 0; i <= alsoNum; i++) {
+ for (int j = 0; j < 2; j++) {
+ _also[i][j] = new Common::String;
+ *_also[i][j] = readAlsoStringFromFile(file);
+ }
+ tmpStr = Common::String::format("\x9D%s\x9D", _also[i][0]->c_str());
+ *_also[i][0] = tmpStr;
+ }
+
+ memset(_lines, 0xFF, sizeof(_lines));
+
+ _lineNum = file.readByte();
+ for (int i = 0; i < _lineNum; i++) {
+ LineType *curLine = &_lines[i];
+ curLine->_x1 = file.readSint16LE();
+ curLine->_y1 = file.readSint16LE();
+ curLine->_x2 = file.readSint16LE();
+ curLine->_y2 = file.readSint16LE();
+ curLine->_color = (Color)file.readByte();
+ }
+
+ memset(_peds, 177, sizeof(_peds));
+ byte pedNum = file.readByte();
+ for (int i = 0; i < pedNum; i++) {
+ PedType *curPed = &_peds[i];
+ curPed->_x = file.readSint16LE();
+ curPed->_y = file.readSint16LE();
+ curPed->_direction = (Direction)file.readByte();
+ }
+
+ _fieldNum = file.readByte();
+ for (int i = 0; i < _fieldNum; i++) {
+ FieldType *curField = &_fields[i];
+ curField->_x1 = file.readSint16LE();
+ curField->_y1 = file.readSint16LE();
+ curField->_x2 = file.readSint16LE();
+ curField->_y2 = file.readSint16LE();
+ }
+
+ for (int i = 0; i < 15; i++) {
+ MagicType *magic = &_magics[i];
+ magic->_operation = file.readByte();
+ magic->_data = file.readUint16LE();
+ }
+
+ for (int i = 0; i < 7; i++) {
+ MagicType *portal = &_portals[i];
+ portal->_operation = file.readByte();
+ portal->_data = file.readUint16LE();
+ }
+
+ _flags.clear();
+ for (int i = 0; i < 26; i++)
+ _flags += file.readByte();
+
+ int16 size = file.readByte();
+ _listen.clear();
+ for (int i = 0; i < size; i++)
+ _listen += file.readByte();
+
+ _graphics->clearAlso();
+
+ CursorMan.showMouse(false);
+ for (int i = 0; i < _lineNum; i++) {
+ // We had to check if the lines are within the borders of the screen.
+ if ((_lines[i]._x1 >= 0) && (_lines[i]._x1 < kScreenWidth) && (_lines[i]._y1 >= 0) && (_lines[i]._y1 < kScreenHeight)
+ && (_lines[i]._x2 >= 0) && (_lines[i]._x2 < kScreenWidth) && (_lines[i]._y2 >= 0) && (_lines[i]._y2 < kScreenHeight))
+ _graphics->setAlsoLine(_lines[i]._x1, _lines[i]._y1, _lines[i]._x2, _lines[i]._y2, _lines[i]._color);
+ }
+ CursorMan.showMouse(true);
+
+ file.close();
+
+ unScramble();
+ for (int i = 0; i <= alsoNum; i++) {
+ tmpStr = Common::String::format(",%s,", _also[i][0]->c_str());
+ *_also[i][0] = tmpStr;
+ }
+}
+
+void AvalancheEngine::loadRoom(byte num) {
+ CursorMan.showMouse(false);
+
+ Common::String filename = Common::String::format("place%d.avd", num);
+ Common::File file;
+ if (!file.open(filename))
+ error("AVALANCHE: File not found: %s", filename.c_str());
+
+ file.seek(146);
+ if (!_roomnName.empty())
+ _roomnName.clear();
+ for (int i = 0; i < 30; i++) {
+ char actChar = file.readByte();
+ if ((32 <= actChar) && (actChar <= 126))
+ _roomnName += actChar;
+ }
+ // Compression method byte follows this...
+
+ file.seek(177);
+
+ _graphics->loadBackground(file);
+ _graphics->refreshBackground();
+
+ file.close();
+
+ loadAlso(num);
+ _background->load(num);
+ CursorMan.showMouse(true);
+}
+
+void AvalancheEngine::findPeople(byte room) {
+ for (int i = 1; i < 29; i++) {
+ if (_whereIs[i] == room) {
+ if (i < 25)
+ _him = (People)(150 + i);
+ else
+ _her = (People)(150 + i);
+ }
+ }
+}
+
+void AvalancheEngine::exitRoom(byte x) {
+ _sound->stopSound();
+ _background->release();
+ _seeScroll = true; // This stops the trippancy system working over the length of this procedure.
+
+ switch (x) {
+ case kRoomSpludwicks:
+ _timer->loseTimer(Timer::kReasonAvariciusTalks);
+ _avariciusTalk = 0;
+ // He doesn't HAVE to be talking for this to work. It just deletes it IF it exists.
+ break;
+ case kRoomBridge:
+ if (_drawbridgeOpen > 0) {
+ _drawbridgeOpen = 4; // Fully open.
+ _timer->loseTimer(Timer::kReasonDrawbridgeFalls);
+ }
+ break;
+ case kRoomOutsideCardiffCastle:
+ _timer->loseTimer(Timer::kReasonCardiffsurvey);
+ break;
+ case kRoomRobins:
+ _timer->loseTimer(Timer::kReasonGettingTiedUp);
+ break;
+ }
+
+ _interrogation = 0; // Leaving the room cancels all the questions automatically.
+ _seeScroll = false; // Now it can work again!
+
+ _lastRoom = _room;
+ if (_room != kRoomMap)
+ _lastRoomNotMap = _room;
+}
+
+/**
+ * Only when entering a NEW town! Not returning to the last one,
+ * but choosing another from the map.
+ * @remarks Originally called 'new_town'
+ */
+void AvalancheEngine::enterNewTown() {
+ _menu->setup();
+
+ switch (_room) {
+ case kRoomOutsideNottsPub: // Entry into Nottingham.
+ if ((_roomCount[kRoomRobins] > 0) && (_beenTiedUp) && (!_takenMushroom))
+ _mushroomGrowing = true;
+ break;
+ case kRoomWiseWomans: // Entry into Argent.
+ if (_talkedToCrapulus && (!_lustieIsAsleep)) {
+ _spludwickAtHome = !((_roomCount[kRoomWiseWomans] % 3) == 1);
+ _crapulusWillTell = !_spludwickAtHome;
+ } else {
+ _spludwickAtHome = true;
+ _crapulusWillTell = false;
+ }
+ if (_boxContent == kObjectWine)
+ _wineState = 3; // Vinegar
+ break;
+ default:
+ break;
+ }
+
+ if ((_room != kRoomOutsideDucks) && (_objects[kObjectOnion - 1]) && !(_onionInVinegar))
+ _rottenOnion = true; // You're holding the onion
+}
+
+void AvalancheEngine::putGeidaAt(byte whichPed, byte ped) {
+ if (ped == 0)
+ return;
+ AnimationType *spr1 = _animation->_sprites[1];
+
+ spr1->init(5, false); // load Geida
+ _animation->appearPed(1, whichPed);
+ spr1->_callEachStepFl = true;
+ spr1->_eachStepProc = Animation::kProcGeida;
+}
+
+void AvalancheEngine::enterRoom(Room roomId, byte ped) {
+ _seeScroll = true; // This stops the trippancy system working over the length of this procedure.
+
+ findPeople(roomId);
+ _room = roomId;
+ if (ped != 0)
+ _roomCount[roomId]++;
+
+ loadRoom(roomId);
+
+ if ((_roomCount[roomId] == 0) && (!getFlag('S')))
+ incScore(1);
+
+ _whereIs[kPeopleAvalot - 150] = _room;
+
+ if (_geidaFollows)
+ _whereIs[kPeopleGeida - 150] = roomId;
+
+ _roomCycles = 0;
+
+ if ((_lastRoom == kRoomMap) && (_lastRoomNotMap != _room))
+ enterNewTown();
+
+ _animation->updateSpeed();
+
+ switch (roomId) {
+ case kRoomYours:
+ if (_avvyInBed) {
+ _background->draw(-1, -1, 2);
+ _graphics->refreshBackground();
+ _timer->addTimer(100, Timer::kProcArkataShouts, Timer::kReasonArkataShouts);
+ }
+ break;
+
+ case kRoomOutsideYours:
+ if (ped > 0) {
+ AnimationType *spr1 = _animation->_sprites[1];
+ if (!_talkedToCrapulus) {
+ _whereIs[kPeopleCrapulus - 150] = kRoomOutsideYours;
+ spr1->init(8, false); // load Crapulus
+
+ if (_roomCount[kRoomOutsideYours] == 1) {
+ _animation->appearPed(1, 3); // Start on the right-hand side of the screen.
+ spr1->walkTo(4); // Walks up to greet you.
+ } else {
+ _animation->appearPed(1, 4); // Starts where he was before.
+ spr1->_facingDir = kDirLeft;
+ }
+
+ spr1->_callEachStepFl = true;
+ spr1->_eachStepProc = Animation::kProcFaceAvvy; // He always faces Avvy.
+
+ } else
+ _whereIs[kPeopleCrapulus - 150] = kRoomNowhere;
+
+ if (_crapulusWillTell) {
+ spr1->init(8, false);
+ _animation->appearPed(1, 1);
+ spr1->walkTo(3);
+ _timer->addTimer(20, Timer::kProcCrapulusSpludOut, Timer::kReasonCrapulusSaysSpludwickOut);
+ _crapulusWillTell = false;
+ }
+ }
+ break;
+
+ case kRoomOutsideSpludwicks:
+ if ((_roomCount[kRoomOutsideSpludwicks] == 1) && (ped == 1)) {
+ _timer->addTimer(20, Timer::kProcBang, Timer::kReasonExplosion);
+ _spludwickAtHome = true;
+ }
+ break;
+
+ case kRoomSpludwicks:
+ if (_spludwickAtHome) {
+ AnimationType *spr1 = _animation->_sprites[1];
+ if (ped > 0) {
+ spr1->init(2, false); // load Spludwick
+ _animation->appearPed(1, 1);
+ _whereIs[kPeopleSpludwick - 150] = kRoomSpludwicks;
+ }
+
+ spr1->_callEachStepFl = true;
+ spr1->_eachStepProc = Animation::kProcGeida;
+ } else
+ _whereIs[kPeopleSpludwick - 150] = kRoomNowhere;
+ break;
+
+ case kRoomBrummieRoad:
+ if (_geidaFollows)
+ putGeidaAt(4, ped);
+ if (_cwytalotGone) {
+ _magics[kColorLightred - 1]._operation = kMagicNothing;
+ _whereIs[kPeopleCwytalot - 150] = kRoomNowhere;
+ } else if (ped > 0) {
+ AnimationType *spr1 = _animation->_sprites[1];
+ spr1->init(4, false); // 4 = Cwytalot
+ spr1->_callEachStepFl = true;
+ spr1->_eachStepProc = Animation::kProcFollowAvvyY;
+ _whereIs[kPeopleCwytalot - 150] = kRoomBrummieRoad;
+
+ if (_roomCount[kRoomBrummieRoad] == 1) { // First time here...
+ _animation->appearPed(1, 1); // He appears on the right of the screen...
+ spr1->walkTo(3); // ...and he walks up...
+ } else {
+ // You've been here before.
+ _animation->appearPed(1, 3); // He's standing in your way straight away...
+ spr1->_facingDir = kDirLeft;
+ }
+ }
+ break;
+
+ case kRoomArgentRoad:
+ if ((_cwytalotGone) && (!_passedCwytalotInHerts) && (ped == 2) && (_roomCount[kRoomArgentRoad] > 3)) {
+ AnimationType *spr1 = _animation->_sprites[1];
+ spr1->init(4, false); // 4 = Cwytalot again
+ _animation->appearPed(1, 0);
+ spr1->walkTo(1);
+ spr1->_vanishIfStill = true;
+ _passedCwytalotInHerts = true;
+ // whereis[#157] = r__Nowhere; // can we fit this in?
+ _timer->addTimer(20, Timer::kProcCwytalotInHerts, Timer::kReasonCwytalotInHerts);
+ }
+ break;
+
+ case kRoomBridge:
+ if (_drawbridgeOpen == 4) { // open
+ _background->draw(-1, -1, 2); // Position of drawbridge
+ _graphics->refreshBackground();
+ _magics[kColorGreen - 1]._operation = kMagicNothing; // You may enter the drawbridge.
+ }
+ if (_geidaFollows)
+ putGeidaAt(ped + 2, ped); // load Geida
+ break;
+
+ case kRoomRobins:
+ if ((ped > 0) && (!_beenTiedUp)) {
+ // A welcome party... or maybe not...
+ AnimationType *spr1 = _animation->_sprites[1];
+ spr1->init(6, false);
+ _animation->appearPed(1, 1);
+ spr1->walkTo(2);
+ _timer->addTimer(36, Timer::kProcGetTiedUp, Timer::kReasonGettingTiedUp);
+ }
+
+ if (_beenTiedUp) {
+ _whereIs[kPeopleRobinHood - 150] = kRoomNowhere;
+ _whereIs[kPeopleFriarTuck - 150] = kRoomNowhere;
+ }
+
+ if (_tiedUp)
+ _background->draw(-1, -1, 1);
+
+ if (!_mushroomGrowing)
+ _background->draw(-1, -1, 2);
+ _graphics->refreshBackground();
+ break;
+
+ case kRoomOutsideCardiffCastle:
+ if (ped > 0) {
+ AnimationType *spr1 = _animation->_sprites[1];
+ switch (_cardiffQuestionNum) {
+ case 0 : // You've answered NONE of his questions.
+ spr1->init(9, false);
+ _animation->appearPed(1, 1);
+ spr1->walkTo(2);
+ _timer->addTimer(47, Timer::kProcCardiffSurvey, Timer::kReasonCardiffsurvey);
+ break;
+ case 5 :
+ _magics[1]._operation = kMagicNothing;
+ break; // You've answered ALL his questions. => nothing happens.
+ default: // You've answered SOME of his questions.
+ spr1->init(9, false);
+ _animation->appearPed(1, 2);
+ spr1->_facingDir = kDirRight;
+ _timer->addTimer(3, Timer::kProcCardiffReturn, Timer::kReasonCardiffsurvey);
+ }
+ }
+
+ if (_cardiffQuestionNum < 5)
+ _interrogation = _cardiffQuestionNum;
+ else
+ _interrogation = 0;
+ break;
+
+ case kRoomMap:
+ // You're entering the map.
+ fadeIn();
+ if (ped > 0)
+ _graphics->zoomOut(_peds[ped - 1]._x, _peds[ped - 1]._y);
+
+ if ((_objects[kObjectWine - 1]) && (_wineState != 3)) {
+ _dialogs->displayScrollChain('Q', 9); // Don't want to waste the wine!
+ _objects[kObjectWine - 1] = false;
+ refreshObjectList();
+ }
+
+ _dialogs->displayScrollChain('Q', 69);
+ break;
+
+ case kRoomCatacombs:
+ if ((ped == 0) || (ped == 3) || (ped == 5) || (ped == 6)) {
+
+ switch (ped) {
+ case 3: // Enter from oubliette
+ _catacombX = 8;
+ _catacombY = 4;
+ break;
+ case 5: // Enter from du Lustie's
+ _catacombX = 8;
+ _catacombY = 7;
+ break;
+ case 6: // Enter from Geida's
+ _catacombX = 4;
+ _catacombY = 1;
+ break;
+ }
+
+ _enterCatacombsFromLustiesRoom = true;
+ _animation->catacombMove(ped);
+ _enterCatacombsFromLustiesRoom = false;
+ }
+ break;
+
+ case kRoomArgentPub:
+ if (_wonNim)
+ _background->draw(-1, -1, 0); // No lute by the settle.
+ _malagauche = 0; // Ready to boot Malagauche
+ if (_givenBadgeToIby) {
+ _background->draw(-1, -1, 7);
+ _background->draw(-1, -1, 8);
+ }
+ _graphics->refreshBackground();
+ break;
+
+ case kRoomLustiesRoom:
+ _npcFacing = 1; // du Lustie.
+ if (_animation->getAvvyClothes() == 0) // Avvy in his normal clothes
+ _timer->addTimer(3, Timer::kProcCallsGuards, Timer::kReasonDuLustieTalks);
+ else if (!_enteredLustiesRoomAsMonk) // already
+ // Presumably, Avvy dressed as a monk.
+ _timer->addTimer(3, Timer::kProcGreetsMonk, Timer::kReasonDuLustieTalks);
+
+ if (_geidaFollows) {
+ putGeidaAt(4, ped);
+ if (_lustieIsAsleep) {
+ _background->draw(-1, -1, 4);
+ _graphics->refreshBackground();
+ }
+ }
+ break;
+
+ case kRoomMusicRoom:
+ if (_jacquesState > 0) {
+ _jacquesState = 5;
+ _background->draw(-1, -1, 1);
+ _graphics->refreshBackground();
+ _background->draw(-1, -1, 3);
+ _magics[kColorBrown - 1]._operation = kMagicNothing;
+ _whereIs[kPeopleJacques - 150] = kRoomNowhere;
+ }
+ if (ped != 0) {
+ _background->draw(-1, -1, 5);
+ _graphics->refreshBackground();
+ _sequence->startMusicRoomSeq();
+ }
+ break;
+
+ case kRoomOutsideNottsPub:
+ if (ped == 2) {
+ _background->draw(-1, -1, 2);
+ _graphics->refreshBackground();
+ _sequence->startDuckSeq();
+ }
+ break;
+
+ case kRoomOutsideArgentPub:
+ if (ped == 2) {
+ _background->draw(-1, -1, 5);
+ _graphics->refreshBackground();
+ _sequence->startMusicRoomSeq();
+ }
+ break;
+
+ case kRoomWiseWomans: {
+ AnimationType *spr1 = _animation->_sprites[1];
+ spr1->init(11, false);
+ if ((_roomCount[kRoomWiseWomans] == 1) && (ped > 0)) {
+ _animation->appearPed(1, 1); // Start on the right-hand side of the screen.
+ spr1->walkTo(3); // Walks up to greet you.
+ } else {
+ _animation->appearPed(1, 3); // Starts where she was before.
+ spr1->_facingDir = kDirLeft;
+ }
+
+ spr1->_callEachStepFl = true;
+ spr1->_eachStepProc = Animation::kProcFaceAvvy; // She always faces Avvy.
+ }
+ break;
+
+ case kRoomInsideCardiffCastle:
+ if (ped > 0) {
+ _animation->_sprites[1]->init(10, false); // Define the dart.
+ _background->draw(-1, -1, 0);
+ _graphics->refreshBackground();
+ _sequence->startCardiffSeq2();
+ } else {
+ _background->draw(-1, -1, 0);
+ if (_arrowInTheDoor)
+ _background->draw(-1, -1, 2);
+ else
+ _background->draw(-1, -1, 1);
+ _graphics->refreshBackground();
+ }
+ break;
+
+ case kRoomAvvysGarden:
+ if (ped == 1) {
+ _background->draw(-1, -1, 1);
+ _graphics->refreshBackground();
+ _sequence->startGardenSeq();
+ }
+ break;
+
+ case kRoomEntranceHall:
+ case kRoomInsideAbbey:
+ case kRoomYourHall:
+ if (ped == 2) {
+#if 0
+ // It was the original:
+ _celer->show_one(-1, -1, 2);
+ _sequence->first_show(1);
+ _sequence->then_show(3);
+ _sequence->start_to_close();
+#endif
+
+ _background->draw(-1, -1, 1);
+ _graphics->refreshBackground();
+ _sequence->startGardenSeq();
+ }
+ break;
+
+ case kRoomAylesOffice:
+ if (_aylesIsAwake)
+ _background->draw(-1, -1, 1);
+ _graphics->refreshBackground();
+ break; // Ayles awake.
+
+ case kRoomGeidas:
+ putGeidaAt(1, ped);
+ break; // load Geida
+
+ case kRoomEastHall:
+ case kRoomWestHall:
+ if (_geidaFollows)
+ putGeidaAt(ped + 1, ped);
+ break;
+
+ case kRoomLusties:
+ if (_geidaFollows)
+ putGeidaAt(ped + 5, ped);
+ break;
+
+ case kRoomNottsPub:
+ if (_sittingInPub)
+ _background->draw(-1, -1, 2);
+ _npcFacing = 1; // Port.
+ break;
+
+ case kRoomOutsideDucks:
+ if (ped == 2) {
+ // Shut the door
+ _background->draw(-1, -1, 2);
+ _graphics->refreshBackground();
+ _sequence->startDuckSeq();
+ }
+ break;
+
+ case kRoomDucks:
+ _npcFacing = 1; // Duck.
+ break;
+
+ default:
+ break;
+ }
+
+ _seeScroll = false; // Now it can work again!
+}
+
+void AvalancheEngine::thinkAbout(byte object, bool type) {
+ _thinks = object;
+ object--;
+
+ Common::String filename;
+ if (type == kThing) {
+ filename = "thinks.avd";
+ } else { // kPerson
+ filename = "folk.avd";
+
+ object -= 149;
+ if (object >= 25)
+ object -= 8;
+ if (object == 20)
+ object--; // Last time...
+ }
+
+ _graphics->loadMouse(kCurWait);
+ CursorMan.showMouse(false);
+ _graphics->drawThinkPic(filename, object);
+ CursorMan.showMouse(true);
+
+ _thinkThing = type;
+}
+
+void AvalancheEngine::drawToolbar() {
+ _graphics->drawToolbar();
+ _animation->setOldDirection(kDirNone);
+ drawDirection();
+}
+
+void AvalancheEngine::drawScore() {
+ uint16 score = _dnascore;
+ int8 numbers[3] = {0, 0, 0};
+ for (int i = 0; i < 2; i++) {
+ byte divisor = 1;
+ for (int j = 0; j < (2 - i); j++)
+ divisor *= 10;
+ numbers[i] = score / divisor;
+ score -= numbers[i] * divisor;
+ }
+ numbers[2] = score;
+
+ CursorMan.showMouse(false);
+
+ for (int i = 0; i < 3; i++) {
+ if (_scoreToDisplay[i] != numbers[i])
+ _graphics->drawDigit(numbers[i], 250 + (i + 1) * 15, 177);
+ }
+
+ CursorMan.showMouse(true);
+
+ for (int i = 0; i < 3; i++)
+ _scoreToDisplay[i] = numbers[i];
+}
+
+void AvalancheEngine::incScore(byte num) {
+ for (int i = 1; i <= num; i++) {
+ _dnascore++;
+
+ if (_soundFx) {
+ for (int j = 1; j <= 97; j++)
+ // Length os 2 is a guess, the original doesn't have a delay specified
+ _sound->playNote(177 + _dnascore * 3, 2);
+ }
+ }
+ warning("STUB: points()");
+
+ drawScore();
+}
+
+void AvalancheEngine::useCompass(const Common::Point &cursorPos) {
+ byte color = _graphics->getScreenColor(cursorPos);
+
+ switch (color) {
+ case kColorGreen:
+ _animation->setDirection(kDirUp);
+ _animation->setMoveSpeed(0, kDirUp);
+ drawDirection();
+ break;
+ case kColorBrown:
+ _animation->setDirection(kDirDown);
+ _animation->setMoveSpeed(0, kDirDown);
+ drawDirection();
+ break;
+ case kColorCyan:
+ _animation->setDirection(kDirLeft);
+ _animation->setMoveSpeed(0, kDirLeft);
+ drawDirection();
+ break;
+ case kColorLightmagenta:
+ _animation->setDirection(kDirRight);
+ _animation->setMoveSpeed(0, kDirRight);
+ drawDirection();
+ break;
+ case kColorRed:
+ case kColorWhite:
+ case kColorLightcyan:
+ case kColorYellow: // Fall-throughs are intended.
+ _animation->stopWalking();
+ drawDirection();
+ break;
+ }
+}
+
+void AvalancheEngine::fxToggle() {
+ warning("STUB: fxtoggle()");
+}
+
+void AvalancheEngine::refreshObjectList() {
+ _carryNum = 0;
+ if (_thinkThing && !_objects[_thinks - 1])
+ thinkAbout(kObjectMoney, kThing); // you always have money
+
+ for (int i = 0; i < kObjectNum; i++) {
+ if (_objects[i]) {
+ _objectList[_carryNum] = i + 1;
+ _carryNum++;
+ }
+ }
+}
+
+/**
+ * @remarks Originally called 'verte'
+ */
+void AvalancheEngine::guideAvvy(Common::Point cursorPos) {
+ if (!_userMovesAvvy)
+ return;
+
+ cursorPos.y /= 2;
+ byte what;
+
+ // _animation->tr[0] is Avalot.)
+ AnimationType *avvy = _animation->_sprites[0];
+ if (cursorPos.x < avvy->_x)
+ what = 1;
+ else if (cursorPos.x > (avvy->_x + avvy->_xLength))
+ what = 2;
+ else
+ what = 0; // On top
+
+ if (cursorPos.y < avvy->_y)
+ what += 3;
+ else if (cursorPos.y > (avvy->_y + avvy->_yLength))
+ what += 6;
+
+ switch (what) {
+ case 0:
+ _animation->stopWalking();
+ break; // Clicked on Avvy: no movement.
+ case 1:
+ _animation->setMoveSpeed(0, kDirLeft);
+ break;
+ case 2:
+ _animation->setMoveSpeed(0, kDirRight);
+ break;
+ case 3:
+ _animation->setMoveSpeed(0, kDirUp);
+ break;
+ case 4:
+ _animation->setMoveSpeed(0, kDirUpLeft);
+ break;
+ case 5:
+ _animation->setMoveSpeed(0, kDirUpRight);
+ break;
+ case 6:
+ _animation->setMoveSpeed(0, kDirDown);
+ break;
+ case 7:
+ _animation->setMoveSpeed(0, kDirDownLeft);
+ break;
+ case 8:
+ _animation->setMoveSpeed(0, kDirDownRight);
+ break;
+ } // No other values are possible.
+
+ drawDirection();
+}
+
+void AvalancheEngine::checkClick() {
+ Common::Point cursorPos = getMousePos();
+
+ /*if (mrelease > 0)
+ after_the_scroll = false;*/
+
+ if ((0 <= cursorPos.y) && (cursorPos.y <= 21))
+ _graphics->loadMouse(kCurUpArrow); // up arrow
+ else if ((317 <= cursorPos.y) && (cursorPos.y <= 339))
+ _graphics->loadMouse(kCurIBeam); //I-beam
+ else if ((340 <= cursorPos.y) && (cursorPos.y <= 399))
+ _graphics->loadMouse(kCurScrewDriver); // screwdriver
+ else if (!_menu->isActive()) { // Dropdown can handle its own pointers.
+ if (_holdLeftMouse) {
+ _graphics->loadMouse(kCurCrosshair); // Mark's crosshairs
+ guideAvvy(cursorPos); // Normally, if you click on the picture, you're guiding Avvy around.
+ } else
+ _graphics->loadMouse(kCurFletch); // fletch
+ }
+
+ if (_holdLeftMouse) {
+ if ((0 <= cursorPos.y) && (cursorPos.y <= 21)) { // Click on the dropdown menu.
+ if (_dropsOk)
+ _menu->update();
+ } else if ((317 <= cursorPos.y) && (cursorPos.y <= 339)) { // Click on the command line.
+ _parser->_inputTextPos = (cursorPos.x - 23) / 8;
+ if (_parser->_inputTextPos > _parser->_inputText.size() + 1)
+ _parser->_inputTextPos = _parser->_inputText.size() + 1;
+ if (_parser->_inputTextPos < 1)
+ _parser->_inputTextPos = 1;
+ _parser->_inputTextPos--;
+ _parser->plotText();
+ } else if ((340 <= cursorPos.y) && (cursorPos.y <= 399)) { // Check the toolbar.
+ if ((137 <= cursorPos.x) && (cursorPos.x <= 207)) { // Control Avvy with the compass.
+ if (_alive && _avvyIsAwake)
+ useCompass(cursorPos);
+ } else if ((208 <= cursorPos.x) && (cursorPos.x <= 260)) { // Examine the _thing.
+ do {
+ updateEvents();
+ } while (_holdLeftMouse);
+
+ if (_thinkThing) {
+ _parser->_thing = _thinks;
+ _parser->_thing += 49;
+ _parser->_person = kPeoplePardon;
+ } else {
+ _parser->_person = (People)_thinks;
+ _parser->_thing = _parser->kPardon;
+ }
+ callVerb(kVerbCodeExam);
+ } else if ((261 <= cursorPos.x) && (cursorPos.x <= 319)) { // Display the score.
+ do {
+ updateEvents();
+ } while (_holdLeftMouse);
+
+ callVerb(kVerbCodeScore);
+ } else if ((320 <= cursorPos.x) && (cursorPos.x <= 357)) { // Change speed.
+ _animation->_sprites[0]->_speedX = kWalk;
+ _animation->updateSpeed();
+ } else if ((358 <= cursorPos.x) && (cursorPos.x <= 395)) { // Change speed.
+ _animation->_sprites[0]->_speedX = kRun;
+ _animation->updateSpeed();
+ } else if ((396 <= cursorPos.x) && (cursorPos.x <= 483))
+ fxToggle();
+ else if ((535 <= cursorPos.x) && (cursorPos.x <= 640))
+ _mouseText.insertChar(kControlNewLine, 0);
+ } else if (!_dropsOk)
+ _mouseText = Common::String(13) + _mouseText;
+ }
+}
+
+void AvalancheEngine::errorLed() {
+ warning("STUB: errorled()");
+}
+
+/**
+ * Displays a fade out, full screen.
+ * This version is different to the one in the original, which was fading in 3 steps.
+ * @remarks Originally called 'dusk'
+ */
+void AvalancheEngine::fadeOut() {
+ byte pal[3], tmpPal[3];
+
+ _graphics->setBackgroundColor(kColorBlack);
+ if (_fxHidden)
+ return;
+ _fxHidden = true;
+
+ for (int i = 0; i < 16; i++) {
+ for (int j = 0; j < 16; j++) {
+ g_system->getPaletteManager()->grabPalette((byte *)tmpPal, j, 1);
+ _fxPal[i][j][0] = tmpPal[0];
+ _fxPal[i][j][1] = tmpPal[1];
+ _fxPal[i][j][2] = tmpPal[2];
+ if (tmpPal[0] >= 16)
+ pal[0] = tmpPal[0] - 16;
+ else
+ pal[0] = 0;
+
+ if (tmpPal[1] >= 16)
+ pal[1] = tmpPal[1] - 16;
+ else
+ pal[1] = 0;
+
+ if (tmpPal[2] >= 16)
+ pal[2] = tmpPal[2] - 16;
+ else
+ pal[2] = 0;
+
+ g_system->getPaletteManager()->setPalette(pal, j, 1);
+ }
+ _system->delayMillis(10);
+ _graphics->refreshScreen();
+ }
+}
+
+/**
+ * Displays a fade in, full screen.
+ * This version is different to the one in the original, which was fading in 3 steps.
+ * @remarks Originally called 'dawn'
+ */
+void AvalancheEngine::fadeIn() {
+ if (_holdTheDawn || !_fxHidden)
+ return;
+
+ _fxHidden = false;
+
+ byte pal[3];
+ for (int i = 15; i >= 0; i--) {
+ for (int j = 0; j < 16; j++) {
+ pal[0] = _fxPal[i][j][0];
+ pal[1] = _fxPal[i][j][1];
+ pal[2] = _fxPal[i][j][2];
+ g_system->getPaletteManager()->setPalette(pal, j, 1);
+ }
+ _system->delayMillis(10);
+ _graphics->refreshScreen();
+ }
+
+ if ((_room == kRoomYours) && _avvyInBed && _teetotal)
+ _graphics->setBackgroundColor(kColorYellow);
+}
+
+void AvalancheEngine::drawDirection() { // It's data is loaded in load_digits().
+ if (_animation->getOldDirection() == _animation->getDirection())
+ return;
+
+ _animation->setOldDirection(_animation->getDirection());
+
+ CursorMan.showMouse(false);
+ _graphics->drawDirection(_animation->getDirection(), 0, 161);
+ CursorMan.showMouse(true);
+}
+
+void AvalancheEngine::gameOver() {
+ _userMovesAvvy = false;
+
+ AnimationType *avvy = _animation->_sprites[0];
+ int16 sx = avvy->_x;
+ int16 sy = avvy->_y;
+
+ avvy->remove();
+ avvy->init(12, true); // 12 = Avalot falls
+ avvy->_stepNum = 0;
+ avvy->appear(sx, sy, kDirUp);
+
+ _timer->addTimer(3, Timer::kProcAvalotFalls, Timer::kReasonFallingOver);
+ _alive = false;
+}
+
+void AvalancheEngine::minorRedraw() {
+ fadeOut();
+
+ enterRoom(_room, 0); // Ped unknown or non-existant.
+
+ for (int i = 0; i < 3; i++)
+ _scoreToDisplay[i] = -1; // impossible digits
+ drawScore();
+
+ fadeIn();
+}
+
+void AvalancheEngine::majorRedraw() {
+ _graphics->refreshScreen();
+}
+
+uint16 AvalancheEngine::bearing(byte whichPed) {
+ AnimationType *avvy = _animation->_sprites[0];
+ PedType *curPed = &_peds[whichPed];
+
+ if (avvy->_x == curPed->_x)
+ return 0;
+
+ int16 deltaX = avvy->_x - curPed->_x;
+ int16 deltaY = avvy->_y - curPed->_y;
+ uint16 result = (uint16)(atan((float)(deltaY / deltaX)) * 180 / M_PI);
+ if (avvy->_x < curPed->_x) {
+ return result + 90;
+ } else {
+ return result + 270;
+ }
+}
+
+/**
+ * @remarks Originally called 'sprite_run'
+ */
+void AvalancheEngine::spriteRun() {
+ _doingSpriteRun = true;
+ _animation->animLink();
+ _doingSpriteRun = false;
+}
+
+// CHECKME: Unused function
+void AvalancheEngine::fixFlashers() {
+ _ledStatus = 177;
+ _animation->setOldDirection(kDirNone);
+ _dialogs->setReadyLight(2);
+ drawDirection();
+}
+
+Common::String AvalancheEngine::intToStr(int32 num) {
+ return Common::String::format("%d", num);
+}
+
+void AvalancheEngine::resetVariables() {
+ _carryNum = 0;
+ for (int i = 0; i < kObjectNum; i++)
+ _objects[i] = false;
+
+ _dnascore = 0;
+ _money = 0;
+ _room = kRoomNowhere;
+ _saveNum = 0;
+ for (int i = 0; i < 100; i++)
+ _roomCount[i] = 0;
+
+ _wonNim = false;
+ _wineState = 0;
+ _cwytalotGone = false;
+ _passwordNum = 0;
+ _aylesIsAwake = false;
+ _drawbridgeOpen = 0;
+ _avariciusTalk = 0;
+ _rottenOnion = false;
+ _onionInVinegar = false;
+ _givenToSpludwick = 0;
+ _brummieStairs = 0;
+ _cardiffQuestionNum = 0;
+ _passedCwytalotInHerts = false;
+ _avvyIsAwake = false;
+ _avvyInBed = false;
+ _userMovesAvvy = false;
+ _npcFacing = 0;
+ _givenBadgeToIby = false;
+ _friarWillTieYouUp = false;
+ _tiedUp = false;
+ _boxContent = 0;
+ _talkedToCrapulus = false;
+ _jacquesState = 0;
+ _bellsAreRinging = false;
+ _standingOnDais = false;
+ _takenPen = false;
+ _arrowInTheDoor = false;
+ _favoriteDrink = "";
+ _favoriteSong = "";
+ _worstPlaceOnEarth = "";
+ _spareEvening = "";
+ _totalTime = 0;
+ _jumpStatus = 0;
+ _mushroomGrowing = false;
+ _spludwickAtHome = false;
+ _lastRoom = kRoomDummy;
+ _lastRoomNotMap = kRoomDummy;
+ _crapulusWillTell = false;
+ _enterCatacombsFromLustiesRoom = false;
+ _teetotal = false;
+ _malagauche = 0;
+ _drinking = 0;
+ _enteredLustiesRoomAsMonk = false;
+ _catacombX = 0;
+ _catacombY = 0;
+ _avvysInTheCupboard = false;
+ _geidaFollows = false;
+ _givenPotionToGeida = false;
+ _lustieIsAsleep = false;
+ _beenTiedUp = false;
+ _sittingInPub = false;
+ _spurgeTalkCount = 0;
+ _metAvaroid = false;
+ _takenMushroom = false;
+ _givenPenToAyles = false;
+ _askedDogfoodAboutNim = false;
+ _startTime = getTimeInSeconds();
+}
+
+void AvalancheEngine::resetAllVariables() {
+ resetVariables();
+ _parser->resetVariables();
+ _nim->resetVariables();
+ _animation->resetVariables();
+ _sequence->resetVariables();
+ _background->resetVariables();
+ _menu->resetVariables();
+ _timer->resetVariables();
+}
+
+void AvalancheEngine::newGame() {
+ for (int i = 0; i < kMaxSprites; i++) {
+ AnimationType *spr = _animation->_sprites[i];
+ if (spr->_quick)
+ spr->remove();
+ }
+ // Deallocate sprite. Sorry, beta testers!
+
+ AnimationType *avvy = _animation->_sprites[0];
+ avvy->init(0, true);
+
+ _alive = true;
+ resetAllVariables();
+
+ _dialogs->setBubbleStateNatural();
+
+ _spareEvening = "answer a questionnaire";
+ _favoriteDrink = "beer";
+ _money = 30; // 2/6
+ _animation->setDirection(kDirStopped);
+ _parser->_wearing = kObjectClothes;
+ _objects[kObjectMoney - 1] = true;
+ _objects[kObjectBodkin - 1] = true;
+ _objects[kObjectBell - 1] = true;
+ _objects[kObjectClothes - 1] = true;
+
+ _thinkThing = true;
+ _thinks = 2;
+ refreshObjectList();
+ _seeScroll = false;
+
+ avvy->appear(300, 117, kDirRight); // Needed to initialize Avalot.
+ //for (gd = 0; gd <= 30; gd++) for (gm = 0; gm <= 1; gm++) also[gd][gm] = nil;
+ // fillchar(previous^,sizeof(previous^),#0); { blank out array }
+ _him = kPeoplePardon;
+ _her = kPeoplePardon;
+ _it = Parser::kPardon;
+ _passwordNum = _rnd->getRandomNumber(29) + 1; //Random(30) + 1;
+ _userMovesAvvy = false;
+ _doingSpriteRun = false;
+ _avvyInBed = true;
+
+ _isLoaded = false;
+
+ enterRoom(kRoomYours, 1);
+ avvy->_visible = false;
+ drawScore();
+ _menu->setup();
+ _clock->update();
+ spriteRun();
+}
+
+bool AvalancheEngine::getFlag(char x) {
+ for (uint16 i = 0; i < _flags.size(); i++) {
+ if (_flags[i] == x)
+ return true;
+ }
+
+ return false;
+}
+
+bool AvalancheEngine::decreaseMoney(uint16 amount) {
+ _money -= amount;
+ if (_money < 0) {
+ _dialogs->displayScrollChain('Q', 2); // "You are now denariusless!"
+ gameOver();
+ return false;
+ } else
+ return true;
+}
+
+Common::String AvalancheEngine::getName(People whose) {
+ static const char lads[17][20] = {
+ "Avalot", "Spludwick", "Crapulus", "Dr. Duck", "Malagauche",
+ "Friar Tuck", "Robin Hood", "Cwytalot", "du Lustie", "the Duke of Cardiff",
+ "Dogfood", "A trader", "Ibythneth", "Ayles", "Port",
+ "Spurge", "Jacques"
+ };
+
+ static const char lasses[4][15] = {"Arkata", "Geida", "\0xB1", "the Wise Woman"};
+
+ if (whose <= kPeopleJacques)
+ return Common::String(lads[whose - kPeopleAvalot]);
+ else if ((whose >= kPeopleArkata) && (whose <= kPeopleWisewoman))
+ return Common::String(lasses[whose - kPeopleArkata]);
+ else
+ error("getName() - Unexpected character id %d", (byte) whose);
+}
+
+Common::String AvalancheEngine::getItem(byte which) {
+ static const char items[kObjectNum][18] = {
+ "some wine", "your money-bag", "your bodkin", "a potion", "a chastity belt",
+ "a crossbow bolt", "a crossbow", "a lute", "a pilgrim's badge", "a mushroom",
+ "a key", "a bell", "a scroll", "a pen", "some ink",
+ "your clothes", "a habit", "an onion"
+ };
+
+ Common::String result;
+ if (which > 150)
+ which -= 149;
+
+ switch (which) {
+ case kObjectWine:
+ switch (_wineState) {
+ case 0:
+ case 1:
+ case 4:
+ result = Common::String(items[which - 1]);
+ break;
+ case 3:
+ result = "some vinegar";
+ break;
+ }
+ break;
+ case kObjectOnion:
+ if (_rottenOnion)
+ result = "a rotten onion";
+ else if (_onionInVinegar)
+ result = "a pickled onion (in the vinegar)";
+ else
+ result = Common::String(items[which - 1]);
+ break;
+ default:
+ if ((which < kObjectNum) && (which > 0))
+ result = Common::String(items[which - 1]);
+ else
+ result = "";
+ }
+ return result;
+}
+
+Common::String AvalancheEngine::f5Does() {
+ switch (_room) {
+ case kRoomYours:
+ if (!_avvyIsAwake)
+ return Common::String::format("%cWWake up", kVerbCodeWake);
+ else if (_avvyInBed)
+ return Common::String::format("%cGGet up", kVerbCodeStand);
+ break;
+ case kRoomInsideCardiffCastle:
+ if (_standingOnDais)
+ return Common::String::format("%cCClimb down", kVerbCodeClimb);
+ else
+ return Common::String::format("%cCClimb up", kVerbCodeClimb);
+ break;
+ case kRoomNottsPub:
+ if (_sittingInPub)
+ return Common::String::format("%cSStand up", kVerbCodeStand);
+ else
+ return Common::String::format("%cSSit down", kVerbCodeSit);
+ break;
+ case kRoomMusicRoom:
+ if (_animation->inField(5))
+ return Common::String::format("%cPPlay the harp", kVerbCodePlay);
+ break;
+ default:
+ break;
+ }
+
+ return Common::String::format("%c", kVerbCodePardon); // If all else fails...
+}
+
+void AvalancheEngine::flipRoom(Room room, byte ped) {
+ assert((ped > 0) && (ped < 15));
+ if (!_alive) {
+ // You can't leave the room if you're dead.
+ _animation->_sprites[0]->_moveX = 0;
+ _animation->_sprites[0]->_moveY = 0; // Stop him from moving.
+ return;
+ }
+
+ if ((room == kRoomDummy) && (_room == kRoomLusties)) {
+ _animation->hideInCupboard();
+ return;
+ }
+
+ if ((_jumpStatus > 0) && (_room == kRoomInsideCardiffCastle)) {
+ // You can't *jump* out of Cardiff Castle!
+ _animation->_sprites[0]->_moveX = 0;
+ return;
+ }
+
+ exitRoom(_room);
+ fadeOut();
+
+ for (int16 i = 1; i < _animation->kSpriteNumbMax; i++) {
+ if (_animation->_sprites[i]->_quick)
+ _animation->_sprites[i]->remove();
+ } // Deallocate sprite
+
+ if (_room == kRoomLustiesRoom)
+ _enterCatacombsFromLustiesRoom = true;
+
+ if (room > kRoomMap)
+ return;
+
+ enterRoom(room, ped);
+ _animation->appearPed(0, ped - 1);
+ _enterCatacombsFromLustiesRoom = false;
+ _animation->setOldDirection(_animation->getDirection());
+ _animation->setDirection(_animation->_sprites[0]->_facingDir);
+ drawDirection();
+
+ fadeIn();
+}
+
+/**
+ * Open the Door.
+ * This slides the door open. The data really ought to be saved in
+ * the Also file, and will be next time. However, for now, they're
+ * here.
+ * @remarks Originally called 'open_the_door'
+ */
+void AvalancheEngine::openDoor(Room whither, byte ped, byte magicnum) {
+ switch (_room) {
+ case kRoomOutsideYours:
+ case kRoomOutsideNottsPub:
+ case kRoomOutsideDucks:
+ _sequence->startOutsideSeq(whither, ped);
+ break;
+ case kRoomInsideCardiffCastle:
+ _sequence->startCardiffSeq(whither, ped);
+ break;
+ case kRoomAvvysGarden:
+ case kRoomEntranceHall:
+ case kRoomInsideAbbey:
+ case kRoomYourHall:
+ _sequence->startHallSeq(whither, ped);
+ break;
+ case kRoomMusicRoom:
+ case kRoomOutsideArgentPub:
+ _sequence->startMusicRoomSeq2(whither, ped);
+ break;
+ case kRoomLusties:
+ switch (magicnum) {
+ case 14:
+ if (_avvysInTheCupboard) {
+ _animation->hideInCupboard();
+ _sequence->startCupboardSeq();
+ return;
+ } else {
+ _animation->appearPed(0, 5);
+ _animation->_sprites[0]->_facingDir = kDirRight;
+ _sequence->startLustiesSeq2(whither, ped);
+ }
+ break;
+ case 12:
+ _sequence->startLustiesSeq3(whither, ped);
+ break;
+ }
+ break;
+ default:
+ _sequence->startDummySeq(whither, ped);
+ }
+}
+
+void AvalancheEngine::setRoom(People persId, Room roomId) {
+ _whereIs[persId - kPeopleAvalot] = roomId;
+}
+
+Room AvalancheEngine::getRoom(People persId) {
+ return _whereIs[persId - kPeopleAvalot];
+}
+} // End of namespace Avalanche
diff --git a/engines/avalanche/avalot.h b/engines/avalanche/avalot.h
new file mode 100644
index 0000000000..9afb4a7b63
--- /dev/null
+++ b/engines/avalanche/avalot.h
@@ -0,0 +1,69 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+/*
+ * This code is based on the original source code of Lord Avalot d'Argent version 1.3.
+ * Copyright (c) 1994-1995 Mike, Mark and Thomas Thurman.
+ */
+
+/* AVALOT The kernel of the program. */
+
+#ifndef AVALANCHE_AVALOT_H
+#define AVALANCHE_AVALOT_H
+
+#include "avalanche/animation.h"
+
+namespace Avalanche {
+class AvalancheEngine;
+
+static const byte kObjectNum = 18; // always preface with a #
+static const int16 kCarryLimit = 12; // carry limit
+
+struct PedType {
+ int16 _x, _y;
+ Direction _direction;
+};
+
+struct MagicType {
+ byte _operation; // one of the operations
+ uint16 _data; // data for them
+};
+
+struct FieldType {
+ int16 _x1, _y1, _x2, _y2;
+};
+
+struct LineType : public FieldType {
+ Color _color;
+};
+
+struct QuasipedType {
+ byte _whichPed;
+ Color _textColor;
+ Room _room;
+ Color _backgroundColor;
+ People _who;
+};
+
+} // End of namespace Avalanche
+
+#endif // AVALANCHE_AVALOT_H
diff --git a/engines/avalanche/background.cpp b/engines/avalanche/background.cpp
new file mode 100644
index 0000000000..5d168a20af
--- /dev/null
+++ b/engines/avalanche/background.cpp
@@ -0,0 +1,370 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public 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 based on the original source code of Lord Avalot d'Argent version 1.3.
+ * Copyright (c) 1994-1995 Mike, Mark and Thomas Thurman.
+ */
+
+/* Original name: CELER The unit for updating the screen pics. */
+
+#include "avalanche/avalanche.h"
+#include "avalanche/background.h"
+
+namespace Avalanche {
+
+const int16 Background::kOnDisk = -1;
+
+Background::Background(AvalancheEngine *vm) {
+ _vm = vm;
+ _spriteNum = 0;
+ _nextBell = 0;
+}
+
+Background::~Background() {
+ release();
+}
+
+/**
+ * @remarks Originally called 'pics_link'
+ */
+void Background::update() {
+ if (_vm->_menu->isActive())
+ return; // No animation when the menus are up.
+
+ switch (_vm->_room) {
+ case kRoomOutsideArgentPub:
+ if ((_vm->_roomCycles % 12) == 0)
+ draw(-1, -1, (_vm->_roomCycles / 12) % 4);
+ break;
+ case kRoomBrummieRoad:
+ if ((_vm->_roomCycles % 2) == 0)
+ draw(-1, -1, (_vm->_roomCycles / 2) % 4);
+ break;
+ case kRoomBridge:
+ if ((_vm->_roomCycles % 2) == 0)
+ draw(-1, -1, 3 + (_vm->_roomCycles / 2) % 4);
+ break;
+ case kRoomYours:
+ if ((!_vm->_avvyIsAwake) && ((_vm->_roomCycles % 4) == 0))
+ draw(-1, -1, (_vm->_roomCycles / 12) % 2);
+ break;
+ case kRoomArgentPub:
+ if (((_vm->_roomCycles % 7) == 1) && (_vm->_malagauche != 177)) {
+ // Malagauche cycle.
+ _vm->_malagauche++;
+ switch (_vm->_malagauche) {
+ case 1:
+ case 11:
+ case 21:
+ draw(-1, -1, 11); // Looks forwards.
+ break;
+ case 8:
+ case 18:
+ case 28:
+ case 32:
+ draw(-1, -1, 10); // Looks at you.
+ break;
+ case 30:
+ draw(-1, -1, 12); // Winks.
+ break;
+ case 33:
+ _vm->_malagauche = 0;
+ break;
+ }
+ }
+
+ switch (_vm->_roomCycles % 200) {
+ case 179:
+ case 197:
+ draw(-1, -1, 4); // Dogfood's drinking cycle.
+ break;
+ case 182:
+ case 194:
+ draw(-1, -1, 5);
+ break;
+ case 185:
+ draw(-1, -1, 6);
+ break;
+ case 199:
+ _vm->_npcFacing = 177; // Impossible value for this.
+ break;
+ default:
+ if (_vm->_roomCycles % 200 <= 178) { // Normally.
+ byte direction = 1;
+ uint16 angle = _vm->bearing(1);
+ if (((angle >= 1) && (angle <= 90)) || ((angle >= 358) && (angle <= 360)))
+ direction = 3;
+ else if ((angle >= 293) && (angle <= 357))
+ direction = 2;
+ else if ((angle >= 270) && (angle <= 292))
+ direction = 4;
+
+ if (direction != _vm->_npcFacing) { // Dogfood.
+ draw(-1, -1, direction - 1);
+ _vm->_npcFacing = direction;
+ }
+ }
+ }
+ break;
+ case kRoomWestHall:
+ if ((_vm->_roomCycles % 3) == 0) {
+ switch ((_vm->_roomCycles / 3) % 6) {
+ case 4:
+ draw(-1, -1, 0);
+ break;
+ case 1:
+ case 3:
+ case 5:
+ draw(-1, -1, 1);
+ break;
+ case 0:
+ case 2:
+ draw(-1, -1, 2);
+ break;
+ }
+ }
+ break;
+ case kRoomLustiesRoom:
+ if (!(_vm->_lustieIsAsleep)) {
+ byte direction = 0;
+ uint16 angle = _vm->bearing(1);
+ if ((_vm->_roomCycles % 45) > 42)
+ direction = 4; // du Lustie blinks.
+ // Bearing of Avvy from du Lustie.
+ else if ((angle <= 45) || ((angle >= 315) && (angle <= 360)))
+ direction = 1; // Middle.
+ else if ((angle >= 45) && (angle <= 180))
+ direction = 2; // Left.
+ else if ((angle >= 181) && (angle <= 314))
+ direction = 3; // Right.
+
+ if (direction != _vm->_npcFacing) { // du Lustie.
+ draw(-1, -1, direction - 1);
+ _vm->_npcFacing = direction;
+ }
+ }
+ break;
+ case kRoomAylesOffice:
+ if ((!_vm->_aylesIsAwake) && (_vm->_roomCycles % 14 == 0)) {
+ switch ((_vm->_roomCycles / 14) % 2) {
+ case 0:
+ draw(-1, -1, 0); // Frame 2: EGA.
+ break;
+ case 1:
+ draw(-1, -1, 2); // Frame 1: Natural.
+ break;
+ }
+ }
+ break;
+ case kRoomRobins:
+ if (_vm->_tiedUp) {
+ switch (_vm->_roomCycles % 54) {
+ case 20:
+ draw(-1, -1, 3); // Frame 4: Avalot blinks.
+ break;
+ case 23:
+ draw(-1, -1, 1); // Frame 1: Back to normal.
+ break;
+ }
+ }
+ break;
+ case kRoomNottsPub: {
+ // Bearing of Avvy from Port.
+ byte direction = 0;
+ uint16 angle = _vm->bearing(4);
+ if ((angle <= 45) || ((angle >= 315) && (angle <= 360)))
+ direction = 2; // Middle.
+ else if ((angle >= 45) && (angle <= 180))
+ direction = 6; // Left.
+ else if ((angle >= 181) && (angle <= 314))
+ direction = 8; // Right.
+
+ if ((_vm->_roomCycles % 60) > 57)
+ direction--; // Blinks.
+
+ if (direction != _vm->_npcFacing) { // Port.
+ draw(-1, -1, direction - 1);
+ _vm->_npcFacing = direction;
+ }
+
+ switch (_vm->_roomCycles % 50) {
+ case 45 :
+ draw(-1, -1, 8); // Spurge blinks.
+ break;
+ case 49 :
+ draw(-1, -1, 9);
+ break;
+ }
+ break;
+ }
+ case kRoomDucks: {
+ if ((_vm->_roomCycles % 3) == 0) // The fire flickers.
+ draw(-1, -1, (_vm->_roomCycles / 3) % 3);
+
+ // Bearing of Avvy from Duck.
+ byte direction = 0;
+ uint16 angle = _vm->bearing(1);
+ if ((angle <= 45) || ((angle >= 315) && (angle <= 360)))
+ direction = 4; // Middle.
+ else if ((angle >= 45) && (angle <= 180))
+ direction = 6; // Left.
+ else if ((angle >= 181) && (angle <= 314))
+ direction = 8; // Right.
+
+ if ((_vm->_roomCycles % 45) > 42)
+ direction++; // Duck blinks.
+
+ if (direction != _vm->_npcFacing) { // Duck.
+ draw(-1, -1, direction - 1);
+ _vm->_npcFacing = direction;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+
+ if ((_vm->_bellsAreRinging) && (_vm->getFlag('B'))) {
+ // They're ringing the bells.
+ switch (_vm->_roomCycles % 4) {
+ case 1:
+ if (_nextBell < 5)
+ _nextBell = 12;
+ _nextBell--;
+ // CHECKME: 2 is a guess. No length in the original?
+ _vm->_sound->playNote(_vm->kNotes[_nextBell], 2);
+ break;
+ case 2:
+ _vm->_sound->stopSound();
+ break;
+ }
+ }
+}
+
+void Background::load(byte number) {
+ Common::File f;
+ _filename = _filename.format("chunk%d.avd", number);
+ if (!f.open(_filename))
+ return; // We skip because some rooms don't have sprites in the background.
+
+ f.seek(44);
+ _spriteNum = f.readByte();
+ for (int i = 0; i < _spriteNum; i++)
+ _offsets[i] = f.readSint32LE();
+
+ for (int i = 0; i < _spriteNum; i++) {
+ f.seek(_offsets[i]);
+
+ SpriteType sprite;
+ sprite._type = (PictureType)(f.readByte());
+ sprite._x = f.readSint16LE();
+ sprite._y = f.readSint16LE();
+ sprite._xl = f.readSint16LE();
+ sprite._yl = f.readSint16LE();
+ sprite._size = f.readSint32LE();
+ bool natural = f.readByte();
+ bool memorize = f.readByte();
+
+ if (memorize) {
+ _sprites[i]._x = sprite._x;
+ _sprites[i]._xl = sprite._xl;
+ _sprites[i]._y = sprite._y;
+ _sprites[i]._yl = sprite._yl;
+ _sprites[i]._type = sprite._type;
+
+ if (natural)
+ _vm->_graphics->getNaturalPicture(_sprites[i]);
+ else {
+ _sprites[i]._size = sprite._size;
+ _sprites[i]._picture = _vm->_graphics->loadPictureRaw(f, _sprites[i]._xl * 8, _sprites[i]._yl + 1);
+ }
+ } else
+ _sprites[i]._x = kOnDisk;
+ }
+ f.close();
+}
+
+void Background::release() {
+ for (int i = 0; i < _spriteNum; i++) {
+ if (_sprites[i]._x > kOnDisk)
+ _sprites[i]._picture.free();
+ }
+}
+
+/**
+ * Draw background animation
+ * @remarks Originally called 'show_one'
+ */
+void Background::draw(int16 destX, int16 destY, byte sprId) {
+ assert(sprId < 40);
+
+ if (_sprites[sprId]._x > kOnDisk) {
+ if (destX < 0) {
+ destX = _sprites[sprId]._x * 8;
+ destY = _sprites[sprId]._y;
+ }
+ drawSprite(destX, destY, _sprites[sprId]);
+ } else {
+ Common::File f;
+ if (!f.open(_filename)) // Filename was set in loadBackgroundSprites().
+ return; // We skip because some rooms don't have sprites in the background.
+
+ f.seek(_offsets[sprId]);
+
+ SpriteType sprite;
+ sprite._type = (PictureType)(f.readByte());
+ sprite._x = f.readSint16LE();
+ sprite._y = f.readSint16LE();
+ sprite._xl = f.readSint16LE();
+ sprite._yl = f.readSint16LE();
+ sprite._size = f.readSint32LE();
+ f.skip(2); // Natural and Memorize are used in Load()
+ sprite._picture = _vm->_graphics->loadPictureRaw(f, sprite._xl * 8, sprite._yl + 1);
+
+ if (destX < 0) {
+ destX = sprite._x * 8;
+ destY = sprite._y;
+ }
+ drawSprite(destX, destY, sprite);
+
+ sprite._picture.free();
+ f.close();
+ }
+}
+
+/**
+ * @remarks Originally called 'display_it'
+ */
+void Background::drawSprite(int16 x, int16 y, SpriteType &sprite) {
+ // These pictures are practically parts of the background. -10 is for the drop-down menu.
+ _vm->_graphics->drawBackgroundSprite(x, y - 10, sprite);
+}
+
+void Background::resetVariables() {
+ _nextBell = 0;
+}
+
+void Background::synchronize(Common::Serializer &sz) {
+ sz.syncAsByte(_nextBell);
+}
+} // End of namespace Avalanche.
diff --git a/engines/avalanche/background.h b/engines/avalanche/background.h
new file mode 100644
index 0000000000..34d7a9a2cc
--- /dev/null
+++ b/engines/avalanche/background.h
@@ -0,0 +1,79 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+/*
+ * This code is based on the original source code of Lord Avalot d'Argent version 1.3.
+ * Copyright (c) 1994-1995 Mike, Mark and Thomas Thurman.
+ */
+
+/* Original name: CELER The unit for updating the screen pics. */
+
+#ifndef AVALANCHE_BACKGROUND_H
+#define AVALANCHE_BACKGROUND_H
+
+#include "common/str.h"
+
+namespace Avalanche {
+class AvalancheEngine;
+
+enum PictureType {kEga, kBgi, kNaturalImage};
+
+struct SpriteType {
+ PictureType _type;
+ int16 _x, _y;
+ int16 _xl, _yl;
+ int32 _size;
+ Graphics::Surface _picture;
+};
+
+class Background {
+public:
+ Background(AvalancheEngine *vm);
+ ~Background();
+
+ void update();
+ void load(byte number);
+ void release();
+
+ // Setting the destination to negative coordinates means the picture should be drawn to it's original position.
+ // If you give it positive values, the picture will be plotted to the desired coordinates on the screen.
+ // By that we get rid of show_one_at(), which would be almost identical and cause a lot of code duplication.
+ void draw(int16 destX, int16 destY, byte sprId);
+ void resetVariables();
+ void synchronize(Common::Serializer &sz);
+
+private:
+ AvalancheEngine *_vm;
+
+ byte _nextBell; // For the ringing.
+ int32 _offsets[40];
+ byte _spriteNum;
+ SpriteType _sprites[40];
+ Common::String _filename;
+ static const int16 kOnDisk; // Value of _sprites[fv]._x when it's not in memory.
+
+ void drawSprite(int16 x, int16 y, SpriteType &sprite);
+};
+
+} // End of namespace Avalanche.
+
+#endif // AVALANCHE_BACKGROUND_H
diff --git a/engines/avalanche/clock.cpp b/engines/avalanche/clock.cpp
new file mode 100644
index 0000000000..1c2c50c3bf
--- /dev/null
+++ b/engines/avalanche/clock.cpp
@@ -0,0 +1,116 @@
+/* ScummVM - Graphic Adventure Engine
+*
+* ScummVM is the legal property of its developers, whose names
+* are too numerous to list here. Please refer to the COPYRIGHT
+* file distributed with this source distribution.
+*
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License
+* as published by the Free Software Foundation; either version 2
+* of the License, or (at your option) any later version.
+
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+
+* You should have received a copy of the GNU General Public 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 based on the original source code of Lord Avalot d'Argent version 1.3.
+* Copyright (c) 1994-1995 Mike: Mark and Thomas Thurman.
+*/
+
+#include "avalanche/clock.h"
+#include "avalanche/avalanche.h"
+
+namespace Avalanche {
+
+Clock::Clock(AvalancheEngine *vm) {
+ _vm = vm;
+ // Magic value to determine if we just created the instance
+ _oldHour = _oldHourAngle = _oldMinute = 17717;
+ _hour = _minute = _second = 0;
+ _hourAngle = 0;
+}
+
+void Clock::update() {
+ TimeDate t;
+ _vm->_system->getTimeAndDate(t);
+ _hour = t.tm_hour;
+ _minute = t.tm_min;
+ _second = t.tm_sec;
+
+ _hourAngle = (_hour % 12) * 30 + _minute / 2;
+
+ if (_oldHour != _hour) {
+ plotHands();
+ chime();
+ }
+
+ if (_oldMinute != _minute)
+ plotHands();
+
+ if ((_hour == 0) && (_oldHour != 0) && (_oldHour != 17717)) {
+ Common::String tmpStr = Common::String::format("Good morning!%c%cYes, it's just past " \
+ "midnight. Are you having an all-night Avvy session? Glad you like the game that much!",
+ kControlNewLine, kControlNewLine);
+ _vm->_dialogs->displayText(tmpStr);
+ }
+ _oldHour = _hour;
+ _oldHourAngle = _hourAngle;
+ _oldMinute = _minute;
+}
+
+Common::Point Clock::calcHand(uint16 angle, uint16 length, Color color) {
+ if (angle > 900) {
+ return(Common::Point(177, 177));
+ }
+
+ return(_vm->_graphics->drawScreenArc(kCenterX, kCenterY, 449 - angle, 450 - angle, length, color));
+}
+
+void Clock::drawHand(const Common::Point &endPoint, Color color) {
+ if (endPoint.x == 177)
+ return;
+
+ _vm->_graphics->drawScreenLine(kCenterX, kCenterY, endPoint.x, endPoint.y, color);
+}
+
+void Clock::plotHands() {
+ _clockHandHour = calcHand(_oldHourAngle, 14, kColorYellow);
+ _clockHandMinute = calcHand(_oldMinute * 6, 17, kColorYellow);
+ drawHand(_clockHandHour, kColorBrown);
+ drawHand(_clockHandMinute, kColorBrown);
+
+ _clockHandHour = calcHand(_hourAngle, 14, kColorBrown);
+ _clockHandMinute = calcHand(_minute * 6, 17, kColorBrown);
+ drawHand(_clockHandHour, kColorYellow);
+ drawHand(_clockHandMinute, kColorYellow);
+}
+
+void Clock::chime() {
+ // Too high - must be first time around
+ // Mute - skip the sound generation
+ if ((_oldHour == 17717) || (!_vm->_soundFx))
+ return;
+
+ byte hour = _hour % 12;
+ if (hour == 0)
+ hour = 12;
+
+ _vm->_graphics->loadMouse(kCurWait);
+
+ for (int i = 1; i <= hour; i++) {
+ for (int j = 1; j <= 3; j++)
+ _vm->_sound->playNote((i % 3) * 64 + 140 - j * 30, 50 - j * 12);
+ if (i != hour)
+ _vm->_system->delayMillis(100);
+ }
+}
+
+} // End of namespace Avalanche
diff --git a/engines/avalanche/clock.h b/engines/avalanche/clock.h
new file mode 100644
index 0000000000..68e8e119f0
--- /dev/null
+++ b/engines/avalanche/clock.h
@@ -0,0 +1,60 @@
+/* ScummVM - Graphic Adventure Engine
+*
+* ScummVM is the legal property of its developers, whose names
+* are too numerous to list here. Please refer to the COPYRIGHT
+* file distributed with this source distribution.
+*
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License
+* as published by the Free Software Foundation; either version 2
+* of the License, or (at your option) any later version.
+
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+
+* You should have received a copy of the GNU General Public 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 based on the original source code of Lord Avalot d'Argent version 1.3.
+* Copyright (c) 1994-1995 Mike: Mark and Thomas Thurman.
+*/
+
+#ifndef AVALANCHE_CLOCK_H
+#define AVALANCHE_CLOCK_H
+
+#include "common/rect.h"
+#include "avalanche/enums.h"
+
+namespace Avalanche {
+class AvalancheEngine;
+
+class Clock {
+public:
+ Clock(AvalancheEngine *vm);
+
+ void update();
+
+private:
+ static const int kCenterX = 510;
+ static const int kCenterY = 183;
+
+ AvalancheEngine *_vm;
+
+ uint16 _hour, _minute, _second, _hourAngle, _oldHour, _oldMinute, _oldHourAngle;
+ Common::Point _clockHandHour, _clockHandMinute;
+
+ Common::Point calcHand(uint16 angle, uint16 length, Color color);
+ void drawHand(const Common::Point &endPoint, Color color);
+ void plotHands();
+ void chime();
+};
+
+} // End of namespace Avalanche
+
+#endif // AVALANCHE_CLOCK_H
diff --git a/engines/avalanche/closing.cpp b/engines/avalanche/closing.cpp
new file mode 100644
index 0000000000..1cb2e84218
--- /dev/null
+++ b/engines/avalanche/closing.cpp
@@ -0,0 +1,75 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public 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 based on the original source code of Lord Avalot d'Argent version 1.3.
+ * Copyright (c) 1994-1995 Mike, Mark and Thomas Thurman.
+ */
+
+/* CLOSING The closing screen and error handler. */
+
+#include "avalanche/avalanche.h"
+#include "avalanche/closing.h"
+
+#include "common/random.h"
+
+namespace Avalanche {
+
+Closing::Closing(AvalancheEngine *vm) {
+ _vm = vm;
+ warning("STUB: Closing::Closing()");
+}
+
+void Closing::getScreen(ScreenType which) {
+ warning("STUB: Closing::getScreen()");
+}
+
+void Closing::showScreen() {
+ warning("STUB: Closing::showScreen()");
+}
+
+void Closing::putIn(Common::String str, uint16 where) {
+ warning("STUB: Closing::putIn()");
+}
+
+void Closing::exitGame() {
+ static const char nouns[12][14] = {
+ "sackbut", "harpsichord", "camel", "conscience", "ice-cream", "serf",
+ "abacus", "castle", "carrots", "megaphone", "manticore", "drawbridge"
+ };
+
+ static const char verbs[12][12] = {
+ "haunt", "daunt", "tickle", "gobble", "erase", "provoke",
+ "surprise", "ignore", "stare at", "shriek at", "frighten", "quieten"
+ };
+
+ _vm->_sound->stopSound();
+
+ getScreen(kScreenNagScreen);
+ byte nounId = _vm->_rnd->getRandomNumber(11);
+ byte verbId = _vm->_rnd->getRandomNumber(11);
+ Common::String result = Common::String::format("%s will %s you", nouns[nounId], verbs[verbId]);
+ putIn(result, 1628);
+ showScreen(); // No halt- it's already set up.
+}
+
+} // End of namespace Avalanche.
diff --git a/engines/avalanche/closing.h b/engines/avalanche/closing.h
new file mode 100644
index 0000000000..25217e347e
--- /dev/null
+++ b/engines/avalanche/closing.h
@@ -0,0 +1,62 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public 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 based on the original source code of Lord Avalot d'Argent version 1.3.
+ * Copyright (c) 1994-1995 Mike, Mark and Thomas Thurman.
+ */
+
+/* CLOSING The closing screen and error handler. */
+
+#ifndef AVALANCHE_CLOSING_H
+#define AVALANCHE_CLOSING_H
+
+#include "common/str.h"
+
+namespace Avalanche {
+class AvalancheEngine;
+
+class Closing {
+public:
+ Closing(AvalancheEngine *vm);
+ void exitGame();
+
+private:
+ // Will be needed during implementation of Closing.
+ enum ScreenType {
+ kScreenBugAlert = 1,
+ kScreenRamCram = 2,
+ kScreenNagScreen = 3,
+ kScreenTwoCopies = 5
+ };
+
+ AvalancheEngine *_vm;
+
+ void getScreen(ScreenType which);
+ void showScreen();
+ void putIn(Common::String str, uint16 where);
+
+};
+
+} // End of namespace Avalanche.
+
+#endif // AVALANCHE_CLOSING_H
diff --git a/engines/avalanche/configure.engine b/engines/avalanche/configure.engine
new file mode 100644
index 0000000000..28d6a558db
--- /dev/null
+++ b/engines/avalanche/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 avalanche "Lord Avalot d'Argent" no
diff --git a/engines/avalanche/console.cpp b/engines/avalanche/console.cpp
new file mode 100644
index 0000000000..e4b52116e4
--- /dev/null
+++ b/engines/avalanche/console.cpp
@@ -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 code is based on the original source code of Lord Avalot d'Argent version 1.3.
+ * Copyright (c) 1994-1995 Mike, Mark and Thomas Thurman.
+ */
+
+#include "avalanche/console.h"
+#include "avalanche/avalanche.h"
+
+namespace Avalanche {
+
+AvalancheConsole::AvalancheConsole(AvalancheEngine *vm) : GUI::Debugger(), _vm(vm) {
+ DCmd_Register("magic_lines", WRAP_METHOD(AvalancheConsole, Cmd_MagicLines));
+}
+
+AvalancheConsole::~AvalancheConsole() {
+}
+
+/**
+ * This command loads up the specified new scene number
+ */
+bool AvalancheConsole::Cmd_MagicLines(int argc, const char **argv) {
+ if (argc != 1) {
+ DebugPrintf("Usage: %s\n", argv[0]);
+ return true;
+ }
+
+ _vm->_showDebugLines = !_vm->_showDebugLines;
+ return false;
+}
+
+} // End of namespace Avalanche
diff --git a/engines/avalanche/console.h b/engines/avalanche/console.h
new file mode 100644
index 0000000000..166515d913
--- /dev/null
+++ b/engines/avalanche/console.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.
+ *
+ */
+
+/*
+ * This code is based on the original source code of Lord Avalot d'Argent version 1.3.
+ * Copyright (c) 1994-1995 Mike, Mark and Thomas Thurman.
+ */
+
+#ifndef AVALANCHE_CONSOLE_H
+#define AVALANCHE_CONSOLE_H
+
+#include "gui/debugger.h"
+
+namespace Avalanche {
+
+class AvalancheEngine;
+
+class AvalancheConsole : public GUI::Debugger {
+public:
+ AvalancheConsole(AvalancheEngine *vm);
+ virtual ~AvalancheConsole(void);
+
+protected:
+ bool Cmd_MagicLines(int argc, const char **argv);
+
+private:
+ AvalancheEngine *_vm;
+};
+
+} // End of namespace Avalanche
+
+#endif // AVALANCHE_CONSOLE_H
diff --git a/engines/avalanche/detection.cpp b/engines/avalanche/detection.cpp
new file mode 100644
index 0000000000..5f4f03a78b
--- /dev/null
+++ b/engines/avalanche/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.
+ *
+ */
+
+/*
+ * This code is based on the original source code of Lord Avalot d'Argent version 1.3.
+ * Copyright (c) 1994-1995 Mike, Mark and Thomas Thurman.
+ */
+
+#include "avalanche/avalanche.h"
+
+#include "common/system.h"
+#include "common/savefile.h"
+
+#include "engines/advancedDetector.h"
+#include "graphics/thumbnail.h"
+
+namespace Avalanche {
+
+uint32 AvalancheEngine::getFeatures() const {
+ return _gameDescription->desc.flags;
+}
+
+const char *AvalancheEngine::getGameId() const {
+ return _gameDescription->desc.gameid;
+}
+
+static const PlainGameDescriptor avalancheGames[] = {
+ {"avalanche", "Lord Avalot d'Argent"},
+ {0, 0}
+};
+
+static const ADGameDescription gameDescriptions[] = {
+ {
+ "avalanche", 0,
+ {
+ {"avalot.sez", 0, "de10eb353228013da3d3297784f81ff9", 48763},
+ {"mainmenu.avd", 0, "89f31211af579a872045b175cc264298", 18880},
+ AD_LISTEND
+ },
+ Common::EN_ANY,
+ Common::kPlatformDOS,
+ ADGF_NO_FLAGS,
+ GUIO0()
+ },
+
+ AD_TABLE_END_MARKER
+};
+
+class AvalancheMetaEngine : public AdvancedMetaEngine {
+public:
+ AvalancheMetaEngine() : AdvancedMetaEngine(gameDescriptions, sizeof(AvalancheGameDescription), avalancheGames) {
+ }
+
+ const char *getName() const {
+ return "Avalanche";
+ }
+
+ const char *getOriginalCopyright() const {
+ return "Avalanche Engine Copyright (c) 1994-1995 Mike, Mark and Thomas Thurman.";
+ }
+
+ bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription *gd) const;
+ bool hasFeature(MetaEngineFeature f) const;
+
+ int getMaximumSaveSlot() const { return 99; }
+ SaveStateList listSaves(const char *target) const;
+ void removeSaveState(const char *target, int slot) const;
+ SaveStateDescriptor querySaveMetaInfos(const char *target, int slot) const;
+};
+
+bool AvalancheMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameDescription *gd) const {
+ if (gd)
+ *engine = new AvalancheEngine(syst, (const AvalancheGameDescription *)gd);
+ return gd != 0;
+}
+
+bool AvalancheMetaEngine::hasFeature(MetaEngineFeature f) const {
+ return
+ (f == kSupportsListSaves) ||
+ (f == kSupportsDeleteSave) ||
+ (f == kSupportsLoadingDuringStartup) ||
+ (f == kSavesSupportMetaInfo) ||
+ (f == kSavesSupportThumbnail);
+}
+
+SaveStateList AvalancheMetaEngine::listSaves(const char *target) const {
+ Common::SaveFileManager *saveFileMan = g_system->getSavefileManager();
+ Common::StringArray filenames;
+ Common::String pattern = target;
+ pattern.toUppercase();
+ pattern += ".???";
+
+ filenames = saveFileMan->listSavefiles(pattern);
+ sort(filenames.begin(), filenames.end()); // Sort (hopefully ensuring we are sorted numerically..)
+
+ SaveStateList saveList;
+ for (Common::StringArray::const_iterator filename = filenames.begin(); filename != filenames.end(); ++filename) {
+ const Common::String &fname = *filename;
+ int slotNum = atoi(fname.c_str() + fname.size() - 3);
+ if (slotNum >= 0 && slotNum <= getMaximumSaveSlot()) {
+ Common::InSaveFile *file = saveFileMan->openForLoading(fname);
+ if (file) {
+ // Check for our signature.
+ uint32 signature = file->readUint32LE();
+ if (signature != MKTAG('A', 'V', 'A', 'L')) {
+ warning("Savegame of incompatible type!");
+ delete file;
+ continue;
+ }
+
+ // Check version.
+ byte saveVersion = file->readByte();
+ if (saveVersion > kSavegameVersion) {
+ warning("Savegame of incompatible version!");
+ delete file;
+ continue;
+ }
+
+ // Read name.
+ uint32 nameSize = file->readUint32LE();
+ if (nameSize >= 255) {
+ delete file;
+ continue;
+ }
+ char *name = new char[nameSize + 1];
+ file->read(name, nameSize);
+ name[nameSize] = 0;
+
+ saveList.push_back(SaveStateDescriptor(slotNum, name));
+ delete[] name;
+ delete file;
+ }
+ }
+ }
+
+ return saveList;
+}
+
+void AvalancheMetaEngine::removeSaveState(const char *target, int slot) const {
+ Common::String fileName = Common::String::format("%s.%03d", target, slot);
+ g_system->getSavefileManager()->removeSavefile(fileName);
+}
+
+SaveStateDescriptor AvalancheMetaEngine::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) {
+ // Check for our signature.
+ uint32 signature = f->readUint32LE();
+ if (signature != MKTAG('A', 'V', 'A', 'L')) {
+ warning("Savegame of incompatible type!");
+ delete f;
+ return SaveStateDescriptor();
+ }
+
+ // Check version.
+ byte saveVersion = f->readByte();
+ if (saveVersion > kSavegameVersion) {
+ warning("Savegame of a too recent version!");
+ delete f;
+ return SaveStateDescriptor();
+ }
+
+ // Read the description.
+ uint32 descSize = f->readUint32LE();
+ Common::String description;
+ for (uint32 i = 0; i < descSize; i++) {
+ char actChar = f->readByte();
+ description += actChar;
+ }
+
+ SaveStateDescriptor desc(slot, description);
+
+ Graphics::Surface *const thumbnail = Graphics::loadThumbnail(*f);
+ desc.setThumbnail(thumbnail);
+
+ delete f;
+ return desc;
+ }
+ return SaveStateDescriptor();
+}
+
+} // End of namespace Avalanche
+
+#if PLUGIN_ENABLED_DYNAMIC(AVALANCHE)
+ REGISTER_PLUGIN_DYNAMIC(AVALANCHE, PLUGIN_TYPE_ENGINE, Avalanche::AvalancheMetaEngine);
+#else
+ REGISTER_PLUGIN_STATIC(AVALANCHE, PLUGIN_TYPE_ENGINE, Avalanche::AvalancheMetaEngine);
+#endif
diff --git a/engines/avalanche/dialogs.cpp b/engines/avalanche/dialogs.cpp
new file mode 100644
index 0000000000..2174df3580
--- /dev/null
+++ b/engines/avalanche/dialogs.cpp
@@ -0,0 +1,1218 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public 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 based on the original source code of Lord Avalot d'Argent version 1.3.
+ * Copyright (c) 1994-1995 Mike, Mark and Thomas Thurman.
+ */
+
+ /* SCROLLS The scroll driver. */
+
+#include "avalanche/avalanche.h"
+#include "avalanche/dialogs.h"
+
+#include "common/random.h"
+
+namespace Avalanche {
+
+const Dialogs::TuneType Dialogs::kTune = {
+ kPitchHigher, kPitchHigher, kPitchLower, kPitchSame, kPitchHigher, kPitchHigher, kPitchLower, kPitchHigher, kPitchHigher, kPitchHigher,
+ kPitchLower, kPitchHigher, kPitchHigher, kPitchSame, kPitchHigher, kPitchLower, kPitchLower, kPitchLower, kPitchLower, kPitchHigher,
+ kPitchHigher, kPitchLower, kPitchLower, kPitchLower, kPitchLower, kPitchSame, kPitchLower, kPitchHigher, kPitchSame, kPitchLower, kPitchHigher
+};
+
+// A quasiped defines how people who aren't sprites talk. For example, quasiped
+// "A" is Dogfood. The rooms aren't stored because I'm leaving that to context.
+const QuasipedType Dialogs::kQuasipeds[16] = {
+ //_whichPed, _foregroundColor, _room, _backgroundColor, _who
+ {1, kColorLightgray, kRoomArgentPub, kColorBrown, kPeopleDogfood}, // A: Dogfood (screen 19).
+ {2, kColorGreen, kRoomArgentPub, kColorWhite, kPeopleIbythneth}, // B: Ibythneth (screen 19).
+ {2, kColorWhite, kRoomYours, kColorMagenta, kPeopleArkata}, // C: Arkata (screen 1).
+ {2, kColorBlack, kRoomLustiesRoom, kColorRed, kPeopleInvisible}, // D: Hawk (screen 23).
+ {2, kColorLightgreen, kRoomOutsideDucks, kColorBrown, kPeopleTrader}, // E: Trader (screen 50).
+ {5, kColorYellow, kRoomRobins, kColorRed, kPeopleAvalot}, // F: Avvy, tied up (scr.42)
+ {1, kColorBlue, kRoomAylesOffice, kColorWhite, kPeopleAyles}, // G: Ayles (screen 16).
+ {1, kColorBrown, kRoomMusicRoom, kColorWhite, kPeopleJacques}, // H: Jacques (screen 7).
+ {1, kColorLightgreen, kRoomNottsPub, kColorGreen, kPeopleSpurge}, // I: Spurge (screen 47).
+ {2, kColorYellow, kRoomNottsPub, kColorRed, kPeopleAvalot}, // J: Avalot (screen 47).
+ {1, kColorLightgray, kRoomLustiesRoom, kColorBlack, kPeopleDuLustie}, // K: du Lustie (screen 23).
+ {1, kColorYellow, kRoomOubliette, kColorRed, kPeopleAvalot}, // L: Avalot (screen 27).
+ {2, kColorWhite, kRoomOubliette, kColorRed, kPeopleInvisible}, // M: Avaroid (screen 27).
+ {3, kColorLightgray, kRoomArgentPub, kColorDarkgray, kPeopleMalagauche},// N: Malagauche (screen 19).
+ {4, kColorLightmagenta, kRoomNottsPub, kColorRed, kPeoplePort}, // O: Port (screen 47).
+ {1, kColorLightgreen, kRoomDucks, kColorDarkgray, kPeopleDrDuck} // P: Duck (screen 51).
+};
+
+Dialogs::Dialogs(AvalancheEngine *vm) {
+ _vm = vm;
+ _noError = true;
+
+ _aboutBox = false;
+ _talkX = 0;
+ _talkY = 0;
+ _maxLineNum = 0;
+ _scReturn = false;
+ _currentFont = kFontStyleRoman;
+ _param = 0;
+ _useIcon = 0;
+ _scrollBells = 0;
+ _underScroll = 0;
+ _shadowBoxX = 0;
+ _shadowBoxY = 0;
+}
+
+void Dialogs::init() {
+ loadFont();
+ resetScrollDriver();
+}
+
+/**
+ * Determine the color of the ready light and draw it
+ * @remarks Originally called 'state'
+ */
+void Dialogs::setReadyLight(byte state) {
+ if (_vm->_ledStatus == state)
+ return; // Already like that!
+
+ Color color = kColorBlack;
+ switch (state) {
+ case 0:
+ color = kColorBlack;
+ break; // Off
+ case 1:
+ case 2:
+ case 3:
+ color = kColorGreen;
+ break; // Hit a key
+ }
+ warning("STUB: Dialogs::setReadyLight()");
+
+ CursorMan.showMouse(false);
+ _vm->_graphics->drawReadyLight(color);
+ CursorMan.showMouse(true);
+ _vm->_ledStatus = state;
+}
+
+void Dialogs::easterEgg() {
+ warning("STUB: Scrolls::easterEgg()");
+}
+
+void Dialogs::say(int16 x, int16 y, Common::String z) {
+ FontType itw;
+ byte lz = z.size();
+
+ bool offset = x % 8 == 4;
+ x /= 8;
+ y++;
+ int16 i = 0;
+ for (int xx = 0; xx < lz; xx++) {
+ switch (z[xx]) {
+ case kControlRoman:
+ _currentFont = kFontStyleRoman;
+ break;
+ case kControlItalic:
+ _currentFont = kFontStyleItalic;
+ break;
+ default: {
+ for (int yy = 0; yy < 12; yy++)
+ itw[(byte)z[xx]][yy] = _fonts[_currentFont][(byte)z[xx]][yy + 2];
+
+ // We have to draw the characters one-by-one because of the accidental font changes.
+ i++;
+ Common::String chr(z[xx]);
+ _vm->_graphics->drawScrollText(chr, itw, 12, (x - 1) * 8 + offset * 4 + i * 8, y, kColorBlack);
+ }
+ }
+ }
+}
+
+/**
+ * One of the 3 "Mode" functions passed as ScrollsFunctionType parameters.
+ * @remarks Originally called 'normscroll'
+ */
+void Dialogs::scrollModeNormal() {
+ // Original code is:
+ // egg : array[1..8] of char = ^P^L^U^G^H+'***';
+ // this is not using kControl characters: it's the secret code to be entered to trigger the easter egg
+ // TODO: To be fixed when the Easter egg code is implemented
+ Common::String egg = Common::String::format("%c%c%c%c%c***", kControlParagraph, kControlLeftJustified, kControlNegative, kControlBell, kControlBackspace);
+ Common::String e = "(c) 1994";
+
+ setReadyLight(3);
+ _vm->_seeScroll = true;
+ _vm->_graphics->loadMouse(kCurFletch);
+
+ _vm->_graphics->saveScreen();
+ _vm->_graphics->showScroll();
+
+ Common::Event event;
+ bool escape = false;
+ while (!_vm->shouldQuit() && !escape) {
+ _vm->_graphics->refreshScreen();
+ while (_vm->getEvent(event)) {
+ if ((event.type == Common::EVENT_LBUTTONUP) ||
+ ((event.type == Common::EVENT_KEYDOWN) && ((event.kbd.keycode == Common::KEYCODE_ESCAPE) ||
+ (event.kbd.keycode == Common::KEYCODE_RETURN) || (event.kbd.keycode == Common::KEYCODE_HASH) ||
+ (event.kbd.keycode == Common::KEYCODE_PLUS)))) {
+ escape = true;
+ break;
+ }
+ }
+ }
+
+ _vm->_graphics->restoreScreen();
+ _vm->_graphics->removeBackup();
+
+ warning("STUB: scrollModeNormal() - Check Easter Egg trigger");
+#if 0
+ char r;
+ bool oktoexit;
+ do {
+ do {
+ _vm->check(); // was "checkclick;"
+
+//#ifdef RECORD slowdown(); basher::count++; #endif
+
+ if (_vm->_enhanced->keypressede())
+ break;
+ } while (!((mrelease > 0) || (buttona1()) || (buttonb1())));
+
+ if (mrelease == 0) {
+ inkey();
+ if (aboutscroll) {
+ move(e[2 - 1], e[1 - 1], 7);
+ e[8 - 1] = inchar;
+ if (egg == e)
+ easteregg();
+ }
+ oktoexit = set::of('\15', '\33', '+', '#', eos).has(inchar);
+ if (!oktoexit) errorled();
+ }
+
+ } while (!((oktoexit) || (mrelease > 0)));
+
+//#ifdef RECORD record_one(); #endif
+
+ _vm->screturn = r == '#'; // "back door"
+#endif
+
+ setReadyLight(0);
+ _vm->_seeScroll = false;
+ _vm->_holdLeftMouse = false; // Used in Lucerna::checkclick().
+
+ warning("STUB: Scrolls::scrollModeNormal()");
+}
+
+/**
+ * One of the 3 "Mode" functions passed as ScrollsFunctionType parameters.
+ * The "asking" scroll. Used indirectly in diplayQuestion().
+ * @remarks Originally called 'dialogue'
+ */
+void Dialogs::scrollModeDialogue() {
+ _vm->_graphics->loadMouse(kCurHand);
+
+ _vm->_graphics->saveScreen();
+ _vm->_graphics->showScroll();
+
+ Common::Event event;
+ while (!_vm->shouldQuit()) {
+ _vm->_graphics->refreshScreen();
+
+ _vm->getEvent(event);
+
+ Common::Point cursorPos = _vm->getMousePos();
+ cursorPos.y /= 2;
+
+ char inChar = 0;
+ if ((event.type == Common::EVENT_KEYDOWN) && (event.kbd.ascii <= 122) && (event.kbd.ascii >= 97)) {
+ inChar = (char)event.kbd.ascii;
+ Common::String temp(inChar);
+ temp.toUppercase();
+ inChar = temp[0];
+ }
+
+ if (_vm->shouldQuit() || (event.type == Common::EVENT_LBUTTONUP) || (event.type == Common::EVENT_KEYDOWN)) {
+ if (((cursorPos.x >= _shadowBoxX - 65) && (cursorPos.y >= _shadowBoxY - 24) && (cursorPos.x <= _shadowBoxX - 5) && (cursorPos.y <= _shadowBoxY - 10))
+ || (inChar == 'Y') || (inChar == 'J') || (inChar == 'O')) { // Yes, Ja, Oui
+ _scReturn = true;
+ break;
+ } else if (((cursorPos.x >= _shadowBoxX + 5) && (cursorPos.y >= _shadowBoxY - 24) && (cursorPos.x <= _shadowBoxX + 65) && (cursorPos.y <= _shadowBoxY - 10))
+ || (inChar == 'N')){ // No, Non, Nein
+ _scReturn = false;
+ break;
+ }
+ }
+ }
+
+ _vm->_graphics->restoreScreen();
+ _vm->_graphics->removeBackup();
+}
+
+void Dialogs::store(byte what, TuneType &played) {
+ memcpy(played, played + 1, sizeof(played) - 1);
+ played[30] = what;
+}
+
+bool Dialogs::theyMatch(TuneType &played) {
+ byte mistakes = 0;
+
+ for (unsigned int i = 0; i < sizeof(played); i++) {
+ if (played[i] != kTune[i])
+ mistakes++;
+ }
+
+ return mistakes < 5;
+}
+
+/**
+ * One of the 3 "Mode" functions passed as ScrollsFunctionType parameters.
+ * Part of the harp mini-game.
+ * @remarks Originally called 'music_Scroll'
+ */
+void Dialogs::scrollModeMusic() {
+ setReadyLight(3);
+ _vm->_seeScroll = true;
+ CursorMan.showMouse(false);
+ _vm->_graphics->loadMouse(kCurFletch);
+
+ TuneType played;
+ for (unsigned int i = 0; i < sizeof(played); i++)
+ played[i] = kPitchInvalid;
+ int8 lastOne = -1, thisOne = -1; // Invalid values.
+
+ _vm->_seeScroll = true;
+
+ _vm->_graphics->saveScreen();
+ _vm->_graphics->showScroll();
+
+ Common::Event event;
+ while (!_vm->shouldQuit()) {
+ _vm->_graphics->refreshScreen();
+
+ _vm->getEvent(event);
+
+ // When we stop playing?
+ if ((event.type == Common::EVENT_LBUTTONDOWN) ||
+ ((event.type == Common::EVENT_KEYDOWN) && ((event.kbd.keycode == Common::KEYCODE_RETURN) || (event.kbd.keycode == Common::KEYCODE_ESCAPE)))) {
+ break;
+ }
+
+ // When we DO play:
+ if ((event.type == Common::EVENT_KEYDOWN)
+ && ((event.kbd.keycode == Common::KEYCODE_q) || (event.kbd.keycode == Common::KEYCODE_w)
+ || (event.kbd.keycode == Common::KEYCODE_e) || (event.kbd.keycode == Common::KEYCODE_r)
+ || (event.kbd.keycode == Common::KEYCODE_t) || (event.kbd.keycode == Common::KEYCODE_y)
+ || (event.kbd.keycode == Common::KEYCODE_u) || (event.kbd.keycode == Common::KEYCODE_i)
+ || (event.kbd.keycode == Common::KEYCODE_o) || (event.kbd.keycode == Common::KEYCODE_p)
+ || (event.kbd.keycode == Common::KEYCODE_LEFTBRACKET) || (event.kbd.keycode == Common::KEYCODE_RIGHTBRACKET))) {
+ byte value = 0;
+ switch (event.kbd.keycode) {
+ case Common::KEYCODE_q:
+ value = 0;
+ break;
+ case Common::KEYCODE_w:
+ value = 1;
+ break;
+ case Common::KEYCODE_e:
+ value = 2;
+ break;
+ case Common::KEYCODE_r:
+ value = 3;
+ break;
+ case Common::KEYCODE_t:
+ value = 4;
+ break;
+ case Common::KEYCODE_y:
+ value = 5;
+ break;
+ case Common::KEYCODE_u:
+ value = 6;
+ break;
+ case Common::KEYCODE_i:
+ value = 7;
+ break;
+ case Common::KEYCODE_o:
+ value = 8;
+ break;
+ case Common::KEYCODE_p:
+ value = 9;
+ break;
+ case Common::KEYCODE_LEFTBRACKET:
+ value = 10;
+ break;
+ case Common::KEYCODE_RIGHTBRACKET:
+ value = 11;
+ break;
+ default:
+ break;
+ }
+
+ lastOne = thisOne;
+ thisOne = value;
+
+ _vm->_sound->playNote(_vm->kNotes[thisOne], 100);
+ _vm->_system->delayMillis(200);
+
+ if (!_vm->_bellsAreRinging) { // These handle playing the right tune.
+ if (thisOne < lastOne)
+ store(kPitchLower, played);
+ else if (thisOne == lastOne)
+ store(kPitchSame, played);
+ else
+ store(kPitchHigher, played);
+ }
+
+ if (theyMatch(played)) {
+ setReadyLight(0);
+ _vm->_timer->addTimer(8, Timer::kProcJacquesWakesUp, Timer::kReasonJacquesWakingUp);
+ break;
+ }
+ }
+ }
+
+ _vm->_graphics->restoreScreen();
+ _vm->_graphics->removeBackup();
+
+ _vm->_seeScroll = false;
+ CursorMan.showMouse(true);
+}
+
+void Dialogs::resetScrollDriver() {
+ _scrollBells = 0;
+ _currentFont = kFontStyleRoman;
+ _useIcon = 0;
+ _vm->_interrogation = 0; // Always reset after a scroll comes up.
+}
+
+/**
+ * Rings the bell x times
+ * @remarks Originally called 'dingdongbell'
+ */
+void Dialogs::ringBell() {
+ for (int i = 0; i < _scrollBells; i++)
+ _vm->errorLed(); // Ring the bell "_scrollBells" times.
+}
+
+/**
+ * This moves the mouse pointer off the scroll so that you can read it.
+ * @remarks Originally called 'dodgem'
+ */
+void Dialogs::dodgem() {
+ _dodgeCoord = _vm->getMousePos();
+ g_system->warpMouse(_dodgeCoord.x, _underScroll); // Move the pointer off the scroll.
+}
+
+/**
+ * This is the opposite of Dodgem.
+ * It moves the mouse pointer back, IF you haven't moved it in the meantime.
+ * @remarks Originally called 'undodgem'
+ */
+void Dialogs::unDodgem() {
+ Common::Point actCoord = _vm->getMousePos();
+ if ((actCoord.x == _dodgeCoord.x) && (actCoord.y == _underScroll))
+ g_system->warpMouse(_dodgeCoord.x, _dodgeCoord.y); // No change, so restore the pointer's original position.
+}
+
+void Dialogs::drawScroll(DialogFunctionType modeFunc) {
+ int16 lx = 0;
+ int16 ly = (_maxLineNum + 1) * 6;
+ int16 ex;
+ for (int i = 0; i <= _maxLineNum; i++) {
+ ex = _scroll[i].size() * 8;
+ if (lx < ex)
+ lx = ex;
+ }
+ int16 mx = 320;
+ int16 my = 100; // Getmaxx & getmaxy div 2, both.
+ lx /= 2;
+ ly -= 2;
+
+ if ((1 <= _useIcon) && (_useIcon <= 34))
+ lx += kHalfIconWidth;
+
+ CursorMan.showMouse(false);
+ _vm->_graphics->drawScroll(mx, lx, my, ly);
+
+ mx -= lx;
+ my -= ly + 2;
+
+ bool centre = false;
+
+ byte iconIndent = 0;
+ switch (_useIcon) {
+ case 0:
+ iconIndent = 0;
+ break; // No icon.
+ case 34:
+ _vm->_graphics->drawSign("about", 28, 76, 15);
+ iconIndent = 0;
+ break;
+ case 35:
+ _vm->_graphics->drawSign("gameover", 52, 59, 71);
+ iconIndent = 0;
+ break;
+ }
+
+ if ((1 <= _useIcon) && (_useIcon <= 33)) { // Standard icon.
+ _vm->_graphics->drawIcon(mx, my + ly / 2, _useIcon);
+ iconIndent = 53;
+ }
+
+ for (int i = 0; i <= _maxLineNum; i++) {
+ if (!_scroll[i].empty())
+ switch (_scroll[i][_scroll[i].size() - 1]) {
+ case kControlCenter:
+ centre = true;
+ _scroll[i].deleteLastChar();
+ break;
+ case kControlLeftJustified:
+ centre = false;
+ _scroll[i].deleteLastChar();
+ break;
+ case kControlQuestion:
+ _shadowBoxX = mx + lx;
+ _shadowBoxY = my + ly;
+ _scroll[i].setChar(' ', 0);
+ _vm->_graphics->drawShadowBox(_shadowBoxX - 65, _shadowBoxY - 24, _shadowBoxX - 5, _shadowBoxY - 10, "Yes.");
+ _vm->_graphics->drawShadowBox(_shadowBoxX + 5, _shadowBoxY - 24, _shadowBoxX + 65, _shadowBoxY - 10, "No.");
+ break;
+ }
+
+ if (centre)
+ say(320 - _scroll[i].size() * 4 + iconIndent, my, _scroll[i]);
+ else
+ say(mx + iconIndent, my, _scroll[i]);
+
+ my += 12;
+ }
+
+ _underScroll = (my + 3) * 2; // Multiplying because of the doubled screen height.
+ ringBell();
+
+ _vm->_dropsOk = false;
+ dodgem();
+
+ (this->*modeFunc)();
+
+ unDodgem();
+ _vm->_dropsOk = true;
+
+ resetScrollDriver();
+}
+
+void Dialogs::drawBubble(DialogFunctionType modeFunc) {
+ Common::Point points[3];
+
+ CursorMan.showMouse(false);
+ int16 xl = 0;
+ int16 yl = (_maxLineNum + 1) * 5;
+ for (int i = 0; i <= _maxLineNum; i++) {
+ uint16 textWidth = _scroll[i].size() * 8;
+ if (textWidth > xl)
+ xl = textWidth;
+ }
+ xl /= 2;
+
+ int16 xw = xl + 18;
+ int16 yw = yl + 7;
+ int16 my = yw * 2 - 2;
+ int16 xc = 0;
+
+ if (_talkX - xw < 0)
+ xc = -(_talkX - xw);
+ if (_talkX + xw > 639)
+ xc = 639 - (_talkX + xw);
+
+ // Compute triangle coords for the tail of the bubble
+ points[0].x = _talkX - 10;
+ points[0].y = yw;
+ points[1].x = _talkX + 10;
+ points[1].y = yw;
+ points[2].x = _talkX;
+ points[2].y = _talkY;
+
+ _vm->_graphics->prepareBubble(xc, xw, my, points);
+
+ // Draw the text of the bubble. The centering of the text was improved here compared to Pascal's settextjustify().
+ // The font is not the same that outtextxy() uses in Pascal. I don't have that, so I used characters instead.
+ // It's almost the same, only notable differences are '?', '!', etc.
+ for (int i = 0; i <= _maxLineNum; i++) {
+ int16 x = xc + _talkX - _scroll[i].size() / 2 * 8;
+ bool offset = _scroll[i].size() % 2;
+ _vm->_graphics->drawScrollText(_scroll[i], _vm->_font, 8, x - offset * 4, (i * 10) + 12, _vm->_graphics->_talkFontColor);
+ }
+
+ ringBell();
+ CursorMan.showMouse(false);
+ _vm->_dropsOk = false;
+
+ // This does the actual drawing to the screen.
+ (this->*modeFunc)();
+
+ _vm->_dropsOk = true;
+ CursorMan.showMouse(true); // sink;
+ resetScrollDriver();
+}
+
+void Dialogs::reset() {
+ _maxLineNum = 0;
+ for (int i = 0; i < 15; i++) {
+ if (!_scroll[i].empty())
+ _scroll[i].clear();
+ }
+}
+
+/**
+ * Natural state of bubbles
+ * @remarks Originally called 'natural'
+ */
+void Dialogs::setBubbleStateNatural() {
+ _talkX = 320;
+ _talkY = 200;
+ _vm->_graphics->setDialogColor(kColorDarkgray, kColorWhite);
+}
+
+Common::String Dialogs::displayMoney() {
+ Common::String result;
+
+ if (_vm->_money < 12) { // just pence
+ result = Common::String::format("%dd", _vm->_money);
+ } else if (_vm->_money < 240) { // shillings & pence
+ if ((_vm->_money % 12) == 0)
+ result = Common::String::format("%d/-", _vm->_money / 12);
+ else
+ result = Common::String::format("%d/%d", _vm->_money / 12, _vm->_money % 12);
+ } else { // L, s & d
+ result = Common::String::format("\x9C%d.%d.%d", _vm->_money / 240, (_vm->_money / 12) % 20,
+ _vm->_money % 12);
+ }
+ if (_vm->_money > 12) {
+ Common::String extraStr = Common::String::format(" (that's %dd)", _vm->_money);
+ result += extraStr;
+ }
+
+ return result;
+}
+
+/**
+ * Strip trailing character in a string
+ * @remarks Originally called 'strip'
+ */
+void Dialogs::stripTrailingSpaces(Common::String &str) {
+ while (str.lastChar() == ' ')
+ str.deleteLastChar();
+ // We don't use String::trim() here because we need the leading whitespaces.
+}
+
+/**
+ * Does the word wrapping.
+ */
+void Dialogs::solidify(byte n) {
+ if (!_scroll[n].contains(' '))
+ return; // No spaces.
+
+ // So there MUST be a space there, somewhere...
+ do {
+ _scroll[n + 1] = _scroll[n][_scroll[n].size() - 1] + _scroll[n + 1];
+ _scroll[n].deleteLastChar();
+ } while (_scroll[n][_scroll[n].size() - 1] != ' ');
+
+ stripTrailingSpaces(_scroll[n]);
+}
+
+/**
+ * @remarks Originally called 'calldriver'
+ * Display text by calling the dialog driver. It unifies the function of the original
+ * 'calldriver' and 'display' by using Common::String instead of a private buffer.
+ */
+void Dialogs::displayText(Common::String text) {
+// bool was_virtual; // Was the mouse cursor virtual on entry to this proc?
+ warning("STUB: Scrolls::calldrivers()");
+
+ _vm->_sound->stopSound();
+
+ setReadyLight(0);
+ _scReturn = false;
+ bool mouthnext = false;
+ bool callSpriteRun = true; // Only call sprite_run the FIRST time.
+
+ switch (text.lastChar()) {
+ case kControlToBuffer:
+ text.deleteLastChar();
+ break; // ^D = (D)on't include pagebreak
+ case kControlSpeechBubble:
+ case kControlQuestion:
+ break; // ^B = speech (B)ubble, ^Q = (Q)uestion in dialogue box
+ default:
+ text.insertChar(kControlParagraph, text.size());
+ }
+
+ for (uint16 i = 0; i < text.size(); i++) {
+ if (mouthnext) {
+ if (text[i] == kControlRegister)
+ _param = 0;
+ else if (('0' <= text[i]) && (text[i] <= '9'))
+ _param = text[i] - 48;
+ else if (('A' <= text[i]) && (text[i] <= 'Z'))
+ _param = text[i] - 55;
+
+ mouthnext = false;
+ } else {
+ switch (text[i]) {
+ case kControlParagraph:
+ if ((_maxLineNum == 0) && (_scroll[0].empty()))
+ break;
+
+ if (callSpriteRun)
+ _vm->spriteRun();
+ callSpriteRun = false;
+
+ drawScroll(&Avalanche::Dialogs::scrollModeNormal);
+
+ reset();
+
+ if (_scReturn)
+ return;
+ break;
+ case kControlBell:
+ _scrollBells++;
+ break;
+ case kControlSpeechBubble:
+ if ((_maxLineNum == 0) && (_scroll[0].empty()))
+ break;
+
+ if (callSpriteRun)
+ _vm->spriteRun();
+ callSpriteRun = false;
+
+ if (_param == 0)
+ setBubbleStateNatural();
+ else if ((1 <= _param) && (_param <= 9)) {
+ assert(_param - 1 < _vm->_animation->kSpriteNumbMax);
+ AnimationType *spr = _vm->_animation->_sprites[_param - 1];
+ if ((_param > _vm->_animation->kSpriteNumbMax) || (!spr->_quick)) { // Not valid.
+ _vm->errorLed();
+ setBubbleStateNatural();
+ } else
+ spr->chatter(); // Normal sprite talking routine.
+ } else if ((10 <= _param) && (_param <= 36)) {
+ // Quasi-peds. (This routine performs the same
+ // thing with QPs as triptype.chatter does with the
+ // sprites.)
+ assert(_param - 10 < 16);
+ PedType *quasiPed = &_vm->_peds[kQuasipeds[_param - 10]._whichPed];
+ _talkX = quasiPed->_x;
+ _talkY = quasiPed->_y; // Position.
+
+ _vm->_graphics->setDialogColor(kQuasipeds[_param - 10]._backgroundColor, kQuasipeds[_param - 10]._textColor);
+ } else {
+ _vm->errorLed(); // Not valid.
+ setBubbleStateNatural();
+ }
+
+ drawBubble(&Avalanche::Dialogs::scrollModeNormal);
+
+ reset();
+
+ if (_scReturn)
+ return;
+ break;
+
+ // CHECME: The whole kControlNegative block seems completely unused, as the only use (the easter egg check) is a false positive
+ case kControlNegative:
+ switch (_param) {
+ case 1:
+ displayText(displayMoney() + kControlToBuffer); // Insert cash balance. (Recursion)
+ break;
+ case 2: {
+ int pwdId = _vm->_parser->kFirstPassword + _vm->_passwordNum;
+ displayText(_vm->_parser->_vocabulary[pwdId]._word + kControlToBuffer);
+ }
+ break;
+ case 3:
+ displayText(_vm->_favoriteDrink + kControlToBuffer);
+ break;
+ case 4:
+ displayText(_vm->_favoriteSong + kControlToBuffer);
+ break;
+ case 5:
+ displayText(_vm->_worstPlaceOnEarth + kControlToBuffer);
+ break;
+ case 6:
+ displayText(_vm->_spareEvening + kControlToBuffer);
+ break;
+ case 9: {
+ Common::String tmpStr = Common::String::format("%d,%d%c",_vm->_catacombX, _vm->_catacombY, kControlToBuffer);
+ displayText(tmpStr);
+ }
+ break;
+ case 10:
+ switch (_vm->_boxContent) {
+ case 0: // Sixpence.
+ displayScrollChain('Q', 37); // You find the sixpence.
+ _vm->_money += 6;
+ _vm->_boxContent = _vm->_parser->kNothing;
+ _vm->incScore(2);
+ return;
+ case Parser::kNothing:
+ displayText("nothing at all. It's completely empty.");
+ break;
+ default:
+ displayText(_vm->getItem(_vm->_boxContent) + '.');
+ }
+ break;
+ case 11:
+ for (int j = 0; j < kObjectNum; j++) {
+ if (_vm->_objects[j])
+ displayText(_vm->getItem(j) + ", " + kControlToBuffer);
+ }
+ break;
+ }
+ break;
+ case kControlIcon:
+ _useIcon = _param;
+ break;
+ case kControlNewLine:
+ _maxLineNum++;
+ break;
+ case kControlQuestion:
+ if (callSpriteRun)
+ _vm->spriteRun();
+ callSpriteRun = false;
+
+ _maxLineNum++;
+ _scroll[_maxLineNum] = kControlQuestion;
+
+ drawScroll(&Avalanche::Dialogs::scrollModeDialogue);
+ reset();
+ break;
+ case kControlRegister:
+ mouthnext = true;
+ break;
+ case kControlInsertSpaces:
+ for (int j = 0; j < 9; j++)
+ _scroll[_maxLineNum] += ' ';
+ break;
+ default: // Add new char.
+ if (_scroll[_maxLineNum].size() == 50) {
+ solidify(_maxLineNum);
+ _maxLineNum++;
+ }
+ _scroll[_maxLineNum] += text[i];
+ break;
+ }
+ }
+ }
+}
+
+void Dialogs::setTalkPos(int16 x, int16 y) {
+ _talkX = x;
+ _talkY = y;
+}
+
+int16 Dialogs::getTalkPosX() {
+ return _talkX;
+}
+
+bool Dialogs::displayQuestion(Common::String question) {
+ displayText(question + kControlNewLine + kControlQuestion);
+
+ if (_scReturn && (_vm->_rnd->getRandomNumber(1) == 0)) { // Half-and-half chance.
+ Common::String tmpStr = Common::String::format("...Positive about that?%cI%c%c%c", kControlRegister, kControlIcon, kControlNewLine, kControlQuestion);
+ displayText(tmpStr); // Be annoying!
+ if (_scReturn && (_vm->_rnd->getRandomNumber(3) == 3)) { // Another 25% chance
+ // \? are used to avoid that ??! is parsed as a trigraph
+ tmpStr = Common::String::format("%c100%% certain\?\?!%c%c%c%c", kControlInsertSpaces, kControlInsertSpaces, kControlIcon, kControlNewLine, kControlQuestion);
+ displayText(tmpStr); // Be very annoying!
+ }
+ }
+
+ return _scReturn;
+}
+
+void Dialogs::loadFont() {
+ Common::File file;
+
+ if (!file.open("avalot.fnt"))
+ error("AVALANCHE: Scrolls: File not found: avalot.fnt");
+
+ for (int16 i = 0; i < 256; i++)
+ file.read(_fonts[0][i], 16);
+ file.close();
+
+ if (!file.open("avitalic.fnt"))
+ error("AVALANCHE: Scrolls: File not found: avitalic.fnt");
+
+ for (int16 i = 0; i < 256; i++)
+ file.read(_fonts[1][i], 16);
+ file.close();
+
+ if (!file.open("ttsmall.fnt"))
+ error("AVALANCHE: Scrolls: File not found: ttsmall.fnt");
+
+ for (int16 i = 0; i < 256; i++)
+ file.read(_vm->_font[i],16);
+ file.close();
+}
+
+/**
+ * Practically this one is a mini-game which called when you play the harp in the monastery.
+ * @remarks Originally called 'musical_scroll'
+ */
+void Dialogs::displayMusicalScroll() {
+ Common::String tmpStr = Common::String::format("To play the harp...%c%cUse these keys:%c%cQ W E R T Y U I O P [ ]%c%cOr press Enter to stop playing.%c",
+ kControlNewLine, kControlNewLine, kControlNewLine, kControlInsertSpaces, kControlNewLine, kControlNewLine, kControlToBuffer);
+ displayText(tmpStr);
+
+ _vm->spriteRun();
+ CursorMan.showMouse(false);
+ drawScroll(&Avalanche::Dialogs::scrollModeMusic);
+ CursorMan.showMouse(true);
+ reset();
+}
+
+void Dialogs::unSkrimble(Common::String &text) {
+ for (uint16 i = 0; i < text.size(); i++)
+ text.setChar((~(text[i] - (i + 1))) % 256, i);
+}
+
+void Dialogs::doTheBubble(Common::String &text) {
+ text.insertChar(kControlSpeechBubble, text.size());
+ assert(text.size() < 2000);
+}
+
+/**
+ * Display a string in a scroll
+ * @remarks Originally called 'dixi'
+ */
+void Dialogs::displayScrollChain(char block, byte point, bool report, bool bubbling) {
+ Common::File indexfile;
+ if (!indexfile.open("avalot.idx"))
+ error("AVALANCHE: Visa: File not found: avalot.idx");
+
+ bool error = false;
+
+ indexfile.seek((toupper(block) - 'A') * 2);
+ uint16 idx_offset = indexfile.readUint16LE();
+ if (idx_offset == 0)
+ error = true;
+
+ indexfile.seek(idx_offset + point * 2);
+ uint16 sez_offset = indexfile.readUint16LE();
+ if (sez_offset == 0)
+ error = true;
+
+ indexfile.close();
+
+ _noError = !error;
+
+ if (error) {
+ if (report) {
+ Common::String todisplay = Common::String::format("%cError accessing scroll %c%d", kControlBell, block, point);
+ displayText(todisplay);
+ }
+ return;
+ }
+
+ Common::File sezfile;
+ if (!sezfile.open("avalot.sez"))
+ ::error("AVALANCHE: Visa: File not found: avalot.sez");
+
+ sezfile.seek(sez_offset);
+ uint16 _bufSize = sezfile.readUint16LE();
+ assert(_bufSize < 2000);
+ char *_buffer = new char[_bufSize];
+ sezfile.read(_buffer, _bufSize);
+ sezfile.close();
+ Common::String text(_buffer, _bufSize);
+ delete[] _buffer;
+
+ unSkrimble(text);
+ if (bubbling)
+ doTheBubble(text);
+ displayText(text);
+}
+
+/**
+ * Start speech
+ * @remarks Originally called 'speech'
+ */
+void Dialogs::speak(byte who, byte subject) {
+ if (subject == 0) { // No subject.
+ displayScrollChain('S', who, false, true);
+ return;
+ }
+
+ // Subject given.
+ _noError = false; // Assume that until we know otherwise.
+
+ Common::File indexfile;
+ if (!indexfile.open("converse.avd"))
+ error("AVALANCHE: Visa: File not found: converse.avd");
+
+ indexfile.seek(who * 2 - 2);
+ uint16 idx_offset = indexfile.readUint16LE();
+ uint16 next_idx_offset = indexfile.readUint16LE();
+
+ if ((idx_offset == 0) || ((((next_idx_offset - idx_offset) / 2) - 1) < subject))
+ return;
+
+ indexfile.seek(idx_offset + subject * 2);
+ uint16 sezOffset = indexfile.readUint16LE();
+ if ((sezOffset == 0) || (indexfile.err()))
+ return;
+ indexfile.close();
+
+ Common::File sezfile;
+ if (!sezfile.open("avalot.sez"))
+ error("AVALANCHE: Visa: File not found: avalot.sez");
+
+ sezfile.seek(sezOffset);
+ uint16 _bufSize = sezfile.readUint16LE();
+ assert(_bufSize < 2000);
+ char *_buffer = new char[_bufSize];
+ sezfile.read(_buffer, _bufSize);
+ sezfile.close();
+ Common::String text(_buffer, _bufSize);
+ delete[] _buffer;
+
+ unSkrimble(text);
+ doTheBubble(text);
+ displayText(text);
+
+ _noError = true;
+}
+
+void Dialogs::talkTo(byte whom) {
+ if (_vm->_parser->_person == kPeoplePardon) {
+ _vm->_parser->_person = (People)_vm->_subjectNum;
+ _vm->_subjectNum = 0;
+ }
+
+ if (_vm->_subjectNum == 0) {
+ switch (whom) {
+ case kPeopleSpludwick:
+ if ((_vm->_lustieIsAsleep) & (!_vm->_objects[kObjectPotion - 1])) {
+ displayScrollChain('Q', 68);
+ _vm->_objects[kObjectPotion - 1] = true;
+ _vm->refreshObjectList();
+ _vm->incScore(3);
+ return;
+ } else if (_vm->_talkedToCrapulus) {
+ // Spludwick - what does he need?
+ // 0 - let it through to use normal routine.
+ switch (_vm->_givenToSpludwick) {
+ case 1: // Fallthrough is intended.
+ case 2: {
+ Common::String objStr = _vm->getItem(AvalancheEngine::kSpludwicksOrder[_vm->_givenToSpludwick]);
+ Common::String tmpStr = Common::String::format("Can you get me %s, please?%c2%c",
+ objStr.c_str(), kControlRegister, kControlSpeechBubble);
+ displayText(tmpStr);
+ }
+ return;
+ case 3:
+ displayScrollChain('Q', 30); // Need any help with the game?
+ return;
+ }
+ } else {
+ displayScrollChain('Q', 42); // Haven't talked to Crapulus. Go and talk to him.
+ return;
+ }
+ break;
+ case kPeopleIbythneth:
+ if (_vm->_givenBadgeToIby) {
+ displayScrollChain('Q', 33); // Thanks a lot!
+ return; // And leave the proc.
+ }
+ break; // Or... just continue, 'cos he hasn't got it.
+ case kPeopleDogfood:
+ if (_vm->_wonNim) { // We've won the game.
+ displayScrollChain('Q', 6); // "I'm Not Playing!"
+ return; // Zap back.
+ } else
+ _vm->_askedDogfoodAboutNim = true;
+ break;
+ case kPeopleAyles:
+ if (!_vm->_aylesIsAwake) {
+ displayScrollChain('Q', 43); // He's fast asleep!
+ return;
+ } else if (!_vm->_givenPenToAyles) {
+ displayScrollChain('Q', 44); // Can you get me a pen, Avvy?
+ return;
+ }
+ break;
+
+ case kPeopleJacques:
+ displayScrollChain('Q', 43);
+ return;
+
+ case kPeopleGeida:
+ if (_vm->_givenPotionToGeida)
+ _vm->_geidaFollows = true;
+ else {
+ displayScrollChain('U', 17);
+ return;
+ }
+ break;
+ case kPeopleSpurge:
+ if (!_vm->_sittingInPub) {
+ displayScrollChain('Q', 71); // Try going over and sitting down.
+ return;
+ } else {
+ if (_vm->_spurgeTalkCount < 5)
+ _vm->_spurgeTalkCount++;
+ if (_vm->_spurgeTalkCount > 1) { // no. 1 falls through
+ displayScrollChain('Q', 70 + _vm->_spurgeTalkCount);
+ return;
+ }
+ }
+ break;
+ }
+ // On a subject. Is there any reason to block it?
+ } else if ((whom == kPeopleAyles) && (!_vm->_aylesIsAwake)) {
+ displayScrollChain('Q', 43); // He's fast asleep!
+ return;
+ }
+
+ if (whom > 149)
+ whom -= 149;
+
+ bool noMatches = true;
+ for (int i = 0; i < _vm->_animation->kSpriteNumbMax; i++) {
+ if (_vm->_animation->_sprites[i]->_characterId == whom) {
+ Common::String tmpStr = Common::String::format("%c%c%c", kControlRegister, i + 49, kControlToBuffer);
+ displayText(tmpStr);
+ noMatches = false;
+ break;
+ }
+ }
+
+ if (noMatches) {
+ Common::String tmpStr = Common::String::format("%c%c%c", kControlRegister, kControlRegister, kControlToBuffer);
+ displayText(tmpStr);
+ }
+
+ speak(whom, _vm->_subjectNum);
+
+ if (!_noError)
+ displayScrollChain('N', whom); // File not found!
+
+ if ((_vm->_subjectNum == 0) && ((whom + 149) == kPeopleCrapulus)) { // Crapulus: get the badge - first time only
+ _vm->_objects[kObjectBadge - 1] = true;
+ _vm->refreshObjectList();
+ displayScrollChain('Q', 1); // Circular from Cardiff.
+ _vm->_talkedToCrapulus = true;
+ _vm->setRoom(kPeopleCrapulus, kRoomDummy); // Crapulus walks off.
+
+ AnimationType *spr = _vm->_animation->_sprites[1];
+ spr->_vanishIfStill = true;
+ spr->walkTo(2); // Walks away.
+
+ _vm->incScore(2);
+ }
+}
+
+/**
+ * This makes Avalot say the response.
+ * @remarks Originally called 'sayit'
+ */
+void Dialogs::sayIt(Common::String str) {
+ Common::String x = str;
+ x.setChar(toupper(x[0]), 0);
+ Common::String tmpStr = Common::String::format("%c1%s.%c%c2", kControlRegister, x.c_str(), kControlSpeechBubble, kControlRegister);
+ displayText(tmpStr);
+}
+
+Common::String Dialogs::personSpeaks() {
+ if ((_vm->_parser->_person == kPeoplePardon) || (_vm->_parser->_person == kPeopleNone)) {
+ if ((_vm->_him == kPeoplePardon) || (_vm->getRoom(_vm->_him) != _vm->_room))
+ _vm->_parser->_person = _vm->_her;
+ else
+ _vm->_parser->_person = _vm->_him;
+ }
+
+ if (_vm->getRoom(_vm->_parser->_person) != _vm->_room) {
+ return Common::String::format("%c1", kControlRegister); // Avvy himself!
+ }
+
+ bool found = false; // The _person we're looking for's code is in _person.
+ Common::String tmpStr;
+
+ for (int i = 0; i < _vm->_animation->kSpriteNumbMax; i++) {
+ AnimationType *curSpr = _vm->_animation->_sprites[i];
+ if (curSpr->_quick && (curSpr->_characterId + 149 == _vm->_parser->_person)) {
+ tmpStr += Common::String::format("%c%c", kControlRegister, '1' + i);
+ found = true;
+ }
+ }
+
+ if (found)
+ return tmpStr;
+
+ for (int i = 0; i < 16; i++) {
+ if ((kQuasipeds[i]._who == _vm->_parser->_person) && (kQuasipeds[i]._room == _vm->_room))
+ tmpStr += Common::String::format("%c%c", kControlRegister, 'A' + i);
+ }
+
+ return tmpStr;
+}
+
+/**
+ * Display a message when (uselessly) giving an object away
+ * @remarks Originally called 'heythanks'
+ */
+void Dialogs::sayThanks(byte thing) {
+ Common::String tmpStr = personSpeaks();
+ tmpStr += Common::String::format("Hey, thanks!%c(But now, you've lost it!)", kControlSpeechBubble);
+ displayText(tmpStr);
+
+ if (thing < kObjectNum)
+ _vm->_objects[thing] = false;
+}
+
+/**
+ * Display a 'Hello' message
+ */
+void Dialogs::sayHello() {
+ Common::String tmpStr = personSpeaks();
+ tmpStr += Common::String::format("Hello.%c", kControlSpeechBubble);
+ displayText(tmpStr);
+}
+
+/**
+ * Display a 'OK' message
+ */
+void Dialogs::sayOK() {
+ Common::String tmpStr = personSpeaks();
+ tmpStr += Common::String::format("That's OK.%c", kControlSpeechBubble);
+ displayText(tmpStr);
+}
+
+/**
+ * Display a 'Silly' message
+ * @remarks Originally called 'silly'
+ */
+void Dialogs::saySilly() {
+ displayText("Don't be silly!");
+}
+
+} // End of namespace Avalanche
diff --git a/engines/avalanche/dialogs.h b/engines/avalanche/dialogs.h
new file mode 100644
index 0000000000..defd152db5
--- /dev/null
+++ b/engines/avalanche/dialogs.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.
+ *
+ */
+
+/*
+ * This code is based on the original source code of Lord Avalot d'Argent version 1.3.
+ * Copyright (c) 1994-1995 Mike, Mark and Thomas Thurman.
+ */
+
+ /* SCROLLS The scroll driver. */
+
+#ifndef AVALANCHE_DIALOGS_H
+#define AVALANCHE_DIALOGS_H
+
+namespace Avalanche {
+class AvalancheEngine;
+
+class Dialogs;
+
+typedef void (Dialogs::*DialogFunctionType)();
+
+class Dialogs {
+public:
+ bool _aboutBox; // Is this the about box? - Used in scrollModeNormal(), not yet fully implemented
+ FontType _fonts[2];
+
+ Dialogs(AvalancheEngine *vm);
+
+ void init();
+ void reset();
+ void setReadyLight(byte state);
+ void displayText(Common::String text);
+ bool displayQuestion(Common::String question);
+ void setTalkPos(int16 x, int16 y);
+ int16 getTalkPosX();
+ void setBubbleStateNatural();
+ void displayMusicalScroll();
+ void displayScrollChain(char block, byte point, bool report = true, bool bubbling = false);
+ void talkTo(byte whom);
+ void sayIt(Common::String str);
+ Common::String personSpeaks();
+ void sayThanks(byte thing);
+ void sayHello();
+ void sayOK();
+ void saySilly();
+private:
+ AvalancheEngine *_vm;
+ int16 _talkX, _talkY;
+
+ enum FontStyle {
+ kFontStyleRoman,
+ kFontStyleItalic
+ };
+
+ typedef int8 TuneType[31];
+
+ static const TuneType kTune;
+ static const int16 kHalfIconWidth = 19;
+ static const QuasipedType kQuasipeds[16];
+
+ Common::String _scroll[15];
+ Common::Point _dodgeCoord;
+ byte _maxLineNum;
+ bool _scReturn;
+ bool _noError;
+ byte _currentFont;
+ byte _param; // For using arguments code
+ byte _useIcon;
+ byte _scrollBells; // no. of times to ring the bell
+ int16 _underScroll; // Y-coord of just under the scroll text.
+ int16 _shadowBoxX, _shadowBoxY;
+
+ void drawBubble(DialogFunctionType modeFunc);
+ void drawScroll(DialogFunctionType modeFunc);
+ void scrollModeNormal();
+ void scrollModeDialogue();
+ void scrollModeMusic();
+
+ // These 2 are used only in musicalScroll().
+ void store(byte what, TuneType &played);
+ bool theyMatch(TuneType &played);
+ void stripTrailingSpaces(Common::String &str);
+ void solidify(byte n);
+ void dodgem();
+ void unDodgem();
+
+ Common::String displayMoney();
+ void easterEgg();
+ void say(int16 x, int16 y, Common::String text);
+ void resetScrollDriver();
+ void ringBell();
+ void loadFont();
+
+ void unSkrimble(Common::String &text);
+ void doTheBubble(Common::String &text);
+ void speak(byte who, byte subject);
+};
+
+} // End of namespace Avalanche
+
+#endif // AVALANCHE_DIALOGS_H
diff --git a/engines/avalanche/enums.h b/engines/avalanche/enums.h
new file mode 100644
index 0000000000..2b5db67609
--- /dev/null
+++ b/engines/avalanche/enums.h
@@ -0,0 +1,132 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public 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 based on the original source code of Lord Avalot d'Argent version 1.3.
+ * Copyright (c) 1994-1995 Mike, Mark and Thomas Thurman.
+ */
+
+#ifndef AVALANCHE_ENUMS_H
+#define AVALANCHE_ENUMS_H
+
+namespace Avalanche {
+enum Color {
+ kColorBlack = 0, kColorBlue, kColorGreen, kColorCyan, kColorRed,
+ kColorMagenta = 5, kColorBrown, kColorLightgray, kColorDarkgray, kColorLightblue,
+ kColorLightgreen = 10, kColorLightcyan, kColorLightred, kColorLightmagenta, kColorYellow,
+ kColorWhite = 15
+};
+
+// CHECKME: kRoomBossKey is a guess
+enum Room {
+ kRoomNowhere = 0, kRoomYours = 1, kRoomOutsideYours = 2, kRoomOutsideSpludwicks = 3,
+ kRoomYourHall = 5, kRoomMusicRoom = 7, kRoomOutsideArgentPub = 9, kRoomArgentRoad = 10,
+ kRoomWiseWomans = 11, kRoomSpludwicks = 12, kRoomInsideAbbey = 13, kRoomOutsideAbbey = 14,
+ kRoomAvvysGarden = 15, kRoomAylesOffice = 16, kRoomArgentPub = 19, kRoomBrummieRoad = 20,
+ kRoomBridge = 21, kRoomLusties = 22, kRoomLustiesRoom = 23, kRoomWestHall = 25,
+ kRoomEastHall = 26, kRoomOubliette = 27, kRoomGeidas = 28, kRoomCatacombs = 29,
+ kRoomEntranceHall = 40, kRoomRobins = 42, kRoomOutsideNottsPub = 46, kRoomNottsPub = 47,
+ kRoomOutsideDucks = 50, kRoomDucks = 51, kRoomOutsideCardiffCastle = 70, kRoomInsideCardiffCastle = 71,
+ kRoomBossKey = 98, kRoomMap = 99, kRoomDummy = 177 // Dummy room
+};
+
+// Objects you can hold:
+enum Object {
+ kObjectWine = 1, kObjectMoney, kObjectBodkin, kObjectPotion, kObjectChastity,
+ kObjectBolt, kObjectCrossbow, kObjectLute, kObjectBadge, kObjectMushroom,
+ kObjectKey, kObjectBell, kObjectPrescription, kObjectPen, kObjectInk,
+ kObjectClothes, kObjectHabit, kObjectOnion, kObjectDummy = 177
+};
+
+// People who hang around this game.
+enum People {
+ // Boys:
+ kPeopleAvalot = 150, kPeopleSpludwick = 151, kPeopleCrapulus = 152, kPeopleDrDuck = 153,
+ kPeopleMalagauche = 154, kPeopleFriarTuck = 155, kPeopleRobinHood = 156, kPeopleCwytalot = 157,
+ kPeopleDuLustie = 158, kPeopleDuke = 159, kPeopleDogfood = 160, kPeopleTrader = 161,
+ kPeopleIbythneth = 162, kPeopleAyles = 163, kPeoplePort = 164, kPeopleSpurge = 165,
+ kPeopleJacques = 166,
+ // Girls:
+ kPeopleArkata = 175, kPeopleGeida = 176, kPeopleInvisible = 177, kPeopleWisewoman = 178,
+ //
+ kPeoplePardon = 254, kPeopleNone = 0
+};
+
+enum VerbCode {
+ kVerbCodeExam = 1, kVerbCodeOpen = 2, kVerbCodePause = 3, kVerbCodeGet = 4, kVerbCodeDrop = 5,
+ kVerbCodeInv = 6, kVerbCodeTalk = 7, kVerbCodeGive = 8, kVerbCodeDrink = 9, kVerbCodeLoad = 10,
+ kVerbCodeSave = 11, kVerbCodePay = 12, kVerbCodeLook = 13, kVerbCodeBreak = 14, kVerbCodeQuit = 15,
+ kVerbCodeSit = 16, kVerbCodeStand = 17, kVerbCodeGo = 18, kVerbCodeInfo = 19, kVerbCodeUndress = 20,
+ kVerbCodeWear = 21, kVerbCodePlay = 22, kVerbCodeRing = 23, kVerbCodeHelp = 24, kVerbCodeLarrypass = 25,
+ kVerbCodePhaon = 26, kVerbCodeBoss = 27, kVerbCodePee = 28, kVerbCodeCheat = 29, kVerbCodeMagic = 30,
+ kVerbCodeRestart = 31, kVerbCodeEat = 32, kVerbCodeListen = 33, kVerbCodeBuy = 34, kVerbCodeAttack = 35,
+ kVerbCodePasswd = 36, kVerbCodeDir = 37, kVerbCodeDie = 38, kVerbCodeScore = 39, kVerbCodePut = 40,
+ kVerbCodeKiss = 41, kVerbCodeClimb = 42, kVerbCodeJump = 43, kVerbCodeHiscores = 44, kVerbCodeWake = 45,
+ kVerbCodeHello = 46, kVerbCodeThanks = 47,
+ kVerbCodeSmartAlec = 249, kVerbCodeExpletive = 253, kVerbCodePardon = 254
+};
+
+enum MouseCursor {
+ kCurUpArrow = 0, kCurScrewDriver = 1, kCurRightArrow = 2, kCurFletch = 3, kCurWait = 4, kCurHand = 5,
+ kCurCrosshair = 6, kCurIBeam = 7
+};
+
+// Magic/portal constants:
+enum Magics {
+ kMagicNothing, // Ignore it if this line is touched.
+ kMagicBounce, // Bounce off this line. Not valid for portals.
+ kMagicExclaim, // Put up a chain of scrolls.
+ kMagicTransport, // Enter new room.
+ kMagicUnfinished, // Unfinished connection.
+ kMagicSpecial, // Special function.
+ kMagicOpenDoor // Opening door.
+};
+
+// Constants to replace the command characters from Pascal.
+// For more information, see: https://github.com/urukgit/avalot/wiki/Scrolldrivers
+enum ControlCharacter {
+ kControlSpeechBubble = 2, // ^B
+ kControlCenter = 3, // ^C
+ kControlToBuffer = 4, // ^D
+ kControlItalic = 6, // ^F
+ kControlBell = 7, // ^G
+ kControlBackspace = 8, // ^H
+ kControlInsertSpaces = 9, // ^I
+ kControlLeftJustified = 12, // ^L
+ kControlNewLine = 13, // ^M
+ kControlParagraph = 16, // ^P
+ kControlQuestion = 17, // ^Q
+ kControlRoman = 18, // ^R
+ kControlRegister = 19, // ^S
+ kControlNegative = 21, // ^U
+ kControlIcon = 22 // ^V
+};
+
+static const int16 kScreenWidth = 640;
+static const int16 kScreenHeight = 200;
+
+static const int16 kWalk = 3;
+static const int16 kRun = 5;
+
+} // End of namespace Avalanche
+
+#endif // AVALANCHE_ENUMS_H
diff --git a/engines/avalanche/graphics.cpp b/engines/avalanche/graphics.cpp
new file mode 100644
index 0000000000..a8efc4be9b
--- /dev/null
+++ b/engines/avalanche/graphics.cpp
@@ -0,0 +1,836 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public 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 based on the original source code of Lord Avalot d'Argent version 1.3.
+ * Copyright (c) 1994-1995 Mike, Mark and Thomas Thurman.
+ */
+
+#include "avalanche/avalanche.h"
+#include "avalanche/graphics.h"
+
+#include "engines/util.h"
+#include "graphics/palette.h"
+
+namespace Avalanche {
+
+const byte GraphicManager::kEgaPaletteIndex[16] = {0, 1, 2, 3, 4, 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63};
+
+const MouseHotspotType GraphicManager::kMouseHotSpots[9] = {
+ {8,0}, // 0 - up-arrow
+ {0,0}, // 1 - screwdriver
+ {15,6}, // 2 - right-arrow
+ {0,0}, // 3 - fletch
+ {8,7}, // 4 - hourglass
+ {4,0}, // 5 - TTHand
+ {8,5}, // 6 - Mark's crosshairs
+ {8,7}, // 7 - I-beam
+ {0,0} // 8 - question mark
+};
+
+GraphicManager::GraphicManager(AvalancheEngine *vm) {
+ _vm = vm;
+ setDialogColor(kColorBlack, kColorWhite);
+}
+
+GraphicManager::~GraphicManager() {
+ _surface.free();
+ _magics.free();
+ _background.free();
+ _screen.free();
+ _scrolls.free();
+ _backup.free();
+
+ for (int i = 0; i < 10; i++)
+ _digits[i].free();
+ for (int i = 0; i < 9; i++)
+ _directions[i].free();
+}
+
+void GraphicManager::init() {
+ initGraphics(kScreenWidth, kScreenHeight * 2, true); // Doubling the height.
+
+ for (int i = 0; i < 64; ++i) {
+ _egaPalette[i][0] = (i >> 2 & 1) * 0xaa + (i >> 5 & 1) * 0x55;
+ _egaPalette[i][1] = (i >> 1 & 1) * 0xaa + (i >> 4 & 1) * 0x55;
+ _egaPalette[i][2] = (i & 1) * 0xaa + (i >> 3 & 1) * 0x55;
+ }
+
+ for (int i = 0; i < 16; i++)
+ g_system->getPaletteManager()->setPalette(_egaPalette[kEgaPaletteIndex[i]], i, 1);
+
+ // Set the "flesh colors":
+ g_system->getPaletteManager()->setPalette(_egaPalette[39], 13, 1);
+ g_system->getPaletteManager()->setPalette(_egaPalette[28], 5, 1);
+
+ _surface.create(kScreenWidth, kScreenHeight, Graphics::PixelFormat::createFormatCLUT8());
+ _magics.create(kScreenWidth, kScreenHeight, Graphics::PixelFormat::createFormatCLUT8());
+ _screen.create(kScreenWidth, kScreenHeight * 2, Graphics::PixelFormat::createFormatCLUT8());
+ _scrolls.create(kScreenWidth, kScreenHeight, Graphics::PixelFormat::createFormatCLUT8());
+}
+
+/**
+ * Load the scoring digits & rwlites
+ * @remarks Originally called 'load_digits'
+ */
+void GraphicManager::loadDigits() {
+ const byte digitsize = 134;
+ const byte rwlitesize = 126;
+
+ Common::File file;
+ if (!file.open("digit.avd"))
+ error("AVALANCHE: File not found: digit.avd");
+
+ for (int i = 0; i < 10; i++) {
+ file.seek(i * digitsize);
+ _digits[i] = loadPictureGraphic(file);
+ }
+
+ for (int i = 0; i < 9; i++) {
+ file.seek(10 * digitsize + i * rwlitesize);
+ _directions[i] = loadPictureGraphic(file);
+ }
+
+ file.close();
+}
+
+void GraphicManager::loadMouse(byte which) {
+ if (which == _vm->_currentMouse)
+ return;
+
+ _vm->_currentMouse = which;
+
+ Common::File f;
+ if (!f.open("mice.avd"))
+ error("AVALANCHE: Gyro: File not found: mice.avd");
+
+ Graphics::Surface cursor;
+ cursor.create(16, 32, Graphics::PixelFormat::createFormatCLUT8());
+ cursor.fillRect(Common::Rect(0, 0, 16, 32), 255);
+
+ // The AND mask.
+ f.seek(kMouseSize * 2 * which + 134);
+
+ Graphics::Surface mask = loadPictureGraphic(f);
+
+ for (int j = 0; j < mask.h; j++) {
+ for (int i = 0; i < mask.w; i++) {
+ byte pixel = *(byte *)mask.getBasePtr(i, j);
+ if (pixel == 0) {
+ *(byte *)cursor.getBasePtr(i, j * 2 ) = 0;
+ *(byte *)cursor.getBasePtr(i, j * 2 + 1) = 0;
+ }
+ }
+ }
+
+ mask.free();
+
+ // The OR mask.
+ f.seek(kMouseSize * 2 * which + 134 * 2);
+
+ mask = loadPictureGraphic(f);
+
+ for (int j = 0; j < mask.h; j++) {
+ for (int i = 0; i < mask.w; i++) {
+ byte pixel = *(byte *)mask.getBasePtr(i, j);
+ if (pixel != 0) {
+ *(byte *)cursor.getBasePtr(i, j * 2 ) = pixel;
+ *(byte *)cursor.getBasePtr(i, j * 2 + 1) = pixel;
+ }
+ }
+ }
+
+ mask.free();
+ f.close();
+
+ CursorMan.replaceCursor(cursor.getPixels(), 16, 32, kMouseHotSpots[which]._horizontal, kMouseHotSpots[which]._vertical * 2, 255, false);
+ cursor.free();
+}
+
+void GraphicManager::drawThinkPic(Common::String filename, int id) {
+ static const int16 picSize = 966;
+ Common::File file;
+ if (!file.open(filename))
+ error("drawThinkPic(): File not found: %s", filename.c_str());
+
+ file.seek(id * picSize + 65);
+ Graphics::Surface picture = loadPictureGraphic(file);
+ drawPicture(_surface, picture, 205, 170);
+
+ picture.free();
+ file.close();
+}
+
+void GraphicManager::drawToolbar() {
+ Common::File file;
+ if (!file.open("useful.avd"))
+ error("drawToolbar(): File not found: useful.avd");
+
+ file.seek(40);
+
+ CursorMan.showMouse(false);
+ Graphics::Surface picture = loadPictureGraphic(file);
+ drawPicture(_surface, picture, 5, 169);
+ CursorMan.showMouse(true);
+
+ picture.free();
+ file.close();
+}
+
+Common::Point GraphicManager::drawArc(Graphics::Surface &surface, int16 x, int16 y, int16 stAngle, int16 endAngle, uint16 radius, Color color) {
+ Common::Point endPoint;
+ const double convfac = M_PI / 180.0;
+
+ int32 xRadius = radius;
+ int32 yRadius = radius * kScreenWidth / (8 * kScreenHeight); // Just don't ask why...
+
+ if (xRadius == 0)
+ xRadius++;
+ if (yRadius == 0)
+ yRadius++;
+
+ // Check for an ellipse with negligable x and y radius.
+ if ((xRadius <= 1) && (yRadius <= 1)) {
+ *(byte *)_scrolls.getBasePtr(x, y) = color;
+ endPoint.x = x;
+ endPoint.y = y;
+ return endPoint;
+ }
+
+ // Check if valid angles.
+ stAngle = stAngle % 361;
+ endAngle = endAngle % 361;
+
+ // If impossible angles, then swap them!
+ if (endAngle < stAngle) {
+ uint16 tmpAngle=endAngle;
+ endAngle=stAngle;
+ stAngle=tmpAngle;
+ }
+
+ // Approximate the number of pixels required by using the circumference equation of an ellipse.
+ uint16 numOfPixels = (uint16)floor(sqrt(3.0) * sqrt(pow(double(xRadius), 2) + pow(double(yRadius), 2)) + 0.5);
+
+ // Calculate the angle precision required.
+ float delta = 90.0 / numOfPixels;
+
+ // Always just go over the first 90 degrees. Could be optimized a
+ // bit if startAngle and endAngle lie in the same quadrant, left as an
+ // exercise for the reader. :)
+ float j = 0;
+
+ // Calculate stop position, go 1 further than 90 because otherwise 1 pixel is sometimes not drawn.
+ uint16 deltaEnd = 91;
+
+ // Set the end point.
+ float tempTerm = endAngle * convfac;
+ endPoint.x = (int16)floor(xRadius * cos(tempTerm) + 0.5) + x;
+ endPoint.y = (int16)floor(yRadius * sin(tempTerm + M_PI) + 0.5) + y;
+
+ // Calculate points.
+ int16 xNext = xRadius;
+ int16 yNext = 0;
+ do {
+ int16 xTemp = xNext;
+ int16 yTemp = yNext;
+ // This is used by both sin and cos.
+ tempTerm = (j + delta) * convfac;
+
+ xNext = (int16)floor(xRadius * cos(tempTerm) + 0.5);
+ yNext = (int16)floor(yRadius * sin(tempTerm + M_PI) + 0.5);
+
+ int16 xp = x + xTemp;
+ int16 xm = x - xTemp;
+ int16 yp = y + yTemp;
+ int16 ym = y - yTemp;
+
+ if ((j >= stAngle) && (j <= endAngle))
+ *(byte *)_scrolls.getBasePtr(xp, yp) = color;
+
+ if (((180 - j) >= stAngle) && ((180 - j) <= endAngle))
+ *(byte *)_scrolls.getBasePtr(xm, yp) = color;
+
+ if (((j + 180) >= stAngle) && ((j + 180) <= endAngle))
+ *(byte *)_scrolls.getBasePtr(xm, ym) = color;
+
+ if (((360 - j) >= stAngle) && ((360 - j) <= endAngle))
+ *(byte *)_scrolls.getBasePtr(xp, ym) = color;
+
+ j += delta;
+ } while (j <= deltaEnd);
+
+ return endPoint;
+}
+
+void GraphicManager::drawLine(int x1, int y1, int x2, int y2, int penX, int penY, Color color) {
+ _surface.drawThickLine(x1, y1, x2, y2, penX, penY, color);
+}
+
+Common::Point GraphicManager::drawScreenArc(int16 x, int16 y, int16 stAngle, int16 endAngle, uint16 radius, Color color) {
+ return drawArc(_surface, x, y, stAngle, endAngle, radius, color);
+}
+
+void GraphicManager::drawPieSlice(int16 x, int16 y, int16 stAngle, int16 endAngle, uint16 radius, Color color) {
+ while (radius > 0)
+ drawArc(_scrolls, x, y, stAngle, endAngle, radius--, color);
+}
+
+void GraphicManager::drawTriangle(Common::Point *p, Color color) {
+ // Draw the borders with a marking color.
+ _scrolls.drawLine(p[0].x, p[0].y, p[1].x, p[1].y, 255);
+ _scrolls.drawLine(p[1].x, p[1].y, p[2].x, p[2].y, 255);
+ _scrolls.drawLine(p[2].x, p[2].y, p[0].x, p[0].y, 255);
+
+ // Get the top and the bottom of the triangle.
+ uint16 maxY = p[0].y, minY = p[0].y;
+ for (int i = 1; i < 3; i++) {
+ if (p[i].y < minY)
+ minY = p[i].y;
+ if (p[i].y > maxY)
+ maxY = p[i].y;
+ }
+
+ // Fill the triangle.
+ for (uint16 y = minY; y <= maxY; y++) {
+ uint16 x = 0;
+ while (*(byte *)_scrolls.getBasePtr(x, y) != 255)
+ x++;
+ uint16 minX = x;
+ uint16 maxX = x;
+ x++;
+ while ((*(byte *)_scrolls.getBasePtr(x, y) != 255) && (x != 639))
+ x++;
+ if (x != 639)
+ maxX = x;
+ if (minX != maxX)
+ _scrolls.drawLine(minX, y, maxX, y, color);
+ }
+
+ // Redraw the borders with the actual color.
+ _scrolls.drawLine(p[0].x, p[0].y, p[1].x, p[1].y, color);
+ _scrolls.drawLine(p[1].x, p[1].y, p[2].x, p[2].y, color);
+ _scrolls.drawLine(p[2].x, p[2].y, p[0].x, p[0].y, color);
+}
+
+void GraphicManager::drawText(Graphics::Surface &surface, const Common::String text, FontType font, byte fontHeight, int16 x, int16 y, Color color) {
+ for (uint i = 0; i < text.size(); i++) {
+ for (int j = 0; j < fontHeight; j++) {
+ byte pixel = font[(byte)text[i]][j];
+ for (int bit = 0; bit < 8; bit++) {
+ byte pixelBit = (pixel >> bit) & 1;
+ if (pixelBit)
+ *(byte *)surface.getBasePtr(x + i * 8 + 7 - bit, y + j) = color;
+ }
+ }
+ }
+}
+
+void GraphicManager::drawNormalText(const Common::String text, FontType font, byte fontHeight, int16 x, int16 y, Color color) {
+ drawText(_surface, text, font, fontHeight, x, y, color);
+}
+
+void GraphicManager::drawScrollText(const Common::String text, FontType font, byte fontHeight, int16 x, int16 y, Color color) {
+ drawText(_scrolls, text, font, fontHeight, x, y, color);
+}
+
+void GraphicManager::drawDigit(int index, int x, int y) {
+ drawPicture(_surface, _digits[index], x, y);
+}
+
+void GraphicManager::drawDirection(int index, int x, int y) {
+ drawPicture(_surface, _directions[index], x, y);
+}
+
+void GraphicManager::drawScrollShadow(int16 x1, int16 y1, int16 x2, int16 y2) {
+ for (byte i = 0; i < 2; i ++) {
+ _scrolls.fillRect(Common::Rect(x1 + i, y1 + i, x1 + i + 1, y2 - i), kColorWhite);
+ _scrolls.fillRect(Common::Rect(x1 + i, y1 + i, x2 - i, y1 + i + 1), kColorWhite);
+
+ _scrolls.fillRect(Common::Rect(x2 - i, y1 + i, x2 - i + 1, y2 - i + 1), kColorDarkgray);
+ _scrolls.fillRect(Common::Rect(x1 + i, y2 - i, x2 - i, y2 - i + 1), kColorDarkgray);
+ }
+}
+
+void GraphicManager::drawShadowBox(int16 x1, int16 y1, int16 x2, int16 y2, Common::String text) {
+ CursorMan.showMouse(false);
+
+ drawScrollShadow(x1, y1, x2, y2);
+
+ bool offset = text.size() % 2;
+ x1 = (x2 - x1) / 2 + x1 - text.size() / 2 * 8 - offset * 3;
+ y1 = (y2 - y1) / 2 + y1 - 4;
+ drawScrollText(text, _vm->_font, 8, x1, y1, kColorBlue);
+ drawScrollText(Common::String('_'), _vm->_font, 8, x1, y1, kColorBlue);
+
+ CursorMan.showMouse(true);
+}
+
+void GraphicManager::drawMenuBar(Color color) {
+ _surface.fillRect(Common::Rect(0, 0, 640, 10), color);
+}
+
+void GraphicManager::drawMenuBlock(int x1, int y1, int x2, int y2, Color color) {
+ _surface.fillRect(Common::Rect(x1, y1, x2, y2), color);
+}
+
+void GraphicManager::drawMenuItem(int x1, int y1, int x2, int y2) {
+ _surface.fillRect(Common::Rect(x1, y1, x2, y2), kMenuBackgroundColor);
+ _surface.frameRect(Common::Rect(x1 - 1, y1 - 1, x2 + 1, y2 + 1), kMenuBorderColor);
+}
+
+void GraphicManager::drawSpeedBar(int speed) {
+ if (speed == kRun) {
+ _surface.drawLine(336, 199, 338, 199, kColorLightblue);
+ _surface.drawLine(371, 199, 373, 199, kColorYellow);
+ } else {
+ _surface.drawLine(371, 199, 373, 199, kColorLightblue);
+ _surface.drawLine(336, 199, 338, 199, kColorYellow);
+ }
+}
+void GraphicManager::drawScroll(int mx, int lx, int my, int ly) {
+ _scrolls.copyFrom(_surface);
+
+ // The right corners of the scroll.
+ drawPieSlice(mx + lx, my - ly, 0, 90, 15, kColorLightgray);
+ drawPieSlice(mx + lx, my + ly, 270, 360, 15, kColorLightgray);
+ drawArc(_scrolls, mx + lx, my - ly, 0, 90, 15, kColorRed);
+ drawArc(_scrolls, mx + lx, my + ly, 270, 360, 15, kColorRed);
+
+ // The body of the scroll.
+ _scrolls.fillRect(Common::Rect(mx - lx - 30, my + ly, mx + lx, my + ly + 6), kColorLightgray);
+ _scrolls.fillRect(Common::Rect(mx - lx - 30, my - ly - 6, mx + lx, my - ly + 1), kColorLightgray);
+ _scrolls.fillRect(Common::Rect(mx - lx - 15, my - ly, mx + lx + 15, my + ly + 1), kColorLightgray);
+
+ // The left corners of the scroll.
+ drawPieSlice(mx - lx - 31, my - ly, 0, 180, 15, kColorDarkgray);
+ drawArc(_scrolls, mx - lx - 31, my - ly, 0, 180, 15, kColorRed);
+ _scrolls.drawLine(mx - lx - 31 - 15, my - ly, mx - lx - 31 + 15, my - ly, kColorRed);
+ drawPieSlice(mx - lx - 31, my + ly, 180, 360, 15, kColorDarkgray);
+ drawArc(_scrolls, mx - lx - 31, my + ly, 180, 360, 15, kColorRed);
+ _scrolls.drawLine(mx - lx - 31 - 15, my + ly, mx - lx - 31 + 15, my + ly, kColorRed);
+
+ // The rear borders of the scroll.
+ _scrolls.fillRect(Common::Rect(mx - lx - 30, my - ly - 6, mx + lx, my - ly - 5), kColorRed);
+ _scrolls.fillRect(Common::Rect(mx - lx - 30, my + ly + 6, mx + lx, my + ly + 7), kColorRed);
+ _scrolls.fillRect(Common::Rect(mx - lx - 15, my - ly, mx - lx - 14, my + ly), kColorRed);
+ _scrolls.fillRect(Common::Rect(mx + lx + 15, my - ly, mx + lx + 16, my + ly), kColorRed);
+}
+
+void GraphicManager::drawBackgroundSprite(int16 x, int16 y, SpriteType &sprite) {
+ drawPicture(_background, sprite._picture, x, y);
+}
+
+void GraphicManager::drawDebugLines() {
+ if (!_vm->_showDebugLines)
+ return;
+
+ for (int i = 0; i < _vm->_lineNum; i++) {
+ LineType *curLine = &_vm->_lines[i];
+ _surface.drawLine(curLine->_x1, curLine->_y1, curLine->_x2, curLine->_y2, curLine->_color);
+ }
+
+ for (int i = 0; i < _vm->_fieldNum; i++) {
+ FieldType *curField = &_vm->_fields[i];
+ if (curField->_x1 < 640)
+ _surface.frameRect(Common::Rect(curField->_x1, curField->_y1, curField->_x2, curField->_y2), kColorLightmagenta);
+ }
+}
+
+void GraphicManager::drawFilledRectangle(Common::Rect rect, Color color) {
+ _surface.fillRect(rect, color);
+}
+
+void GraphicManager::drawRectangle(Common::Rect rect, Color color) {
+ _surface.frameRect(rect, color);
+}
+
+void GraphicManager::nimLoad() {
+ Common::File file;
+ Common::String filename = "nim.avd";
+
+ if (!file.open(filename))
+ error("AVALANCHE: Scrolls: File not found: %s", filename.c_str());
+
+ file.seek(41);
+
+ _nimStone = loadPictureSign(file, 7, 23);
+ for (int i = 0; i < 3; i++)
+ _nimInitials[i] = loadPictureSign(file, 7, 23);
+ _nimLogo = loadPictureSign(file, 30, 37);
+
+ file.close();
+}
+
+void GraphicManager::nimDrawStone(int x, int y) {
+ drawPicture(_surface, _nimStone, x, y);
+}
+
+void GraphicManager::nimDrawInitials() {
+ for (int i = 0; i < 3; i++)
+ drawPicture(_surface, _nimInitials[i], 0, 75 + i * 35);
+}
+
+void GraphicManager::nimDrawLogo() {
+ drawPicture(_surface, _nimLogo, 392, 5);
+}
+
+void GraphicManager::nimFree() {
+ _nimStone.free();
+ for (int i = 0; i < 3; i++)
+ _nimInitials[i].free();
+ _nimLogo.free();
+}
+
+/**
+ * This function mimics Pascal's getimage().
+ */
+Graphics::Surface GraphicManager::loadPictureGraphic(Common::File &file) {
+ // The height and the width are stored in 2-2 bytes. We have to add 1 to each because Pascal stores the value of them -1.
+ uint16 width = file.readUint16LE() + 1;
+ uint16 height = file.readUint16LE() + 1;
+
+ Graphics::Surface picture; // We make a Surface object for the picture itself.
+ picture.create(width, height, Graphics::PixelFormat::createFormatCLUT8());
+
+ // Produce the picture. We read it in row-by-row, and every row has 4 planes.
+ for (int y = 0; y < height; y++) {
+ for (int8 plane = 3; plane >= 0; plane--) { // The planes are in the opposite way.
+ for (uint16 x = 0; x < width; x += 8) {
+ byte pixel = file.readByte();
+ for (int bit = 0; bit < 8; bit++) {
+ byte pixelBit = (pixel >> bit) & 1;
+ if (pixelBit != 0)
+ *(byte *)picture.getBasePtr(x + 7 - bit, y) += (pixelBit << plane);
+ }
+ }
+ }
+ }
+ return picture;
+}
+
+/**
+ * Reads Row-planar EGA data.
+ * This function is our own creation, very much like the one above. The main differences are that
+ * we don't read the width and the height from the file, the planes are in a different order
+ * and we read the picture plane-by-plane.
+ */
+Graphics::Surface GraphicManager::loadPictureRaw(Common::File &file, uint16 width, uint16 height) {
+ Graphics::Surface picture;
+ picture.create(width, height, Graphics::PixelFormat::createFormatCLUT8());
+
+ for (int plane = 0; plane < 4; plane++) {
+ for (uint16 y = 0; y < height; y++) {
+ for (uint16 x = 0; x < width; x += 8) {
+ byte pixel = file.readByte();
+ for (int i = 0; i < 8; i++) {
+ byte pixelBit = (pixel >> i) & 1;
+ *(byte *)picture.getBasePtr(x + 7 - i, y) += (pixelBit << plane);
+ }
+ }
+ }
+ }
+
+ return picture;
+}
+
+Graphics::Surface GraphicManager::loadPictureSign(Common::File &file, int xl, int yl) {
+ // I know it looks very similar to the other loadPicture methods, but in truth it's the combination of the two.
+ uint16 width = xl * 8;
+ uint16 height = yl;
+
+ Graphics::Surface picture; // We make a Surface object for the picture itself.
+ picture.create(width, height, Graphics::PixelFormat::createFormatCLUT8());
+
+ // Produce the picture. We read it in row-by-row, and every row has 4 planes.
+ for (int yy = 0; yy < height; yy++) {
+ for (int8 plane = 0; plane < 4; plane++) { // The planes are in the "right" order.
+ for (uint16 xx = 0; xx < width; xx += 8) {
+ byte pixel = file.readByte();
+ for (int bit = 0; bit < 8; bit++) {
+ byte pixelBit = (pixel >> bit) & 1;
+ if (pixelBit != 0)
+ *(byte *)picture.getBasePtr(xx + 7 - bit, yy) += (pixelBit << plane);
+ }
+ }
+ }
+ }
+
+ return picture;
+}
+
+/**
+* Shifts the whole screen down by one line and fills the gap with black.
+*/
+void GraphicManager::shiftScreen() {
+ for (uint16 y = _surface.h - 1; y > 1; y--)
+ memcpy(_surface.getBasePtr(0, y), _surface.getBasePtr(0, y - 1), _surface.w);
+
+ _surface.drawLine(0, 0, _surface.w, 0, kColorBlack);
+}
+
+void GraphicManager::clearAlso() {
+ _magics.fillRect(Common::Rect(0, 0, 640, 200), 0);
+ _magics.frameRect(Common::Rect(0, 45, 640, 161), 15);
+}
+
+void GraphicManager::clearTextBar() {
+ _surface.fillRect(Common::Rect(24, 161, 640, 169), kColorBlack); // Black out the line of the text.
+}
+
+void GraphicManager::setAlsoLine(int x1, int y1, int x2, int y2, Color color) {
+ _magics.drawLine(x1, y1, x2, y2, color);
+}
+
+void GraphicManager::drawScreenLine(int16 x, int16 y, int16 x2, int16 y2, Color color) {
+ _surface.drawLine(x, y, x2, y2, color);
+}
+
+byte GraphicManager::getAlsoColor(int x1, int y1, int x2, int y2) {
+ byte returnColor = 0;
+ for (int16 i = x1; i <= x2; i++) {
+ for (int16 j = y1; j <= y2; j++) {
+ byte actColor = *(byte *)_magics.getBasePtr(i, j);
+ returnColor = MAX(returnColor, actColor);
+ }
+ }
+
+ return returnColor;
+}
+
+byte GraphicManager::getScreenColor(Common::Point pos) {
+ return *(byte *)_surface.getBasePtr(pos.x, pos.y / 2);
+}
+
+void GraphicManager::drawSprite(AnimationType *sprite, byte picnum, int16 x, int16 y) {
+ // First we make the pixels of the sprite blank.
+ for (int j = 0; j < sprite->_yLength; j++) {
+ for (int i = 0; i < sprite->_xLength; i++) {
+ if ((x + i < _surface.w) && (y + j < _surface.h)) {
+ if (((*sprite->_sil[picnum])[j][i / 8] >> ((7 - i % 8)) & 1) == 0)
+ *(byte *)_surface.getBasePtr(x + i, y + j) = 0;
+ }
+ }
+ }
+
+ // Then we draw the picture to the blank places.
+ uint16 maniPos = 0; // Because the original manitype starts at 5!!! See Graphics.h for definition.
+
+ for (int j = 0; j < sprite->_yLength; j++) {
+ for (int8 plane = 3; plane >= 0; plane--) { // The planes are in the opposite way.
+ for (uint16 i = 0; i < sprite->_xLength; i += 8) {
+ byte pixel = (*sprite->_mani[picnum])[maniPos++];
+ for (int bit = 0; bit < 8; bit++) {
+ if ((x + i + 7 < _surface.w) && (y + j < _surface.h)) {
+ byte pixelBit = (pixel >> bit) & 1;
+ *(byte *)_surface.getBasePtr(x + i + 7 - bit, y + j) += (pixelBit << plane);
+ }
+ }
+ }
+ }
+ }
+}
+
+void GraphicManager::drawPicture(Graphics::Surface &target, const Graphics::Surface picture, uint16 destX, uint16 destY) {
+ // Copy the picture to the given place on the screen.
+ uint16 maxX = picture.w;
+ uint16 maxY = picture.h;
+
+ if (destX + maxX > target.w)
+ maxX = target.w - destX;
+
+ if (destY + maxY > target.h)
+ maxY = target.h - destY;
+
+ for (uint16 y = 0; y < maxY; y++) {
+ for (uint16 x = 0; x < maxX; x++)
+ *(byte *)target.getBasePtr(x + destX, y + destY) = *(const byte *)picture.getBasePtr(x, y);
+ }
+}
+
+void GraphicManager::drawCursor(byte pos) {
+ int pixPos = 24 + (pos * 8);
+ // Draw the '_' character.
+ for (int i = 0; i < 8; i++)
+ *(byte *)_surface.getBasePtr(pixPos + i, 168) = kColorWhite;
+}
+
+void GraphicManager::drawReadyLight(Color color) {
+ _surface.fillRect(Common::Rect(419, 195, 438, 197), color);
+}
+
+/**
+ * This is for drawing a big "about" or "gameover" picture loaded from a file into an empty scroll.
+ */
+void GraphicManager::drawSign(Common::String fn, int16 xl, int16 yl, int16 y) {
+ Common::File file;
+ Common::String filename = Common::String::format("%s.avd", fn.c_str());
+
+ if (!file.open(filename))
+ error("AVALANCHE: Scrolls: File not found: %s", filename.c_str());
+
+ Graphics::Surface sign; // We make a Surface object for the picture itself.
+ sign = loadPictureSign(file, xl, yl);
+ uint16 width = xl * 8;
+ drawPicture(_scrolls, sign, kScreenWidth / 2 - width / 2, y); // x coord: center the picture.
+
+ file.close();
+}
+
+/**
+ * Draws an icon to the current scroll.
+ * @remarks Originally called 'geticon'
+ */
+void GraphicManager::drawIcon(int16 x, int16 y, byte which) {
+ Common::File file;
+
+ if (!file.open("icons.avd"))
+ error("AVALANCHE: Scrolls: File not found: icons.avd");
+
+ which--;
+ file.seek(which * 426);
+
+ Graphics::Surface icon = loadPictureGraphic(file);
+ drawPicture(_scrolls, icon, x, y);
+
+ icon.free();
+ file.close();
+}
+
+void GraphicManager::prepareBubble(int xc, int xw, int my, Common::Point points[3]) {
+ // Backup the screen before drawing the bubble.
+ _scrolls.copyFrom(_surface);
+
+ int16 talkX = _vm->_dialogs->getTalkPosX();
+ // The body of the bubble.
+ _scrolls.fillRect(Common::Rect(xc + talkX - xw + 9, 7, talkX + xw - 8 + xc, my + 1), _talkBackgroundColor);
+ _scrolls.fillRect(Common::Rect(xc + talkX - xw - 1, 12, talkX + xw + xc + 2, my - 4), _talkBackgroundColor);
+
+ // Top the 4 rounded corners of the bubble.
+ drawPieSlice(xc + talkX + xw - 10, 11, 0, 90, 9, _talkBackgroundColor);
+ drawPieSlice(xc + talkX + xw - 10, my - 4, 270, 360, 9, _talkBackgroundColor);
+ drawPieSlice(xc + talkX - xw + 10, 11, 90, 180, 9, _talkBackgroundColor);
+ drawPieSlice(xc + talkX - xw + 10, my - 4, 180, 270, 9, _talkBackgroundColor);
+
+ // "Tail" of the speech bubble.
+ drawTriangle(points, _talkBackgroundColor);
+}
+
+/**
+ * Set the background of the text to the desired color.
+ */
+void GraphicManager::wipeChar(int x, int y, Color color) {
+ for (int k = 0; k < 8; k++)
+ *(byte *)_surface.getBasePtr(x + k, y) = color;
+}
+
+void GraphicManager::drawChar(byte ander, int x, int y, Color color) {
+ byte pixel = ander;
+ for (int bit = 0; bit < 8; bit++) {
+ byte pixelBit = (pixel >> bit) & 1;
+ if (pixelBit)
+ *(byte *)_surface.getBasePtr(x + 7 - bit, y) = color;
+ }
+}
+void GraphicManager::refreshScreen() {
+ // These cycles are for doubling the screen height.
+ for (uint16 y = 0; y < _screen.h / 2; y++) {
+ memcpy(_screen.getBasePtr(0, y * 2), _surface.getBasePtr(0, y), _screen.w);
+ memcpy(_screen.getBasePtr(0, y * 2 + 1), _surface.getBasePtr(0, y), _screen.w);
+ }
+ // Now we copy the stretched picture to the screen.
+ g_system->copyRectToScreen(_screen.getPixels(), _screen.pitch, 0, 0, kScreenWidth, kScreenHeight * 2);
+ g_system->updateScreen();
+}
+
+void GraphicManager::loadBackground(Common::File &file) {
+ _background.free();
+ _background = loadPictureRaw(file, kBackgroundWidth, kBackgroundHeight);
+}
+
+void GraphicManager::refreshBackground() {
+ drawPicture(_surface, _background, 0, 10);
+}
+
+/**
+ * Only used when entering the map.
+ * @remarks Originally called 'zoomout'
+ */
+void GraphicManager::zoomOut(int16 x, int16 y) {
+ //setlinestyle(dottedln, 0, 1); TODO: Implement it with a dotted line style!!!
+
+ saveScreen();
+ for (byte i = 1; i <= 20; i ++) {
+ int16 x1 = x - (x / 20) * i;
+ int16 y1 = y - ((y - 10) / 20) * i;
+ int16 x2 = x + (((639 - x) / 20) * i);
+ int16 y2 = y + (((161 - y) / 20) * i);
+
+ _surface.frameRect(Common::Rect(x1, y1, x2, y2), kColorWhite);
+ refreshScreen();
+ _vm->_system->delayMillis(17);
+
+ restoreScreen();
+ }
+ removeBackup();
+}
+
+void GraphicManager::showScroll() {
+ _surface.copyFrom(_scrolls); // TODO: Rework it using getSubArea !!!!!!!
+}
+
+void GraphicManager::getNaturalPicture(SpriteType &sprite) {
+ sprite._type = kNaturalImage; // We simply read from the screen and later, in drawSprite() we draw it right back.
+ sprite._size = sprite._xl * 8 * sprite._yl + 1;
+ sprite._picture.create(sprite._xl * 8, sprite._yl + 1, Graphics::PixelFormat::createFormatCLUT8());
+ for (uint16 y = 0; y < sprite._yl + 1; y++) {
+ for (uint16 x = 0; x < sprite._xl * 8; x++)
+ *(byte *)sprite._picture.getBasePtr(x, y) = *(byte *)_vm->_graphics->_surface.getBasePtr(sprite._x * 8 + x, sprite._y + y);
+ }
+}
+
+void GraphicManager::saveScreen() {
+ _backup.copyFrom(_surface);
+}
+
+void GraphicManager::removeBackup() {
+ _backup.free();
+}
+
+void GraphicManager::restoreScreen() {
+ _surface.copyFrom(_backup);
+ refreshScreen();
+}
+
+void GraphicManager::setDialogColor(Color bg, Color text) {
+ _talkBackgroundColor = bg;
+ _talkFontColor = text;
+}
+
+/**
+* Changes the black color of the palette to the selected one.
+* @remarks Originally called 'background'
+*/
+void GraphicManager::setBackgroundColor(Color newColor) {
+ g_system->getPaletteManager()->setPalette(_egaPalette[kEgaPaletteIndex[newColor]], kColorBlack, 1);
+}
+
+} // End of namespace Avalanche
diff --git a/engines/avalanche/graphics.h b/engines/avalanche/graphics.h
new file mode 100644
index 0000000000..636ae6fdf9
--- /dev/null
+++ b/engines/avalanche/graphics.h
@@ -0,0 +1,165 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public 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 based on the original source code of Lord Avalot d'Argent version 1.3.
+ * Copyright (c) 1994-1995 Mike, Mark and Thomas Thurman.
+ */
+
+#ifndef AVALANCHE_GRAPHICS_H
+#define AVALANCHE_GRAPHICS_H
+
+#include "avalanche/enums.h"
+
+#include "common/file.h"
+#include "common/rect.h"
+#include "graphics/surface.h"
+
+namespace Avalanche {
+class AvalancheEngine;
+class AnimationType;
+struct SpriteType;
+
+typedef byte FontType[256][16];
+typedef byte ManiType[2049];
+typedef byte SilType[51][11]; // 35, 4
+
+struct MouseHotspotType {
+ int16 _horizontal, _vertical;
+};
+
+class GraphicManager {
+public:
+ static const MouseHotspotType kMouseHotSpots[9];
+ Color _talkBackgroundColor, _talkFontColor;
+
+ GraphicManager(AvalancheEngine *vm);
+ ~GraphicManager();
+ void init();
+ void loadDigits();
+ void loadMouse(byte which);
+
+ void drawLine(int x1, int y1, int x2, int y2, int penX, int penY, Color color);
+ Common::Point drawScreenArc(int16 x, int16 y, int16 stAngle, int16 endAngle, uint16 radius, Color color);
+ void drawPieSlice(int16 x, int16 y, int16 stAngle, int16 endAngle, uint16 radius, Color color);
+ void drawTriangle(Common::Point *p, Color color);
+ void drawNormalText(const Common::String text, FontType font, byte fontHeight, int16 x, int16 y, Color color);
+ void drawScrollText(const Common::String text, FontType font, byte fontHeight, int16 x, int16 y, Color color);
+ void drawDigit(int index, int x, int y);
+ void drawDirection(int index, int x, int y);
+ void drawScrollShadow(int16 x1, int16 y1, int16 x2, int16 y2);
+ void drawShadowBox(int16 x1, int16 y1, int16 x2, int16 y2, Common::String text);
+ void drawScroll(int mx, int lx, int my, int ly);
+ void drawMenuBar(Color color);
+ void drawSpeedBar(int speed);
+ void drawBackgroundSprite(int16 x, int16 y, SpriteType &sprite);
+ void drawMenuBlock(int x1, int y1, int x2, int y2, Color color);
+ void drawMenuItem(int x1, int y1, int x2, int y2);
+ void wipeChar(int x, int y, Color color);
+ void drawChar(byte ander, int x, int y, Color color);
+ void drawDebugLines();
+
+ // For the mini-game "Nim".
+ void drawFilledRectangle(Common::Rect rect, Color color);
+ void drawRectangle(Common::Rect rect, Color color);
+ void nimLoad();
+ void nimDrawStone(int x, int y);
+ void nimDrawInitials();
+ void nimDrawLogo();
+ void nimFree();
+
+ // Used in wobble()
+ void shiftScreen();
+
+ void clearAlso();
+ void clearTextBar();
+ void setAlsoLine(int x1, int y1, int x2, int y2, Color color);
+ byte getAlsoColor(int x1, int y1, int x2, int y2);
+ byte getScreenColor(Common::Point pos);
+
+ // Further information about this: http://www.shikadi.net/moddingwiki/Raw_EGA_data
+ Graphics::Surface loadPictureRaw(Common::File &file, uint16 width, uint16 height);
+
+ void drawSprite(AnimationType *sprite, byte picnum, int16 x, int16 y);
+ void drawThinkPic(Common::String filename, int id);
+ void drawToolbar();
+ void drawCursor(byte pos);
+ void drawReadyLight(Color color);
+ void drawSign(Common::String name, int16 xl, int16 yl, int16 y);
+ void drawIcon(int16 x, int16 y, byte which);
+ void drawScreenLine(int16 x, int16 y, int16 x2, int16 y2, Color color);
+ void prepareBubble(int xc, int xw, int my, Common::Point points[3]);
+ void refreshScreen();
+ void loadBackground(Common::File &file);
+ void refreshBackground();
+ void setBackgroundColor(Color newColor);
+ void setDialogColor(Color bg, Color text);
+
+ void zoomOut(int16 x, int16 y);
+ void showScroll();
+ void getNaturalPicture(SpriteType &sprite);
+
+ void saveScreen();
+ void restoreScreen();
+ void removeBackup();
+
+private:
+ static const int16 kMouseSize = 134;
+ static const uint16 kBackgroundWidth = kScreenWidth;
+ static const byte kEgaPaletteIndex[16];
+ static const byte kBackgroundHeight = 8 * 12080 / kScreenWidth; // With 640 width it's 151.
+ // The 8 = number of bits in a byte, and 12080 comes from Lucerna::load().
+
+ Graphics::Surface _background;
+ Graphics::Surface _backup;
+ Graphics::Surface _digits[10]; // digitsize and rwlitesize are defined in loadDigits() !!!
+ Graphics::Surface _directions[9]; // Maybe it will be needed to move them to the class itself instead.
+ Graphics::Surface _magics; // Lucerna::draw_also_lines() draws the "magical" lines here. Further information: https://github.com/urukgit/avalot/wiki/Also
+ Graphics::Surface _screen; // Only used in refreshScreen() to make it more optimized. (No recreation of it at every call of the function.)
+ Graphics::Surface _scrolls;
+ Graphics::Surface _surface;
+
+ // For the mini-game "Nim".
+ Graphics::Surface _nimStone;
+ Graphics::Surface _nimInitials[3];
+ Graphics::Surface _nimLogo;
+
+ byte _egaPalette[64][3];
+
+ AvalancheEngine *_vm;
+
+ // Further information about these two: http://www.shikadi.net/moddingwiki/Raw_EGA_data
+ Graphics::Surface loadPictureGraphic(Common::File &file); // Reads Graphic-planar EGA data.
+ Graphics::Surface loadPictureSign(Common::File &file, int xl, int yl); // Reads a tricky type of picture used for the "game over"/"about" scrolls and in the mini-game Nim.
+
+ void drawText(Graphics::Surface &surface, const Common::String text, FontType font, byte fontHeight, int16 x, int16 y, Color color);
+ void drawPicture(Graphics::Surface &target, const Graphics::Surface picture, uint16 destX, uint16 destY);
+
+ // Taken from Free Pascal's Procedure InternalEllipseDefault. Used to replace Pascal's procedure arc.
+ // Returns the end point of the arc. (Needed in Clock.)
+ // TODO: Make it more accurate later.
+ Common::Point drawArc(Graphics::Surface &surface, int16 x, int16 y, int16 stAngle, int16 endAngle, uint16 radius, Color color);
+};
+
+} // End of namespace Avalanche
+
+#endif // AVALANCHE_GRAPHICS_H
diff --git a/engines/avalanche/menu.cpp b/engines/avalanche/menu.cpp
new file mode 100644
index 0000000000..c3fa709ee4
--- /dev/null
+++ b/engines/avalanche/menu.cpp
@@ -0,0 +1,844 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+/*
+ * This code is based on the original source code of Lord Avalot d'Argent version 1.3.
+ * Copyright (c) 1994-1995 Mike, Mark and Thomas Thurman.
+ */
+
+/* Original name: DROPDOWN A customized version of Oopmenu (qv). */
+
+#include "avalanche/avalanche.h"
+#include "avalanche/menu.h"
+
+namespace Avalanche {
+
+void HeadType::init(char trig, char altTrig, Common::String title, byte pos, MenuFunc setupFunc, MenuFunc chooseFunc, Menu *menu) {
+ _trigger = trig;
+ _altTrigger = altTrig;
+ _title = title;
+ _position = pos;
+ _xpos = _position * _menu->kSpacing + _menu->kIndent;
+ _xright = (_position + 1) * _menu->kSpacing + _menu->kIndent;
+ _setupFunc = setupFunc;
+ _chooseFunc = chooseFunc;
+
+ _menu = menu;
+}
+
+void HeadType::draw() {
+ CursorMan.showMouse(false);
+ _menu->drawMenuText(_xpos, 1, _trigger, _title, true, false);
+ CursorMan.showMouse(true);
+}
+
+void HeadType::highlight() {
+ CursorMan.showMouse(false);
+
+ _menu->_vm->_sound->stopSound();
+ _menu->drawMenuText(_xpos, 1, _trigger, _title, true, true);
+
+ _menu->_activeMenuItem._left = _xpos;
+ _menu->_activeMenuItem._activeNow = true;
+ _menu->_activeMenuItem._activeNum = _position;
+ _menu->_menuActive = true;
+
+ // Force reload and redraw of cursor.
+ _menu->_vm->_currentMouse = 177;
+
+}
+
+bool HeadType::parseAltTrigger(char key) {
+ if (key != _altTrigger)
+ return true;
+ return false;
+}
+
+void MenuItem::init(Menu *menu) {
+ _menu = menu;
+
+ _activeNow = false;
+ _activeNum = 1;
+ _menu->_menuActive = false;
+}
+
+void MenuItem::reset() {
+ _optionNum = 0;
+ _width = 0;
+ _firstlix = false;
+ _oldY = 0;
+ _highlightNum = 0;
+}
+
+void MenuItem::setupOption(Common::String title, char trigger, Common::String shortcut, bool valid) {
+ uint16 width = (title + shortcut).size() + 3;
+ if (_width < width)
+ _width = width;
+
+ _options[_optionNum]._title = title;
+ _options[_optionNum]._trigger = trigger;
+ _options[_optionNum]._shortcut = shortcut;
+ _options[_optionNum]._valid = valid;
+ _optionNum++;
+}
+
+void MenuItem::displayOption(byte y, bool highlit) {
+ Common::String text = _options[y]._title;
+ while (text.size() + _options[y]._shortcut.size() < _width)
+ text += ' '; // Pad _options[y] with spaces.
+ text += _options[y]._shortcut;
+
+ Color backgroundColor;
+ if (highlit)
+ backgroundColor = kColorBlack;
+ else
+ backgroundColor = kColorLightgray;
+
+ _menu->_vm->_graphics->drawMenuBlock((_flx1 + 1) * 8, 3 + (y + 1) * 10, (_flx2 + 1) * 8, 13 + (y + 1) * 10, backgroundColor);
+ _menu->drawMenuText(_left, 4 + (y + 1) * 10, _options[y]._trigger, text, _options[y]._valid, highlit);
+}
+
+void MenuItem::display() {
+ CursorMan.showMouse(false);
+
+ _firstlix = true;
+ _flx1 = _left - 2;
+ _flx2 = _left + _width;
+ _fly = 15 + _optionNum * 10;
+ _activeNow = true;
+ _menu->_menuActive = true;
+
+ _menu->_vm->_graphics->drawMenuItem((_flx1 + 1) * 8, 12, (_flx2 + 1) * 8, _fly);
+
+ displayOption(0, true);
+ for (int y = 1; y < _optionNum; y++)
+ displayOption(y, false);
+
+ _menu->_vm->_currentMouse = 177;
+
+ CursorMan.showMouse(true); // 4 = fletch
+}
+
+void MenuItem::wipe() {
+ CursorMan.showMouse(false);
+
+ _menu->drawMenuText(_menu->_menuBar._menuItems[_menu->_activeMenuItem._activeNum]._xpos, 1,
+ _menu->_menuBar._menuItems[_menu->_activeMenuItem._activeNum]._trigger,
+ _menu->_menuBar._menuItems[_menu->_activeMenuItem._activeNum]._title, true, false);
+
+ _activeNow = false;
+ _menu->_menuActive = false;
+ _firstlix = false;
+
+ CursorMan.showMouse(true);
+}
+
+void MenuItem::moveHighlight(int8 inc) {
+ if (inc != 0) {
+ int8 highlightNum = _highlightNum + inc;
+ if ((highlightNum < 0) || (highlightNum >= _optionNum))
+ return;
+ _highlightNum = highlightNum;
+ }
+ CursorMan.showMouse(false);
+ displayOption(_oldY, false);
+ displayOption(_highlightNum, true);
+ _oldY = _highlightNum;
+ CursorMan.showMouse(true);
+}
+
+/**
+ * This makes the menu highlight follow the mouse.
+ * @remarks Originally called 'lightup'
+ */
+void MenuItem::lightUp(Common::Point cursorPos) {
+ if ((cursorPos.x < _flx1 * 8) || (cursorPos.x > _flx2 * 8) || (cursorPos.y <= 25) || (cursorPos.y > ((_fly - 3) * 2 + 1)))
+ return;
+ _highlightNum = (cursorPos.y - 26) / 20;
+ if (_highlightNum == _oldY)
+ return;
+ moveHighlight(0);
+}
+
+void MenuItem::select(byte which) {
+ if (!_options[which]._valid)
+ return;
+
+ _choiceNum = which;
+ wipe();
+
+ if (_choiceNum == _optionNum)
+ _choiceNum--; // Off the bottom.
+ if (_choiceNum > _optionNum)
+ _choiceNum = 0; // Off the top, I suppose.
+
+ (_menu->*_menu->_menuBar._menuItems[_activeNum]._chooseFunc)();
+}
+
+void MenuItem::parseKey(char c) {
+ c = toupper(c);
+ bool found = false;
+ for (int i = 0; i < _optionNum; i++) {
+ if ((toupper(_options[i]._trigger) == c) && _options[i]._valid) {
+ select(i);
+ found = true;
+ }
+ }
+ if (!found)
+ _menu->_vm->_sound->blip();
+}
+
+MenuBar::MenuBar() {
+ _menuNum = 0;
+ _menu = nullptr;
+}
+
+void MenuBar::init(Menu *menu) {
+ _menu = menu;
+ _menuNum = 0;
+}
+
+void MenuBar::createMenuItem(char trig, Common::String title, char altTrig, MenuFunc setupFunc, MenuFunc chooseFunc) {
+ _menuItems[_menuNum].init(trig, altTrig, title, _menuNum, setupFunc, chooseFunc, _menu);
+ _menuNum++;
+}
+
+void MenuBar::draw() {
+ _menu->_vm->_graphics->drawMenuBar(kMenuBackgroundColor);
+
+ byte savecp = _menu->_vm->_cp;
+ _menu->_vm->_cp = 3;
+
+ for (int i = 0; i < _menuNum; i++)
+ _menuItems[i].draw();
+
+ _menu->_vm->_cp = savecp;
+}
+
+void MenuBar::parseAltTrigger(char c) {
+ byte i = 0;
+ while ((i < _menuNum) && (_menuItems[i].parseAltTrigger(c)))
+ i++;
+ if (i == _menuNum)
+ return;
+ setupMenuItem(i);
+}
+
+void MenuBar::setupMenuItem(byte which) {
+ if (_menu->_activeMenuItem._activeNow) {
+ _menu->_activeMenuItem.wipe(); // Get rid of menu.
+ if (_menu->_activeMenuItem._activeNum == _menuItems[which]._position)
+ return; // Clicked on own highlight.
+ }
+ _menuItems[which].highlight();
+ (_menu->*_menuItems[which]._setupFunc)();
+}
+
+void MenuBar::chooseMenuItem(int16 x) {
+ for (int i = 0; i < _menuNum; i++) {
+ if ((x > _menuItems[i]._xpos * 8) && (x < _menuItems[i]._xright * 8)) {
+ setupMenuItem(i);
+ break;
+ }
+ }
+}
+
+Menu::Menu(AvalancheEngine *vm) {
+ _vm = vm;
+ _activeMenuItem.init(this);
+ _menuBar.init(this);
+
+ _menuActive = false;
+ _lastPerson = kPeopleNone;
+}
+
+void Menu::findWhatYouCanDoWithIt() {
+ switch (_vm->_thinks) {
+ case kObjectWine:
+ case kObjectPotion:
+ case kObjectInk:
+ _verbStr = Common::String(kVerbCodeExam) + kVerbCodeDrink;
+ break;
+ case kObjectBell:
+ _verbStr = Common::String(kVerbCodeExam) + kVerbCodeRing;
+ break;
+ case kObjectChastity:
+ _verbStr = Common::String(kVerbCodeExam) + kVerbCodeWear;
+ break;
+ case kObjectLute:
+ _verbStr = Common::String(kVerbCodeExam) + kVerbCodePlay;
+ break;
+ case kObjectMushroom:
+ case kObjectOnion:
+ _verbStr = Common::String(kVerbCodeExam) + kVerbCodeEat;
+ break;
+ case kObjectClothes:
+ _verbStr = Common::String(kVerbCodeExam) + kVerbCodeWear;
+ break;
+ default:
+ _verbStr = kVerbCodeExam; // Anything else.
+ }
+}
+
+void Menu::drawMenuText(int16 x, int16 y, char trigger, Common::String text, bool valid, bool highlighted) {
+ Color fontColor;
+ Color backgroundColor;
+ if (highlighted) {
+ fontColor = kColorWhite;
+ backgroundColor = kColorBlack;
+ } else {
+ fontColor = kColorBlack;
+ backgroundColor = kColorLightgray;
+ }
+
+ byte ander;
+ if (valid)
+ ander = 255;
+ else
+ ander = 170;
+
+ FontType font;
+ for (uint i = 0; i < text.size(); i++) {
+ for (int j = 0; j < 8; j++) {
+ byte idx = text[i];
+ font[idx][j] = _vm->_font[idx][j] & ander; // Set the font.
+ // And set the background of the text to the desired color.
+ _vm->_graphics->wipeChar(x * 8 + i * 8, y + j, backgroundColor);
+ }
+ }
+
+ _vm->_graphics->drawNormalText(text, font, 8, x * 8, y, fontColor);
+
+ // Underline the selected character.
+ if ((trigger == 0) || !text.contains(trigger) )
+ return;
+ else {
+ byte i;
+ for (i = 0; text[i] != trigger; i++)
+ ; // Search for the character in the string.
+
+ _vm->_graphics->drawChar(ander, x * 8 + i * 8, y + 8, fontColor);
+ }
+
+ _vm->_graphics->refreshScreen();
+}
+
+void Menu::bleep() {
+ _vm->_sound->playNote(177, 7);
+}
+
+void Menu::parseKey(char r, char re) {
+#if 0
+ switch (r) {
+ case 0:
+ case 224: {
+ switch (re) {
+ case 'K':
+ if (_activeMenuItem._activeNum > 1) {
+ _activeMenuItem.wipe();
+ _menuBar.setupMenuItem(_activeMenuItem._activeNum - 1);
+ } else {
+ // Get menu on the left-hand side.
+ _activeMenuItem.wipe();
+ _menuBar.chooseMenuItem((_menuBar._menuNum - 1) * kSpacing + kIndent);
+ }
+ break;
+ case 'M':
+ if (_activeMenuItem._activeNum < _menuBar._menuNum) {
+ _activeMenuItem.wipe();
+ _menuBar.setupMenuItem(_activeMenuItem._activeNum + 1);
+ } else {
+ // Get menu on the far right-hand side.
+ _activeMenuItem.wipe();
+ _menuBar.chooseMenuItem(kIndent);
+ }
+ break;
+ case 'H':
+ _activeMenuItem.moveHighlight(-1);
+ break;
+ case 'P':
+ _activeMenuItem.moveHighlight(1);
+ break;
+ default:
+ _menuBar.parseAltTrigger(re);
+ }
+ }
+ break;
+ case 13:
+ _activeMenuItem.select(_activeMenuItem._highlightNum);
+ break;
+ default:
+ if (_activeMenuItem._activeNow)
+ _activeMenuItem.parseKey(r);
+ }
+#endif
+
+ warning("STUB: Dropdown::parseKey()"); // To be implemented properly later! Don't remove the comment above!
+}
+
+Common::String Menu::selectGender(byte x) {
+ if (x < 175)
+ return "im";
+ else
+ return "er";
+}
+
+void Menu::setupMenuGame() {
+ _activeMenuItem.reset();
+ _activeMenuItem.setupOption("Help...", 'H', "f1", true);
+ _activeMenuItem.setupOption("Boss Key", 'B', "alt-B", false);
+ _activeMenuItem.setupOption("Untrash screen", 'U', "ctrl-f7", true);
+ _activeMenuItem.setupOption("Score and rank", 'S', "f9", true);
+ _activeMenuItem.setupOption("About Avvy...", 'A', "shift-f10", true);
+ _activeMenuItem.display();
+}
+
+void Menu::setupMenuFile() {
+ _activeMenuItem.reset();
+ _activeMenuItem.setupOption("New game", 'N', "f4", true);
+ _activeMenuItem.setupOption("Load...", 'L', "^f3", true);
+ _activeMenuItem.setupOption("Save", 'S', "^f2", _vm->_alive);
+ _activeMenuItem.setupOption("Save As...", 'v', "", _vm->_alive);
+ _activeMenuItem.setupOption("DOS Shell", 'D', "alt-1", false);
+ _activeMenuItem.setupOption("Quit", 'Q', "alt-X", true);
+ _activeMenuItem.display();
+}
+
+void Menu::setupMenuAction() {
+ _activeMenuItem.reset();
+
+ Common::String f5Does = _vm->f5Does();
+ for (int i = 0; i < 2; i++)
+ if (!f5Does.empty())
+ f5Does.deleteChar(0);
+ if (f5Does.empty())
+ _activeMenuItem.setupOption("Do something", 'D', "f5", false);
+ else
+ _activeMenuItem.setupOption(f5Does, f5Does[0], "f5", true);
+ _activeMenuItem.setupOption("Pause game", 'P', "f6", true);
+ if (_vm->_room == kRoomMap)
+ _activeMenuItem.setupOption("Journey thither", 'J', "f7", _vm->_animation->nearDoor());
+ else
+ _activeMenuItem.setupOption("Open the door", 'O', "f7", _vm->_animation->nearDoor());
+ _activeMenuItem.setupOption("Look around", 'L', "f8", true);
+ _activeMenuItem.setupOption("Inventory", 'I', "Tab", true);
+ if (_vm->_animation->_sprites[0]->_speedX == kWalk)
+ _activeMenuItem.setupOption("Run fast", 'R', "^R", true);
+ else
+ _activeMenuItem.setupOption("Walk slowly", 'W', "^W", true);
+
+ _activeMenuItem.display();
+}
+
+void Menu::setupMenuPeople() {
+ if (!people.empty())
+ people.clear();
+
+ _activeMenuItem.reset();
+
+ for (int i = kPeopleAvalot; i <= kPeopleWisewoman; i++) {
+ if (_vm->getRoom((People)i) == _vm->_room) {
+ _activeMenuItem.setupOption(_vm->getName((People)i), getNameChar((People)i), "", true);
+ people += i;
+ }
+ }
+
+ _activeMenuItem.display();
+}
+
+void Menu::setupMenuObjects() {
+ _activeMenuItem.reset();
+ for (int i = 0; i < kObjectNum; i++) {
+ if (_vm->_objects[i])
+ _activeMenuItem.setupOption(getThing(i + 1), getThingChar(i + 1), "", true);
+ }
+ _activeMenuItem.display();
+}
+
+void Menu::setupMenuWith() {
+ _activeMenuItem.reset();
+
+ if (_vm->_thinkThing) {
+ findWhatYouCanDoWithIt();
+
+ for (uint i = 0; i < _verbStr.size(); i++) {
+ char vbchar;
+ Common::String verb;
+
+ _vm->_parser->verbOpt(_verbStr[i], verb, vbchar);
+ _activeMenuItem.setupOption(verb, vbchar, "", true);
+ }
+
+ // We disable the "give" option if: (a), you haven't selected anybody, (b), the _person you've selected isn't in the room,
+ // or (c), the _person you've selected is YOU!
+
+ if ((_lastPerson == kPeopleAvalot) || (_lastPerson == _vm->_parser->kNothing)
+ || (_vm->getRoom(_lastPerson) != _vm->_room))
+ _activeMenuItem.setupOption("Give to...", 'G', "", false); // Not here.
+ else {
+ _activeMenuItem.setupOption(Common::String("Give to ") + _vm->getName(_lastPerson), 'G', "", true);
+ _verbStr = _verbStr + kVerbCodeGive;
+ }
+ } else {
+ _activeMenuItem.setupOption("Examine", 'x', "", true);
+ _activeMenuItem.setupOption(Common::String("Talk to h") + selectGender(_vm->_thinks), 'T', "", true);
+ _verbStr = Common::String(kVerbCodeExam) + kVerbCodeTalk;
+ switch (_vm->_thinks) {
+ case kPeopleGeida:
+ case kPeopleArkata:
+ _activeMenuItem.setupOption("Kiss her", 'K', "", true);
+ _verbStr = _verbStr + kVerbCodeKiss;
+ break;
+ case kPeopleDogfood:
+ _activeMenuItem.setupOption("Play his game", 'P', "", !_vm->_wonNim); // True if you HAVEN'T won.
+ _verbStr = _verbStr + kVerbCodePlay;
+ break;
+ case kPeopleMalagauche: {
+ bool isSober = !_vm->_teetotal;
+ _activeMenuItem.setupOption("Buy some wine", 'w', "", !_vm->_objects[kObjectWine - 1]);
+ _activeMenuItem.setupOption("Buy some beer", 'b', "", isSober);
+ _activeMenuItem.setupOption("Buy some whisky", 'h', "", isSober);
+ _activeMenuItem.setupOption("Buy some cider", 'c', "", isSober);
+ _activeMenuItem.setupOption("Buy some mead", 'm', "", isSober);
+ _verbStr = _verbStr + 101 + 100 + 102 + 103 + 104;
+ }
+ break;
+ case kPeopleTrader:
+ _activeMenuItem.setupOption("Buy an onion", 'o', "", !_vm->_objects[kObjectOnion - 1]);
+ _verbStr = _verbStr + 105;
+ break;
+ }
+ }
+ _activeMenuItem.display();
+}
+
+void Menu::runMenuGame() {
+ // Help, boss, untrash screen.
+ switch (_activeMenuItem._choiceNum) {
+ case 0:
+ _vm->callVerb(kVerbCodeHelp);
+ break;
+ case 1:
+ _vm->callVerb(kVerbCodeBoss);
+ break;
+ case 2:
+ _vm->majorRedraw();
+ break;
+ case 3:
+ _vm->callVerb(kVerbCodeScore);
+ break;
+ case 4:
+ _vm->callVerb(kVerbCodeInfo);
+ break;
+ }
+}
+
+void Menu::runMenuFile() {
+ // New game, load, save, save as, DOS shell, about, quit.
+ switch (_activeMenuItem._choiceNum) {
+ case 0:
+ _vm->callVerb(kVerbCodeRestart);
+ break;
+ case 1:
+ if (!_vm->_parser->_realWords[1].empty())
+ _vm->_parser->_realWords[1].clear();
+ _vm->callVerb(kVerbCodeLoad);
+ break;
+ // Case 2 is 'Save', Case 3 is 'Save As'. Both triggers ScummVM save screen.
+ case 2:
+ case 3:
+ if (!_vm->_parser->_realWords[1].empty())
+ _vm->_parser->_realWords[1].clear();
+ _vm->callVerb(kVerbCodeSave);
+ break;
+ case 4:
+ // Command Prompt, disabled
+ break;
+ case 5:
+ _vm->callVerb(kVerbCodeQuit);
+ break;
+ }
+}
+
+void Menu::runMenuAction() {
+ // Get up, pause game, open door, look, inventory, walk/run.
+ switch (_activeMenuItem._choiceNum) {
+ case 0: {
+ _vm->_parser->_person = kPeoplePardon;
+ _vm->_parser->_thing = _vm->_parser->kPardon;
+ Common::String f5Does = _vm->f5Does();
+ VerbCode verb = (VerbCode)(byte)f5Does[0];
+ _vm->callVerb(verb);
+ }
+ break;
+ case 1:
+ _vm->_parser->_thing = _vm->_parser->kPardon;
+ _vm->callVerb(kVerbCodePause);
+ break;
+ case 2:
+ _vm->callVerb(kVerbCodeOpen);
+ break;
+ case 3:
+ _vm->_parser->_thing = _vm->_parser->kPardon;
+ _vm->callVerb(kVerbCodeLook);
+ break;
+ case 4:
+ _vm->callVerb(kVerbCodeInv);
+ break;
+ case 5: {
+ AnimationType *avvy = _vm->_animation->_sprites[0];
+ if (avvy->_speedX == kWalk)
+ avvy->_speedX = kRun;
+ else
+ avvy->_speedX = kWalk;
+ _vm->_animation->updateSpeed();
+ }
+ break;
+ }
+}
+
+void Menu::runMenuObjects() {
+ _vm->thinkAbout(_vm->_objectList[_activeMenuItem._choiceNum], AvalancheEngine::kThing);
+}
+
+void Menu::runMenuPeople() {
+ _vm->thinkAbout(people[_activeMenuItem._choiceNum], AvalancheEngine::kPerson);
+ _lastPerson = (People)people[_activeMenuItem._choiceNum];
+}
+
+void Menu::runMenuWith() {
+ _vm->_parser->_thing = _vm->_thinks;
+
+ if (_vm->_thinkThing) {
+ _vm->_parser->_thing += 49;
+
+ if (_verbStr[_activeMenuItem._choiceNum] == kVerbCodeGive)
+ _vm->_parser->_person = _lastPerson;
+ else
+ _vm->_parser->_person = kPeoplePardon;
+ } else {
+ switch (_verbStr[_activeMenuItem._choiceNum]) {
+ case 100: // Beer
+ case 102: // Whisky
+ case 103: // Cider
+ _vm->_parser->_thing = _verbStr[_activeMenuItem._choiceNum];
+ _vm->callVerb(kVerbCodeBuy);
+ return;
+ case 101: // Wine
+ _vm->_parser->_thing = 50;
+ _vm->callVerb(kVerbCodeBuy);
+ return;
+ case 104: // Mead
+ _vm->_parser->_thing = 107;
+ _vm->callVerb(kVerbCodeBuy);
+ return;
+ case 105: // Onion (trader)
+ _vm->_parser->_thing = 67;
+ _vm->callVerb(kVerbCodeBuy);
+ return;
+ default:
+ _vm->_parser->_person = (People)_vm->_parser->_thing;
+ _vm->_parser->_thing = Parser::kPardon;
+ _vm->_subjectNum = 0;
+ }
+ }
+ _vm->callVerb((VerbCode)(byte)_verbStr[_activeMenuItem._choiceNum]);
+}
+
+void Menu::setup() {
+ _menuBar.init(this);
+ _activeMenuItem.init(this);
+
+ _menuBar.createMenuItem('F', "File", '!', &Avalanche::Menu::setupMenuFile, &Avalanche::Menu::runMenuFile);
+ _menuBar.createMenuItem('G', "Game", 34, &Avalanche::Menu::setupMenuGame, &Avalanche::Menu::runMenuGame);
+ _menuBar.createMenuItem('A', "Action", 30, &Avalanche::Menu::setupMenuAction, &Avalanche::Menu::runMenuAction);
+ _menuBar.createMenuItem('O', "Objects", 24, &Avalanche::Menu::setupMenuObjects, &Avalanche::Menu::runMenuObjects);
+ _menuBar.createMenuItem('P', "People", 25, &Avalanche::Menu::setupMenuPeople, &Avalanche::Menu::runMenuPeople);
+ _menuBar.createMenuItem('W', "With", 17, &Avalanche::Menu::setupMenuWith, &Avalanche::Menu::runMenuWith);
+
+ _menuBar.draw();
+}
+
+void Menu::update() { // TODO: Optimize it ASAP!!! It really needs it...
+ _vm->_graphics->saveScreen();
+
+ Common::Point cursorPos = _vm->getMousePos();
+ while (!_activeMenuItem._activeNow && (cursorPos.y <= 21) && _vm->_holdLeftMouse) {
+ _menuBar.chooseMenuItem(cursorPos.x);
+ do
+ _vm->updateEvents();
+ while (_vm->_holdLeftMouse && !_vm->shouldQuit());
+
+ while (!_vm->shouldQuit()) {
+ do {
+ _vm->updateEvents();
+
+ // We update the cursor's picture.
+ cursorPos = _vm->getMousePos();
+ // Change arrow...
+ if ((0 <= cursorPos.y) && (cursorPos.y <= 21))
+ _vm->_graphics->loadMouse(kCurUpArrow); // Up arrow
+ else if ((22 <= cursorPos.y) && (cursorPos.y <= 339)) {
+ if ((cursorPos.x >= _activeMenuItem._flx1 * 8) && (cursorPos.x <= _activeMenuItem._flx2 * 8) && (cursorPos.y > 21) && (cursorPos.y <= _activeMenuItem._fly * 2 + 1))
+ _vm->_graphics->loadMouse(kCurRightArrow); // Right-arrow
+ else
+ _vm->_graphics->loadMouse(kCurFletch); // Fletch
+ } else if ((340 <= cursorPos.y) && (cursorPos.y <= 399))
+ _vm->_graphics->loadMouse(kCurScrewDriver); // Screwdriver
+
+ _activeMenuItem.lightUp(cursorPos);
+
+ _vm->_graphics->refreshScreen();
+ } while (!_vm->_holdLeftMouse && !_vm->shouldQuit());
+
+ if (_vm->_holdLeftMouse) {
+ if (cursorPos.y > 21) {
+ if (!((_activeMenuItem._firstlix) && ((cursorPos.x >= _activeMenuItem._flx1 * 8) && (cursorPos.x <= _activeMenuItem._flx2 * 8)
+ && (cursorPos.y >= 24) && (cursorPos.y <= (_activeMenuItem._fly * 2 + 1))))) {
+ // Clicked OUTSIDE the menu.
+ if (_activeMenuItem._activeNow) {
+ _activeMenuItem.wipe();
+ _vm->_holdLeftMouse = false;
+ _vm->_graphics->removeBackup();
+ return;
+ } // No "else"- clicking on menu has no effect (only releasing).
+ }
+ } else {
+ // Clicked on menu bar.
+ if (_activeMenuItem._activeNow) {
+ _activeMenuItem.wipe();
+ _vm->_graphics->restoreScreen();
+
+ if (((_activeMenuItem._left * 8) <= cursorPos.x) && (cursorPos.x <= (_activeMenuItem._left * 8 + 80))) { // 80: the width of one menu item on the bar in pixels.
+ // If we clicked on the same menu item (the one that is already active) on the bar...
+ _vm->_holdLeftMouse = false;
+ _vm->_graphics->removeBackup();
+ return;
+ } else {
+ _vm->_holdLeftMouse = true;
+ break;
+ }
+ }
+ }
+
+ // NOT clicked button...
+ if ((_activeMenuItem._firstlix) && ((cursorPos.x >= _activeMenuItem._flx1 * 8) && (cursorPos.x <= _activeMenuItem._flx2 * 8)
+ && (cursorPos.y >= 12) && (cursorPos.y <= (_activeMenuItem._fly * 2 + 1)))) {
+
+ // We act only if the button is released over a menu item.
+ while (!_vm->shouldQuit()) {
+ cursorPos = _vm->getMousePos();
+ _activeMenuItem.lightUp(cursorPos);
+ _vm->_graphics->refreshScreen();
+
+ _vm->updateEvents();
+ if (!_vm->_holdLeftMouse)
+ break;
+ }
+
+ uint16 which = (cursorPos.y - 26) / 20;
+ _activeMenuItem.select(which);
+ if (_activeMenuItem._options[which]._valid) { // If the menu item wasn't active, we do nothing.
+ _vm->_graphics->removeBackup();
+ return;
+ }
+ }
+ }
+ }
+ }
+
+ _vm->_graphics->removeBackup();
+}
+
+char Menu::getThingChar(byte which) {
+ static const char thingsChar[] = "WMBParCLguKeSnIohn"; // V=Vinegar
+
+ char result;
+ switch (which) {
+ case kObjectWine:
+ if (_vm->_wineState == 3)
+ result = 'V'; // Vinegar
+ else
+ result = thingsChar[which - 1];
+ break;
+ default:
+ result = thingsChar[which - 1];
+ }
+ return result;
+}
+
+byte Menu::getNameChar(People whose) {
+ static const char ladChar[] = "ASCDMTRwLfgeIyPu";
+ static const char lassChar[] = "kG\0xB1o";
+
+ if (whose <= kPeopleJacques)
+ return ladChar[whose - kPeopleAvalot];
+ else if ((whose >= kPeopleArkata) && (whose <= kPeopleWisewoman))
+ return lassChar[whose - kPeopleArkata];
+ else
+ error("getName() - Unexpected character id %d", (byte) whose);
+}
+
+Common::String Menu::getThing(byte which) {
+ static const char things[kObjectNum][20] = {
+ "Wine", "Money-bag", "Bodkin", "Potion", "Chastity belt",
+ "Crossbow bolt", "Crossbow", "Lute", "Pilgrim's badge", "Mushroom", "Key",
+ "Bell", "Scroll", "Pen", "Ink", "Clothes", "Habit", "Onion"
+ };
+
+ Common::String result;
+ switch (which) {
+ case kObjectWine:
+ switch (_vm->_wineState) {
+ case 1:
+ case 4:
+ result = Common::String(things[which - 1]);
+ break;
+ case 3:
+ result = "Vinegar";
+ break;
+ }
+ break;
+ case kObjectOnion:
+ if (_vm->_rottenOnion)
+ result = Common::String("rotten onion");
+ else
+ result = Common::String(things[which - 1]);
+ break;
+ default:
+ result = Common::String(things[which - 1]);
+ }
+ return result;
+}
+
+bool Menu::isActive() {
+ return _menuActive;
+}
+
+void Menu::init() {
+ _menuActive = false;
+}
+
+void Menu::resetVariables() {
+ _lastPerson = kPeoplePardon;
+}
+} // End of namespace Avalanche.
diff --git a/engines/avalanche/menu.h b/engines/avalanche/menu.h
new file mode 100644
index 0000000000..b7674fbb9d
--- /dev/null
+++ b/engines/avalanche/menu.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.
+ *
+ */
+
+/*
+ * This code is based on the original source code of Lord Avalot d'Argent version 1.3.
+ * Copyright (c) 1994-1995 Mike, Mark and Thomas Thurman.
+ */
+
+/* Original name: DROPDOWN A customized version of Oopmenu (qv). */
+
+#ifndef AVALANCHE_MENU_H
+#define AVALANCHE_MENU_H
+
+#include "common/str.h"
+
+namespace Avalanche {
+class AvalancheEngine;
+
+class Menu;
+
+typedef void (Menu::*MenuFunc)();
+static const Color kMenuBackgroundColor = kColorLightgray;
+static const Color kMenuBorderColor = kColorBlack;
+
+class HeadType {
+public:
+ Common::String _title;
+ char _trigger, _altTrigger;
+ byte _position;
+ int16 _xpos, _xright;
+ MenuFunc _setupFunc, _chooseFunc;
+
+ void init(char trig, char alTtrig, Common::String title, byte pos, MenuFunc setupFunc, MenuFunc chooseFunc, Menu *menu);
+ void draw();
+ void highlight();
+ bool parseAltTrigger(char key);
+
+private:
+ Menu *_menu;
+};
+
+struct OptionType {
+ Common::String _title;
+ byte _trigger;
+ Common::String _shortcut;
+ bool _valid;
+};
+
+class MenuItem {
+public:
+ OptionType _options[12];
+ uint16 _width, _left;
+ bool _firstlix;
+ int16 _flx1, _flx2, _fly;
+ bool _activeNow; // Is there an active option now?
+ byte _activeNum; // And if so, which is it?
+ byte _choiceNum; // Your choice?
+
+ void init(Menu *menu);
+ void reset();
+ void setupOption(Common::String title, char trigger, Common::String shortcut, bool valid);
+ void display();
+ void wipe();
+ void lightUp(Common::Point cursorPos);
+ void select(byte which);
+
+private:
+ byte _oldY; // used by lightUp
+ byte _optionNum;
+ byte _highlightNum;
+
+ Menu *_menu;
+
+ void displayOption(byte y, bool highlit);
+ void moveHighlight(int8 inc);
+
+ // CHECKME: Useless function?
+ void parseKey(char c);
+};
+
+class MenuBar {
+public:
+ HeadType _menuItems[8];
+ byte _menuNum;
+
+ MenuBar();
+ void init(Menu *menu);
+ void createMenuItem(char trig, Common::String title, char altTrig, MenuFunc setupFunc, MenuFunc chooseFunc);
+ void draw();
+ void chooseMenuItem(int16 x);
+
+private:
+ Menu *_menu;
+
+ void setupMenuItem(byte which);
+ // CHECKME: Useless function
+ void parseAltTrigger(char c);
+};
+
+class Menu {
+public:
+ friend class HeadType;
+ friend class MenuItem;
+ friend class MenuBar;
+
+ MenuItem _activeMenuItem;
+ MenuBar _menuBar;
+
+ Menu(AvalancheEngine *vm);
+
+ void update();
+ void setup(); // Standard menu bar.
+ bool isActive();
+ void init();
+ void resetVariables();
+
+private:
+ static const byte kIndent = 5;
+ static const byte kSpacing = 10;
+
+// Checkme: Useless constants?
+// static const Color kMenuFontColor = kColorBlack;
+// static const Color kHighlightBackgroundColor = kColorBlack;
+// static const Color kHighlightFontColor = kColorWhite;
+// static const Color kDisabledColor = kColorDarkgray;
+
+ Common::String people;
+ Common::String _verbStr; // what you can do with your object. :-)
+ bool _menuActive; // Kludge so we don't have to keep referring to the menu.
+ People _lastPerson; // Last person to have been selected using the People menu.
+
+ AvalancheEngine *_vm;
+
+ Common::String selectGender(byte x); // Returns "im" for boys, and "er" for girls.
+ void findWhatYouCanDoWithIt();
+ void drawMenuText(int16 x, int16 y, char trigger, Common::String text, bool valid, bool highlighted);
+ void bleep();
+
+ char getThingChar(byte which);
+ byte getNameChar(People whose);
+ Common::String getThing(byte which);
+
+ void setupMenuGame();
+ void setupMenuFile();
+ void setupMenuAction();
+ void setupMenuPeople();
+ void setupMenuObjects();
+ void setupMenuWith();
+
+ void runMenuGame();
+ void runMenuFile();
+ void runMenuAction();
+ void runMenuObjects();
+ void runMenuPeople();
+ void runMenuWith();
+
+ // CHECKME: Useless function?
+ void parseKey(char r, char re);
+};
+
+} // End of namespace Avalanche.
+
+#endif // AVALANCHE_MENU_H
diff --git a/engines/avalanche/module.mk b/engines/avalanche/module.mk
new file mode 100644
index 0000000000..39ca94e3f8
--- /dev/null
+++ b/engines/avalanche/module.mk
@@ -0,0 +1,28 @@
+MODULE := engines/avalanche
+
+MODULE_OBJS = \
+ animation.o \
+ avalanche.o \
+ avalot.o \
+ background.o \
+ closing.o \
+ console.o \
+ detection.o \
+ graphics.o \
+ menu.o \
+ parser.o \
+ pingo.o \
+ dialogs.o \
+ sequence.o \
+ sound.o \
+ timer.o \
+ nim.o \
+ clock.o
+
+# This module can be built as a plugin
+ifeq ($(ENABLE_AVALANCHE), DYNAMIC_PLUGIN)
+PLUGIN := 1
+endif
+
+# Include common rules
+include $(srcdir)/rules.mk
diff --git a/engines/avalanche/nim.cpp b/engines/avalanche/nim.cpp
new file mode 100644
index 0000000000..e4897a6d49
--- /dev/null
+++ b/engines/avalanche/nim.cpp
@@ -0,0 +1,575 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public 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 based on the original source code of Lord Avalot d'Argent version 1.3.
+ * Copyright (c) 1994-1995 Mike, Mark and Thomas Thurman.
+ */
+
+#include "avalanche/avalanche.h"
+#include "avalanche/nim.h"
+
+namespace Avalanche {
+
+const char * const Nim::kNames[2] = {"Avalot", "Dogfood"};
+
+Nim::Nim(AvalancheEngine *vm) {
+ _vm = vm;
+
+ resetVariables();
+}
+
+void Nim::resetVariables() {
+ _playedNim = 0;
+ _turns = 0;
+ _dogfoodsTurn = false;
+ _stonesLeft = 0;
+ _clicked = false;
+ _row = 0;
+ _number = 0;
+ _squeak = false;
+ _lmo = false;
+
+ for (int i = 0; i < 3; i++) {
+ _old[i] = 0;
+ _stones[i] = 0;
+ _inAp[i] = 0;
+ _r[i] = 0;
+ }
+}
+
+void Nim::synchronize(Common::Serializer &sz) {
+ if (sz.isLoading() && sz.getVersion() < 2)
+ return;
+
+ sz.syncAsByte(_playedNim);
+}
+
+void Nim::playNim() {
+ if (_vm->_wonNim) { // Already won the game.
+ _vm->_dialogs->displayScrollChain('Q', 6);
+ return;
+ }
+
+ if (!_vm->_askedDogfoodAboutNim) {
+ _vm->_dialogs->displayScrollChain('Q', 84);
+ return;
+ }
+
+ _vm->_dialogs->displayScrollChain('Q', 3);
+ _playedNim++;
+
+ _vm->_graphics->saveScreen();
+ _vm->fadeOut();
+
+ CursorMan.showMouse(false);
+ setup();
+ board();
+ //CursorMan.showMouse(true);
+
+ do {
+
+ startMove();
+ if (_dogfoodsTurn)
+ dogFood();
+ else {
+ CursorMan.showMouse(true);
+ takeSome();
+ CursorMan.showMouse(false);
+ }
+ _stones[_row] -= _number;
+ showChanges();
+ } while (_stonesLeft != 0);
+
+ endOfGame(); // Winning sequence is A1, B3, B1, C1, C1, btw.
+
+ _vm->fadeOut();
+ _vm->_graphics->restoreScreen();
+ _vm->_graphics->removeBackup();
+ _vm->fadeIn();
+ CursorMan.showMouse(true);
+
+ if (_dogfoodsTurn) {
+ // Dogfood won - as usual.
+ if (_playedNim == 1) // Your first game.
+ _vm->_dialogs->displayScrollChain('Q', 4); // Goody! Play me again?
+ else
+ _vm->_dialogs->displayScrollChain('Q', 5); // Oh, look at that! I've won again!
+ _vm->decreaseMoney(4); // And you've just lost 4d!
+ } else {
+ // You won - strange!
+ _vm->_dialogs->displayScrollChain('Q', 7);
+ _vm->_objects[kObjectLute - 1] = true;
+ _vm->refreshObjectList();
+ _vm->_wonNim = true;
+ _vm->_background->draw(-1, -1, 0); // Show the settle with no lute on it.
+
+ // 7 points for winning!
+ _vm->incScore(7);
+ }
+
+ if (_playedNim == 1) {
+ // 3 points for playing your 1st game.
+ _vm->incScore(3);
+ }
+}
+
+void Nim::chalk(int x, int y, Common::String text) {
+ const Color greys[] = { kColorBlack, kColorDarkgray, kColorLightgray, kColorWhite };
+
+ for (int i = 0; i < 4; i++) {
+ _vm->_graphics->drawNormalText(text, _vm->_font, 8, x - i, y, greys[i]);
+ _vm->_graphics->refreshScreen();
+ int freq = i * 100 * text.size();
+ if (freq == 0)
+ _vm->_system->delayMillis(3);
+ else
+ _vm->_sound->playNote(freq, 3);
+ _vm->_system->delayMillis(30);
+ }
+}
+
+void Nim::setup() {
+ _vm->fadeIn();
+ _vm->_graphics->nimLoad();
+
+ _vm->_graphics->drawFilledRectangle(Common::Rect(0, 0, 640, 200), kColorBlack);
+ // Upper left rectangle.
+ _vm->_graphics->drawRectangle(Common::Rect(10, 5, 381, 71), kColorRed);
+ _vm->_graphics->drawFilledRectangle(Common::Rect(11, 6, 380, 70), kColorBrown);
+ // Bottom right rectangle.
+ _vm->_graphics->drawRectangle(Common::Rect(394, 50, 635, 198), kColorRed);
+ _vm->_graphics->drawFilledRectangle(Common::Rect(395, 51, 634, 197), kColorBrown);
+
+ _vm->_graphics->nimDrawLogo();
+ _vm->_graphics->nimDrawInitials();
+
+ _vm->_graphics->drawNormalText("SCOREBOARD:", _vm->_font, 8, 475, 45, kColorWhite);
+ _vm->_graphics->drawNormalText("Turn:", _vm->_font, 8, 420, 55, kColorYellow);
+ _vm->_graphics->drawNormalText("Player:", _vm->_font, 8, 490, 55, kColorYellow);
+ _vm->_graphics->drawNormalText("Move:", _vm->_font, 8, 570, 55, kColorYellow);
+
+ chalk(27, 7, "Take pieces away with:");
+ chalk(77, 17, "1) the mouse (click leftmost)");
+ chalk(53, 27, "or 2) the keyboard:");
+ chalk(220, 27, Common::String(24) + '/' + 25 + ": choose row,");
+ chalk(164, 37, Common::String("+/- or ") + 27 + '/' + 26 + ": more/fewer,");
+ chalk(204, 47, "Enter: take stones.");
+
+ _vm->_graphics->refreshScreen();
+
+ for (int i = 0; i < 3; i++)
+ _stones[i] = i + 3;
+ _stonesLeft = 12;
+
+ _turns = 0;
+ _dogfoodsTurn = true;
+
+ _row = 0;
+ _number = 1;
+ for (int i = 0; i < 3; i++)
+ _old[i] = 0;
+}
+
+void Nim::board() {
+ _vm->_graphics->drawFilledRectangle(Common::Rect(57, 72, 393, 200), kColorBlack);
+ for (int i = 0; i < 3; i++)
+ for (int j = 0; j < _stones[i]; j++)
+ _vm->_graphics->nimDrawStone(64 + j * 8 * 8, 75 + i * 35);
+ // It's practically the body of the Pascal function "plotstone()", reimplemented.
+ // It's the only place where we use it, so there's no reason to keep it separated as a function.
+ _vm->_graphics->refreshScreen();
+}
+
+void Nim::startMove() {
+ _turns++;
+ Common::String turnsStr = Common::String::format("%d", _turns);
+ int y = 55 + _turns * 10;
+ _dogfoodsTurn = !_dogfoodsTurn;
+ chalk(433, y, turnsStr);
+ chalk(493, y, kNames[_dogfoodsTurn]);
+ for (int i = 0; i < 3; i++)
+ _old[i] = _stones[i];
+}
+
+void Nim::showChanges() {
+ chalk(573, 55 + _turns * 10, Common::String('A' + _row) + Common::String('0' + _number));
+ board();
+ _stonesLeft -= _number;
+}
+
+void Nim::blip() {
+ _vm->_sound->playNote(1771, 3);
+}
+
+void Nim::findNextUp() {
+ while (_stones[_row] == 0) {
+ _row--;
+ if (_row < 0)
+ _row = 2;
+ }
+
+ if (_number > _stones[_row])
+ _number = _stones[_row];
+}
+
+void Nim::findNextDown() {
+ while (_stones[_row] == 0) {
+ _row++;
+ if (_row > 2)
+ _row = 0;
+ }
+
+ if (_number > _stones[_row])
+ _number = _stones[_row];
+}
+
+bool Nim::checkInput() {
+ while (!_vm->shouldQuit()) {
+ _vm->_graphics->refreshScreen();
+ Common::Event event;
+ while (_vm->getEvent(event)) {
+ if (event.type == Common::EVENT_LBUTTONUP) {
+ Common::Point cursorPos = _vm->getMousePos();
+
+ int8 newRow = (cursorPos.y / 2 - 38) / 35 - 1;
+ if ((newRow < 0) || (newRow > 2)) {
+ blip();
+ return false;
+ }
+
+ int8 newNum = _stones[newRow] - ((cursorPos.x - 64) / 64);
+ if ((newNum < 1) || (newNum > _stones[newRow])) {
+ blip();
+ return false;
+ }
+
+ _number = newNum;
+ _row = newRow;
+
+ return true;
+ } else if (event.type == Common::EVENT_KEYDOWN) {
+ switch (event.kbd.keycode) {
+ case Common::KEYCODE_LEFT:
+ case Common::KEYCODE_KP_PLUS:
+ if (_stones[_row] > _number)
+ _number++;
+ return false;
+ case Common::KEYCODE_RIGHT:
+ case Common::KEYCODE_KP_MINUS:
+ if (_number > 1)
+ _number--;
+ return false;
+ case Common::KEYCODE_1:
+ _number = 1;
+ return false;
+ case Common::KEYCODE_2:
+ if (_stones[_row] >= 2)
+ _number = 2;
+ return false;
+ case Common::KEYCODE_3:
+ if (_stones[_row] >= 3)
+ _number = 3;
+ else
+ _number = _stones[_row];
+ return false;
+ case Common::KEYCODE_4:
+ if (_stones[_row] >= 4)
+ _number = 4;
+ else
+ _number = _stones[_row];
+ return false;
+ case Common::KEYCODE_5:
+ if (_stones[_row] == 5)
+ _number = 5;
+ else
+ _number = _stones[_row];
+ return false;
+ case Common::KEYCODE_HOME:
+ _number = _stones[_row];
+ return false;
+ case Common::KEYCODE_END:
+ _number = 1;
+ return false;
+ case Common::KEYCODE_UP:
+ _row--;
+ if (_row < 0)
+ _row = 2;
+ findNextUp();
+ return false;
+ case Common::KEYCODE_DOWN:
+ _row++;
+ if (_row > 2)
+ _row = 0;
+ findNextDown();
+ return false;
+ case Common::KEYCODE_a:
+ if (_stones[0] != 0) {
+ _row = 0;
+ if (_number > _stones[_row])
+ _number = _stones[_row];
+ }
+ return false;
+ case Common::KEYCODE_b:
+ if (_stones[1] != 0) {
+ _row = 1;
+ if (_number > _stones[_row])
+ _number = _stones[_row];
+ }
+ return false;
+ case Common::KEYCODE_c:
+ if (_stones[2] != 0) {
+ _row = 2;
+ if (_number > _stones[_row])
+ _number = _stones[_row];
+ }
+ return false;
+ case Common::KEYCODE_PAGEUP:
+ _row = 0;
+ findNextDown();
+ return false;
+ case Common::KEYCODE_PAGEDOWN:
+ _row = 2;
+ findNextUp();
+ return false;
+ case Common::KEYCODE_RETURN:
+ return true;
+ default:
+ break;
+ }
+ }
+ }
+ }
+ return false;
+}
+
+void Nim::takeSome() {
+ _number = 1;
+
+ do {
+ byte sr;
+ do {
+ sr = _stones[_row];
+ if (sr == 0) {
+ if (_row == 2)
+ _row = 0;
+ else
+ _row++;
+ _number = 1;
+ }
+ } while (sr == 0);
+
+ if (_number > sr)
+ _number = sr;
+
+ int x1 = 63 + (_stones[_row] - _number) * 64;
+ int y1 = 38 + 35 * (_row + 1);
+ int x2 = 54 + _stones[_row] * 64;
+ int y2 = 63 + 35 * (_row + 1);
+ _vm->_graphics->drawRectangle(Common::Rect(x1, y1, x2, y2), kColorBlue); // Draw the selection rectangle.
+ _vm->_graphics->refreshScreen();
+
+ bool confirm = false;
+ do {
+ confirm = checkInput();
+
+ if (!confirm) {
+ _vm->_graphics->drawRectangle(Common::Rect(x1, y1, x2, y2), kColorBlack); // Erase the previous selection.
+ x1 = 63 + (_stones[_row] - _number) * 64;
+ y1 = 38 + 35 * (_row + 1);
+ x2 = 54 + _stones[_row] * 64;
+ y2 = 63 + 35 * (_row + 1);
+ _vm->_graphics->drawRectangle(Common::Rect(x1, y1, x2, y2), kColorBlue); // Draw the new one.
+ _vm->_graphics->refreshScreen();
+ }
+ } while (!confirm);
+
+ return;
+
+ } while (true);
+}
+
+void Nim::endOfGame() {
+ chalk(595, 55 + _turns * 10, "Wins!");
+ _vm->_graphics->drawNormalText("- - - Press any key... - - -", _vm->_font, 8, 100, 190, kColorWhite);
+
+ Common::Event event;
+ bool escape = false;
+ while (!_vm->shouldQuit() && !escape) {
+ _vm->_graphics->refreshScreen();
+ while (_vm->getEvent(event)) {
+ if ((event.type == Common::EVENT_LBUTTONUP) || (event.type == Common::EVENT_KEYDOWN)) {
+ escape = true;
+ break;
+ }
+ }
+ }
+
+ _vm->_graphics->nimFree();
+}
+
+bool Nim::find(byte x) {
+ bool ret = false;
+ for (int i = 0; i < 3; i++) {
+ if (_stones[i] == x) {
+ ret = true;
+ _inAp[i] = true;
+ }
+ }
+ return ret;
+}
+
+void Nim::findAp(byte start, byte stepSize) {
+ byte thisOne = 0;
+ byte matches = 0;
+
+ for (int i = 0; i < 3; i++)
+ _inAp[i] = 0; // Blank 'em all!
+
+ for (int i = 0; i < 3; i++) {
+ if (find(start + i * stepSize))
+ matches++;
+ else
+ thisOne = i;
+ }
+
+ // Now... Matches must be 0, 1, 2, or 3.
+ // 0 / 1 mean there are no A.P.s here, so we'll keep looking,
+ // 2 means there is a potential A.P.that we can create (ideal!), and
+ // 3 means that we're already in an A.P. (Trouble!)
+
+ byte ooo = 0; // Odd one out.
+
+ switch (matches) {
+ case 2:
+ for (int i = 0; i < 3; i++) { // Find which one didn't fit the A.P.
+ if (!_inAp[i])
+ ooo = i;
+ }
+
+ if (_stones[ooo] > (start + thisOne * stepSize)) { // Check if it's possible!
+ // Create an A.P.
+ _row = ooo; // Already calculated.
+ // Start + thisone * stepsize will give the amount we SHOULD have here.
+ _number = _stones[_row] - (start + thisOne * stepSize);
+ _lmo = true;
+ return;
+ }
+ break;
+ case 3: // We're actually IN an A.P! Trouble! Oooh dear.
+ // Take 1 from the largest pile.
+ _row = _r[2];
+ _number = 1;
+ _lmo = true;
+ return;
+ default:
+ break;
+ }
+}
+
+void Nim::dogFood() {
+ _lmo = false;
+ byte live = 0;
+ byte sr[3];
+
+ for (int i = 0; i < 3; i++) {
+ if (_stones[i] > 0) {
+ _r[live] = i;
+ sr[live] = _stones[i];
+ live++;
+ }
+ }
+
+ switch (live) {
+ case 1: // Only one is free - so take 'em all!
+ _row = _r[0];
+ _number = _stones[_r[0]];
+ return;
+ case 2: // Two are free - make them equal!
+ if (sr[0] > sr[1]) { // T > b
+ _row = _r[0];
+ _number = sr[0] - sr[1];
+ }
+ else if (sr[0] < sr[1]) { // B > t
+ _row = _r[1];
+ _number = sr[1] - sr[0];
+ }
+ else { // B = t... oh no, we've lost!
+ _row = _r[0];
+ _number = 1;
+ }
+ return;
+ case 3: {
+ // Ho hum... this'll be difficult!
+ // There are three possible courses of action when we have 3 lines left:
+ // 1) Look for 2 equal lines, then take the odd one out.
+ // 2) Look for A.P.s, and capitalise on them.
+ // 3) Go any old where.
+ const byte other[3][2] = { { 2, 3 }, { 1, 3 }, { 1, 2 } };
+
+ for (int i = 0; i < 3; i++) { // Look for 2 equal lines.
+ if (_stones[other[i][0]] == _stones[other[i][1]]) {
+ _row = i; // This row.
+ _number = _stones[i]; // All of 'em.
+ return;
+ }
+ }
+
+ bool sorted;
+ do {
+ sorted = true;
+ for (int i = 0; i < 2; i++) {
+ if (sr[i] > sr[i + 1]) {
+ byte temp = sr[i + 1];
+ sr[i + 1] = sr[i];
+ sr[i] = temp;
+
+ temp = _r[i + 1];
+ _r[i + 1] = _r[i];
+ _r[i] = temp;
+
+ sorted = false;
+ }
+ }
+ } while (!sorted);
+
+ // Now we look for A.P.s...
+ for (int i = 1; i <= 3; i++) {
+ findAp(i, 1); // There are 3 "1"s.
+ if (_lmo)
+ return; // Cut - out.
+ }
+ findAp(1, 2); // Only "2" possible.
+ if (_lmo)
+ return;
+
+ // A.P.search must have failed - use the default move.
+ _row = _r[2];
+ _number = 1;
+ return;
+ }
+ default:
+ break;
+ }
+}
+
+} // End of namespace Avalanche
diff --git a/engines/avalanche/nim.h b/engines/avalanche/nim.h
new file mode 100644
index 0000000000..7e5f55e69f
--- /dev/null
+++ b/engines/avalanche/nim.h
@@ -0,0 +1,79 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+/*
+ * This code is based on the original source code of Lord Avalot d'Argent version 1.3.
+ * Copyright (c) 1994-1995 Mike, Mark and Thomas Thurman.
+ */
+
+#ifndef AVALANCHE_NIM_H
+#define AVALANCHE_NIM_H
+
+namespace Avalanche {
+
+class Nim {
+public:
+ Nim(AvalancheEngine *vm);
+ void resetVariables();
+ void synchronize(Common::Serializer &sz);
+ void playNim();
+
+private:
+ AvalancheEngine *_vm;
+
+ static const char * const kNames[2];
+
+ byte _old[3];
+ byte _stones[3];
+ byte _turns;
+ bool _dogfoodsTurn;
+ byte _stonesLeft;
+ bool _clicked;
+ int8 _row;
+ byte _number;
+ bool _squeak;
+ byte _playedNim; // How many times you've played Nim.
+
+ // Inner variables for dogFood(), find() and findAp().
+ bool _inAp[3];
+ bool _lmo; // Let Me Out!
+ byte _r[3];
+
+ void chalk(int x, int y, Common::String text);
+ void setup();
+ void board();
+ void startMove();
+ void showChanges();
+ void blip();
+ void findNextUp(); // Inner function for checkInput().
+ void findNextDown(); // Same as above.
+ bool checkInput(); // It returns TRUE if the player confirmed his selection of stones either by pressing RETURN or by clicking on a stone.
+ void takeSome();
+ void endOfGame();
+ bool find(byte x); // This gives TRUE if there's a pile with x stones in.
+ void findAp(byte start, byte stepSize);
+ void dogFood(); // AI procedure to play the game.
+};
+
+} // End of namespace Avalanche
+
+#endif // AVALANCHE_NIM_H
diff --git a/engines/avalanche/parser.cpp b/engines/avalanche/parser.cpp
new file mode 100644
index 0000000000..b0524a0d7e
--- /dev/null
+++ b/engines/avalanche/parser.cpp
@@ -0,0 +1,2488 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public 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 based on the original source code of Lord Avalot d'Argent version 1.3.
+ * Copyright (c) 1994-1995 Mike, Mark and Thomas Thurman.
+ */
+
+#include "avalanche/avalanche.h"
+#include "avalanche/parser.h"
+#include "avalanche/nim.h"
+
+#include "gui/saveload.h"
+
+namespace Avalanche {
+
+const char *Parser::kCopyright = "1995";
+const char *Parser::kVersionNum = "1.30";
+
+Parser::Parser(AvalancheEngine *vm) {
+ _vm = vm;
+
+ _verb = kVerbCodePardon;
+ _thing = kPardon;
+ _person = kPeopleNone;
+ _polite = false;
+ _inputTextPos = 0;
+ _quote = false;
+ _cursorState = false;
+ _weirdWord = false;
+ _wearing = kNothing;
+ _thing2 = 0;
+ _sworeNum = 0;
+ _alcoholLevel = 0;
+
+ _boughtOnion = false;
+}
+
+void Parser::init() {
+ if (!_inputText.empty())
+ _inputText.clear();
+ _inputTextPos = 0;
+
+ _weirdWord = false;
+
+ // Initailaze the vocabulary.
+ // Verbs: 1-49
+ _vocabulary[0].init(1, "EXAMINE");
+ _vocabulary[1].init(1, "READ");
+ _vocabulary[2].init(1, "XAM");
+ _vocabulary[3].init(2, "OPEN");
+ _vocabulary[4].init(2, "LEAVE");
+ _vocabulary[5].init(2, "UNLOCK");
+ _vocabulary[6].init(3, "PAUSE");
+ _vocabulary[7].init(47, "TA"); // Early to avoid Take and Talk.
+ _vocabulary[8].init(4, "TAKE");
+ _vocabulary[9].init(4, "GET");
+ _vocabulary[10].init(4, "PICK");
+ _vocabulary[11].init(5, "DROP");
+ _vocabulary[12].init(6, "INVENTORY");
+ _vocabulary[13].init(7, "TALK");
+ _vocabulary[14].init(7, "SAY");
+ _vocabulary[15].init(7, "ASK");
+ _vocabulary[16].init(8, "GIVE");
+ _vocabulary[17].init(9, "DRINK");
+ _vocabulary[18].init(9, "IMBIBE");
+ _vocabulary[19].init(9, "DRAIN");
+ _vocabulary[20].init(10, "LOAD");
+ _vocabulary[21].init(10, "RESTORE");
+ _vocabulary[22].init(11, "SAVE");
+ _vocabulary[23].init(12, "BRIBE");
+ _vocabulary[24].init(12, "PAY");
+ _vocabulary[25].init(13, "LOOK");
+ _vocabulary[26].init(14, "BREAK");
+ _vocabulary[27].init(15, "QUIT");
+ _vocabulary[28].init(15, "EXIT");
+ _vocabulary[29].init(16, "SIT");
+ _vocabulary[30].init(16, "SLEEP");
+ _vocabulary[31].init(17, "STAND");
+
+ _vocabulary[32].init(18, "GO");
+ _vocabulary[33].init(19, "INFO");
+ _vocabulary[34].init(20, "UNDRESS");
+ _vocabulary[35].init(20, "DOFF");
+ _vocabulary[36].init(21, "DRESS");
+ _vocabulary[37].init(21, "WEAR");
+ _vocabulary[38].init(21, "DON");
+ _vocabulary[39].init(22, "PLAY");
+ _vocabulary[40].init(22, "STRUM");
+ _vocabulary[41].init(23, "RING");
+ _vocabulary[42].init(24, "HELP");
+ _vocabulary[43].init(25, "KENDAL");
+ _vocabulary[44].init(26, "CAPYBARA");
+ _vocabulary[45].init(27, "BOSS");
+ _vocabulary[46].init(255, "NINET"); // block for NINETY
+ _vocabulary[47].init(28, "URINATE");
+ _vocabulary[48].init(28, "MINGITE");
+ _vocabulary[49].init(29, "NINETY");
+ _vocabulary[50].init(30, "ABRACADABRA");
+ _vocabulary[51].init(30, "PLUGH");
+ _vocabulary[52].init(30, "XYZZY");
+ _vocabulary[53].init(30, "HOCUS");
+ _vocabulary[54].init(30, "POCUS");
+ _vocabulary[55].init(30, "IZZY");
+ _vocabulary[56].init(30, "WIZZY");
+ _vocabulary[57].init(30, "PLOVER");
+ _vocabulary[58].init(30, "MELENKURION");
+ _vocabulary[59].init(30, "ZORTON");
+ _vocabulary[60].init(30, "BLERBI");
+ _vocabulary[61].init(30, "THURB");
+ _vocabulary[62].init(30, "SNOEZE");
+ _vocabulary[63].init(30, "SAMOHT");
+ _vocabulary[64].init(30, "NOSIDE");
+ _vocabulary[65].init(30, "PHUGGG");
+ _vocabulary[66].init(30, "KNERL");
+ _vocabulary[67].init(30, "MAGIC");
+ _vocabulary[68].init(30, "KLAETU");
+ _vocabulary[69].init(30, "VODEL");
+ _vocabulary[70].init(30, "BONESCROLLS");
+ _vocabulary[71].init(30, "RADOF");
+
+ _vocabulary[72].init(31, "RESTART");
+ _vocabulary[73].init(32, "SWALLOW");
+ _vocabulary[74].init(32, "EAT");
+ _vocabulary[75].init(33, "LISTEN");
+ _vocabulary[76].init(33, "HEAR");
+ _vocabulary[77].init(34, "BUY");
+ _vocabulary[78].init(34, "PURCHASE");
+ _vocabulary[79].init(34, "ORDER");
+ _vocabulary[80].init(34, "DEMAND");
+ _vocabulary[81].init(35, "ATTACK");
+ _vocabulary[82].init(35, "HIT");
+ _vocabulary[83].init(35, "KILL");
+ _vocabulary[84].init(35, "PUNCH");
+ _vocabulary[85].init(35, "KICK");
+ _vocabulary[86].init(35, "SHOOT");
+ _vocabulary[87].init(35, "FIRE");
+
+ // Passwords: 36
+ _vocabulary[88].init(36, "TIROS");
+ _vocabulary[89].init(36, "WORDY");
+ _vocabulary[90].init(36, "STACK");
+ _vocabulary[91].init(36, "SHADOW");
+ _vocabulary[92].init(36, "OWL");
+ _vocabulary[93].init(36, "ACORN");
+ _vocabulary[94].init(36, "DOMESDAY");
+ _vocabulary[95].init(36, "FLOPPY");
+ _vocabulary[96].init(36, "DIODE");
+ _vocabulary[97].init(36, "FIELD");
+ _vocabulary[98].init(36, "COWSLIP");
+ _vocabulary[99].init(36, "OSBYTE");
+ _vocabulary[100].init(36, "OSCLI");
+ _vocabulary[101].init(36, "TIMBER");
+ _vocabulary[102].init(36, "ADVAL");
+ _vocabulary[103].init(36, "NEUTRON");
+ _vocabulary[104].init(36, "POSITRON");
+ _vocabulary[105].init(36, "ELECTRON");
+ _vocabulary[106].init(36, "CIRCUIT");
+ _vocabulary[107].init(36, "AURUM");
+ _vocabulary[108].init(36, "PETRIFY");
+ _vocabulary[109].init(36, "EBBY");
+ _vocabulary[110].init(36, "CATAPULT");
+ _vocabulary[111].init(36, "GAMERS");
+ _vocabulary[112].init(36, "FUDGE");
+ _vocabulary[113].init(36, "CANDLE");
+ _vocabulary[114].init(36, "BEEB");
+ _vocabulary[115].init(36, "MICRO");
+ _vocabulary[116].init(36, "SESAME");
+ _vocabulary[117].init(36, "LORDSHIP");
+
+ _vocabulary[118].init(37, "DIR");
+ _vocabulary[119].init(37, "LS");
+ _vocabulary[120].init(38, "DIE");
+ _vocabulary[121].init(39, "SCORE");
+ _vocabulary[122].init(40, "PUT");
+ _vocabulary[123].init(40, "INSERT");
+ _vocabulary[124].init(41, "KISS");
+ _vocabulary[125].init(41, "SNOG");
+ _vocabulary[126].init(41, "CUDDLE");
+ _vocabulary[127].init(42, "CLIMB");
+ _vocabulary[128].init(42, "CLAMBER");
+ _vocabulary[129].init(43, "JUMP");
+ _vocabulary[130].init(44, "HIGHSCORES");
+ _vocabulary[131].init(44, "HISCORES");
+ _vocabulary[132].init(45, "WAKEN");
+ _vocabulary[133].init(45, "AWAKEN");
+ _vocabulary[134].init(46, "HELLO");
+ _vocabulary[135].init(46, "HI");
+ _vocabulary[136].init(46, "YO");
+ _vocabulary[137].init(47, "THANKS"); // = 47, "ta", which was defined earlier.
+
+ // Nouns - Objects: 50-100
+ _vocabulary[138].init(50, "WINE");
+ _vocabulary[139].init(50, "BOOZE");
+ _vocabulary[140].init(50, "NASTY");
+ _vocabulary[141].init(50, "VINEGAR");
+ _vocabulary[142].init(51, "MONEYBAG");
+ _vocabulary[143].init(51, "BAG");
+ _vocabulary[144].init(51, "CASH");
+ _vocabulary[145].init(51, "DOSH");
+ _vocabulary[146].init(51, "WALLET");
+ _vocabulary[147].init(52, "BODKIN");
+ _vocabulary[148].init(52, "DAGGER");
+ _vocabulary[149].init(53, "POTION");
+ _vocabulary[150].init(54, "CHASTITY");
+ _vocabulary[151].init(54, "BELT");
+ _vocabulary[152].init(55, "BOLT");
+ _vocabulary[153].init(55, "ARROW");
+ _vocabulary[154].init(55, "DART");
+ _vocabulary[155].init(56, "CROSSBOW");
+ _vocabulary[156].init(56, "BOW");
+ _vocabulary[157].init(57, "LUTE");
+ _vocabulary[158].init(58, "PILGRIM");
+ _vocabulary[159].init(58, "BADGE");
+ _vocabulary[160].init(59, "MUSHROOMS");
+ _vocabulary[161].init(59, "TOADSTOOLS");
+ _vocabulary[162].init(60, "KEY");
+ _vocabulary[163].init(61, "BELL");
+ _vocabulary[164].init(62, "PRESCRIPT");
+ _vocabulary[165].init(62, "SCROLL");
+ _vocabulary[166].init(62, "MESSAGE");
+ _vocabulary[167].init(63, "PEN");
+ _vocabulary[168].init(63, "QUILL");
+ _vocabulary[169].init(64, "INK");
+ _vocabulary[170].init(64, "INKPOT");
+ _vocabulary[171].init(65, "CLOTHES");
+ _vocabulary[172].init(66, "HABIT");
+ _vocabulary[173].init(66, "DISGUISE");
+ _vocabulary[174].init(67, "ONION");
+
+ _vocabulary[175].init(99, "PASSWORD");
+
+ // Objects from Also are placed between 101 and 131.
+ // Nouns - People - Male: 150-174
+ _vocabulary[176].init(150, "AVVY");
+ _vocabulary[177].init(150, "AVALOT");
+ _vocabulary[178].init(150, "YOURSELF");
+ _vocabulary[179].init(150, "ME");
+ _vocabulary[180].init(150, "MYSELF");
+ _vocabulary[181].init(151, "SPLUDWICK");
+ _vocabulary[182].init(151, "THOMAS");
+ _vocabulary[183].init(151, "ALCHEMIST");
+ _vocabulary[184].init(151, "CHEMIST");
+ _vocabulary[185].init(152, "CRAPULUS");
+ _vocabulary[186].init(152, "SERF");
+ _vocabulary[187].init(152, "SLAVE");
+ _vocabulary[188].init(158, "DU"); // Put in early for Baron DU Lustie to save confusion with Duck & Duke.
+ _vocabulary[189].init(152, "CRAPPY");
+ _vocabulary[190].init(153, "DUCK");
+ _vocabulary[191].init(153, "DOCTOR");
+ _vocabulary[192].init(154, "MALAGAUCHE");
+ _vocabulary[193].init(155, "FRIAR");
+ _vocabulary[194].init(155, "TUCK");
+ _vocabulary[195].init(156, "ROBIN");
+ _vocabulary[196].init(156, "HOOD");
+ _vocabulary[197].init(157, "CWYTALOT");
+ _vocabulary[198].init(157, "GUARD");
+ _vocabulary[199].init(157, "BRIDGEKEEP");
+ _vocabulary[200].init(158, "BARON");
+ _vocabulary[201].init(158, "LUSTIE");
+ _vocabulary[202].init(159, "DUKE");
+ _vocabulary[203].init(159, "GRACE");
+ _vocabulary[204].init(160, "DOGFOOD");
+ _vocabulary[205].init(160, "MINSTREL");
+ _vocabulary[206].init(161, "TRADER");
+ _vocabulary[207].init(161, "SHOPKEEPER");
+ _vocabulary[208].init(161, "STALLHOLDER");
+ _vocabulary[209].init(162, "PILGRIM");
+ _vocabulary[210].init(162, "IBYTHNETH");
+ _vocabulary[211].init(163, "ABBOT");
+ _vocabulary[212].init(163, "AYLES");
+ _vocabulary[213].init(164, "PORT");
+ _vocabulary[214].init(165, "SPURGE");
+ _vocabulary[215].init(166, "JACQUES");
+ _vocabulary[216].init(166, "SLEEPER");
+ _vocabulary[217].init(166, "RINGER");
+
+ // Nouns - People - Female: 175-199
+ _vocabulary[218].init(175, "WIFE");
+ _vocabulary[219].init(175, "ARKATA");
+ _vocabulary[220].init(176, "GEDALODAVA");
+ _vocabulary[221].init(176, "GEIDA");
+ _vocabulary[222].init(176, "PRINCESS");
+ _vocabulary[223].init(178, "WISE");
+ _vocabulary[224].init(178, "WITCH");
+
+ // Pronouns: 200-224
+ _vocabulary[225].init(200, "HIM");
+ _vocabulary[226].init(200, "MAN");
+ _vocabulary[227].init(200, "GUY");
+ _vocabulary[228].init(200, "DUDE");
+ _vocabulary[229].init(200, "CHAP");
+ _vocabulary[230].init(200, "FELLOW");
+ _vocabulary[231].init(201, "HER");
+ _vocabulary[232].init(201, "GIRL");
+ _vocabulary[233].init(201, "WOMAN");
+ _vocabulary[234].init(202, "IT");
+ _vocabulary[235].init(202, "THING");
+ _vocabulary[236].init(203, "MONK");
+ _vocabulary[237].init(204, "BARMAN");
+ _vocabulary[238].init(204, "BARTENDER");
+
+ // Prepositions: 225-249
+ _vocabulary[239].init(225, "TO");
+ _vocabulary[240].init(226, "AT");
+ _vocabulary[241].init(227, "UP");
+ _vocabulary[242].init(228, "INTO");
+ _vocabulary[243].init(228, "INSIDE");
+ _vocabulary[244].init(229, "OFF");
+ _vocabulary[245].init(230, "UP");
+ _vocabulary[246].init(231, "DOWN");
+ _vocabulary[247].init(232, "ON");
+
+ // Please: 251
+ _vocabulary[248].init(251, "PLEASE");
+
+ // About: 252
+ _vocabulary[249].init(252, "ABOUT");
+ _vocabulary[250].init(252, "CONCERNING");
+
+ // Swear words: 253
+ /* I M P O R T A N T M E S S A G E
+
+ DO *NOT* READ THE LINES BELOW IF YOU ARE OF A SENSITIVE
+ DISPOSITION. THOMAS IS *NOT* RESPONSIBLE FOR THEM.
+ GOODNESS KNOWS WHO WROTE THEM.
+ READ THEM AT YOUR OWN RISK. BETTER STILL, DON'T READ THEM.
+ WHY ARE YOU SNOOPING AROUND IN MY PROGRAM, ANYWAY? */
+ _vocabulary[251].init(253, "SHIT");
+ _vocabulary[252].init(28 , "PISS");
+ _vocabulary[253].init(28 , "PEE");
+ _vocabulary[254].init(253, "FART");
+ _vocabulary[255].init(253, "FUCK");
+ _vocabulary[256].init(253, "BALLS");
+ _vocabulary[257].init(253, "BLAST");
+ _vocabulary[258].init(253, "BUGGER");
+ _vocabulary[259].init(253, "KNICKERS");
+ _vocabulary[260].init(253, "BLOODY");
+ _vocabulary[261].init(253, "HELL");
+ _vocabulary[262].init(253, "DAMN");
+ _vocabulary[263].init(253, "SMEG");
+ // ...and other even ruder words. You didn't read them, did you? Good.
+
+ // Answer-back smart-alec words: 249
+ _vocabulary[264].init(249, "YES");
+ _vocabulary[265].init(249, "NO");
+ _vocabulary[266].init(249, "BECAUSE");
+
+ // Noise words: 255
+ _vocabulary[267].init(255, "THE");
+ _vocabulary[268].init(255, "A");
+ _vocabulary[269].init(255, "NOW");
+ _vocabulary[270].init(255, "SOME");
+ _vocabulary[271].init(255, "AND");
+ _vocabulary[272].init(255, "THAT");
+ _vocabulary[273].init(255, "POCUS");
+ _vocabulary[274].init(255, "HIS");
+ _vocabulary[275].init(255, "THIS");
+ _vocabulary[276].init(255, "SENTINEL"); // for "Ken SENT Me"
+}
+
+void Parser::handleInputText(const Common::Event &event) {
+ byte inChar = event.kbd.ascii;
+ warning("STUB: Parser::handleInputText()");
+// if (_vm->_menu->_activeMenuItem._activeNow) {
+// _vm->_menu->parseKey(inChar, _vm->_enhanced->extd);
+// } else {
+ if (_inputText.size() < 76) {
+ if ((inChar == '"') || (inChar == '`')) {
+ if (_quote)
+ inChar = '`';
+ else
+ inChar = '"';
+ _quote = !_quote; // quote - unquote
+ }
+
+ _inputText.insertChar(inChar, _inputTextPos);
+ _inputTextPos++;
+ plotText();
+ } else
+ _vm->_sound->blip();
+// }
+}
+
+void Parser::handleBackspace() {
+ if (_vm->_menu->_activeMenuItem._activeNow)
+ return;
+
+ if (_inputTextPos > 0) {
+ _inputTextPos--;
+ if ((_inputText[_inputTextPos] == '"') || (_inputText[_inputTextPos] == '`'))
+ _quote = !_quote;
+ _inputText.deleteChar(_inputTextPos);
+ plotText();
+ } else
+ _vm->_sound->blip();
+}
+
+void Parser::handleReturn() {
+ if (_vm->_menu->_activeMenuItem._activeNow)
+ tryDropdown();
+ else if (!_inputText.empty()) {
+ _inputTextBackup = _inputText;
+ parse();
+ doThat();
+ _inputText.clear();
+ wipeText();
+ }
+}
+
+void Parser::handleFunctionKey(const Common::Event &event) {
+ switch (event.kbd.keycode) {
+ case Common::KEYCODE_F1:
+ _vm->callVerb(kVerbCodeHelp);
+ break;
+ case Common::KEYCODE_F2:
+ if (event.kbd.flags & Common::KBD_CTRL) {
+ clearWords();
+ _vm->callVerb(kVerbCodeSave);
+ } else
+ _vm->_sound->toggleSound();
+ break;
+ case Common::KEYCODE_F3:
+ if (event.kbd.flags & Common::KBD_CTRL) {
+ clearWords();
+ _vm->callVerb(kVerbCodeLoad);
+ } else if (_inputText.size() < _inputTextBackup.size()) {
+ _inputText = _inputText + &(_inputTextBackup.c_str()[_inputText.size()]);
+ _inputTextPos = _inputText.size();
+ plotText();
+ }
+ break;
+ case Common::KEYCODE_F4:
+ if (event.kbd.flags & Common::KBD_ALT)
+ _vm->callVerb(kVerbCodeQuit);
+ else
+ _vm->callVerb(kVerbCodeRestart);
+ break;
+ case Common::KEYCODE_F5: {
+ _person = kPeoplePardon;
+ _thing = kPardon;
+ Common::String f5does = _vm->f5Does();
+ VerbCode verb = (VerbCode)(byte)f5does[0];
+ _vm->callVerb(verb);
+ }
+ break;
+ case Common::KEYCODE_F6:
+ _vm->callVerb(kVerbCodePause);
+ break;
+ case Common::KEYCODE_F7:
+ if (event.kbd.flags & Common::KBD_CTRL)
+ _vm->majorRedraw();
+ else
+ _vm->callVerb(kVerbCodeOpen);
+ break;
+ case Common::KEYCODE_F8:
+ _vm->callVerb(kVerbCodeLook);
+ break;
+ case Common::KEYCODE_F9:
+ _vm->callVerb(kVerbCodeScore);
+ break;
+ case Common::KEYCODE_F10:
+ if (event.kbd.flags & Common::KBD_SHIFT)
+ _vm->callVerb(kVerbCodeInfo);
+ else
+ _vm->callVerb(kVerbCodeQuit);
+ break;
+ case Common::KEYCODE_F11:
+ clearWords();
+ _vm->callVerb(kVerbCodeSave);
+ break;
+ case Common::KEYCODE_F12:
+ clearWords();
+ _vm->callVerb(kVerbCodeLoad);
+ break;
+ default:
+ break;
+ }
+}
+
+void Parser::plotText() {
+ CursorMan.showMouse(false);
+ cursorOff();
+
+ _vm->_graphics->clearTextBar();
+ _vm->_graphics->drawNormalText(_inputText, _vm->_font, 8, 24, 161, kColorWhite);
+
+ cursorOn();
+ CursorMan.showMouse(true);
+}
+
+void Parser::cursorOn() {
+ if (_cursorState == true)
+ return;
+ _vm->_graphics->drawCursor(_inputTextPos);
+ _cursorState = true;
+}
+
+void Parser::cursorOff() {
+ if (_cursorState == false)
+ return;
+ _vm->_graphics->drawCursor(_inputTextPos);
+ _cursorState = false;
+}
+
+/**
+ * Asks the parsekey proc in Dropdown if it knows it.
+ */
+void Parser::tryDropdown() {
+ // TODO: Implement at the same time with Dropdown's keyboard handling.
+ warning("STUB: Parser::tryDropdown()");
+}
+
+/**
+ * Returns the index of the first appearance of crit in src.
+ */
+int16 Parser::getPos(const Common::String &crit, const Common::String &src) {
+ if (src.contains(crit))
+ return strstr(src.c_str(),crit.c_str()) - src.c_str();
+ else
+ return -1;
+}
+
+void Parser::wipeText() {
+ CursorMan.showMouse(false);
+ cursorOff();
+
+ _vm->_graphics->clearTextBar();
+
+ _quote = true;
+ _inputTextPos = 0;
+
+ cursorOn();
+ CursorMan.showMouse(true);
+}
+
+void Parser::clearWords() {
+ for (int i = 0; i < 11; i++) {
+ if (!_realWords[i].empty())
+ _realWords[i].clear();
+ }
+}
+
+byte Parser::wordNum(Common::String word) {
+ if (word.empty())
+ return 0;
+
+ for (int32 i = kParserWordsNum - 1; i >= 0; i--) {
+ if (_vocabulary[i]._word == word)
+ return _vocabulary[i]._number;
+ }
+
+ // If not found as a whole, we look for it as a substring.
+ for (int32 i = kParserWordsNum - 1; i >= 0; i--) {
+ if (Common::String(_vocabulary[i]._word.c_str(), word.size()) == word)
+ return _vocabulary[i]._number;
+ }
+
+ return kPardon;
+}
+
+void Parser::replace(Common::String oldChars, byte newChar) {
+ int16 pos = getPos(oldChars, _thats);
+ while (pos != -1) {
+ if (newChar == 0)
+ _thats.deleteChar(pos);
+ else {
+ for (uint i = pos; i < pos + oldChars.size(); i++)
+ _thats.deleteChar(pos);
+ _thats.insertChar(newChar, pos);
+ }
+ pos = getPos(oldChars, _thats);
+ }
+}
+
+Common::String Parser::rank() {
+ static const RankType ranks[9] = {
+ {0, "Beginner"}, {10, "Novice"},
+ {20, "Improving"}, {35, "Not bad"},
+ {50, "Passable"}, {65, "Good"},
+ {80, "Experienced"}, {108, "The BEST!"},
+ {32767, "copyright'93"}
+ };
+
+ for (int i = 0; i < 8; i++) {
+ if ((_vm->_dnascore >= ranks[i]._score) && (_vm->_dnascore < ranks[i + 1]._score))
+ return Common::String(ranks[i]._title);
+ }
+ return "";
+}
+
+Common::String Parser::totalTime() {
+ uint16 h, m, s;
+
+ uint32 curTime = _vm->getTimeInSeconds() - _vm->_startTime;
+ if (_vm->_isLoaded)
+ curTime += _vm->_totalTime;
+
+ h = (uint16)(curTime / 3600);
+ s = (uint16)(curTime % 3600);
+ m = s / 60;
+ s = s % 60;
+
+ Common::String result = "You've been playing for ";
+ if (h > 0)
+ result += Common::String::format("%d hours, ", h);
+ if ((m > 0) || (h != 0))
+ result += Common::String::format("%d minutes and ", m);
+ return result + Common::String::format("%d seconds", s);
+}
+
+void Parser::cheatParse(Common::String codes) {
+ warning("STUB: Parser::cheatParse()");
+}
+
+/**
+ * Strips punctuation from word.
+ */
+void Parser::stripPunctuation(Common::String &word) {
+ const char punct[] = "~`!@#$%^&*()_+-={}[]:\"|;'\\,./<>?";
+
+ for (int i = 0; i < 32; i++) {
+ for (;;) {
+ int16 pos = getPos(Common::String(punct[i]), word);
+ if (pos == -1)
+ break;
+ word.deleteChar(pos);
+ }
+ }
+}
+
+void Parser::displayWhat(byte target, bool animate, bool &ambiguous) {
+ if (target == kPardon) {
+ ambiguous = true;
+ if (animate)
+ _vm->_dialogs->displayText("Whom?");
+ else
+ _vm->_dialogs->displayText("What?");
+ } else {
+ if (animate) {
+ Common::String tmpStr = Common::String::format("{ %s }", _vm->getName((People)target).c_str());
+ _vm->_dialogs->displayText(tmpStr);
+ } else {
+ Common::String z = _vm->getItem(target);
+ if (z != "") {
+ Common::String tmpStr = Common::String::format("{ %s }", z.c_str());
+ _vm->_dialogs->displayText(tmpStr);
+ }
+ }
+ }
+}
+
+bool Parser::doPronouns() {
+ bool ambiguous = false;
+
+ for (uint i = 0; i < _thats.size(); i++) {
+ byte wordCode = _thats[i];
+ switch (wordCode) {
+ case 200:
+ displayWhat(_vm->_him, true, ambiguous);
+ _thats.setChar(_vm->_him, i);
+ break;
+ case 201:
+ displayWhat(_vm->_her, true, ambiguous);
+ _thats.setChar(_vm->_her, i);
+ break;
+ case 202:
+ displayWhat(_vm->_it, false, ambiguous);
+ _thats.setChar(_vm->_it, i);
+ break;
+ }
+ }
+
+ return ambiguous;
+}
+
+void Parser::properNouns() {
+ _inputText.toLowercase();
+
+ // We set every word's first character to uppercase.
+ for (uint i = 1; i < (_inputText.size() - 1); i++) {
+ if (_inputText[i] == ' ')
+ _inputText.setChar(toupper(_inputText[i + 1]), i + 1);
+ }
+
+ // And the first character as well.
+ _inputText.setChar(toupper(_inputText[0]), 0);
+}
+
+void Parser::storeInterrogation(byte interrogation) {
+ if (_inputText.empty())
+ return;
+
+ // Strip _inputText:
+ while ((_inputText[0] == ' ') && (!_inputText.empty()))
+ _inputText.deleteChar(0);
+ while ((_inputText.lastChar() == ' ') && (!_inputText.empty()))
+ _inputText.deleteLastChar();
+
+ _vm->_timer->loseTimer(Timer::kReasonCardiffsurvey); // If you want to use any other timer, put this into the case statement.
+
+ switch (interrogation) {
+ case 1:
+ _inputText.toLowercase();
+ _vm->_dialogs->sayIt(_inputText);
+ _vm->_favoriteDrink = _inputText;
+ _vm->_cardiffQuestionNum = 2;
+ break;
+ case 2:
+ properNouns();
+ _vm->_dialogs->sayIt(_inputText);
+ _vm->_favoriteSong = _inputText;
+ _vm->_cardiffQuestionNum = 3;
+ break;
+ case 3:
+ properNouns();
+ _vm->_dialogs->sayIt(_inputText);
+ _vm->_worstPlaceOnEarth = _inputText;
+ _vm->_cardiffQuestionNum = 4;
+ break;
+ case 4:
+ _inputText.toLowercase();
+ _vm->_dialogs->sayIt(_inputText);
+ if (!_vm->_spareEvening.empty())
+ _vm->_spareEvening.clear();
+ _vm->_spareEvening = _inputText;
+ _vm->_dialogs->displayScrollChain('Z', 5); // His closing statement...
+ _vm->_animation->_sprites[1]->walkTo(3); // The end of the drawbridge
+ _vm->_animation->_sprites[1]->_vanishIfStill = true; // Then go away!
+ _vm->_magics[1]._operation = kMagicNothing;
+ _vm->_cardiffQuestionNum = 5;
+ break;
+ case 99:
+ //store_high(_inputText);
+ warning("STUB: Parser::store_interrogation()");
+ break;
+ }
+
+ if (interrogation < 4)
+ _vm->_timer->cardiffSurvey();
+}
+
+void Parser::parse() {
+ // First parsing - word identification
+ if (!_thats.empty())
+ _thats.clear();
+
+ _polite = false;
+ _verb = kVerbCodePardon;
+ _thing = kPardon;
+ _thing2 = kPardon;
+ _person = kPeoplePardon;
+ clearWords();
+
+ // A cheat mode attempt.
+ if (_inputText[0] == '.') {
+ cheatParse(_inputText);
+ _thats = kNothing;
+ return;
+ }
+
+ // Are we being interrogated right now?
+ if (_vm->_interrogation > 0) {
+ storeInterrogation(_vm->_interrogation);
+ _weirdWord = true;
+ return;
+ }
+
+ // Actually process the command.
+ Common::String inputText = _inputText + ' ';
+ Common::String inputTextUpper = inputText;
+ byte n = 0;
+ inputTextUpper.toUppercase();
+ while (!inputTextUpper.empty()) {
+ while ((!inputTextUpper.empty()) && (inputTextUpper[0] == ' ')) {
+ inputTextUpper.deleteChar(0);
+ inputText.deleteChar(0);
+ }
+ if (inputTextUpper.empty())
+ break;
+
+ // Get the following word of the strings.
+ byte size = getPos(Common::String(' '), inputTextUpper) + 1;
+ char *subStr = new char[size];
+ Common::strlcpy(subStr, inputTextUpper.c_str(), size);
+ Common::String thisword = subStr;
+ Common::strlcpy(subStr, inputText.c_str(), size);
+ _realWords[n] = subStr;
+ delete[] subStr;
+
+ stripPunctuation(inputTextUpper);
+
+ bool notfound = true;
+
+ // Check also[] first, which contains words about the actual room.
+ if (!thisword.empty()) {
+ for (int i = 0; i < 31; i++) {
+ if ((_vm->_also[i][0]) && (getPos(',' + thisword, *_vm->_also[i][0]) > -1)) {
+ _thats += Common::String(99 + i);
+ notfound = false;
+ }
+ }
+ }
+
+ // Check Accis's own table (words[]) for "global" commands.
+ if (notfound) {
+ byte answer = wordNum(thisword);
+ if (answer == kPardon) {
+ notfound = true;
+ _thats = _thats + kPardon;
+ } else
+ _thats = _thats + answer;
+ n++;
+ }
+
+ // Delete words we already processed.
+ int16 spacePos = getPos(Common::String(' '), inputTextUpper);
+ if (spacePos > -1) {
+ for (int i = 0; i <= spacePos; i++)
+ inputTextUpper.deleteChar(0);
+ }
+
+ spacePos = getPos(Common::String(' '), inputText);
+ if (spacePos > -1) {
+ for (int i = 0; i <= spacePos; i++)
+ inputText.deleteChar(0);
+ }
+ }
+
+ Common::String unkString;
+ int16 pos = getPos(Common::String('\xFE'), _thats);
+ if (pos > -1)
+ unkString = _realWords[pos];
+ else
+ unkString.clear();
+
+ // Replace words' codes that mean the same.
+ replace(Common::String("\xFF"), 0); // zap noise words
+ replace(Common::String("\xD\xE2"), 1); // "look at" = "examine"
+ replace(Common::String("\xD\xE4"), 1); // "look in" = "examine"
+ replace(Common::String("\x4\xE6"), 17); // "get up" = "stand"
+ replace(Common::String("\x4\xE7"), 17); // "get down" = "stand"... well, why not?
+ replace(Common::String("\x12\xE4"), 2); // "go in" = "open [door]"
+ replace(Common::String("\x1C\xE5"), 253); // "P' off" is a swear word
+ replace(Common::String("\x4\x6"), 6); // "Take inventory" (remember Colossal Adventure?)
+ replace(Common::String("\x28\xE8"), 21); // "put on" = "don"
+ replace(Common::String("\x4\xE5"), 20); // "take off" = "doff"
+
+ // Words that could mean more than one _person
+ if (_vm->_room == kRoomNottsPub)
+ replace(Common::String('\xCC'), 164); // Barman = Port
+ else
+ replace(Common::String('\xCC'), 154); // Barman = Malagauche
+
+ switch (_vm->_room) {
+ case kRoomAylesOffice:
+ replace(Common::String('\xCB'), 163); // Monk = Ayles
+ break;
+ case kRoomMusicRoom:
+ replace(Common::String('\xCB'), 166); // Monk = Jacques
+ break;
+ default:
+ replace(Common::String('\xCB'), 162); // Monk = Ibythneth
+ }
+
+ if (doPronouns()) {
+ _weirdWord = true;
+ _thats = kNothing;
+ return;
+ }
+
+ // Second parsing.
+ _vm->_subjectNum = 0; // Find subject of conversation.
+
+ for (int i = 0; (i < 11) && !_realWords[i].empty(); i++) {
+ if ((_realWords[i][0] == '\'') || (_realWords[i][0] == '\"')) {
+ _vm->_subjectNum = (byte)_thats[i];
+ _thats.setChar(kMoved, i);
+ break;
+ }
+ }
+
+ if ((_vm->_subjectNum == 0) && !_thats.empty()) { // Still not found.
+ for (uint16 i = 0; i < _thats.size() - 1; i++) {
+ if ((byte)_thats[i] == 252) { // The word is "about", or something similar.
+ _vm->_subjectNum = (byte)_thats[i + 1];
+ _thats.setChar(0, i + 1);
+ break;
+ }
+ }
+ }
+
+ if ((_vm->_subjectNum == 0) && !_thats.empty()) { // STILL not found! Must be the word after "say".
+ for (uint16 i = 0; i < _thats.size() - 1; i++) {
+ if (((byte)_thats[i] == 7) && ((byte)_thats[i + 1] != 0) && !((225 <= (byte)_thats[i + 1]) && ((byte)_thats[i + 1] <= 229))) {
+ // SAY not followed by a preposition
+ _vm->_subjectNum = (byte)_thats[i + 1];
+ _thats.setChar(0, i + 1);
+ break;
+ }
+ }
+ }
+
+ for (int16 i = _thats.size() - 1; i >= 0; i--) { // Reverse order, so first will be used.
+ byte curChar = (byte)_thats[i];
+ if ((curChar == 253) || (curChar == 249) || ((1 <= curChar) && (curChar <= 49)))
+ _verb = (VerbCode)curChar;
+ else if ((50 <= curChar) && (curChar <= 149)) {
+ _thing2 = _thing;
+ _thing = curChar;
+ } else if ((150 <= curChar) && (curChar <= 199))
+ _person = (People)curChar;
+ else if (curChar == 251)
+ _polite = true;
+ }
+
+ if ((!unkString.empty()) && (_verb != kVerbCodeExam) && (_verb != kVerbCodeTalk) &&
+ (_verb != kVerbCodeSave) && (_verb != kVerbCodeLoad) && (_verb != kVerbCodeDir)) {
+ Common::String tmpStr = Common::String::format("Sorry, but I have no idea what \"%s\" means. Can you rephrase it?", unkString.c_str());
+ _vm->_dialogs->displayText(tmpStr);
+ _weirdWord = true;
+ } else
+ _weirdWord = false;
+
+ if (_thats.empty())
+ _thats = kNothing;
+
+ if (_thing != kPardon)
+ _vm->_it = _thing;
+
+ if (_person != kPardon) {
+ if (_person < kPeopleArkata)
+ _vm->_him = _person;
+ else
+ _vm->_her = _person;
+ }
+}
+
+/**
+ * Examine a standard object-thing
+ */
+void Parser::examineObject() {
+ if (_thing != _vm->_thinks)
+ _vm->thinkAbout(_thing, AvalancheEngine::kThing);
+ switch (_thing) {
+ case kObjectWine :
+ // 4 is perfect wine. 0 is not holding the wine.
+ switch (_vm->_wineState) {
+ case 1:
+ // Normal examine wine scroll
+ _vm->_dialogs->displayScrollChain('T', 1);
+ break;
+ case 2:
+ // Bad wine
+ _vm->_dialogs->displayScrollChain('D', 6);
+ break;
+ case 3:
+ // Vinegar
+ _vm->_dialogs->displayScrollChain('D', 7);
+ break;
+ }
+ break;
+ case kObjectOnion:
+ if (_vm->_rottenOnion)
+ // Yucky onion
+ _vm->_dialogs->displayScrollChain('Q', 21);
+ else
+ // Normal onion
+ _vm->_dialogs->displayScrollChain('T', 18);
+ break;
+ default:
+ // Ordinarily
+ _vm->_dialogs->displayScrollChain('T', _thing);
+ }
+}
+
+bool Parser::isPersonHere() {
+ // Person equivalent of "isHolding".
+ if ((_person == kPeoplePardon) || (_person == kPeopleNone) || (_vm->getRoom(_person) == _vm->_room))
+ return true;
+ else {
+ Common::String tmpStr;
+ if (_person < kPeopleArkata)
+ tmpStr = "He isn't around at the moment.";
+ else
+ tmpStr = "She isn't around at the moment.";
+ _vm->_dialogs->displayText(tmpStr);
+ return false;
+ }
+}
+
+void Parser::exampers() {
+ if (isPersonHere()) {
+ if (_thing != _vm->_thinks)
+ _vm->thinkAbout(_person, AvalancheEngine::kPerson);
+
+ byte newPerson = _person - 149;
+
+ if ((_person == kPeopleDogfood) && _vm->_wonNim)
+ // "I'm Not Playing!"
+ _vm->_dialogs->displayScrollChain('Q', 8);
+ else if ((_person == kPeopleDuLustie) && _vm->_lustieIsAsleep)
+ // He's asleep.
+ _vm->_dialogs->displayScrollChain('Q', 65);
+ else
+ _vm->_dialogs->displayScrollChain('P', newPerson);
+
+ if ((_person == kPeopleAyles) && !_vm->_aylesIsAwake)
+ _vm->_dialogs->displayScrollChain('Q', 13);
+
+ // CHECKME: Present in the original, but it doesn't make sense.
+ // _person = newPerson;
+ }
+}
+
+/**
+ * Return whether Avvy is holding an object or not
+ * @remarks Originally called 'holding'
+ */
+bool Parser::isHolding() {
+ // Also object
+ if ((51 <= _thing) && (_thing <= 99))
+ return true;
+ if (_thing == 0)
+ return false;
+
+ bool holdingResult = false;
+
+ if (_thing >= 100)
+ _vm->_dialogs->displayText("Be reasonable!");
+ else if (_thing <= kObjectNum) {
+ if (!_vm->_objects[_thing - 1])
+ // Verbs that need "_thing" to be in the inventory.
+ _vm->_dialogs->displayText("You're not holding it, Avvy.");
+ else
+ holdingResult = true;
+ } else
+ holdingResult = true;
+
+ return holdingResult;
+}
+
+void Parser::openBox(bool isOpening) {
+ if ((_vm->_room == kRoomYours) && (_thing == 54)) {
+ _vm->_background->draw(-1, -1, 4);
+
+ _vm->_background->update();
+ _vm->_animation->animLink();
+ _vm->_graphics->refreshScreen();
+
+ _vm->_system->delayMillis(55);
+
+ if (!isOpening) {
+ _vm->_background->draw(-1, -1, 5);
+ _vm->_background->update();
+ _vm->_animation->animLink();
+ _vm->_graphics->refreshScreen();
+ }
+ }
+}
+
+void Parser::examine() {
+ // EITHER it's an object OR it's an Also OR it's a _person OR it's something else.
+ if ((_person == kPeoplePardon) && (_thing != kPardon)) {
+ if (isHolding()) {
+ // Remember: it's been slipped! Ie subtract 49.
+ if ((1 <= _thing) && (_thing <= 49))
+ // Standard object
+ examineObject();
+ else if ((50 <= _thing) && (_thing <= 100)) {
+ // Also _thing
+ int id = _thing - 50;
+ assert(id < 31);
+ openBox(true);
+ _vm->_dialogs->displayText(*_vm->_also[id][1]);
+ openBox(false);
+ }
+ }
+ } else if (_person != kPardon)
+ exampers();
+ else
+ // Don't know: guess.
+ _vm->_dialogs->displayText("It's just as it looks on the picture.");
+}
+
+void Parser::inventory() {
+ byte itemNum = 0;
+ Common::String tmpStr = Common::String("You're carrying ");
+
+ for (int i = 0; i < kObjectNum; i++) {
+ if (_vm->_objects[i]) {
+ itemNum++;
+ if (itemNum == _vm->_carryNum)
+ tmpStr += "and ";
+
+ tmpStr += _vm->getItem(i + 1);
+
+ if ((i + 1) == _wearing)
+ tmpStr += ", which you're wearing";
+
+ if (itemNum < _vm->_carryNum)
+ tmpStr += ", ";
+ }
+ }
+
+ if (_wearing == kNothing)
+ tmpStr += Common::String::format("...%c%c...and you're stark naked!", kControlNewLine, kControlNewLine);
+ else
+ tmpStr += '.';
+
+ _vm->_dialogs->displayText(tmpStr);
+}
+
+/**
+ * Eat something.
+ */
+void Parser::swallow() {
+ switch (_thing) {
+ case kObjectWine:
+ // _wineState == 4 for perfect wine
+ switch (_vm->_wineState) {
+ case 1:
+ if (_vm->_teetotal) {
+ _vm->_dialogs->displayScrollChain('D', 6);
+ return;
+ }
+ _vm->_dialogs->displayScrollChain('U', 1);
+ _vm->_animation->wobble();
+ _vm->_dialogs->displayScrollChain('U', 2);
+ _vm->_objects[kObjectWine - 1] = false;
+ _vm->refreshObjectList();
+ drink();
+ break;
+ case 2:
+ case 3:
+ // You can't drink it!
+ _vm->_dialogs->displayScrollChain('D', 8);
+ break;
+ }
+ break;
+ case kObjectPotion:
+ _vm->_graphics->setBackgroundColor(kColorRed);
+ _vm->_dialogs->displayScrollChain('U', 3);
+ _vm->gameOver();
+ _vm->_graphics->setBackgroundColor(kColorBlack);
+ break;
+ case kObjectInk:
+ _vm->_dialogs->displayScrollChain('U', 4);
+ break;
+ case kObjectChastity:
+ _vm->_dialogs->displayScrollChain('U', 5);
+ break;
+ case kObjectMushroom:
+ _vm->_dialogs->displayScrollChain('U', 6);
+ _vm->gameOver();
+ break;
+ case kObjectOnion:
+ if (_vm->_rottenOnion)
+ _vm->_dialogs->displayScrollChain('U', 11);
+ else {
+ _vm->_dialogs->displayScrollChain('U', 8);
+ _vm->_objects[kObjectOnion - 1] = false;
+ _vm->refreshObjectList();
+ }
+ break;
+ default:
+ if ((_vm->_room == kRoomArgentPub) || (_vm->_room == kRoomNottsPub))
+ _vm->_dialogs->displayText("Try BUYing things before you drink them!");
+ else
+ _vm->_dialogs->displayText("The taste of it makes you retch!");
+ }
+}
+
+/**
+ * this lists the other people in the room.
+ */
+void Parser::peopleInRoom() {
+ // First compute the number of people in the room.
+ byte numPeople = 0;
+ for (int i = 151; i < 179; i++) { // Start at 1 so we don't list Avvy himself!
+ if (_vm->getRoom((People)i) == _vm->_room)
+ numPeople++;
+ }
+
+ // If nobody's here, we can cut out straight away.
+ if (numPeople == 0)
+ return;
+
+ Common::String tmpStr;
+ byte actPerson = 0;
+ for (int i = 151; i < 179; i++) {
+ if (_vm->getRoom((People)i) == _vm->_room) {
+ actPerson++;
+ if (actPerson == 1)
+ // Display first name on the list.
+ tmpStr = _vm->getName((People)i);
+ else if (actPerson < numPeople)
+ // Display one the names in the middle of the list
+ tmpStr += ", " + _vm->getName((People)i);
+ else
+ // Display the last name of the list
+ tmpStr += " and " + _vm->getName((People)i);
+ }
+ }
+
+ if (numPeople == 1)
+ tmpStr += " is";
+ else
+ tmpStr += " are";
+
+ _vm->_dialogs->displayText(tmpStr + " here.");
+}
+
+/**
+ * This is called when you say "look".
+ */
+void Parser::lookAround() {
+ _vm->_dialogs->displayText(*_vm->_also[0][1]);
+ switch (_vm->_room) {
+ case kRoomSpludwicks:
+ if (_vm->_avariciusTalk > 0)
+ _vm->_dialogs->displayScrollChain('Q', 23);
+ else
+ peopleInRoom();
+ break;
+ case kRoomRobins:
+ if (_vm->_tiedUp)
+ _vm->_dialogs->displayScrollChain('Q', 38);
+ if (_vm->_mushroomGrowing)
+ _vm->_dialogs->displayScrollChain('Q', 55);
+ break;
+ case kRoomInsideCardiffCastle:
+ if (!_vm->_takenPen)
+ _vm->_dialogs->displayScrollChain('Q', 49);
+ break;
+ case kRoomLustiesRoom:
+ if (_vm->_lustieIsAsleep)
+ _vm->_dialogs->displayScrollChain('Q', 65);
+ break;
+ case kRoomCatacombs:
+ switch (_vm->_catacombY * 256 + _vm->_catacombX) {
+ case 258 :
+ // Inside art gallery.
+ _vm->_dialogs->displayScrollChain('Q', 80);
+ break;
+ case 514 :
+ // Outside ditto.
+ _vm->_dialogs->displayScrollChain('Q', 81);
+ break;
+ case 260 :
+ // Outside Geida's room.
+ _vm->_dialogs->displayScrollChain('Q', 82);
+ break;
+ }
+ break;
+ default:
+ peopleInRoom();
+ }
+}
+
+void Parser::openDoor() {
+ // Special cases.
+ switch (_vm->_room) {
+ case kRoomYours:
+ if (_vm->_animation->inField(1)) {
+ // Opening the box.
+ _thing = 54; // The box.
+ _person = kPeoplePardon;
+ examine();
+ return;
+ }
+ break;
+ case kRoomSpludwicks:
+ if (_thing == 61) {
+ _vm->_dialogs->displayScrollChain('Q', 85);
+ return;
+ }
+ break;
+ default:
+ break;
+ }
+
+ if ((!_vm->_userMovesAvvy) && (_vm->_room != kRoomLusties))
+ // No doors can open if you can't move Avvy.
+ return;
+
+ for (int i = 0; i < 7; i++) {
+ if (_vm->_animation->inField(i + 8)) {
+ MagicType *portal = &_vm->_portals[i];
+ switch (portal->_operation) {
+ case kMagicExclaim:
+ _vm->_animation->_sprites[0]->bounce();
+ _vm->_dialogs->displayScrollChain('X', portal->_data);
+ break;
+ case kMagicTransport:
+ _vm->flipRoom((Room)((portal->_data) >> 8), portal->_data & 0x0F);
+ break;
+ case kMagicUnfinished:
+ _vm->_animation->_sprites[0]->bounce();
+ _vm->_dialogs->displayText("Sorry. This place is not available yet!");
+ break;
+ case kMagicSpecial:
+ _vm->_animation->callSpecial(portal->_data);
+ break;
+ case kMagicOpenDoor:
+ _vm->openDoor((Room)(portal->_data >> 8), portal->_data & 0x0F, i + 9);
+ break;
+ }
+
+ return;
+ }
+ }
+
+ if (_vm->_room == kRoomMap)
+ _vm->_dialogs->displayText("Avvy, you can complete the whole game without ever going " \
+ "to anywhere other than Argent, Birmingham, Cardiff, Nottingham and Norwich.");
+ else
+ _vm->_dialogs->displayText("Door? What door?");
+}
+
+/**
+ * Called when you call kVerbCodeput.
+ */
+void Parser::putProc() {
+ if (!isHolding())
+ return;
+
+ // Slip the second object.
+ _thing2 -= 49;
+ char temp = _thing;
+ _thing = _thing2;
+ if (!isHolding())
+ return;
+ _thing = temp;
+
+ // Thing is the _thing which you're putting in. _thing2 is where you're putting it.
+ switch (_thing2) {
+ case kObjectWine:
+ if (_thing == kObjectOnion) {
+ if (_vm->_rottenOnion)
+ _vm->_dialogs->displayText("That's a bit like shutting the stable door after the horse has bolted!");
+ else {
+ // Put onion into wine?
+ if (_vm->_wineState != 3) {
+ Common::String tmpStr = Common::String::format("%cOignon au vin%c is a bit too strong for your tastes!",
+ kControlItalic, kControlRoman);
+ _vm->_dialogs->displayText(tmpStr);
+ } else {
+ // Put onion into vinegar! Yes!
+ _vm->_onionInVinegar = true;
+ _vm->incScore(7);
+ _vm->_dialogs->displayScrollChain('U', 9);
+ }
+ }
+ } else
+ _vm->_dialogs->saySilly();
+ break;
+
+ case 54:
+ if (_vm->_room == kRoomYours) {
+ // Put something into the box.
+ if (_vm->_boxContent != kNothing)
+ _vm->_dialogs->displayText("There's something in the box already, Avvy. Try taking that out first.");
+ else {
+ switch (_thing) {
+ case kObjectMoney:
+ _vm->_dialogs->displayText("You'd better keep some ready cash on you!");
+ break;
+ case kObjectBell:
+ _vm->_dialogs->displayText("That's a silly place to keep a bell.");
+ break;
+ case kObjectBodkin:
+ _vm->_dialogs->displayText("But you might need it!");
+ break;
+ case kObjectOnion:
+ _vm->_dialogs->displayText("Just give it to Spludwick, Avvy!");
+ break;
+ default:
+ // Put the object into the box...
+ if (_wearing == _thing) {
+ Common::String tmpStr = Common::String::format("You'd better take %s off first!", _vm->getItem(_thing).c_str());
+ _vm->_dialogs->displayText(tmpStr);
+ } else {
+ // Open box.
+ openBox(true);
+
+ _vm->_boxContent = _thing;
+ _vm->_objects[_thing - 1] = false;
+ _vm->refreshObjectList();
+ _vm->_dialogs->displayText("OK, it's in the box.");
+
+ // Shut box.
+ openBox(false);
+ }
+ }
+ }
+ } else
+ _vm->_dialogs->saySilly();
+ break;
+
+ default:
+ _vm->_dialogs->saySilly();
+ }
+}
+
+/**
+ * Display text when ingredients are not in the right order
+ * @remarks Originally called 'not_in_order'
+ */
+void Parser::notInOrder() {
+ Common::String itemStr = _vm->getItem(_vm->kSpludwicksOrder[_vm->_givenToSpludwick]);
+ Common::String tmpStr = Common::String::format("Sorry, I need the ingredients in the right order for this potion. " \
+ "What I need next is %s%c2%c", itemStr.c_str(), kControlRegister, kControlSpeechBubble);
+ _vm->_dialogs->displayText(tmpStr);
+}
+
+/**
+ * Move Spludwick to cauldron
+ * @remarks Originally called 'go_to_cauldron'
+ */
+void Parser::goToCauldron() {
+ // Stops Geida_Procs.
+ _vm->_animation->_sprites[1]->_callEachStepFl = false;
+ _vm->_timer->addTimer(1, Timer::kProcSpludwickGoesToCauldron, Timer::kReasonSpludwickWalk);
+ _vm->_animation->_sprites[1]->walkTo(1);
+}
+
+/**
+ * Check is it's possible to give something to Spludwick
+ * The result of this function is whether or not he says "Hey, thanks!".
+ * @remarks Originally called 'give2spludwick'
+ */
+bool Parser::giveToSpludwick() {
+ if (_vm->kSpludwicksOrder[_vm->_givenToSpludwick] != _thing) {
+ notInOrder();
+ return false;
+ }
+
+ switch (_thing) {
+ case kObjectOnion:
+ _vm->_objects[kObjectOnion - 1] = false;
+ if (_vm->_rottenOnion)
+ _vm->_dialogs->displayScrollChain('Q', 22);
+ else {
+ _vm->_givenToSpludwick++;
+ _vm->_dialogs->displayScrollChain('Q', 20);
+ goToCauldron();
+ _vm->incScore(3);
+ }
+ _vm->refreshObjectList();
+ break;
+ case kObjectInk:
+ _vm->_objects[kObjectInk - 1] = false;
+ _vm->refreshObjectList();
+ _vm->_givenToSpludwick++;
+ _vm->_dialogs->displayScrollChain('Q', 24);
+ goToCauldron();
+ _vm->incScore(3);
+ break;
+ case kObjectMushroom:
+ _vm->_objects[kObjectMushroom - 1] = false;
+ _vm->_dialogs->displayScrollChain('Q', 25);
+ _vm->incScore(5);
+ _vm->_givenToSpludwick++;
+ goToCauldron();
+ _vm->_objects[kObjectPotion - 1] = true;
+ _vm->refreshObjectList();
+ break;
+ default:
+ return true;
+ }
+ return false;
+}
+
+void Parser::drink() {
+ _alcoholLevel++;
+ if (_alcoholLevel == 5) {
+ // Get the key.
+ _vm->_objects[kObjectKey - 1] = true;
+ _vm->_teetotal = true;
+ _vm->_avvyIsAwake = false;
+ _vm->_avvyInBed = true;
+ _vm->refreshObjectList();
+ _vm->fadeOut();
+ _vm->flipRoom(kRoomYours, 1);
+ _vm->_graphics->setBackgroundColor(kColorYellow);
+ _vm->_animation->_sprites[0]->_visible = false;
+ }
+}
+
+void Parser::cardiffClimbing() {
+ if (_vm->_standingOnDais) {
+ // Clamber up.
+ _vm->_dialogs->displayText("You climb down, back onto the floor.");
+ _vm->_standingOnDais = false;
+ _vm->_animation->appearPed(0, 2);
+ } else if (_vm->_animation->inField(0)) {
+ // Clamber down
+ _vm->_dialogs->displayText("You clamber up onto the dais.");
+ _vm->_standingOnDais = true;
+ _vm->_animation->appearPed(0, 1);
+ } else
+ _vm->_dialogs->displayText("Get a bit closer, Avvy.");
+}
+
+void Parser::already() {
+ _vm->_dialogs->displayText("You're already standing!");
+}
+
+/**
+ * Called when you ask Avvy to stand.
+ */
+void Parser::standUp() {
+ switch (_vm->_room) {
+ case kRoomYours:
+ // Avvy isn't asleep.
+ if (_vm->_avvyIsAwake && _vm->_avvyInBed) {
+ // But he's in bed.
+ if (_vm->_teetotal) {
+ _vm->_dialogs->displayScrollChain('D', 12);
+ _vm->_graphics->setBackgroundColor(kColorBlack);
+ _vm->_dialogs->displayScrollChain('D', 14);
+ }
+ _vm->_animation->_sprites[0]->_visible = true;
+ _vm->_userMovesAvvy = true;
+ _vm->_animation->appearPed(0, 1);
+ _vm->_animation->setDirection(kDirLeft);
+ // Display a picture of empty pillow in the background.
+ _vm->_background->draw(-1, -1, 3);
+ _vm->incScore(1);
+ _vm->_avvyInBed = false;
+ _vm->_timer->loseTimer(Timer::kReasonArkataShouts);
+ } else
+ already();
+ break;
+
+ case kRoomInsideCardiffCastle:
+ cardiffClimbing();
+ break;
+
+ case kRoomNottsPub:
+ if (_vm->_sittingInPub) {
+ // Not sitting down.
+ _vm->_background->draw(-1, -1, 3);
+ // But standing up.
+ _vm->_animation->_sprites[0]->_visible = true;
+ // And walking away.
+ _vm->_animation->appearPed(0, 3);
+ // Really not sitting down.
+ _vm->_sittingInPub = false;
+ // And ambulant.
+ _vm->_userMovesAvvy = true;
+ } else
+ already();
+ break;
+ default:
+ already();
+ }
+}
+
+void Parser::getProc(char thing) {
+ switch (_vm->_room) {
+ case kRoomYours:
+ if (_vm->_animation->inField(1)) {
+ if (_vm->_boxContent == thing) {
+ _vm->_background->draw(-1, -1, 4);
+ _vm->_dialogs->displayText("OK, I've got it.");
+ _vm->_objects[thing - 1] = true;
+ _vm->refreshObjectList();
+ _vm->_boxContent = kNothing;
+ _vm->_background->draw(-1, -1, 5);
+ } else {
+ Common::String tmpStr = Common::String::format("I can't see %s in the box.", _vm->getItem(thing).c_str());
+ _vm->_dialogs->displayText(tmpStr);
+ }
+ } else
+ _vm->_dialogs->displayScrollChain('Q', 57);
+ break;
+ case kRoomInsideCardiffCastle:
+ switch (thing) {
+ case kObjectPen:
+ if (_vm->_animation->inField(1)) {
+ // Standing on the dais.
+ if (_vm->_takenPen)
+ _vm->_dialogs->displayText("It's not there, Avvy.");
+ else {
+ // OK: we're taking the pen, and it's there.
+ // No pen there now.
+ _vm->_background->draw(-1, -1, 3);
+ // Zap!
+ _vm->_animation->callSpecial(3);
+ _vm->_takenPen = true;
+ _vm->_objects[kObjectPen - 1] = true;
+ _vm->refreshObjectList();
+ _vm->_dialogs->displayText("Taken.");
+ }
+ } else if (_vm->_standingOnDais)
+ _vm->_dialogs->displayScrollChain('Q', 53);
+ else
+ _vm->_dialogs->displayScrollChain('Q', 51);
+ break;
+ case kObjectBolt:
+ _vm->_dialogs->displayScrollChain('Q', 52);
+ break;
+ default:
+ _vm->_dialogs->displayScrollChain('Q', 57);
+ }
+ break;
+ case kRoomRobins:
+ if ((thing == kObjectMushroom) & (_vm->_animation->inField(0)) & (_vm->_mushroomGrowing)) {
+ _vm->_background->draw(-1, -1, 2);
+ _vm->_dialogs->displayText("Got it!");
+ _vm->_mushroomGrowing = false;
+ _vm->_takenMushroom = true;
+ _vm->_objects[kObjectMushroom - 1] = true;
+ _vm->refreshObjectList();
+ _vm->incScore(3);
+ } else
+ _vm->_dialogs->displayScrollChain('Q', 57);
+ break;
+ default:
+ _vm->_dialogs->displayScrollChain('Q', 57);
+ }
+}
+
+/**
+ * Give the lute to Geida
+ * @remarks Originally called 'give_Geida_the_lute'
+ */
+void Parser::giveGeidaTheLute() {
+ if (_vm->_room != kRoomLustiesRoom) {
+ Common::String tmpStr = Common::String::format("Not yet. Try later!%c2%c", kControlRegister, kControlSpeechBubble);
+ _vm->_dialogs->displayText(tmpStr);
+ return;
+ }
+ _vm->_objects[kObjectLute - 1] = false;
+ _vm->refreshObjectList();
+ // She plays it.
+ _vm->_dialogs->displayScrollChain('Q', 64);
+
+ _vm->_timer->addTimer(1, Timer::kProcGiveLuteToGeida, Timer::kReasonGeidaSings);
+ //_vm->_enid->backToBootstrap(4); TODO: Replace it with proper ScummVM-friendly function(s)! Do not remove until then!
+}
+
+void Parser::playHarp() {
+ if (_vm->_animation->inField(6))
+ _vm->_dialogs->displayMusicalScroll();
+ else
+ _vm->_dialogs->displayText("Get a bit closer to it, Avvy!");
+}
+
+void Parser::winSequence() {
+ _vm->_dialogs->displayScrollChain('Q', 78);
+ _vm->_sequence->startWinSeq();
+ _vm->_timer->addTimer(30, Timer::kProcWinning, Timer::kReasonWinning);
+}
+
+/**
+ * @remarks Originally called 'do_that'
+ */
+void Parser::doThat() {
+ static const char booze[8][8] = {"Bitter", "GIED", "Whisky", "Cider", "", "", "", "Mead"};
+ static const char kWhat[] = "That's not possible!";
+
+ if (_thats == Common::String(kNothing)) {
+ if (!_thats.empty())
+ _thats.clear();
+ return;
+ }
+
+ if (_weirdWord)
+ return;
+
+ if (_thing < 200)
+ // "Slip" object
+ _thing -= 49;
+
+ if (_vm->_tiedUp) {
+ _vm->_dialogs->displayText("You better stay quiet now!");
+ return;
+ }
+
+ if ((_verb != kVerbCodeLoad) && (_verb != kVerbCodeSave) && (_verb != kVerbCodeQuit) && (_verb != kVerbCodeInfo) && (_verb != kVerbCodeHelp)
+ && (_verb != kVerbCodeLarrypass) && (_verb != kVerbCodePhaon) && (_verb != kVerbCodeBoss) && (_verb != kVerbCodeCheat) && (_verb != kVerbCodeRestart)
+ && (_verb != kVerbCodeDir) && (_verb != kVerbCodeScore) && (_verb != kVerbCodeHiscores) && (_verb != kVerbCodeSmartAlec)) {
+ if (!_vm->_alive) {
+ _vm->_dialogs->displayText("You're dead, so don't talk. What are you, a ghost or something? " \
+ "Try restarting, or restoring a saved game!");
+ return;
+ }
+ if (!_vm->_avvyIsAwake && (_verb != kVerbCodeWake)) {
+ _vm->_dialogs->displayText("Talking in your sleep? Try waking up!");
+ return;
+ }
+ }
+
+ switch (_verb) {
+ case kVerbCodeExam:
+ examine();
+ break;
+ case kVerbCodeOpen:
+ openDoor();
+ break;
+ case kVerbCodePause: {
+ // Note that the original game doesn't care about the "O.K." box neither, it accepts
+ // clicks from everywhere on the screen to continue. Just like my code.
+ Common::String tmpStr = Common::String::format("Game paused.%c%c%cPress Enter, Esc, or click the mouse on the `O.K.\" " \
+ "box to continue.", kControlCenter, kControlNewLine, kControlNewLine);
+ _vm->_dialogs->displayText(tmpStr);
+ }
+ break;
+ case kVerbCodeGet:
+ if (_thing != kPardon) {
+ // Legitimate try to pick something up.
+ if (_vm->_carryNum >= kCarryLimit)
+ _vm->_dialogs->displayText("You can't carry any more!");
+ else
+ getProc(_thing);
+ } else {
+ // Not... ditto.
+ if (_person != kPeoplePardon)
+ _vm->_dialogs->displayText("You can't sweep folk off their feet!");
+ else
+ _vm->_dialogs->displayText("I assure you, you don't need it.");
+ }
+ break;
+ case kVerbCodeDrop:
+ _vm->_dialogs->displayText("Two years ago you dropped a florin in the street. Three days " \
+ "later it was gone! So now you never leave ANYTHING lying around. OK?");
+ break;
+ case kVerbCodeInv:
+ inventory();
+ break;
+ case kVerbCodeTalk:
+ if (_person == kPeoplePardon) {
+ if (_vm->_subjectNum == 99) {
+ // They typed "say password".
+ Common::String tmpStr = Common::String::format("Yes, but what %cis%c the password?", kControlItalic, kControlRoman);
+ _vm->_dialogs->displayText(tmpStr);
+ } else if (((1 <= _vm->_subjectNum) && (_vm->_subjectNum <= 49)) || (_vm->_subjectNum == 253) || (_vm->_subjectNum == 249)) {
+ _thats.deleteChar(0);
+
+ for (int i = 0; i < 10; i++)
+ _realWords[i] = _realWords[i + 1];
+
+ _verb = (VerbCode)_vm->_subjectNum;
+ doThat();
+ return;
+ } else {
+ _person = (People)_vm->_subjectNum;
+ _vm->_subjectNum = 0;
+ if ((_person == kPeopleNone) || (_person == kPeoplePardon))
+ _vm->_dialogs->displayText("Talk to whom?");
+ else if (isPersonHere())
+ _vm->_dialogs->talkTo(_person);
+ }
+ } else if (isPersonHere())
+ _vm->_dialogs->talkTo(_person);
+ break;
+ case kVerbCodeGive:
+ if (isHolding()) {
+ if (_person == kPeoplePardon)
+ _vm->_dialogs->displayText("Give to whom?");
+ else if (isPersonHere()) {
+ switch (_thing) {
+ case kObjectMoney :
+ _vm->_dialogs->displayText("You can't bring yourself to give away your moneybag.");
+ break;
+ case kObjectBodkin:
+ case kObjectBell:
+ case kObjectClothes:
+ case kObjectHabit :
+ _vm->_dialogs->displayText("Don't give it away, it might be useful!");
+ break;
+ default:
+ switch (_person) {
+ case kPeopleCrapulus:
+ if (_thing == kObjectWine) {
+ _vm->_dialogs->displayText("Crapulus grabs the wine and gulps it down.");
+ _vm->_objects[kObjectWine - 1] = false;
+ } else
+ _vm->_dialogs->sayThanks(_thing - 1);
+ break;
+ case kPeopleCwytalot:
+ if ((_thing == kObjectCrossbow) || (_thing == kObjectBolt))
+ _vm->_dialogs->displayText("You might be able to influence Cwytalot more if you used it!");
+ else
+ _vm->_dialogs->sayThanks(_thing - 1);
+ break;
+ case kPeopleSpludwick:
+ if (giveToSpludwick())
+ _vm->_dialogs->sayThanks(_thing - 1);
+ break;
+ case kPeopleIbythneth:
+ if (_thing == kObjectBadge) {
+ _vm->_dialogs->displayScrollChain('Q', 32); // Thanks! Wow!
+ _vm->incScore(3);
+ _vm->_objects[kObjectBadge - 1] = false;
+ _vm->_objects[kObjectHabit - 1] = true;
+ _vm->_givenBadgeToIby = true;
+ _vm->_background->draw(-1, -1, 7);
+ _vm->_background->draw(-1, -1, 8);
+ } else
+ _vm->_dialogs->sayThanks(_thing - 1);
+ break;
+ case kPeopleAyles:
+ if (_vm->_aylesIsAwake) {
+ if (_thing == kObjectPen) {
+ _vm->_objects[kObjectPen - 1] = false;
+ _vm->_dialogs->displayScrollChain('Q', 54);
+ _vm->_objects[kObjectInk - 1] = true;
+ _vm->_givenPenToAyles = true;
+ _vm->refreshObjectList();
+ _vm->incScore(2);
+ } else
+ _vm->_dialogs->sayThanks(_thing - 1);
+ } else
+ _vm->_dialogs->displayText("But he's asleep!");
+ break;
+ case kPeopleGeida:
+ switch (_thing) {
+ case kObjectPotion:
+ _vm->_objects[kObjectPotion - 1] = false;
+ // She drinks it.
+ _vm->_dialogs->displayScrollChain('U', 16);
+ _vm->incScore(2);
+ _vm->_givenPotionToGeida = true;
+ _vm->refreshObjectList();
+ break;
+ case kObjectLute:
+ giveGeidaTheLute();
+ break;
+ default:
+ _vm->_dialogs->sayThanks(_thing - 1);
+ }
+ break;
+ case kPeopleArkata:
+ switch (_thing) {
+ case kObjectPotion:
+ if (_vm->_givenPotionToGeida)
+ winSequence();
+ else
+ // That Geida woman!
+ _vm->_dialogs->displayScrollChain('Q', 77);
+ break;
+ default:
+ _vm->_dialogs->sayThanks(_thing - 1);
+ }
+ break;
+ default:
+ _vm->_dialogs->sayThanks(_thing - 1);
+ }
+ }
+ }
+ // Just in case...
+ _vm->refreshObjectList();
+ }
+ break;
+
+ case kVerbCodeEat:
+ case kVerbCodeDrink:
+ if (isHolding())
+ swallow();
+ break;
+
+ case kVerbCodeLoad: {
+ GUI::SaveLoadChooser *dialog = new GUI::SaveLoadChooser("Restore game:", "Restore", false);
+ int16 savegameId = dialog->runModalWithCurrentTarget();
+ delete dialog;
+
+ if (savegameId < 0)
+ // dialog aborted, nothing to load
+ return;
+
+ _vm->loadGame(savegameId);
+ }
+ break;
+ case kVerbCodeSave: {
+ GUI::SaveLoadChooser *dialog = new GUI::SaveLoadChooser("Save game:", "Save", true);
+ int16 savegameId = dialog->runModalWithCurrentTarget();
+ Common::String savegameDescription = dialog->getResultString();
+ delete dialog;
+
+ if (savegameId < 0)
+ // dialog aborted, nothing to save
+ return;
+
+ _vm->saveGame(savegameId, savegameDescription);
+ }
+ break;
+ case kVerbCodePay:
+ _vm->_dialogs->displayText("No money need change hands.");
+ break;
+ case kVerbCodeLook:
+ lookAround();
+ break;
+ case kVerbCodeBreak:
+ _vm->_dialogs->displayText("Vandalism is prohibited within this game!");
+ break;
+ case kVerbCodeQuit:
+ if (!_polite)
+ _vm->_dialogs->displayText("How about a `please\", Avvy?");
+ else {
+ Common::String tmpStr = Common::String::format("%cC%cDo you really want to quit?", kControlRegister, kControlIcon);
+ if (_vm->_dialogs->displayQuestion(tmpStr))
+ _vm->_letMeOut = true;
+ }
+ break;
+ case kVerbCodeGo:
+ _vm->_dialogs->displayText("Just use the arrow keys to walk there.");
+ break;
+ case kVerbCodeInfo: {
+ _vm->_dialogs->_aboutBox = true;
+
+ Common::String toDisplay;
+ for (int i = 0; i < 7; i++)
+ toDisplay += kControlNewLine;
+ toDisplay = toDisplay + "LORD AVALOT D'ARGENT" + kControlCenter + kControlNewLine
+ + "The medi\x91val descendant of" + kControlNewLine
+ + "Denarius Avaricius Sextus" + kControlNewLine + kControlNewLine
+ + "version " + kVersionNum + kControlNewLine + kControlNewLine + "Copyright \xEF "
+ + kCopyright + ", Mark, Mike and Thomas Thurman." + kControlRegister + 'Y' + kControlIcon;
+ _vm->_dialogs->displayText(toDisplay);
+ _vm->_dialogs->_aboutBox = false;
+ }
+ break;
+ case kVerbCodeUndress:
+ if (_wearing == kNothing)
+ _vm->_dialogs->displayText("You're already stark naked!");
+ else if (_vm->_avvysInTheCupboard) {
+ Common::String tmpStr = Common::String::format("You take off %s.", _vm->getItem(_wearing).c_str());
+ _vm->_dialogs->displayText(tmpStr);
+ _wearing = kNothing;
+ _vm->refreshObjectList();
+ } else
+ _vm->_dialogs->displayText("Hadn't you better find somewhere more private, Avvy?");
+ break;
+ case kVerbCodeWear:
+ if (isHolding()) { // Wear something.
+ switch (_thing) {
+ case kObjectChastity:
+ // \? are used to avoid that ??! is parsed as a trigraph
+ _vm->_dialogs->displayText("Hey, what kind of a weirdo are you\?\?!");
+ break;
+ case kObjectClothes:
+ case kObjectHabit: {
+ // Change clothes!
+ if (_wearing != kNothing) {
+ if (_wearing == _thing)
+ _vm->_dialogs->displayText("You're already wearing that.");
+ else
+ _vm->_dialogs->displayText("You'll be rather warm wearing two sets of clothes!");
+ return;
+ } else
+ _wearing = _thing;
+
+ _vm->refreshObjectList();
+
+ byte i;
+ if (_thing == kObjectHabit)
+ i = 3;
+ else
+ i = 0;
+
+ _vm->_animation->setAvvyClothes(i);
+ }
+ break;
+ default:
+ _vm->_dialogs->displayText(kWhat);
+ }
+ }
+ break;
+ case kVerbCodePlay:
+ if (_thing == kPardon) {
+ // They just typed "play"...
+ switch (_vm->_room) {
+ case kRoomArgentPub:
+ _vm->_nim->playNim(); // ...in the pub, => play Nim.
+ break;
+ case kRoomMusicRoom:
+ playHarp();
+ break;
+ default:
+ break;
+ }
+ } else if (isHolding()) {
+ switch (_thing) {
+ case kObjectLute :
+ _vm->_dialogs->displayScrollChain('U', 7);
+
+ if (_vm->getRoom(kPeopleCwytalot) == _vm->_room)
+ _vm->_dialogs->displayScrollChain('U', 10);
+
+ if (_vm->getRoom(kPeopleDuLustie) == _vm->_room)
+ _vm->_dialogs->displayScrollChain('U', 15);
+ break;
+ case 52:
+ if (_vm->_room == kRoomMusicRoom)
+ playHarp();
+ else
+ _vm->_dialogs->displayText(kWhat);
+ break;
+ case 55:
+ if (_vm->_room == kRoomArgentPub)
+ // play_nim();
+ warning("STUB: Parser::doThat() - case kVerbCodeplay - play_nim()");
+ else
+ _vm->_dialogs->displayText(kWhat);
+ break;
+ default:
+ _vm->_dialogs->displayText(kWhat);
+ }
+ }
+ break;
+ case kVerbCodeRing:
+ if (isHolding()) {
+ if (_thing == kObjectBell) {
+ _vm->_dialogs->displayText("Ding, dong, ding, dong, ding, dong, ding, dong...");
+ if ((_vm->_bellsAreRinging) & (_vm->getFlag('B')))
+ // '\?' are used to avoid that '??!' is parsed as a trigraph
+ _vm->_dialogs->displayText("(Are you trying to join in, Avvy\?\?!)");
+ } else
+ _vm->_dialogs->displayText(kWhat);
+ }
+ break;
+ case kVerbCodeHelp:
+ // boot_help();
+ warning("STUB: Parser::doThat() - case kVerbCodehelp");
+ break;
+ case kVerbCodeLarrypass:
+ _vm->_dialogs->displayText("Wrong game!");
+ break;
+ case kVerbCodePhaon:
+ _vm->_dialogs->displayText("Hello, Phaon!");
+ break;
+ case kVerbCodeBoss:
+ // bosskey();
+ warning("STUB: Parser::doThat() - case kVerbCodeboss");
+ break;
+ case kVerbCodePee:
+ if (_vm->getFlag('P')) {
+ _vm->_dialogs->displayText("Hmm, I don't think anyone will notice...");
+ _vm->_timer->addTimer(4, Timer::kProcUrinate, Timer::kReasonGoToToilet);
+ } else {
+ Common::String tmpStr = Common::String::format("It would be %cVERY%c unwise to do that here, Avvy!", kControlItalic, kControlRoman);
+ _vm->_dialogs->displayText(tmpStr);
+ }
+ break;
+ case kVerbCodeCheat: {
+ Common::String tmpStr = Common::String::format("%cCheat mode now enabled.", kControlItalic);
+ _vm->_dialogs->displayText(tmpStr);
+ _vm->_cheat = true;
+ }
+ break;
+ case kVerbCodeMagic:
+ if (_vm->_avariciusTalk > 0)
+ _vm->_dialogs->displayScrollChain('Q', 19);
+ else {
+ if ((_vm->_room == kRoomSpludwicks) & (_vm->_animation->inField(1))) {
+ // Avaricius appears!
+ _vm->_dialogs->displayScrollChain('Q', 17);
+ if (_vm->getRoom(kPeopleSpludwick) == kRoomSpludwicks)
+ _vm->_dialogs->displayScrollChain('Q', 18);
+ else {
+ Avalanche::AnimationType *spr = _vm->_animation->_sprites[1];
+ // Avaricius
+ spr->init(1, false);
+ _vm->_animation->appearPed(1, 3);
+ spr->walkTo(4);
+ spr->_callEachStepFl = true;
+ spr->_eachStepProc = Animation::kProcBackAndForth;
+ _vm->_avariciusTalk = 14;
+ _vm->_timer->addTimer(177, Timer::kProcAvariciusTalks, Timer::kReasonAvariciusTalks);
+ }
+ } else
+ _vm->_dialogs->displayText("Nothing appears to happen...");
+ }
+ break;
+ case kVerbCodeSmartAlec:
+ _vm->_dialogs->displayText("Listen, smart alec, that was just rhetoric.");
+ break;
+ case kVerbCodeExpletive:
+ switch (_sworeNum) {
+ case 0: {
+ Common::String tmpStr = Common::String::format("Avvy! Do you mind? There might be kids playing!%c%c" \
+ "(I shouldn't say it again, if I were you!)", kControlNewLine, kControlNewLine);
+ _vm->_dialogs->displayText(tmpStr);
+ }
+ break;
+ case 1: {
+ Common::String tmpStr = Common::String::format("You hear a distant rumble of thunder. Must you always" \
+ "do things I tell you not to?%c%cDon't do it again!", kControlNewLine, kControlNewLine);
+ _vm->_dialogs->displayText(tmpStr);
+ }
+ break;
+ default: {
+ _vm->_animation->thunder();
+ Common::String tmpStr = Common::String::format("A crack of lightning shoots from the sky, and fries you." \
+ "%c%c(`Such is the anger of the gods, Avvy!\")", kControlNewLine, kControlNewLine);
+ _vm->_dialogs->displayText(tmpStr);
+ _vm->gameOver();
+ }
+ }
+ _sworeNum++;
+ break;
+ case kVerbCodeListen:
+ if ((_vm->_bellsAreRinging) & (_vm->getFlag('B')))
+ _vm->_dialogs->displayText("All other noise is drowned out by the ringing of the bells.");
+ else if (_vm->_listen.empty())
+ _vm->_dialogs->displayText("You can't hear anything much at the moment, Avvy.");
+ else
+ _vm->_dialogs->displayText(_vm->_listen);
+ break;
+ case kVerbCodeBuy:
+ // What are they trying to buy?
+ switch (_vm->_room) {
+ case kRoomArgentPub:
+ // We're in a pub, and near the bar.
+ if (_vm->_animation->inField(5)) {
+ switch (_thing) {
+ case 51:
+ case 53:
+ case 54:
+ case 58:
+ // Beer, whisky, cider or mead.
+ if (_vm->_malagauche == 177) {
+ // Already getting us one.
+ _vm->_dialogs->displayScrollChain('D', 15);
+ return;
+ }
+
+ if (_vm->_teetotal) {
+ _vm->_dialogs->displayScrollChain('D', 6);
+ return;
+ }
+
+ if (_alcoholLevel == 0)
+ _vm->incScore(3);
+
+ _vm->_background->draw(-1, -1, 11);
+ _vm->_dialogs->displayText(Common::String(booze[_thing - 51]) + ", please." + kControlRegister + '1' + kControlSpeechBubble);
+ _vm->_drinking = _thing;
+
+ _vm->_background->draw(-1, -1, 9);
+ _vm->_malagauche = 177;
+ _vm->_timer->addTimer(27, Timer::kProcBuyDrinks, Timer::kReasonDrinks);
+ break;
+ case 52:
+ examine();
+ break; // We have a right one here - buy Pepsi??!
+ case kObjectWine:
+ if (_vm->_objects[kObjectWine - 1])
+ // We've already got the wine!
+ // 1 bottle's shufishent!
+ _vm->_dialogs->displayScrollChain('D', 2);
+ else {
+ if (_vm->_malagauche == 177) {
+ // Already getting us one.
+ _vm->_dialogs->displayScrollChain('D', 15);
+ return;
+ }
+
+ if (_vm->_carryNum >= kCarryLimit) {
+ _vm->_dialogs->displayText("Your hands are full.");
+ return;
+ }
+
+ _vm->_background->draw(-1, -1, 11);
+ Common::String tmpStr = Common::String::format("Wine, please.%c1%c", kControlRegister, kControlSpeechBubble);
+ _vm->_dialogs->displayText(tmpStr);
+ if (_alcoholLevel == 0)
+ _vm->incScore(3);
+ _vm->_background->draw(-1, -1, 9);
+ _vm->_malagauche = 177;
+
+ _vm->_timer->addTimer(27, Timer::kProcBuyWine, Timer::kReasonDrinks);
+ }
+ break;
+ }
+ } else
+ // Go to the bar!
+ _vm->_dialogs->displayScrollChain('D', 5);
+ break;
+
+ case kRoomOutsideDucks:
+ if (_vm->_animation->inField(5)) {
+ if (_thing == kObjectOnion) {
+ if (_vm->_objects[kObjectOnion - 1])
+ // Not planning to juggle with the things!
+ _vm->_dialogs->displayScrollChain('D', 10);
+ else if (_vm->_carryNum >= kCarryLimit)
+ _vm->_dialogs->displayText("Before you ask, you remember that your hands are full.");
+ else {
+ if (_boughtOnion)
+ _vm->_dialogs->displayScrollChain('D', 11);
+ else {
+ _vm->_dialogs->displayScrollChain('D', 9);
+ _vm->incScore(3);
+ }
+ // It costs thruppence.
+ _vm->decreaseMoney(3);
+ _vm->_objects[kObjectOnion - 1] = true;
+ _vm->refreshObjectList();
+ _boughtOnion = true;
+ // It's OK when it leaves the stall!
+ _vm->_rottenOnion = false;
+ _vm->_onionInVinegar = false;
+ }
+ } else
+ _vm->_dialogs->displayScrollChain('D', 0);
+ } else
+ _vm->_dialogs->displayScrollChain('D', 0);
+ break;
+
+ case kRoomNottsPub:
+ // Can't sell to southerners.
+ _vm->_dialogs->displayScrollChain('N', 15);
+ break;
+ default:
+ // Can't buy that.
+ _vm->_dialogs->displayScrollChain('D', 0);
+ }
+ break;
+ case kVerbCodeAttack:
+ if ((_vm->_room == kRoomBrummieRoad) &&
+ ((_person == kPeopleCwytalot) || (_thing == kObjectCrossbow) || (_thing == kObjectBolt)) &&
+ (_vm->getRoom(kPeopleCwytalot) == _vm->_room)) {
+ switch (_vm->_objects[kObjectBolt - 1] + _vm->_objects[kObjectCrossbow - 1] * 2) {
+ // 0 = neither, 1 = only bolt, 2 = only crossbow, 3 = both.
+ case 0:
+ _vm->_dialogs->displayScrollChain('Q', 10);
+ _vm->_dialogs->displayText("(At the very least, don't use your bare hands!)");
+ break;
+ case 1:
+ _vm->_dialogs->displayText("Attack _vm->him with only a crossbow bolt? Are you planning on playing darts?!");
+ break;
+ case 2:
+ _vm->_dialogs->displayText("Come on, Avvy! You're not going to get very far with only a crossbow!");
+ break;
+ case 3:
+ _vm->_dialogs->displayScrollChain('Q', 11);
+ _vm->_cwytalotGone = true;
+ _vm->_objects[kObjectBolt - 1] = false;
+ _vm->_objects[kObjectCrossbow - 1] = false;
+ _vm->refreshObjectList();
+ _vm->_magics[11]._operation = kMagicNothing;
+ _vm->incScore(7);
+ _vm->_animation->_sprites[1]->walkTo(1);
+ _vm->_animation->_sprites[1]->_vanishIfStill = true;
+ _vm->_animation->_sprites[1]->_callEachStepFl = false;
+ _vm->setRoom(kPeopleCwytalot, kRoomDummy);
+ break;
+ default:
+ // Please try not to be so violent!
+ _vm->_dialogs->displayScrollChain('Q', 10);
+ }
+ } else
+ _vm->_dialogs->displayScrollChain('Q', 10);
+ break;
+ case kVerbCodePasswd:
+ if (_vm->_room != kRoomBridge)
+ _vm->_dialogs->displayScrollChain('Q', 12);
+ else {
+ bool ok = true;
+ for (uint i = 0; i < _thats.size(); i++) {
+ Common::String temp = _realWords[i];
+ temp.toUppercase();
+ int pwdId = _vm->_passwordNum + kFirstPassword;
+ for (uint j = 0; j < _vocabulary[pwdId]._word.size(); j++) {
+ if (_vocabulary[pwdId]._word[j] != temp[j])
+ ok = false;
+ }
+ }
+
+ if (ok) {
+ if (_vm->_drawbridgeOpen != 0)
+ _vm->_dialogs->displayText("Contrary to your expectations, the drawbridge fails to close again.");
+ else {
+ _vm->incScore(4);
+ _vm->_dialogs->displayText("The drawbridge opens!");
+ _vm->_timer->addTimer(7, Timer::kProcOpenDrawbridge, Timer::kReasonDrawbridgeFalls);
+ _vm->_drawbridgeOpen = 1;
+ }
+ } else
+ _vm->_dialogs->displayScrollChain('Q', 12);
+ }
+ break;
+ case kVerbCodeDie:
+ _vm->gameOver();
+ break;
+ case kVerbCodeScore: {
+ Common::String tmpStr = Common::String::format("Your score is %d,%c%cout of a possible 128.%c%c " \
+ "This gives you a rank of %s.%c%c%s", _vm->_dnascore, kControlCenter, kControlNewLine, kControlNewLine,
+ kControlNewLine, rank().c_str(), kControlNewLine, kControlNewLine, totalTime().c_str());
+ _vm->_dialogs->displayText(tmpStr);
+ }
+ break;
+ case kVerbCodePut:
+ putProc();
+ break;
+ case kVerbCodeStand:
+ standUp();
+ break;
+ case kVerbCodeKiss:
+ if (_person == kPeoplePardon)
+ _vm->_dialogs->displayText("Kiss whom?");
+ else if (isPersonHere()) {
+ switch (_person) {
+ case kPeopleArkata:
+ _vm->_dialogs->displayScrollChain('U', 12);
+ break;
+ case kPeopleGeida:
+ _vm->_dialogs->displayScrollChain('U', 13);
+ break;
+ case kPeopleWisewoman:
+ _vm->_dialogs->displayScrollChain('U', 14);
+ break;
+ default:
+ // You WHAT?
+ _vm->_dialogs->displayScrollChain('U', 5);
+ }
+ } else if ((kPeopleAvalot <= _person) && (_person < kPeopleArkata))
+ _vm->_dialogs->displayText("Hey, what kind of a weirdo are you??");
+
+ break;
+ case kVerbCodeClimb:
+ if (_vm->_room == kRoomInsideCardiffCastle)
+ cardiffClimbing();
+ else
+ // In the wrong room!
+ _vm->_dialogs->displayText("Not with your head for heights, Avvy!");
+ break;
+ case kVerbCodeJump:
+ _vm->_timer->addTimer(1, Timer::kProcJump, Timer::kReasonJumping);
+ _vm->_userMovesAvvy = false;
+ break;
+ case kVerbCodeHiscores:
+ // show_highs();
+ warning("STUB: Parser::doThat() - case kVerbCodehighscores");
+ break;
+ case kVerbCodeWake:
+ if (isPersonHere())
+ switch (_person) {
+ case kPeoplePardon:
+ case kPeopleAvalot:
+ case 0:
+ if (!_vm->_avvyIsAwake) {
+ _vm->_avvyIsAwake = true;
+ _vm->incScore(1);
+ _vm->_avvyInBed = true;
+ // Picture of Avvy, awake in bed.
+ _vm->_background->draw(-1, -1, 2);
+ if (_vm->_teetotal)
+ _vm->_dialogs->displayScrollChain('D', 13);
+ } else
+ _vm->_dialogs->displayText("You're already awake, Avvy!");
+ break;
+ case kPeopleAyles:
+ if (!_vm->_aylesIsAwake)
+ _vm->_dialogs->displayText("You can't seem to wake him by yourself.");
+ break;
+ case kPeopleJacques: {
+ Common::String tmpStr = Common::String::format("Brother Jacques, Brother Jacques, are you asleep?%c1%c" \
+ "Hmmm... that doesn't seem to do any good...", kControlRegister, kControlSpeechBubble);
+ _vm->_dialogs->displayText(tmpStr);
+ }
+ break;
+ default:
+ _vm->_dialogs->displayText("It's difficult to awaken people who aren't asleep...!");
+ }
+ break;
+ case kVerbCodeSit:
+ if (_vm->_room == kRoomNottsPub) {
+ if (_vm->_sittingInPub)
+ _vm->_dialogs->displayText("You're already sitting!");
+ else {
+ // Move Avvy to the place, and sit him down.
+ _vm->_animation->_sprites[0]->walkTo(3);
+ _vm->_timer->addTimer(1, Timer::kProcAvvySitDown, Timer::kReasonSittingDown);
+ }
+ } else {
+ // Default doodah.
+ _vm->fadeOut();
+ _vm->fadeIn();
+ Common::String tmpStr = Common::String::format("A few hours later...%cnothing much has happened...", kControlParagraph);
+ _vm->_dialogs->displayText(tmpStr);
+ }
+ break;
+ case kVerbCodeRestart:
+ if (_vm->_dialogs->displayQuestion("Restart game and lose changes?")) {
+ _vm->fadeOut();
+ _vm->newGame();
+ _vm->fadeIn();
+ }
+ break;
+ case kVerbCodePardon:
+ _vm->_dialogs->displayText("Hey, a verb would be helpful!");
+ break;
+ case kVerbCodeHello:
+ _vm->_dialogs->sayHello();
+ break;
+ case kVerbCodeThanks:
+ _vm->_dialogs->sayOK();
+ break;
+ default:
+ Common::String tmpStr = Common::String::format("%cUnhandled verb: %d", kControlBell, _verb);
+ _vm->_dialogs->displayText(tmpStr);
+ }
+}
+
+void Parser::verbOpt(byte verb, Common::String &answer, char &ansKey) {
+ // kVerbCodegive isn't dealt with by this procedure, but by ddm__with.
+ switch (verb) {
+ case kVerbCodeExam:
+ answer = "Examine";
+ ansKey = 'x';
+ break;
+ case kVerbCodeDrink:
+ answer = "Drink";
+ ansKey = 'D';
+ break;
+ case kVerbCodeWear:
+ answer = "Wear";
+ ansKey = 'W';
+ break;
+ case kVerbCodeRing:
+ answer = "Ring";
+ ansKey = 'R';
+ break; // Only the bell!
+ case kVerbCodePlay:
+ answer = "Play";
+ ansKey = 'P';
+ break;
+ case kVerbCodeEat:
+ answer = "Eat";
+ ansKey = 'E';
+ break;
+ default:
+ answer = "? Unknown!"; // Bug!
+ ansKey = '?';
+ }
+}
+
+void Parser::doVerb(VerbCode id) {
+ _weirdWord = false;
+ _polite = true;
+ _verb = id;
+ doThat();
+}
+
+void Parser::resetVariables() {
+ _wearing = kNothing;
+ _sworeNum = 0;
+ _alcoholLevel = 0;
+ _boughtOnion = false;
+}
+
+void Parser::synchronize(Common::Serializer &sz) {
+ sz.syncAsByte(_wearing);
+ sz.syncAsByte(_sworeNum);
+ sz.syncAsByte(_alcoholLevel);
+ if (sz.isLoading() && sz.getVersion() < 2) {
+ int dummy;
+ sz.syncAsByte(dummy);
+ }
+ sz.syncAsByte(_boughtOnion);
+}
+
+} // End of namespace Avalanche
diff --git a/engines/avalanche/parser.h b/engines/avalanche/parser.h
new file mode 100644
index 0000000000..20066329e5
--- /dev/null
+++ b/engines/avalanche/parser.h
@@ -0,0 +1,153 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public 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 based on the original source code of Lord Avalot d'Argent version 1.3.
+ * Copyright (c) 1994-1995 Mike, Mark and Thomas Thurman.
+ */
+
+#ifndef AVALANCHE_PARSER_H
+#define AVALANCHE_PARSER_H
+
+#include "avalanche/enums.h"
+
+#include "common/events.h"
+#include "common/str.h"
+#include "common/serializer.h"
+
+namespace Avalanche {
+class AvalancheEngine;
+
+class Parser {
+public:
+ static const int16 kParserWordsNum = 277; // How many words does the parser know?
+ static const int16 kFirstPassword = 88; // words[kFirstPassword] should equal "TIROS".
+ static const byte kPardon = 254; // Didn't understand / wasn't given.
+ static const byte kNothing = 250;
+ static const byte kMoved = 0; // This word was moved. (Usually because it was the subject of conversation.)
+
+ struct VocabEntry {
+ byte _number;
+ Common::String _word;
+
+ void init(byte number, Common::String word) {
+ _number = number;
+ _word = word;
+ }
+ };
+
+ VocabEntry _vocabulary[kParserWordsNum];
+
+ Common::String _realWords[11];
+ VerbCode _verb;
+ byte _thing;
+ People _person;
+ bool _polite;
+ Common::String _inputText;
+ Common::String _inputTextBackup;
+ byte _inputTextPos;
+ bool _quote;
+ bool _cursorState;
+ bool _weirdWord;
+
+ byte _wearing; // what you're wearing
+
+ Parser(AvalancheEngine *vm);
+
+ void init();
+ void parse();
+ void doThat();
+ void verbOpt(byte verb, Common::String &answer, char &ansKey);
+ void drink();
+
+ void handleInputText(const Common::Event &event);
+ void handleBackspace();
+ void handleReturn();
+ void handleFunctionKey(const Common::Event &event);
+ void plotText();
+ void cursorOn();
+ void cursorOff();
+ void tryDropdown();
+ int16 getPos(const Common::String &crit, const Common::String &src);
+ void doVerb(VerbCode id);
+
+ void resetVariables();
+ void synchronize(Common::Serializer &sz);
+
+private:
+ AvalancheEngine *_vm;
+
+ struct RankType {
+ uint16 _score;
+ char _title[20];
+ };
+
+ static const char *kCopyright;
+ static const char *kVersionNum;
+
+ Common::String _thats;
+ byte _thing2;
+ byte _sworeNum; // number of times you've sworn
+ byte _alcoholLevel; // Your blood alcohol level.
+ bool _boughtOnion; // Have you bought an onion yet?
+
+ byte wordNum(Common::String word);
+ void replace(Common::String oldChars, byte newChar);
+
+ Common::String rank();
+ Common::String totalTime();
+
+ void clearWords();
+ void cheatParse(Common::String codes);
+ void stripPunctuation(Common::String &word);
+ void displayWhat(byte target, bool animate, bool &ambiguous);
+ bool doPronouns();
+ void properNouns();
+ void lookAround();
+ void openDoor();
+ void storeInterrogation(byte interrogation);
+ void examineObject();
+ bool isPersonHere();
+ void exampers();
+ bool isHolding();
+ void openBox(bool isOpening);
+ void examine();
+ void inventory();
+ void swallow();
+ void peopleInRoom();
+ void putProc();
+ void notInOrder();
+ void goToCauldron();
+ bool giveToSpludwick();
+ void cardiffClimbing();
+ void already();
+ void standUp();
+ void getProc(char thing);
+ void giveGeidaTheLute();
+ void playHarp();
+ void winSequence();
+ void wipeText();
+};
+
+} // End of namespace Avalanche
+
+#endif // AVALANCHE_PARSER_H
diff --git a/engines/avalanche/pingo.cpp b/engines/avalanche/pingo.cpp
new file mode 100644
index 0000000000..40467ab839
--- /dev/null
+++ b/engines/avalanche/pingo.cpp
@@ -0,0 +1,94 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public 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 based on the original source code of Lord Avalot d'Argent version 1.3.
+ * Copyright (c) 1994-1995 Mike, Mark and Thomas Thurman.
+ */
+
+/* PINGO Full-screen sub-parts of the game. */
+
+#include "avalanche/avalanche.h"
+#include "avalanche/pingo.h"
+
+namespace Avalanche {
+
+Pingo::Pingo(AvalancheEngine *vm) {
+ _vm = vm;
+}
+
+void Pingo::dPlot(int16 x, int16 y, Common::String z) {
+ warning("STUB: Pingo::dPlot()");
+}
+
+void Pingo::bossKey() {
+ warning("STUB: Pingo::bossKey()");
+}
+
+void Pingo::copy02() { // taken from Wobble (below)
+ warning("STUB: Pingo::copy02()");
+}
+
+void Pingo::copy03() { // taken from Wobble (below)
+ warning("STUB: Pingo::copy03()");
+}
+
+void Pingo::copyPage(byte frp, byte top) { // taken from Copy02 (above)
+ warning("STUB: Pingo::copyPage()");
+}
+
+void Pingo::winningPic() {
+ Common::File f;
+ _vm->fadeOut();
+
+ if (!f.open("finale.avd"))
+ error("AVALANCHE: File not found: finale.avd");
+
+#if 0
+ for (int bit = 0; bit <= 3; bit++) {
+ port[0x3c4] = 2;
+ port[0x3ce] = 4;
+ port[0x3c5] = 1 << bit;
+ port[0x3cf] = bit;
+ blockread(f, mem[0xa000 * 0], 16000);
+ }
+#endif
+
+ f.close();
+
+ warning("STUB: Pingo::winningPic()");
+
+ _vm->fadeIn();
+
+#if 0
+ do {
+ _vm->check();
+ } while (!(keypressed() || (mrelease > 0)));
+ while (keypressed())
+ char r = readkey();
+ major_redraw();
+#endif
+
+ warning("STUB: Pingo::winningPic()");
+}
+
+} // End of namespace Avalanche.
diff --git a/engines/avalanche/pingo.h b/engines/avalanche/pingo.h
new file mode 100644
index 0000000000..6eecaf6453
--- /dev/null
+++ b/engines/avalanche/pingo.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.
+ *
+ */
+
+/*
+ * This code is based on the original source code of Lord Avalot d'Argent version 1.3.
+ * Copyright (c) 1994-1995 Mike, Mark and Thomas Thurman.
+ */
+
+/* PINGO Full-screen sub-parts of the game. */
+
+#ifndef AVALANCHE_PINGO_H
+#define AVALANCHE_PINGO_H
+
+#include "common/str.h"
+
+namespace Avalanche {
+class AvalancheEngine;
+
+class Pingo {
+public:
+ Pingo(AvalancheEngine *vm);
+
+ void bossKey();
+ void copy02();
+ void copy03();
+ void copyPage(byte frp, byte top);
+ void winningPic();
+
+private:
+ AvalancheEngine *_vm;
+
+ void dPlot(int16 x, int16 y, Common::String z);
+};
+
+} // End of namespace Avalanche.
+
+#endif // AVALANCHE_PINGO_H
diff --git a/engines/avalanche/sequence.cpp b/engines/avalanche/sequence.cpp
new file mode 100644
index 0000000000..3a60c4ec1d
--- /dev/null
+++ b/engines/avalanche/sequence.cpp
@@ -0,0 +1,230 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public 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 based on the original source code of Lord Avalot d'Argent version 1.3.
+ * Copyright (c) 1994-1995 Mike, Mark and Thomas Thurman.
+ */
+
+/* SEQUENCE The sequencer. */
+
+#include "avalanche/avalanche.h"
+#include "avalanche/sequence.h"
+
+namespace Avalanche {
+
+Sequence::Sequence(AvalancheEngine *vm) {
+ _vm = vm;
+
+ resetVariables();
+}
+
+void Sequence::resetVariables() {
+ _flipToWhere = kRoomNowhere;
+ _flipToPed = 0;
+}
+
+void Sequence::init(byte what) {
+ _seq[0] = what;
+
+ for (int i = 1; i < kSeqLength; i++)
+ _seq[i] = 0;
+}
+
+void Sequence::add(byte what) {
+ for (int16 i = 0; i < kSeqLength; i++) {
+ if (_seq[i] == 0) {
+ _seq[i] = what;
+ return;
+ }
+ }
+}
+
+void Sequence::switchRoom(Room where, byte ped) {
+ add(kNowFlip);
+
+ _flipToWhere = where;
+ _flipToPed = ped;
+}
+
+void Sequence::startTimer() {
+ _vm->_timer->loseTimer(Timer::kReasonSequencer);
+ _vm->_timer->addTimer(7, Timer::kProcSequence, Timer::kReasonSequencer);
+}
+
+void Sequence::startTimerImmobilized() {
+ // They can't move.
+ _vm->_userMovesAvvy = false;
+ // And they're not moving now.
+ _vm->_animation->stopWalking();
+ // Apart from that, it's the same thing.
+ startTimer();
+}
+
+void Sequence::shoveLeft() {
+ for (uint i = 0; i < kSeqLength - 1; i++)
+ _seq[i] = _seq[i + 1];
+ _seq[kSeqLength - 1] = 0;
+}
+
+void Sequence::callSequencer() {
+ byte curSeq = _seq[0];
+
+ switch (curSeq) {
+ case 0:
+ // No more routines.
+ return;
+ break;
+ case kNowFlip:
+ // Flip room.
+ _vm->_userMovesAvvy = true;
+ _vm->flipRoom(_flipToWhere, _flipToPed);
+ shoveLeft();
+ break;
+ }
+
+ if (curSeq <= 176) {
+ // Show a frame.
+ _vm->_background->draw(-1, -1, curSeq - 1);
+ shoveLeft();
+ }
+
+ // Make sure this PROC gets called again.
+ startTimer();
+}
+
+void Sequence::startHallSeq(Room whither, byte ped) {
+ init(1);
+ add(2);
+ switchRoom(whither, ped);
+ startTimerImmobilized();
+}
+
+void Sequence::startOutsideSeq(Room whither, byte ped) {
+ init(1);
+ add(2);
+ add(3);
+ switchRoom(whither, ped);
+ startTimerImmobilized();
+}
+
+void Sequence::startCardiffSeq(Room whither, byte ped) {
+ init(1);
+ add(5);
+ switchRoom(whither, ped);
+ startTimerImmobilized();
+}
+
+void Sequence::startNaughtyDukeSeq() {
+ init(2);
+ startTimer();
+}
+
+void Sequence::startGardenSeq() {
+ init(2);
+ add(1);
+ add(3);
+ startTimer();
+}
+
+void Sequence::startDuckSeq() {
+ init(3);
+ add(2);
+ add(1);
+ add(4);
+ startTimer();
+}
+
+void Sequence::startLustiesSeq3(Room whither, byte ped) {
+ init(4);
+ add(5);
+ add(6);
+ switchRoom(whither, ped);
+ startTimerImmobilized();
+}
+
+void Sequence::startMusicRoomSeq2(Room whither, byte ped) {
+ init(5);
+ add(6);
+ switchRoom(whither, ped);
+ startTimerImmobilized();
+}
+
+void Sequence::startGeidaLuteSeq() {
+ init(5);
+ // He falls asleep...
+ add(6);
+ // Not really closing, but we're using the same procedure.
+ startTimer();
+}
+
+void Sequence::startMusicRoomSeq() {
+ init(6);
+ add(5);
+ add(7);
+ startTimer();
+}
+
+void Sequence::startWinSeq() {
+ init(7);
+ add(8);
+ add(9);
+ startTimer();
+}
+
+void Sequence::startCupboardSeq() {
+ init(8);
+ add(7);
+ startTimer();
+}
+
+void Sequence::startLustiesSeq2(Room whither, byte ped) {
+ init(8);
+ add(9);
+ switchRoom(whither, ped);
+ startTimerImmobilized();
+}
+
+void Sequence::startCardiffSeq2() {
+ init(1);
+ if (_vm->_arrowInTheDoor)
+ add(3);
+ else
+ add(2);
+
+ if (_vm->_takenPen)
+ _vm->_background->draw(-1, -1, 3);
+
+ startTimer();
+}
+
+void Sequence::startDummySeq(Room whither, byte ped) {
+ switchRoom(whither, ped);
+ startTimerImmobilized();
+}
+
+void Sequence::synchronize(Common::Serializer &sz) {
+ sz.syncBytes(_seq, kSeqLength);
+ sz.syncAsByte(_flipToWhere);
+ sz.syncAsByte(_flipToPed);
+}
+} // End of namespace Avalanche.
diff --git a/engines/avalanche/sequence.h b/engines/avalanche/sequence.h
new file mode 100644
index 0000000000..d3c1b54963
--- /dev/null
+++ b/engines/avalanche/sequence.h
@@ -0,0 +1,80 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+/*
+ * This code is based on the original source code of Lord Avalot d'Argent version 1.3.
+ * Copyright (c) 1994-1995 Mike, Mark and Thomas Thurman.
+ */
+
+/* SEQUENCE The sequencer. */
+
+#ifndef AVALANCHE_SEQUENCE_H
+#define AVALANCHE_SEQUENCE_H
+
+namespace Avalanche {
+class AvalancheEngine;
+
+class Sequence {
+private:
+ static const int16 kNowFlip = 177;
+ static const int16 kSeqLength = 10;
+
+ byte _seq[kSeqLength];
+
+ Room _flipToWhere;
+ byte _flipToPed;
+
+ AvalancheEngine *_vm;
+
+ void shoveLeft(); // This is called by Timer when it's time to do another frame. It shifts everything to the left.
+ void init(byte what);
+ void add(byte what);
+ void switchRoom(Room where, byte ped);
+ void startTimer();
+ void startTimerImmobilized();
+
+public:
+ Sequence(AvalancheEngine *vm);
+ void synchronize(Common::Serializer &sz);
+ void resetVariables();
+ void callSequencer();
+
+ void startCupboardSeq();
+ void startMusicRoomSeq();
+ void startMusicRoomSeq2(Room whither, byte ped);
+ void startGardenSeq();
+ void startGeidaLuteSeq();
+ void startWinSeq();
+ void startNaughtyDukeSeq();
+ void startLustiesSeq2(Room whither, byte ped);
+ void startLustiesSeq3(Room whither, byte ped);
+ void startHallSeq(Room whither, byte ped);
+ void startCardiffSeq(Room whither, byte ped);
+ void startOutsideSeq(Room whither, byte ped);
+ void startDuckSeq();
+ void startCardiffSeq2();
+ void startDummySeq(Room whither, byte ped);
+};
+
+} // End of namespace Avalanche.
+
+#endif // AVALANCHE_SEQUENCE_H
diff --git a/engines/avalanche/sound.cpp b/engines/avalanche/sound.cpp
new file mode 100644
index 0000000000..c324df4713
--- /dev/null
+++ b/engines/avalanche/sound.cpp
@@ -0,0 +1,88 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public 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 "avalanche/avalanche.h"
+#include "avalanche/sound.h"
+
+#include "audio/audiostream.h"
+#include "common/config-manager.h"
+
+namespace Avalanche {
+
+SoundHandler::SoundHandler(AvalancheEngine *vm) : _vm(vm) {
+ _soundFl = true;
+ _speakerStream = new Audio::PCSpeaker(_vm->_mixer->getOutputRate());
+ _vm->_mixer->playStream(Audio::Mixer::kSFXSoundType, &_speakerHandle,
+ _speakerStream, -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::YES, true);
+}
+
+SoundHandler::~SoundHandler() {
+ _vm->_mixer->stopHandle(_speakerHandle);
+}
+
+/**
+ * Stop any sound that might be playing
+ */
+void SoundHandler::stopSound() {
+ _vm->_mixer->stopAll();
+}
+
+/**
+ * Turn digitized sound on and off
+ */
+void SoundHandler::toggleSound() {
+ _soundFl = !_soundFl;
+}
+
+void SoundHandler::syncVolume() {
+ int soundVolume;
+
+ if (ConfMan.getBool("sfx_mute") || ConfMan.getBool("mute"))
+ soundVolume = -1;
+ else
+ soundVolume = MIN(255, ConfMan.getInt("sfx_volume"));
+
+ _vm->_mixer->setVolumeForSoundType(Audio::Mixer::kSFXSoundType, soundVolume);
+}
+
+void SoundHandler::playNote(int freq, int length) {
+ // Does the user not want any sound?
+ if (!_soundFl || !_vm->_mixer->isReady())
+ return;
+
+ // Start a note playing (we will stop it when the timer expires).
+ _speakerStream->play(Audio::PCSpeaker::kWaveFormSquare, freq, length);
+}
+
+void SoundHandler::click() {
+ _vm->_mixer->stopAll();
+
+ playNote(7177, 1);
+}
+
+void SoundHandler::blip() {
+ _vm->_mixer->stopAll();
+
+ playNote(177, 77);
+}
+
+} // End of namespace Avalanche
diff --git a/engines/avalanche/sound.h b/engines/avalanche/sound.h
new file mode 100644
index 0000000000..25b6b267d3
--- /dev/null
+++ b/engines/avalanche/sound.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 AVALANCHE_SOUND_H
+#define AVALANCHE_SOUND_H
+
+#include "audio/mixer.h"
+#include "audio/softsynth/pcspk.h"
+
+namespace Avalanche {
+
+class SoundHandler {
+public:
+ bool _soundFl;
+
+ SoundHandler(AvalancheEngine *vm);
+ ~SoundHandler();
+
+ void toggleSound();
+ void playNote(int freq, int length);
+ void click();
+ void blip();
+ void syncVolume();
+ void stopSound();
+
+private:
+ AvalancheEngine *_vm;
+ Audio::PCSpeaker *_speakerStream;
+ Audio::SoundHandle _speakerHandle;
+};
+
+} // End of namespace Avalanche
+
+#endif // AVALANCHE_SOUND_H
diff --git a/engines/avalanche/timer.cpp b/engines/avalanche/timer.cpp
new file mode 100644
index 0000000000..c8ea820c0e
--- /dev/null
+++ b/engines/avalanche/timer.cpp
@@ -0,0 +1,693 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public 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 based on the original source code of Lord Avalot d'Argent version 1.3.
+ * Copyright (c) 1994-1995 Mike, Mark and Thomas Thurman.
+ */
+
+/* Original name: TIMEOUT The scheduling unit. */
+
+#include "avalanche/avalanche.h"
+#include "avalanche/timer.h"
+
+namespace Avalanche {
+
+Timer::Timer(AvalancheEngine *vm) {
+ _vm = vm;
+
+ resetVariables();
+}
+
+/**
+ * Add a nex timer
+ * @remarks Originally called 'set_up_timer'
+ */
+void Timer::addTimer(int32 duration, byte action, byte reason) {
+ byte i = 0;
+ while ((i < 7) && (_times[i]._timeLeft != 0)) {
+ if (_times[i]._reason == reason) // We only add a timer if it's not already in the array.
+ return;
+ i++;
+ }
+
+ if (i == 7)
+ return; // Oh dear... No timer left
+
+ // Everything's OK here!
+ _times[i]._timeLeft = duration;
+ _times[i]._action = action;
+ _times[i]._reason = reason;
+}
+
+/**
+ * Update the timers
+ * @remarks Originally called 'one_tick'
+ */
+void Timer::updateTimer() {
+ if (_vm->_menu->isActive())
+ return;
+
+ for (int i = 0; i < 7; i++) {
+ if (_times[i]._timeLeft <= 0)
+ continue;
+
+ _times[i]._timeLeft--;
+
+ if (_times[i]._timeLeft == 0) {
+ switch (_times[i]._action) {
+ case kProcOpenDrawbridge :
+ openDrawbridge();
+ break;
+ case kProcAvariciusTalks :
+ avariciusTalks();
+ break;
+ case kProcUrinate :
+ urinate();
+ break;
+ case kProcToilet :
+ toilet();
+ break;
+ case kProcBang:
+ bang();
+ break;
+ case kProcBang2:
+ bang2();
+ break;
+ case kProcStairs:
+ stairs();
+ break;
+ case kProcCardiffSurvey:
+ cardiffSurvey();
+ break;
+ case kProcCardiffReturn:
+ cardiffReturn();
+ break;
+ case kProcCwytalotInHerts:
+ cwytalotInHerts();
+ break;
+ case kProcGetTiedUp:
+ getTiedUp();
+ break;
+ case kProcGetTiedUp2:
+ getTiedUp2();
+ break;
+ case kProcHangAround:
+ hangAround();
+ break;
+ case kProcHangAround2:
+ hangAround2();
+ break;
+ case kProcAfterTheShootemup:
+ afterTheShootemup();
+ break;
+ case kProcJacquesWakesUp:
+ jacquesWakesUp();
+ break;
+ case kProcNaughtyDuke:
+ naughtyDuke();
+ break;
+ case kProcNaughtyDuke2:
+ naughtyDuke2();
+ break;
+ case kProcNaughtyDuke3:
+ naughtyDuke3();
+ break;
+ case kProcJump:
+ jump();
+ break;
+ case kProcSequence:
+ _vm->_sequence->callSequencer();
+ break;
+ case kProcCrapulusSpludOut:
+ crapulusSaysSpludOut();
+ break;
+ case kProcDawnDelay:
+ _vm->fadeIn();
+ break;
+ case kProcBuyDrinks:
+ buyDrinks();
+ break;
+ case kProcBuyWine:
+ buyWine();
+ break;
+ case kProcCallsGuards:
+ callsGuards();
+ break;
+ case kProcGreetsMonk:
+ greetsMonk();
+ break;
+ case kProcFallDownOubliette:
+ fallDownOubliette();
+ break;
+ case kProcMeetAvaroid:
+ meetAvaroid();
+ break;
+ case kProcRiseUpOubliette:
+ riseUpOubliette();
+ break;
+ case kProcRobinHoodAndGeida:
+ robinHoodAndGeida();
+ break;
+ case kProcRobinHoodAndGeidaTalk:
+ robinHoodAndGeidaTalk();
+ break;
+ case kProcAvalotReturns:
+ avalotReturns();
+ break;
+ case kProcAvvySitDown:
+ avvySitDown();
+ break;
+ case kProcGhostRoomPhew:
+ ghostRoomPhew();
+ break;
+ case kProcArkataShouts:
+ arkataShouts();
+ break;
+ case kProcWinning:
+ winning();
+ break;
+ case kProcAvalotFalls:
+ avalotFalls();
+ break;
+ case kProcSpludwickGoesToCauldron:
+ spludwickGoesToCauldron();
+ break;
+ case kProcSpludwickLeavesCauldron:
+ spludwickLeavesCauldron();
+ break;
+ case kProcGiveLuteToGeida:
+ giveLuteToGeida();
+ break;
+ }
+ }
+ }
+
+ _vm->_roomCycles++; // Cycles since you've been in this room.
+}
+
+void Timer::loseTimer(byte which) {
+ for (int i = 0; i < 7; i++) {
+ if (_times[i]._reason == which)
+ _times[i]._timeLeft = 0; // Cancel this one!
+ }
+
+}
+
+void Timer::openDrawbridge() {
+ _vm->_drawbridgeOpen++;
+ _vm->_background->draw(-1, -1, _vm->_drawbridgeOpen - 2);
+
+ if (_vm->_drawbridgeOpen == 4)
+ _vm->_magics[1]._operation = kMagicNothing; // You may enter the drawbridge.
+ else
+ addTimer(7, kProcOpenDrawbridge, kReasonDrawbridgeFalls);
+}
+
+void Timer::avariciusTalks() {
+ _vm->_dialogs->displayScrollChain('Q', _vm->_avariciusTalk);
+ _vm->_avariciusTalk++;
+
+ if (_vm->_avariciusTalk < 17)
+ addTimer(177, kProcAvariciusTalks, kReasonAvariciusTalks);
+ else
+ _vm->incScore(3);
+}
+
+void Timer::urinate() {
+ _vm->_animation->_sprites[0]->turn(kDirUp);
+ _vm->_animation->stopWalking();
+ _vm->drawDirection();
+ addTimer(14, kProcToilet, kReasonGoToToilet);
+}
+
+void Timer::toilet() {
+ _vm->_dialogs->displayText("That's better!");
+}
+
+void Timer::bang() {
+ Common::String tmpStr = Common::String::format("%c< BANG! >", kControlItalic);
+ _vm->_dialogs->displayText(tmpStr);
+ addTimer(30, kProcBang2, kReasonExplosion);
+}
+
+void Timer::bang2() {
+ _vm->_dialogs->displayText("Hmm... sounds like Spludwick's up to something...");
+}
+
+void Timer::stairs() {
+ _vm->_sound->blip();
+ _vm->_animation->_sprites[0]->walkTo(3);
+ _vm->_background->draw(-1, -1, 1);
+ _vm->_brummieStairs = 2;
+ _vm->_magics[10]._operation = kMagicSpecial;
+ _vm->_magics[10]._data = 2; // Reached the bottom of the stairs.
+ _vm->_magics[3]._operation = kMagicNothing; // Stop them hitting the sides (or the game will hang.)
+}
+
+void Timer::cardiffSurvey() {
+ if (_vm->_cardiffQuestionNum == 0) {
+ _vm->_cardiffQuestionNum++;
+ _vm->_dialogs->displayScrollChain('Q', 27);
+ }
+
+ _vm->_dialogs->displayScrollChain('Z', _vm->_cardiffQuestionNum);
+ _vm->_interrogation = _vm->_cardiffQuestionNum;
+ addTimer(182, kProcCardiffSurvey, kReasonCardiffsurvey);
+}
+
+void Timer::cardiffReturn() {
+ _vm->_dialogs->displayScrollChain('Q', 28);
+ cardiffSurvey(); // Add end of question.
+}
+
+void Timer::cwytalotInHerts() {
+ _vm->_dialogs->displayScrollChain('Q', 29);
+}
+
+void Timer::getTiedUp() {
+ _vm->_dialogs->displayScrollChain('Q', 34); // ...Trouble!
+ _vm->_userMovesAvvy = false;
+ _vm->_beenTiedUp = true;
+ _vm->_animation->stopWalking();
+
+ AnimationType *spr = _vm->_animation->_sprites[1];
+ spr->stopWalk();
+ spr->stopHoming();
+ spr->_callEachStepFl = true;
+ spr->_eachStepProc = Animation::kProcGrabAvvy;
+ addTimer(70, kProcGetTiedUp2, kReasonGettingTiedUp);
+}
+
+void Timer::getTiedUp2() {
+ _vm->_animation->_sprites[0]->walkTo(3);
+ _vm->_animation->_sprites[1]->walkTo(4);
+ _vm->_magics[3]._operation = kMagicNothing; // No effect when you touch the boundaries.
+ _vm->_friarWillTieYouUp = true;
+}
+
+void Timer::hangAround() {
+ _vm->_animation->_sprites[1]->_doCheck = false;
+
+ AnimationType *avvy = _vm->_animation->_sprites[0];
+ avvy->init(7, true); // Robin Hood
+ _vm->setRoom(kPeopleRobinHood, kRoomRobins);
+ _vm->_animation->appearPed(0, 1);
+ _vm->_dialogs->displayScrollChain('Q', 39);
+ avvy->walkTo(6);
+ addTimer(55, kProcHangAround2, kReasonHangingAround);
+}
+
+void Timer::hangAround2() {
+ _vm->_dialogs->displayScrollChain('Q', 40);
+ AnimationType *spr = _vm->_animation->_sprites[1];
+ spr->_vanishIfStill = false;
+ spr->walkTo(3);
+ _vm->setRoom(kPeopleFriarTuck, kRoomRobins);
+ _vm->_dialogs->displayScrollChain('Q', 41);
+ _vm->_animation->_sprites[0]->remove();
+ spr->remove(); // Get rid of Robin Hood and Friar Tuck.
+
+ addTimer(1, kProcAfterTheShootemup, kReasonHangingAround);
+ // Immediately call the following proc (when you have a chance).
+
+ _vm->_tiedUp = false;
+
+ // _vm->_enid->backToBootstrap(1); Call the shoot-'em-up. TODO: Replace it with proper ScummVM-friendly function(s)! Do not remove until then!
+}
+
+void Timer::afterTheShootemup() {
+ // Only placed this here to replace the minigame. TODO: Remove it when the shoot em' up is implemented!
+ _vm->flipRoom(_vm->_room, 1);
+
+ _vm->_animation->_sprites[0]->init(0, true); // Avalot.
+ _vm->_animation->appearPed(0, 1);
+ _vm->_userMovesAvvy = true;
+ _vm->_objects[kObjectCrossbow - 1] = true;
+ _vm->refreshObjectList();
+
+ // Same as the added line above: TODO: Remove it later!!!
+ _vm->_dialogs->displayText(Common::String("P.S.: There should have been the mini-game called \"shoot em' up\", " \
+ "but I haven't implemented it yet: you get the crossbow automatically.") + kControlNewLine + kControlNewLine + "Peter (uruk)");
+
+#if 0
+ byte shootscore, gain;
+
+ shootscore = mem[storage_seg * storage_ofs];
+ gain = (shootscore + 5) / 10; // Rounding up.
+
+ display(string("\6Your score was ") + strf(shootscore) + '.' + "\r\rYou gain (" +
+ strf(shootscore) + " 0xF6 10) = " + strf(gain) + " points.");
+
+ if (gain > 20) {
+ display("But we won't let you have more than 20 points!");
+ points(20);
+ } else
+ points(gain);
+#endif
+
+ warning("STUB: Timer::after_the_shootemup()");
+
+ _vm->_dialogs->displayScrollChain('Q', 70);
+}
+
+void Timer::jacquesWakesUp() {
+ _vm->_jacquesState++;
+
+ switch (_vm->_jacquesState) { // Additional pictures.
+ case 1 :
+ _vm->_background->draw(-1, -1, 0); // Eyes open.
+ _vm->_dialogs->displayScrollChain('Q', 45);
+ break;
+ case 2 : // Going through the door.
+ _vm->_background->draw(-1, -1, 1); // Not on the floor.
+ _vm->_background->draw(-1, -1, 2); // But going through the door.
+ _vm->_magics[5]._operation = kMagicNothing; // You can't wake him up now.
+ break;
+ case 3 : // Gone through the door.
+ _vm->_background->draw(-1, -1, 1); // Not on the floor, either.
+ _vm->_background->draw(-1, -1, 3); // He's gone... so the door's open.
+ _vm->setRoom(kPeopleJacques, kRoomNowhere); // Gone!
+ break;
+ }
+
+ if (_vm->_jacquesState == 5) {
+ _vm->_bellsAreRinging = true;
+ _vm->_aylesIsAwake = true;
+ _vm->incScore(2);
+ }
+
+ switch (_vm->_jacquesState) {
+ case 1:
+ case 2:
+ case 3:
+ addTimer(12, kProcJacquesWakesUp, kReasonJacquesWakingUp);
+ break;
+ case 4:
+ addTimer(24, kProcJacquesWakesUp, kReasonJacquesWakingUp);
+ break;
+ }
+}
+
+void Timer::naughtyDuke() { // This is when the Duke comes in and takes your money.
+ AnimationType *spr = _vm->_animation->_sprites[1];
+ spr->init(9, false); // Here comes the Duke.
+ _vm->_animation->appearPed(1, 0); // He starts at the door...
+ spr->walkTo(2); // He walks over to you.
+
+ // Let's get the door opening.
+ _vm->_background->draw(-1, -1, 0);
+ _vm->_sequence->startNaughtyDukeSeq();
+
+ addTimer(50, kProcNaughtyDuke2, kReasonNaughtyDuke);
+}
+
+void Timer::naughtyDuke2() {
+ AnimationType *spr = _vm->_animation->_sprites[1];
+ _vm->_dialogs->displayScrollChain('Q', 48); // "Ha ha, it worked again!"
+ spr->walkTo(0); // Walk to the door.
+ spr->_vanishIfStill = true; // Then go away!
+
+ addTimer(32, kProcNaughtyDuke3, kReasonNaughtyDuke);
+}
+
+void Timer::naughtyDuke3() {
+ _vm->_background->draw(-1, -1, 0);
+ _vm->_sequence->startNaughtyDukeSeq();
+}
+
+void Timer::jump() {
+ AnimationType *avvy = _vm->_animation->_sprites[0];
+
+ _vm->_jumpStatus++;
+ switch (_vm->_jumpStatus) {
+ case 1:
+ case 2:
+ case 3:
+ case 5:
+ case 7:
+ case 9:
+ avvy->_y--;
+ break;
+ case 12:
+ case 13:
+ case 14:
+ case 16:
+ case 18:
+ case 19:
+ avvy->_y++;
+ break;
+ }
+
+ if (_vm->_jumpStatus == 20) { // End of jump.
+ _vm->_userMovesAvvy = true;
+ _vm->_jumpStatus = 0;
+ } else // Still jumping.
+ addTimer(1, kProcJump, kReasonJumping);
+
+ if ((_vm->_jumpStatus == 10) // You're at the highest point of your jump.
+ && (_vm->_room == kRoomInsideCardiffCastle)
+ && (_vm->_arrowInTheDoor == true)
+ && (_vm->_animation->inField(2))) { // Beside the wall
+ // Grab the arrow!
+ if (_vm->_carryNum >= kCarryLimit)
+ _vm->_dialogs->displayText("You fail to grab it, because your hands are full.");
+ else {
+ _vm->_background->draw(-1, -1, 1);
+ _vm->_arrowInTheDoor = false; // You've got it.
+ _vm->_objects[kObjectBolt - 1] = true;
+ _vm->refreshObjectList();
+ _vm->_dialogs->displayScrollChain('Q', 50);
+ _vm->incScore(3);
+ }
+ }
+}
+
+void Timer::crapulusSaysSpludOut() {
+ _vm->_dialogs->displayScrollChain('Q', 56);
+ _vm->_crapulusWillTell = false;
+}
+
+void Timer::buyDrinks() {
+ _vm->_background->draw(-1, -1, 10); // Malagauche gets up again.
+ _vm->_malagauche = 0;
+
+ _vm->_dialogs->displayScrollChain('D', _vm->_drinking); // Display message about it.
+ _vm->_animation->wobble(); // Do the special effects.
+ _vm->_dialogs->displayScrollChain('D', 1); // That'll be thruppence.
+ if (_vm->decreaseMoney(3)) // Pay 3d.
+ _vm->_dialogs->displayScrollChain('D', 3); // Tell 'em you paid up.
+ _vm->_parser->drink();
+}
+
+void Timer::buyWine() {
+ _vm->_background->draw(-1, -1, 10); // Malagauche gets up again.
+ _vm->_malagauche = 0;
+
+ _vm->_dialogs->displayScrollChain('D', 50); // You buy the wine.
+ _vm->_dialogs->displayScrollChain('D', 1); // It'll be thruppence.
+ if (_vm->decreaseMoney(3)) {
+ _vm->_dialogs->displayScrollChain('D', 4); // You paid up.
+ _vm->_objects[kObjectWine - 1] = true;
+ _vm->refreshObjectList();
+ _vm->_wineState = 1; // OK Wine.
+ }
+}
+
+void Timer::callsGuards() {
+ _vm->_dialogs->displayScrollChain('Q', 58); // "GUARDS!!!"
+ _vm->gameOver();
+}
+
+void Timer::greetsMonk() {
+ _vm->_dialogs->displayScrollChain('Q', 59);
+ _vm->_enteredLustiesRoomAsMonk = true;
+}
+
+void Timer::fallDownOubliette() {
+ _vm->_magics[8]._operation = kMagicNothing;
+
+ AnimationType *avvy = _vm->_animation->_sprites[0];
+ avvy->_moveY++; // Increments dx/dy!
+ avvy->_y += avvy->_moveY; // Dowwwn we go...
+ addTimer(3, kProcFallDownOubliette, kReasonFallingDownOubliette);
+}
+
+void Timer::meetAvaroid() {
+ if (_vm->_metAvaroid) {
+ Common::String tmpStr = Common::String::format("You can't expect to be %cthat%c lucky twice in a row!",
+ kControlItalic, kControlRoman);
+ _vm->_dialogs->displayText(tmpStr);
+ _vm->gameOver();
+ } else {
+ _vm->_dialogs->displayScrollChain('Q', 60);
+ _vm->_metAvaroid = true;
+ addTimer(1, kProcRiseUpOubliette, kReasonRisingUpOubliette);
+
+ AnimationType *avvy = _vm->_animation->_sprites[0];
+ avvy->_facingDir = kDirLeft;
+ avvy->_x = 151;
+ avvy->_moveX = -3;
+ avvy->_moveY = -5;
+
+ _vm->_graphics->setBackgroundColor(kColorGreen);
+ }
+}
+
+void Timer::riseUpOubliette() {
+ AnimationType *avvy = _vm->_animation->_sprites[0];
+ avvy->_visible = true;
+ avvy->_moveY++; // Decrements dx/dy!
+ avvy->_y -= avvy->_moveY; // Uuuupppp we go...
+ if (avvy->_moveY > 0)
+ addTimer(3, kProcRiseUpOubliette, kReasonRisingUpOubliette);
+ else
+ _vm->_userMovesAvvy = true;
+}
+
+void Timer::robinHoodAndGeida() {
+ AnimationType *avvy = _vm->_animation->_sprites[0];
+ avvy->init(7, true);
+ _vm->_animation->appearPed(0, 6);
+ avvy->walkTo(5);
+
+ AnimationType *spr = _vm->_animation->_sprites[1];
+ spr->stopWalk();
+ spr->_facingDir = kDirLeft;
+ addTimer(20, kProcRobinHoodAndGeidaTalk, kReasonRobinHoodAndGeida);
+ _vm->_geidaFollows = false;
+}
+
+void Timer::robinHoodAndGeidaTalk() {
+ _vm->_dialogs->displayScrollChain('Q', 66);
+
+ AnimationType *avvy = _vm->_animation->_sprites[0];
+ AnimationType *spr = _vm->_animation->_sprites[1];
+ avvy->walkTo(1);
+ spr->walkTo(1);
+ avvy->_vanishIfStill = true;
+ spr->_vanishIfStill = true;
+
+ addTimer(162, kProcAvalotReturns, kReasonRobinHoodAndGeida);
+}
+
+void Timer::avalotReturns() {
+ AnimationType *avvy = _vm->_animation->_sprites[0];
+ AnimationType *spr = _vm->_animation->_sprites[1];
+ avvy->remove();
+ spr->remove();
+ avvy->init(0, true);
+ _vm->_animation->appearPed(0, 0);
+ _vm->_dialogs->displayScrollChain('Q', 67);
+ _vm->_userMovesAvvy = true;
+}
+
+/**
+ * This is used when you sit down in the pub in Notts. It loops around
+ * so that it will happen when Avvy stops walking.
+ * @remarks Originally called 'avvy_sit_down'
+ */
+void Timer::avvySitDown() {
+ AnimationType *avvy = _vm->_animation->_sprites[0];
+ if (avvy->_homing) // Still walking.
+ addTimer(1, kProcAvvySitDown, kReasonSittingDown);
+ else {
+ _vm->_background->draw(-1, -1, 2);
+ _vm->_sittingInPub = true;
+ _vm->_userMovesAvvy = false;
+ avvy->_visible = false;
+ }
+}
+
+void Timer::ghostRoomPhew() {
+ Common::String tmpStr = Common::String::format("%cPHEW!%c You're glad to get out of %cthere!",
+ kControlItalic, kControlRoman, kControlItalic);
+ _vm->_dialogs->displayText(tmpStr);
+}
+
+void Timer::arkataShouts() {
+ if (_vm->_teetotal)
+ return;
+
+ _vm->_dialogs->displayScrollChain('Q', 76);
+ addTimer(160, kProcArkataShouts, kReasonArkataShouts);
+}
+
+void Timer::winning() {
+ _vm->_dialogs->displayScrollChain('Q', 79);
+ _vm->_pingo->winningPic();
+
+ warning("STUB: Timer::winning()");
+#if 0
+ do {
+ _vm->checkclick();
+ } while (!(_vm->mrelease == 0));
+#endif
+ // TODO: To be implemented with Pingo::winningPic().
+
+ _vm->callVerb(kVerbCodeScore);
+ _vm->_dialogs->displayText(" T H E E N D ");
+ _vm->_letMeOut = true;
+}
+
+void Timer::avalotFalls() {
+ AnimationType *avvy = _vm->_animation->_sprites[0];
+ if (avvy->_stepNum < 5) {
+ avvy->_stepNum++;
+ addTimer(3, kProcAvalotFalls, kReasonFallingOver);
+ } else {
+ Common::String toDisplay = Common::String::format("%c%c%c%c%c%c%c%c%c%c%c%c%cZ%c",
+ kControlNewLine, kControlNewLine, kControlNewLine, kControlNewLine,
+ kControlNewLine, kControlNewLine, kControlInsertSpaces, kControlInsertSpaces,
+ kControlInsertSpaces, kControlInsertSpaces, kControlInsertSpaces,
+ kControlInsertSpaces, kControlRegister, kControlIcon);
+ _vm->_dialogs->displayText(toDisplay);
+ }
+}
+
+void Timer::spludwickGoesToCauldron() {
+ if (_vm->_animation->_sprites[1]->_homing)
+ addTimer(1, kProcSpludwickGoesToCauldron, kReasonSpludwickWalk);
+ else
+ addTimer(17, kProcSpludwickLeavesCauldron, kReasonSpludwickWalk);
+}
+
+void Timer::spludwickLeavesCauldron() {
+ _vm->_animation->_sprites[1]->_callEachStepFl = true; // So that normal procs will continue.
+}
+
+void Timer::giveLuteToGeida() { // Moved here from Acci.
+ _vm->_dialogs->displayScrollChain('Q', 86);
+ _vm->incScore(4);
+ _vm->_lustieIsAsleep = true;
+ _vm->_sequence->startGeidaLuteSeq();
+}
+
+void Timer::resetVariables() {
+ for (int i = 0; i < 7; i++) {
+ _times[i]._timeLeft = 0;
+ _times[i]._action = 0;
+ _times[i]._reason = 0;
+ }
+}
+
+} // End of namespace Avalanche.
diff --git a/engines/avalanche/timer.h b/engines/avalanche/timer.h
new file mode 100644
index 0000000000..9a91c4d24b
--- /dev/null
+++ b/engines/avalanche/timer.h
@@ -0,0 +1,178 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public 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 based on the original source code of Lord Avalot d'Argent version 1.3.
+ * Copyright (c) 1994-1995 Mike, Mark and Thomas Thurman.
+ */
+
+/* Original name: TIMEOUT The scheduling unit. */
+
+#ifndef AVALANCHE_TIMER_H
+#define AVALANCHE_TIMER_H
+
+namespace Avalanche {
+class AvalancheEngine;
+
+class Timer {
+public:
+ // Reason runs between 1 and 28.
+ enum Reason {
+ kReasonDrawbridgeFalls = 2,
+ kReasonAvariciusTalks = 3,
+ kReasonGoToToilet = 4,
+ kReasonExplosion = 5,
+ kReasonBrummieStairs = 6,
+ kReasonCardiffsurvey = 7,
+ kReasonCwytalotInHerts = 8,
+ kReasonGettingTiedUp = 9,
+ kReasonHangingAround = 10, // Tied to the tree in Nottingham.
+ kReasonJacquesWakingUp = 11,
+ kReasonNaughtyDuke = 12,
+ kReasonJumping = 13,
+ kReasonSequencer = 14,
+ kReasonCrapulusSaysSpludwickOut = 15,
+ kReasonDawndelay = 16,
+ kReasonDrinks = 17,
+ kReasonDuLustieTalks = 18,
+ kReasonFallingDownOubliette = 19,
+ kReasonMeetingAvaroid = 20,
+ kReasonRisingUpOubliette = 21,
+ kReasonRobinHoodAndGeida = 22,
+ kReasonSittingDown = 23,
+ kReasonGhostRoomPhew = 1,
+ kReasonArkataShouts = 24,
+ kReasonWinning = 25,
+ kReasonFallingOver = 26,
+ kReasonSpludwickWalk = 27,
+ kReasonGeidaSings = 28
+ };
+
+ // Proc runs between 1 and 41.
+ enum Proc {
+ kProcOpenDrawbridge = 3,
+ kProcAvariciusTalks = 4,
+ kProcUrinate = 5,
+ kProcToilet = 6,
+ kProcBang = 7,
+ kProcBang2 = 8,
+ kProcStairs = 9,
+ kProcCardiffSurvey = 10,
+ kProcCardiffReturn = 11,
+ kProcCwytalotInHerts = 12,
+ kProcGetTiedUp = 13,
+ kProcGetTiedUp2 = 1,
+ kProcHangAround = 14,
+ kProcHangAround2 = 15,
+ kProcAfterTheShootemup = 32,
+ kProcJacquesWakesUp = 16,
+ kProcNaughtyDuke = 17,
+ kProcNaughtyDuke2 = 18,
+ kProcNaughtyDuke3 = 38,
+ kProcJump = 19,
+ kProcSequence = 20,
+ kProcCrapulusSpludOut = 21,
+ kProcDawnDelay = 22,
+ kProcBuyDrinks = 23,
+ kProcBuyWine = 24,
+ kProcCallsGuards = 25,
+ kProcGreetsMonk = 26,
+ kProcFallDownOubliette = 27,
+ kProcMeetAvaroid = 28,
+ kProcRiseUpOubliette = 29,
+ kProcRobinHoodAndGeida = 2,
+ kProcRobinHoodAndGeidaTalk = 30,
+ kProcAvalotReturns = 31,
+ kProcAvvySitDown = 33, // In Nottingham.
+ kProcGhostRoomPhew = 34,
+ kProcArkataShouts = 35,
+ kProcWinning = 36,
+ kProcAvalotFalls = 37,
+ kProcSpludwickGoesToCauldron = 39,
+ kProcSpludwickLeavesCauldron = 40,
+ kProcGiveLuteToGeida = 41
+ };
+
+ struct TimerType {
+ int32 _timeLeft;
+ byte _action;
+ byte _reason;
+ };
+
+ TimerType _times[7];
+
+ Timer(AvalancheEngine *vm);
+
+ void resetVariables();
+ void addTimer(int32 duration, byte action, byte reason);
+ void updateTimer();
+ void loseTimer(byte which);
+
+ // Procedures to do things at the end of amounts of time:
+ void openDrawbridge();
+ void avariciusTalks();
+ void urinate();
+ void toilet();
+ void bang();
+ void bang2();
+ void stairs();
+ void cardiffSurvey();
+ void cardiffReturn();
+ void cwytalotInHerts();
+ void getTiedUp();
+ void getTiedUp2();
+ void hangAround();
+ void hangAround2();
+ void afterTheShootemup();
+ void jacquesWakesUp();
+ void naughtyDuke();
+ void naughtyDuke2();
+ void naughtyDuke3();
+ void jump();
+ void crapulusSaysSpludOut();
+ void buyDrinks();
+ void buyWine();
+ void callsGuards();
+ void greetsMonk();
+ void fallDownOubliette();
+ void meetAvaroid();
+ void riseUpOubliette();
+ void robinHoodAndGeida();
+ void robinHoodAndGeidaTalk();
+ void avalotReturns();
+ void avvySitDown();
+ void ghostRoomPhew();
+ void arkataShouts();
+ void winning();
+ void avalotFalls();
+ void spludwickGoesToCauldron();
+ void spludwickLeavesCauldron();
+ void giveLuteToGeida();
+
+private:
+ AvalancheEngine *_vm;
+
+};
+
+} // End of namespace Avalanche.
+
+#endif // AVALANCHE_TIMER_H
diff --git a/engines/cge/bitmap.cpp b/engines/cge/bitmap.cpp
index 989d2bbe99..5acd111c97 100644
--- a/engines/cge/bitmap.cpp
+++ b/engines/cge/bitmap.cpp
@@ -72,16 +72,16 @@ Bitmap::Bitmap(CGEEngine *vm, uint16 w, uint16 h, uint8 fill)
// + room for wash table
assert(v != NULL);
- *(uint16 *) v = TO_LE_16(kBmpCPY | dsiz); // data chunk hader
+ WRITE_LE_UINT16(v, (kBmpCPY | dsiz)); // data chunk hader
memset(v + 2, fill, dsiz); // data bytes
- *(uint16 *)(v + lsiz - 2) = TO_LE_16(kBmpSKP | ((kScrWidth / 4) - dsiz)); // gap
+ WRITE_LE_UINT16(v + lsiz - 2, (kBmpSKP | ((kScrWidth / 4) - dsiz))); // gap
// Replicate lines
byte *destP;
for (destP = v + lsiz; destP < (v + psiz); destP += lsiz)
Common::copy(v, v + lsiz, destP);
- *(uint16 *)(v + psiz - 2) = TO_LE_16(kBmpEOI); // plane trailer uint16
+ WRITE_LE_UINT16(v + psiz - 2, kBmpEOI); // plane trailer uint16
// Replicate planes
for (destP = v + psiz; destP < (v + 4 * psiz); destP += psiz)
diff --git a/engines/cge/cge_main.cpp b/engines/cge/cge_main.cpp
index ae4dee6090..602b36d6ef 100644
--- a/engines/cge/cge_main.cpp
+++ b/engines/cge/cge_main.cpp
@@ -539,14 +539,12 @@ void CGEEngine::setMapBrick(int x, int z) {
debugC(1, kCGEDebugEngine, "CGEEngine::setMapBrick(%d, %d)", x, z);
Square *s = new Square(this);
- if (s) {
- char n[6];
- s->gotoxy(x * kMapGridX, kMapTop + z * kMapGridZ);
- sprintf(n, "%02d:%02d", x, z);
- _clusterMap[z][x] = 1;
- s->setName(n);
- _vga->_showQ->insert(s, _vga->_showQ->first());
- }
+ char n[6];
+ s->gotoxy(x * kMapGridX, kMapTop + z * kMapGridZ);
+ sprintf(n, "%02d:%02d", x, z);
+ _clusterMap[z][x] = 1;
+ s->setName(n);
+ _vga->_showQ->insert(s, _vga->_showQ->first());
}
void CGEEngine::keyClick() {
@@ -1046,7 +1044,7 @@ void CGEEngine::loadSprite(const char *fname, int ref, int scene, int col = 0, i
for (line = sprf.readLine(); !sprf.eos(); line = sprf.readLine()) {
len = line.size();
lcnt++;
- strcpy(tmpStr, line.c_str());
+ Common::strlcpy(tmpStr, line.c_str(), sizeof(tmpStr));
if (len == 0 || *tmpStr == '.')
continue;
@@ -1132,7 +1130,7 @@ void CGEEngine::loadSprite(const char *fname, int ref, int scene, int col = 0, i
_sprite->_flags._bDel = true;
// Extract the filename, without the extension
- strcpy(_sprite->_file, fname);
+ Common::strlcpy(_sprite->_file, fname, sizeof(_sprite->_file));
char *p = strchr(_sprite->_file, '.');
if (p)
*p = '\0';
@@ -1158,7 +1156,7 @@ void CGEEngine::loadScript(const char *fname) {
char *p;
lcnt++;
- strcpy(tmpStr, line.c_str());
+ Common::strlcpy(tmpStr, line.c_str(), sizeof(tmpStr));
if ((line.size() == 0) || (*tmpStr == '.'))
continue;
diff --git a/engines/cge/configure.engine b/engines/cge/configure.engine
new file mode 100644
index 0000000000..72af1197be
--- /dev/null
+++ b/engines/cge/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 cge "CGE" yes
diff --git a/engines/cge/detection.cpp b/engines/cge/detection.cpp
index 3b01421903..c377970c51 100644
--- a/engines/cge/detection.cpp
+++ b/engines/cge/detection.cpp
@@ -117,6 +117,18 @@ static const CgeGameDescription gameDescriptions[] = {
},
{
{
+ "soltys", "Soltys Freeware v1.0",
+ {
+ {"vol.cat", 0, "fcae86b20eaa5cedec17b24fa5e85eb4", 50176},
+ {"vol.dat", 0, "ff10d54acc2c95696c57e05819b6906f", 8450151},
+ AD_LISTEND
+ },
+ Common::ES_ESP, Common::kPlatformDOS, ADGF_NO_FLAGS , GUIO0()
+ },
+ kGameTypeSoltys
+ },
+ {
+ {
// Polish version, provided by Strangerke
"sfinx", "Sfinx Freeware",
{
diff --git a/engines/cge/fileio.cpp b/engines/cge/fileio.cpp
index 609d5e86aa..8ee726c46d 100644
--- a/engines/cge/fileio.cpp
+++ b/engines/cge/fileio.cpp
@@ -70,7 +70,7 @@ ResourceManager::ResourceManager() {
_catFile = new Common::File();
_catFile->open(kCatName);
- if ((!_datFile) || (!_catFile))
+ if (!_datFile->isOpen() || !_catFile->isOpen())
error("Unable to open data files");
for (int i = 0; i < kBtLevel; i++) {
@@ -93,8 +93,8 @@ ResourceManager::~ResourceManager() {
delete _buff[i]._page;
}
-uint16 ResourceManager::XCrypt(void *buf, uint16 length) {
- byte *b = static_cast<byte *>(buf);
+uint16 ResourceManager::XCrypt(byte *buf, uint16 length) {
+ byte *b = buf;
for (uint16 i = 0; i < length; i++)
*b++ ^= kCryptSeed;
@@ -106,7 +106,7 @@ bool ResourceManager::seek(int32 offs, int whence) {
return _datFile->seek(offs, whence);
}
-uint16 ResourceManager::read(void *buf, uint16 length) {
+uint16 ResourceManager::read(byte *buf, uint16 length) {
if (!_datFile->isOpen())
return 0;
@@ -178,7 +178,7 @@ bool ResourceManager::exist(const char *name) {
return scumm_stricmp(find(name)->_key, name) == 0;
}
-uint16 ResourceManager::catRead(void *buf, uint16 length) {
+uint16 ResourceManager::catRead(byte *buf, uint16 length) {
if (!_catFile->isOpen())
return 0;
@@ -225,7 +225,7 @@ EncryptedStream::EncryptedStream(CGEEngine *vm, const char *name) : _vm(vm) {
_readStream = new Common::MemoryReadStream(dataBuffer, bufSize, DisposeAfterUse::YES);
}
-uint32 EncryptedStream::read(void *dataPtr, uint32 dataSize) {
+uint32 EncryptedStream::read(byte *dataPtr, uint32 dataSize) {
return _readStream->read(dataPtr, dataSize);
}
diff --git a/engines/cge/fileio.h b/engines/cge/fileio.h
index cee1fa79ef..653aabae8f 100644
--- a/engines/cge/fileio.h
+++ b/engines/cge/fileio.h
@@ -83,15 +83,15 @@ class ResourceManager {
} _buff[kBtLevel];
BtPage *getPage(int level, uint16 pageId);
- uint16 catRead(void *buf, uint16 length);
+ uint16 catRead(byte *buf, uint16 length);
Common::File *_catFile;
Common::File *_datFile;
- uint16 XCrypt(void *buf, uint16 length);
+ uint16 XCrypt(byte *buf, uint16 length);
public:
ResourceManager();
~ResourceManager();
- uint16 read(void *buf, uint16 length);
+ uint16 read(byte *buf, uint16 length);
bool seek(int32 offs, int whence = 0);
BtKeypack *find(const char *key);
@@ -111,7 +111,7 @@ public:
bool seek(int32 offset);
int32 pos();
int32 size();
- uint32 read(void *dataPtr, uint32 dataSize);
+ uint32 read(byte *dataPtr, uint32 dataSize);
Common::String readLine();
};
diff --git a/engines/cge/sound.cpp b/engines/cge/sound.cpp
index b378898955..892b826318 100644
--- a/engines/cge/sound.cpp
+++ b/engines/cge/sound.cpp
@@ -186,6 +186,10 @@ DataCk *Fx::load(int idx, int ref) {
DataCk *Fx::loadWave(EncryptedStream *file) {
byte *data = (byte *)malloc(file->size());
+
+ if (!data)
+ return 0;
+
file->read(data, file->size());
return new DataCk(data, file->size());
diff --git a/engines/cge/text.cpp b/engines/cge/text.cpp
index 27bb0608fd..08ff005e1e 100644
--- a/engines/cge/text.cpp
+++ b/engines/cge/text.cpp
@@ -69,7 +69,7 @@ int16 Text::count() {
for (line = tf.readLine(); !tf.eos(); line = tf.readLine()) {
char *s;
assert(line.size() <= 513);
- strcpy(tmpStr, line.c_str());
+ Common::strlcpy(tmpStr, line.c_str(), sizeof(tmpStr));
if ((s = strtok(tmpStr, " =,;/\t\n")) == NULL)
continue;
if (!Common::isDigit(*s))
@@ -101,8 +101,7 @@ void Text::load() {
for (idx = 0, line = tf.readLine(); !tf.eos(); line = tf.readLine()) {
int n = line.size();
char *s;
- assert(n <= 513);
- strcpy(tmpStr, line.c_str());
+ Common::strlcpy(tmpStr, line.c_str(), sizeof(tmpStr));
if ((s = strtok(tmpStr, " =,;/\t\n")) == NULL)
continue;
if (!Common::isDigit(*s))
diff --git a/engines/cge/vga13h.cpp b/engines/cge/vga13h.cpp
index c0407cab42..4954e638ab 100644
--- a/engines/cge/vga13h.cpp
+++ b/engines/cge/vga13h.cpp
@@ -214,8 +214,7 @@ Sprite *Sprite::expand() {
for (line = sprf.readLine(); !sprf.eos(); line = sprf.readLine()) {
len = line.size();
- assert(len <= 513);
- strcpy(tmpStr, line.c_str());
+ Common::strlcpy(tmpStr, line.c_str(), sizeof(tmpStr));
lcnt++;
if (len == 0 || *tmpStr == '.')
continue;
diff --git a/engines/cine/configure.engine b/engines/cine/configure.engine
new file mode 100644
index 0000000000..2b7e2085fa
--- /dev/null
+++ b/engines/cine/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 cine "Cinematique evo 1" yes
diff --git a/engines/cine/script_fw.cpp b/engines/cine/script_fw.cpp
index 176380c14f..2abe32f797 100644
--- a/engines/cine/script_fw.cpp
+++ b/engines/cine/script_fw.cpp
@@ -380,8 +380,7 @@ RawScript::RawScript(const FWScriptInfo &info, const byte *data, uint16 s) :
* Copy constructor
*/
RawScript::RawScript(const RawScript &src) : _size(src._size),
- _data(new byte[_size + 1]), _labels(src._labels) {
-
+ _data(new byte[src._size + 1]), _labels(src._labels) {
assert(_data);
memcpy(_data, src._data, _size + 1);
}
diff --git a/engines/cine/sound.cpp b/engines/cine/sound.cpp
index 10404ae56b..de6f91d8c3 100644
--- a/engines/cine/sound.cpp
+++ b/engines/cine/sound.cpp
@@ -281,7 +281,7 @@ void PCSoundDriver::resetChannel(int channel) {
}
AdLibSoundDriver::AdLibSoundDriver(Audio::Mixer *mixer)
- : _mixer(mixer) {
+ : _upCb(0), _upRef(0), _mixer(mixer) {
_sampleRate = _mixer->getOutputRate();
_opl = makeAdLibOPL(_sampleRate);
memset(_channelsVolumeTable, 0, sizeof(_channelsVolumeTable));
@@ -309,9 +309,7 @@ void AdLibSoundDriver::setupChannel(int channel, const byte *data, int instrumen
volume = 0;
}
volume += volume / 4;
- if (volume > 127) {
- volume = 127;
- }
+
_channelsVolumeTable[channel] = volume;
setupInstrument(data, channel);
}
diff --git a/engines/composer/composer.cpp b/engines/composer/composer.cpp
index 5db778dfda..10906480fe 100644
--- a/engines/composer/composer.cpp
+++ b/engines/composer/composer.cpp
@@ -42,12 +42,23 @@
#include "composer/composer.h"
#include "composer/graphics.h"
#include "composer/resource.h"
+#include "composer/console.h"
namespace Composer {
ComposerEngine::ComposerEngine(OSystem *syst, const ComposerGameDescription *gameDesc) : Engine(syst), _gameDescription(gameDesc) {
_rnd = new Common::RandomSource("composer");
_audioStream = NULL;
+ _currSoundPriority = 0;
+ _currentTime = 0;
+ _lastTime = 0;
+ _needsUpdate = true;
+ _directoriesToStrip = 1;
+ _mouseVisible = true;
+ _mouseEnabled = false;
+ _mouseSpriteId = 0;
+ _lastButton = NULL;
+ _console = NULL;
}
ComposerEngine::~ComposerEngine() {
@@ -64,6 +75,7 @@ ComposerEngine::~ComposerEngine() {
i->_surface.free();
delete _rnd;
+ delete _console;
}
Common::Error ComposerEngine::run() {
@@ -79,12 +91,6 @@ Common::Error ComposerEngine::run() {
_queuedScripts[i]._scriptId = 0;
}
- _mouseVisible = true;
- _mouseEnabled = false;
- _mouseSpriteId = 0;
- _lastButton = NULL;
-
- _directoriesToStrip = 1;
if (!_bookIni.loadFromFile("book.ini")) {
_directoriesToStrip = 0;
if (!_bookIni.loadFromFile("programs/book.ini")) {
@@ -103,7 +109,6 @@ Common::Error ComposerEngine::run() {
height = atoi(getStringFromConfig("Common", "Height").c_str());
initGraphics(width, height, true);
_screen.create(width, height, Graphics::PixelFormat::createFormatCLUT8());
- _needsUpdate = true;
Graphics::Cursor *cursor = Graphics::makeDefaultWinCursor();
CursorMan.replaceCursor(cursor->getSurface(), cursor->getWidth(), cursor->getHeight(), cursor->getHotspotX(),
@@ -111,13 +116,16 @@ Common::Error ComposerEngine::run() {
CursorMan.replaceCursorPalette(cursor->getPalette(), cursor->getPaletteStartIndex(), cursor->getPaletteCount());
delete cursor;
- loadLibrary(0);
+ _console = new Console(this);
- _currentTime = 0;
- _lastTime = 0;
+ loadLibrary(0);
uint fps = atoi(getStringFromConfig("Common", "FPS").c_str());
- uint frameTime = 1000 / fps;
+ uint frameTime = 125; // Default to 125ms (1000/8)
+ if (fps != 0)
+ frameTime = 1000 / fps;
+ else
+ warning("FPS in book.ini is zero. Defaulting to 8...");
uint32 lastDrawTime = 0;
while (!shouldQuit()) {
@@ -187,11 +195,11 @@ Common::Error ComposerEngine::run() {
case Common::EVENT_KEYDOWN:
switch (event.kbd.keycode) {
case Common::KEYCODE_d:
- /*if (event.kbd.hasFlags(Common::KBD_CTRL)) {
+ if (event.kbd.hasFlags(Common::KBD_CTRL)) {
// Start the debugger
getDebugger()->attach();
getDebugger()->onFrame();
- }*/
+ }
break;
case Common::KEYCODE_q:
diff --git a/engines/composer/composer.h b/engines/composer/composer.h
index 7d8022455a..f945df8bb1 100644
--- a/engines/composer/composer.h
+++ b/engines/composer/composer.h
@@ -34,11 +34,14 @@
#include "engines/engine.h"
#include "engines/util.h"
+#include "gui/debugger.h"
+
#include "graphics/surface.h"
#include "audio/mixer.h"
#include "composer/resource.h"
+#include "composer/console.h"
namespace Audio {
class QueuingAudioStream;
@@ -159,6 +162,9 @@ public:
const ComposerGameDescription *_gameDescription;
+ Console *_console;
+ GUI::Debugger *getDebugger() { return _console; }
+
private:
Common::RandomSource *_rnd;
diff --git a/engines/composer/configure.engine b/engines/composer/configure.engine
new file mode 100644
index 0000000000..71a79acb5d
--- /dev/null
+++ b/engines/composer/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 composer "Magic Composer" yes
diff --git a/engines/composer/console.cpp b/engines/composer/console.cpp
new file mode 100644
index 0000000000..8c68b3205b
--- /dev/null
+++ b/engines/composer/console.cpp
@@ -0,0 +1,31 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public 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 "composer/composer.h"
+
+namespace Composer {
+
+Console::Console(ComposerEngine *vm) : GUI::Debugger() {
+ _vm = vm;
+}
+
+} // End of namespace Composer
diff --git a/engines/composer/console.h b/engines/composer/console.h
new file mode 100644
index 0000000000..0567d8bc6f
--- /dev/null
+++ b/engines/composer/console.h
@@ -0,0 +1,40 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public 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 COMPOSER_CONSOLE_H
+#define COMPOSER_CONSOLE_H
+
+namespace Composer {
+
+class ComposerEngine;
+
+class Console : public GUI::Debugger {
+public:
+ Console(ComposerEngine *vm);
+
+private:
+ ComposerEngine *_vm;
+};
+
+} // End of namespace Composer
+
+#endif /* COMPOSER_CONSOLE_H */
diff --git a/engines/composer/module.mk b/engines/composer/module.mk
index 8bfaf932e8..c879d53630 100644
--- a/engines/composer/module.mk
+++ b/engines/composer/module.mk
@@ -1,6 +1,7 @@
MODULE := engines/composer
MODULE_OBJS = \
+ console.o \
composer.o \
detection.o \
graphics.o \
diff --git a/engines/configure.engines b/engines/configure.engines
deleted file mode 100644
index 13611a5037..0000000000
--- a/engines/configure.engines
+++ /dev/null
@@ -1,56 +0,0 @@
-# This file is included from the main "configure" script
-# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps]
-add_engine scumm "SCUMM" yes "scumm_7_8 he" "v0-v6 games"
-add_engine scumm_7_8 "v7 & v8 games" yes
-add_engine he "HE71+ games" yes
-add_engine agi "AGI" yes
-add_engine agos "AGOS" yes "agos2" "AGOS 1 games"
-add_engine agos2 "AGOS 2 games" yes
-add_engine cge "CGE" yes
-add_engine cine "Cinematique evo 1" yes
-add_engine composer "Magic Composer" yes
-add_engine cruise "Cinematique evo 2" yes
-add_engine draci "Dragon History" yes
-add_engine drascula "Drascula: The Vampire Strikes Back" yes
-add_engine dreamweb "Dreamweb" yes
-add_engine fullpipe "Full Pipe" no
-add_engine gob "Gobli*ns" yes
-add_engine groovie "Groovie" yes "groovie2" "7th Guest"
-add_engine groovie2 "Groovie 2 games" no "" "" "jpeg"
-add_engine hopkins "Hopkins FBI" yes "" "" "16bit"
-add_engine hugo "Hugo Trilogy" yes
-add_engine kyra "Kyra" yes "lol eob" "Legend of Kyrandia 1-3"
-add_engine lol "Lands of Lore" yes
-add_engine eob "Eye of the Beholder" yes
-add_engine lastexpress "The Last Express" no "" "" "16bit"
-add_engine lure "Lure of the Temptress" yes
-add_engine made "MADE" yes
-add_engine mohawk "Mohawk" yes "cstime myst riven" "Living Books"
-add_engine mortevielle "Mortevielle" no
-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 neverhood "Neverhood" no
-add_engine parallaction "Parallaction" yes
-add_engine pegasus "The Journeyman Project: Pegasus Prime" yes "" "" "16bit"
-add_engine queen "Flight of the Amazon Queen" yes
-add_engine saga "SAGA" yes "ihnm saga2" "ITE"
-add_engine ihnm "IHNM" yes
-add_engine saga2 "SAGA 2 games" no
-add_engine sci "SCI" yes "sci32" "SCI 0-1.1 games"
-add_engine sci32 "SCI32 games" no
-add_engine sky "Beneath a Steel Sky" yes
-add_engine sword1 "Broken Sword" yes
-add_engine sword2 "Broken Sword II" yes
-add_engine sword25 "Broken Sword 2.5" no "" "" "png zlib 16bit"
-add_engine teenagent "Teen Agent" yes
-add_engine testbed "TestBed: the Testing framework" no
-add_engine tinsel "Tinsel" yes
-add_engine toltecs "3 Skulls of the Toltecs" yes
-add_engine toon "Toonstruck" yes
-add_engine touche "Touche: The Adventures of the Fifth Musketeer" yes
-add_engine tony "Tony Tough and the Night of Roasted Moths" yes "" "" "16bit"
-add_engine tsage "TsAGE" yes
-add_engine tucker "Bud Tucker in Double Trouble" yes
-add_engine wintermute "Wintermute" no "" "" "jpeg png zlib vorbis 16bit"
-add_engine bbvs "Beavis and Butthead in Virtual Stupidity" no
diff --git a/engines/cruise/configure.engine b/engines/cruise/configure.engine
new file mode 100644
index 0000000000..925da25370
--- /dev/null
+++ b/engines/cruise/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 cruise "Cinematique evo 2" yes
diff --git a/engines/draci/barchive.cpp b/engines/draci/barchive.cpp
index 31dfe62dee..584367fdfb 100644
--- a/engines/draci/barchive.cpp
+++ b/engines/draci/barchive.cpp
@@ -203,12 +203,12 @@ void BArchive::openArchive(const Common::String &path) {
uint32 fileOffset;
fileOffset = reader.readUint32LE();
- _f.seek(fileOffset); // Seek to next file in archive
+ _f.seek(fileOffset); // Seek to next file in archive
- _files[i]._compLength = _f.readUint16LE(); // Compressed size
+ _files[i]._compLength = _f.readUint16LE(); // Compressed size
// should be the same as uncompressed
- _files[i]._length = _f.readUint16LE(); // Original size
+ _files[i]._length = _f.readUint16LE(); // Original size
_files[i]._offset = fileOffset; // Offset of file from start
@@ -216,9 +216,9 @@ void BArchive::openArchive(const Common::String &path) {
assert(compressionType == 0 &&
"Compression type flag is non-zero (file is compressed)");
- _files[i]._crc = _f.readByte(); // CRC checksum of the file
- _files[i]._data = NULL; // File data will be read in on demand
- _files[i]._stopper = 0; // Dummy value; not used in BAR files, needed in DFW
+ _files[i]._crc = _f.readByte(); // CRC checksum of the file
+ _files[i]._data = NULL; // File data will be read in on demand
+ _files[i]._stopper = 0; // Dummy value; not used in BAR files, needed in DFW
}
// Last footer item should be equal to footerOffset
diff --git a/engines/draci/configure.engine b/engines/draci/configure.engine
new file mode 100644
index 0000000000..09022b06f5
--- /dev/null
+++ b/engines/draci/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 draci "Dragon History" yes
diff --git a/engines/draci/draci.cpp b/engines/draci/draci.cpp
index 6aa8477887..06730cfba7 100644
--- a/engines/draci/draci.cpp
+++ b/engines/draci/draci.cpp
@@ -92,6 +92,32 @@ DraciEngine::DraciEngine(OSystem *syst, const ADGameDescription *gameDesc)
DebugMan.addDebugChannel(kDraciWalkingDebugLevel, "walking", "Walking debug info");
_console = new DraciConsole(this);
+
+ _screen = 0;
+ _mouse = 0;
+ _game = 0;
+ _script = 0;
+ _anims = 0;
+ _sound = 0;
+ _music = 0;
+ _smallFont = 0;
+ _bigFont = 0;
+ _iconsArchive = 0;
+ _objectsArchive = 0;
+ _spritesArchive = 0;
+ _paletteArchive = 0;
+ _roomsArchive = 0;
+ _overlaysArchive = 0;
+ _animationsArchive = 0;
+ _walkingMapsArchive = 0;
+ _itemsArchive = 0;
+ _itemImagesArchive = 0;
+ _initArchive = 0;
+ _stringsArchive = 0;
+ _soundsArchive = 0;
+ _dubbingArchive = 0;
+ _showWalkingMap = 0;
+ _pauseStartTime = 0;
}
bool DraciEngine::hasFeature(EngineFeature f) const {
diff --git a/engines/draci/game.cpp b/engines/draci/game.cpp
index c4108cc0c7..009f1bb3d2 100644
--- a/engines/draci/game.cpp
+++ b/engines/draci/game.cpp
@@ -52,6 +52,55 @@ enum {
Game::Game(DraciEngine *vm) : _vm(vm), _walkingState(vm) {
uint i;
+ _dialogueLinesNum = 0;
+ _blockNum = 0;
+
+ for (i = 0; i < kDialogueLines; i++)
+ _dialogueAnims[0] = 0;
+
+ _loopStatus = kStatusOrdinary;
+ _loopSubstatus = kOuterLoop;
+ _shouldQuit = 0;
+ _shouldExitLoop = 0;
+ _isReloaded = 0;
+ _speechTick = 0;
+ _speechDuration = 0;
+ _objUnderCursor = 0;
+ _animUnderCursor = 0;
+ _markedAnimationIndex = 0;
+ _scheduledPalette = 0;
+ _fadePhases = 0;
+ _fadePhase = 0;
+ _fadeTick = 0;
+ _mouseChangeTick = 0;
+ _enableQuickHero = 0;
+ _wantQuickHero = 0;
+ _enableSpeedText = 0;
+ _titleAnim = 0;
+ _inventoryAnim = 0;
+ _walkingMapOverlay = 0;
+ _walkingShortestPathOverlay = 0;
+ _walkingObliquePathOverlay = 0;
+ _currentItem = 0;
+ _itemUnderCursor = 0;
+ _previousItemPosition = 0;
+
+ for (i = 0; i < kInventorySlots; i++)
+ _inventory[i] = 0;
+
+ _newRoom = 0;
+ _newGate = 0;
+ _previousRoom = 0;
+ _pushedNewRoom = 0;
+ _pushedNewGate = 0;
+ _currentDialogue = 0;
+ _dialogueArchive = 0;
+ _dialogueBlocks = 0;
+ _dialogueBegin = 0;
+ _dialogueExit = 0;
+ _currentBlock = 0;
+ _lastBlock = 0;
+
BArchive *initArchive = _vm->_initArchive;
const BAFile *file;
@@ -951,9 +1000,9 @@ void Game::dialogueMenu(int dialogueID) {
debugC(7, kDraciLogicDebugLevel,
"hit: %d, _lines[hit]: %d, lastblock: %d, dialogueLines: %d, dialogueExit: %d",
- hit, _lines[hit], _lastBlock, _dialogueLinesNum, _dialogueExit);
+ hit, (hit >= 0 ? _lines[hit] : -1), _lastBlock, _dialogueLinesNum, _dialogueExit);
- if ((!_dialogueExit) && (hit != -1) && (_lines[hit] != -1)) {
+ if ((!_dialogueExit) && (hit >= 0) && (_lines[hit] != -1)) {
if ((oldLines == 1) && (_dialogueLinesNum == 1) && (_lines[hit] == _lastBlock)) {
break;
}
@@ -1361,7 +1410,7 @@ void Game::enterNewRoom() {
// for the dragon in the persons array
if (_newRoom == _info._mapRoom) {
_persons[kDragonObject]._x = 160;
- _persons[kDragonObject]._y = 0;
+ _persons[kDragonObject]._y = 0;
}
// Set the appropriate loop status before loading the room
diff --git a/engines/draci/script.cpp b/engines/draci/script.cpp
index 8ff60033ed..504476869e 100644
--- a/engines/draci/script.cpp
+++ b/engines/draci/script.cpp
@@ -41,65 +41,65 @@ namespace Draci {
void Script::setupCommandList() {
/** A table of all the commands the game player uses */
static const GPL2Command gplCommands[] = {
- { 0, 0, "gplend", 0, { }, NULL },
- { 0, 1, "exit", 0, { }, NULL },
- { 1, 1, "goto", 1, { kGPL2Ident }, &Script::c_Goto },
- { 2, 1, "Let", 2, { kGPL2Ident, kGPL2Math }, &Script::c_Let },
- { 3, 1, "if", 2, { kGPL2Math, kGPL2Ident }, &Script::c_If },
- { 4, 1, "Start", 2, { kGPL2Ident, kGPL2Str }, &Script::start },
- { 5, 1, "Load", 2, { kGPL2Ident, kGPL2Str }, &Script::load },
- { 5, 2, "StartPlay", 2, { kGPL2Ident, kGPL2Str }, &Script::startPlay },
- { 5, 3, "JustTalk", 0, { }, &Script::justTalk },
- { 5, 4, "JustStay", 0, { }, &Script::justStay },
- { 6, 1, "Talk", 2, { kGPL2Ident, kGPL2Str }, &Script::talk },
- { 7, 1, "ObjStat", 2, { kGPL2Ident, kGPL2Ident }, &Script::objStat },
- { 7, 2, "ObjStat_On", 2, { kGPL2Ident, kGPL2Ident }, &Script::objStatOn },
- { 8, 1, "IcoStat", 2, { kGPL2Ident, kGPL2Ident }, &Script::icoStat },
- { 9, 1, "Dialogue", 1, { kGPL2Str }, &Script::dialogue },
- { 9, 2, "ExitDialogue", 0, { }, &Script::exitDialogue },
- { 9, 3, "ResetDialogue", 0, { }, &Script::resetDialogue },
- { 9, 4, "ResetDialogueFrom", 0, { }, &Script::resetDialogueFrom },
- { 9, 5, "ResetBlock", 1, { kGPL2Ident }, &Script::resetBlock },
- { 10, 1, "WalkOn", 3, { kGPL2Num, kGPL2Num, kGPL2Ident }, &Script::walkOn },
- { 10, 2, "StayOn", 3, { kGPL2Num, kGPL2Num, kGPL2Ident }, &Script::stayOn },
- { 10, 3, "WalkOnPlay", 3, { kGPL2Num, kGPL2Num, kGPL2Ident }, &Script::walkOnPlay },
- { 11, 1, "LoadPalette", 1, { kGPL2Str }, &Script::loadPalette },
- { 12, 1, "SetPalette", 0, { }, &Script::setPalette },
- { 12, 2, "BlackPalette", 0, { }, &Script::blackPalette },
- { 13, 1, "FadePalette", 3, { kGPL2Num, kGPL2Num, kGPL2Num }, &Script::fadePalette },
- { 13, 2, "FadePalettePlay", 3, { kGPL2Num, kGPL2Num, kGPL2Num }, &Script::fadePalettePlay },
- { 14, 1, "NewRoom", 2, { kGPL2Ident, kGPL2Num }, &Script::newRoom },
- { 15, 1, "ExecInit", 1, { kGPL2Ident }, &Script::execInit },
- { 15, 2, "ExecLook", 1, { kGPL2Ident }, &Script::execLook },
- { 15, 3, "ExecUse", 1, { kGPL2Ident }, &Script::execUse },
- { 18, 1, "LoadMusic", 1, { kGPL2Str }, &Script::loadMusic },
- { 18, 2, "StartMusic", 0, { }, &Script::startMusic },
- { 18, 3, "StopMusic", 0, { }, &Script::stopMusic },
- { 19, 1, "Mark", 0, { }, &Script::mark },
- { 19, 2, "Release", 0, { }, &Script::release },
- { 20, 1, "Play", 0, { }, &Script::play },
- { 21, 1, "LoadMap", 1, { kGPL2Str }, &Script::loadMap },
- { 21, 2, "RoomMap", 0, { }, &Script::roomMap },
- { 22, 1, "DisableQuickHero", 0, { }, &Script::disableQuickHero },
- { 22, 2, "EnableQuickHero", 0, { }, &Script::enableQuickHero },
- { 23, 1, "DisableSpeedText", 0, { }, &Script::disableSpeedText },
- { 23, 2, "EnableSpeedText", 0, { }, &Script::enableSpeedText },
- { 24, 1, "QuitGame", 0, { }, &Script::quitGame },
- { 25, 1, "PushNewRoom", 0, { }, &Script::pushNewRoom },
- { 25, 2, "PopNewRoom", 0, { }, &Script::popNewRoom },
+ { 0, 0, "gplend", 0, { }, NULL },
+ { 0, 1, "exit", 0, { }, NULL },
+ { 1, 1, "goto", 1, { kGPL2Ident }, &Script::c_Goto },
+ { 2, 1, "Let", 2, { kGPL2Ident, kGPL2Math }, &Script::c_Let },
+ { 3, 1, "if", 2, { kGPL2Math, kGPL2Ident }, &Script::c_If },
+ { 4, 1, "Start", 2, { kGPL2Ident, kGPL2Str }, &Script::start },
+ { 5, 1, "Load", 2, { kGPL2Ident, kGPL2Str }, &Script::load },
+ { 5, 2, "StartPlay", 2, { kGPL2Ident, kGPL2Str }, &Script::startPlay },
+ { 5, 3, "JustTalk", 0, { }, &Script::justTalk },
+ { 5, 4, "JustStay", 0, { }, &Script::justStay },
+ { 6, 1, "Talk", 2, { kGPL2Ident, kGPL2Str }, &Script::talk },
+ { 7, 1, "ObjStat", 2, { kGPL2Ident, kGPL2Ident }, &Script::objStat },
+ { 7, 2, "ObjStat_On", 2, { kGPL2Ident, kGPL2Ident }, &Script::objStatOn },
+ { 8, 1, "IcoStat", 2, { kGPL2Ident, kGPL2Ident }, &Script::icoStat },
+ { 9, 1, "Dialogue", 1, { kGPL2Str }, &Script::dialogue },
+ { 9, 2, "ExitDialogue", 0, { }, &Script::exitDialogue },
+ { 9, 3, "ResetDialogue", 0, { }, &Script::resetDialogue },
+ { 9, 4, "ResetDialogueFrom", 0, { }, &Script::resetDialogueFrom },
+ { 9, 5, "ResetBlock", 1, { kGPL2Ident }, &Script::resetBlock },
+ { 10, 1, "WalkOn", 3, { kGPL2Num, kGPL2Num, kGPL2Ident }, &Script::walkOn },
+ { 10, 2, "StayOn", 3, { kGPL2Num, kGPL2Num, kGPL2Ident }, &Script::stayOn },
+ { 10, 3, "WalkOnPlay", 3, { kGPL2Num, kGPL2Num, kGPL2Ident }, &Script::walkOnPlay },
+ { 11, 1, "LoadPalette", 1, { kGPL2Str }, &Script::loadPalette },
+ { 12, 1, "SetPalette", 0, { }, &Script::setPalette },
+ { 12, 2, "BlackPalette", 0, { }, &Script::blackPalette },
+ { 13, 1, "FadePalette", 3, { kGPL2Num, kGPL2Num, kGPL2Num }, &Script::fadePalette },
+ { 13, 2, "FadePalettePlay", 3, { kGPL2Num, kGPL2Num, kGPL2Num }, &Script::fadePalettePlay },
+ { 14, 1, "NewRoom", 2, { kGPL2Ident, kGPL2Num }, &Script::newRoom },
+ { 15, 1, "ExecInit", 1, { kGPL2Ident }, &Script::execInit },
+ { 15, 2, "ExecLook", 1, { kGPL2Ident }, &Script::execLook },
+ { 15, 3, "ExecUse", 1, { kGPL2Ident }, &Script::execUse },
+ { 18, 1, "LoadMusic", 1, { kGPL2Str }, &Script::loadMusic },
+ { 18, 2, "StartMusic", 0, { }, &Script::startMusic },
+ { 18, 3, "StopMusic", 0, { }, &Script::stopMusic },
+ { 19, 1, "Mark", 0, { }, &Script::mark },
+ { 19, 2, "Release", 0, { }, &Script::release },
+ { 20, 1, "Play", 0, { }, &Script::play },
+ { 21, 1, "LoadMap", 1, { kGPL2Str }, &Script::loadMap },
+ { 21, 2, "RoomMap", 0, { }, &Script::roomMap },
+ { 22, 1, "DisableQuickHero", 0, { }, &Script::disableQuickHero },
+ { 22, 2, "EnableQuickHero", 0, { }, &Script::enableQuickHero },
+ { 23, 1, "DisableSpeedText", 0, { }, &Script::disableSpeedText },
+ { 23, 2, "EnableSpeedText", 0, { }, &Script::enableSpeedText },
+ { 24, 1, "QuitGame", 0, { }, &Script::quitGame },
+ { 25, 1, "PushNewRoom", 0, { }, &Script::pushNewRoom },
+ { 25, 2, "PopNewRoom", 0, { }, &Script::popNewRoom },
// The following commands are not used in the original game files.
- { 16, 1, "RepaintInventory", 0, { }, NULL },
- { 16, 2, "ExitInventory", 0, { }, NULL },
- { 17, 1, "ExitMap", 0, { }, NULL },
- { 18, 4, "FadeOutMusic", 1, { kGPL2Num }, NULL },
- { 18, 5, "FadeInMusic", 1, { kGPL2Num }, NULL },
+ { 16, 1, "RepaintInventory", 0, { }, NULL },
+ { 16, 2, "ExitInventory", 0, { }, NULL },
+ { 17, 1, "ExitMap", 0, { }, NULL },
+ { 18, 4, "FadeOutMusic", 1, { kGPL2Num }, NULL },
+ { 18, 5, "FadeInMusic", 1, { kGPL2Num }, NULL },
// The following commands are not even defined in the game
// sources, but their numbers are allocated for internal
// purposes of the old player.
- { 26, 1, "ShowCheat", 0, { }, NULL },
- { 26, 2, "HideCheat", 0, { }, NULL },
- { 26, 3, "ClearCheat", 1, { kGPL2Num }, NULL },
- { 27, 1, "FeedPassword", 3, { kGPL2Num, kGPL2Num, kGPL2Num }, NULL }
+ { 26, 1, "ShowCheat", 0, { }, NULL },
+ { 26, 2, "HideCheat", 0, { }, NULL },
+ { 26, 3, "ClearCheat", 1, { kGPL2Num }, NULL },
+ { 27, 1, "FeedPassword", 3, { kGPL2Num, kGPL2Num, kGPL2Num }, NULL }
};
/** Operators used by the mathematical evaluator */
diff --git a/engines/draci/sprite.cpp b/engines/draci/sprite.cpp
index 965cdabf3e..9a78904d25 100644
--- a/engines/draci/sprite.cpp
+++ b/engines/draci/sprite.cpp
@@ -38,9 +38,9 @@ const Displacement kNoDisplacement = { 0, 0, 1.0, 1.0 };
* height height of the image in the buffer
*/
static void transformToRows(byte *img, uint16 width, uint16 height) {
- byte *buf = new byte[width * height];
+ byte *buf = new byte[(uint)(width * height)];
byte *tmp = buf;
- memcpy(buf, img, width * height);
+ memcpy(buf, img, (uint)(width * height));
for (uint16 i = 0; i < width; ++i) {
for (uint16 j = 0; j < height; ++j) {
diff --git a/engines/draci/surface.cpp b/engines/draci/surface.cpp
index 3676c6edac..4156398070 100644
--- a/engines/draci/surface.cpp
+++ b/engines/draci/surface.cpp
@@ -82,7 +82,7 @@ void Surface::markClean() {
void Surface::fill(uint color) {
byte *ptr = (byte *)getPixels();
- memset(ptr, color, w * h);
+ memset(ptr, color, (uint)(w * h));
}
/**
diff --git a/engines/draci/walking.cpp b/engines/draci/walking.cpp
index f1ae769d80..195b968860 100644
--- a/engines/draci/walking.cpp
+++ b/engines/draci/walking.cpp
@@ -556,9 +556,15 @@ bool WalkingState::alignHeroToEdge(const Common::Point &p1, const Common::Point
}
bool reachedEnd;
if (movement == kMoveLeft || movement == kMoveRight) {
+ if (p2Diff.x == 0) {
+ error("Wrong value for horizontal movement");
+ }
reachedEnd = movement == kMoveLeft ? hero->x <= p2.x : hero->x >= p2.x;
hero->y += hero->x * p2Diff.y / p2Diff.x - prevHero.x * p2Diff.y / p2Diff.x;
} else {
+ if (p2Diff.y == 0) {
+ error("Wrong value for vertical movement");
+ }
reachedEnd = movement == kMoveUp ? hero->y <= p2.y : hero->y >= p2.y;
hero->x += hero->y * p2Diff.x / p2Diff.y - prevHero.y * p2Diff.x / p2Diff.y;
}
diff --git a/engines/draci/walking.h b/engines/draci/walking.h
index a43aeb272a..7e4a3184f5 100644
--- a/engines/draci/walking.h
+++ b/engines/draci/walking.h
@@ -103,7 +103,17 @@ struct GPL2Program;
class WalkingState {
public:
- explicit WalkingState(DraciEngine *vm) : _vm(vm) { stopWalking(); }
+ explicit WalkingState(DraciEngine *vm) : _vm(vm) {
+ _dir = kDirectionLast;
+ _startingDirection = kMoveUndefined;
+ _segment = 0;
+ _lastAnimPhase = 0;
+ _turningFinished = 0;
+ _callbackOffset = 0;
+
+ stopWalking();
+ }
+
~WalkingState() {}
void stopWalking();
diff --git a/engines/drascula/animation.cpp b/engines/drascula/animation.cpp
index 1145c8c3ff..ee981c36da 100644
--- a/engines/drascula/animation.cpp
+++ b/engines/drascula/animation.cpp
@@ -1645,10 +1645,10 @@ void DrasculaEngine::animation_9_6() {
int v_cd;
- animate("fin.bin", 14);
+ (void)animate("fin.bin", 14);
playMusic(13);
flags[5] = 1;
- animate("drf.bin", 16);
+ (void)animate("drf.bin", 16);
fadeToBlack(0);
clearRoom();
curX = -1;
diff --git a/engines/drascula/configure.engine b/engines/drascula/configure.engine
new file mode 100644
index 0000000000..b9b76638fd
--- /dev/null
+++ b/engines/drascula/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 drascula "Drascula: The Vampire Strikes Back" yes
diff --git a/engines/drascula/converse.cpp b/engines/drascula/converse.cpp
index 95a5f7d87f..b3749445ec 100644
--- a/engines/drascula/converse.cpp
+++ b/engines/drascula/converse.cpp
@@ -168,19 +168,19 @@ void DrasculaEngine::converse(int index) {
// delete stream;
if (currentChapter == 2 && !strcmp(fileName, "op_5.cal") && flags[38] == 1 && flags[33] == 1) {
- strcpy(phrase3, _text[405]);
+ Common::strlcpy(phrase3, _text[405], 128);
strcpy(sound3, "405.als");
answer3 = 31;
}
if (currentChapter == 6 && !strcmp(fileName, "op_12.cal") && flags[7] == 1) {
- strcpy(phrase3, _text[273]);
+ Common::strlcpy(phrase3, _text[273], 128);
strcpy(sound3, "273.als");
answer3 = 14;
}
if (currentChapter == 6 && !strcmp(fileName, "op_12.cal") && flags[10] == 1) {
- strcpy(phrase3, _text[274]);
+ Common::strlcpy(phrase3, _text[274], 128);
strcpy(sound3, "274.als");
answer3 = 15;
}
diff --git a/engines/drascula/drascula.cpp b/engines/drascula/drascula.cpp
index cde00baa32..14cb4be5a0 100644
--- a/engines/drascula/drascula.cpp
+++ b/engines/drascula/drascula.cpp
@@ -89,6 +89,85 @@ DrasculaEngine::DrasculaEngine(OSystem *syst, const DrasculaGameDescription *gam
_talkSequences = 0;
_currentSaveSlot = 0;
+ bjX = 0;
+ bjY = 0;
+ trackBJ = 0;
+ framesWithoutAction = 0;
+ term_int = 0;
+ currentChapter = 0;
+ _loadedDifferentChapter = 0;
+ musicStopped = 0;
+ FrameSSN = 0;
+ globalSpeed = 0;
+ LastFrame = 0;
+ flag_tv = 0;
+ _charMapSize = 0;
+ _itemLocationsSize = 0;
+ _polXSize = 0;
+ _verbBarXSize = 0;
+ _x1dMenuSize = 0;
+ _frameXSize = 0;
+ _candleXSize = 0;
+ _pianistXSize = 0;
+ _drunkXSize = 0;
+ _roomPreUpdatesSize = 0;
+ _roomUpdatesSize = 0;
+ _roomActionsSize = 0;
+ _talkSequencesSize = 0;
+ _numLangs = 0;
+ feetHeight = 0;
+ floorX1 = 0;
+ floorY1 = 0;
+ floorX2 = 0;
+ floorY2 = 0;
+ lowerLimit = 0;
+ upperLimit = 0;
+ trackFinal = 0;
+ walkToObject = 0;
+ objExit = 0;
+ _startTime = 0;
+ hasAnswer = 0;
+ savedTime = 0;
+ breakOut = 0;
+ vonBraunX = 0;
+ trackVonBraun = 0;
+ vonBraunHasMoved = 0;
+ newHeight = 0;
+ newWidth = 0;
+ color_solo = 0;
+ igorX = 0;
+ igorY = 0;
+ trackIgor = 0;
+ drasculaX = 0;
+ drasculaY = 0;
+ trackDrascula = 0;
+ _roomNumber = 0;
+ numRoomObjs = 0;
+ takeObject = 0;
+ pickedObject = 0;
+ _subtitlesDisabled = 0;
+ _menuBar = 0;
+ _menuScreen = 0;
+ _hasName = 0;
+ curExcuseLook = 0;
+ curExcuseAction = 0;
+ frame_y = 0;
+ curX = 0;
+ curY = 0;
+ characterMoved = 0;
+ curDirection = 0;
+ trackProtagonist = 0;
+ _characterFrame = 0;
+ hare_se_ve = 0;
+ roomX = 0;
+ roomY = 0;
+ checkFlags = 0;
+ doBreak = 0;
+ stepX = 0;
+ stepY = 0;
+ curHeight = 0;
+ curWidth = 0;
+
_color = 0;
blinking = 0;
_mouseX = 0;
@@ -97,6 +176,20 @@ DrasculaEngine::DrasculaEngine(OSystem *syst, const DrasculaGameDescription *gam
_rightMouseButton = 0;
*textName = 0;
+ crosshairCursor = 0;
+ mouseCursor = 0;
+ bgSurface = 0;
+ backSurface = 0;
+ cursorSurface = 0;
+ drawSurface3 = 0;
+ drawSurface2 = 0;
+ tableSurface = 0;
+ extraSurface = 0;
+ screenSurface = 0;
+ frontSurface = 0;
+ previousMusic = 0;
+ roomMusic = 0;
+
_rnd = new Common::RandomSource("drascula");
_console = 0;
@@ -297,7 +390,7 @@ Common::Error DrasculaEngine::run() {
memset(iconName, 0, sizeof(iconName));
for (i = 0; i < 6; i++)
- strcpy(iconName[i + 1], _textverbs[i]);
+ Common::strlcpy(iconName[i + 1], _textverbs[i], 13);
assignPalette(defaultPalette);
@@ -771,6 +864,11 @@ void DrasculaEngine::updateEvents() {
#endif
switch (event.type) {
case Common::EVENT_KEYDOWN:
+ if (event.kbd.keycode == Common::KEYCODE_d && event.kbd.hasFlags(Common::KBD_CTRL)) {
+ // Start the debugger
+ getDebugger()->attach();
+ getDebugger()->onFrame();
+ }
addKeyToBuffer(event.kbd);
break;
case Common::EVENT_KEYUP:
diff --git a/engines/drascula/drascula.h b/engines/drascula/drascula.h
index 944191b5fb..53fce9c212 100644
--- a/engines/drascula/drascula.h
+++ b/engines/drascula/drascula.h
@@ -38,6 +38,8 @@
#include "engines/savestate.h"
+#include "drascula/console.h"
+
#include "audio/mixer.h"
#include "engines/engine.h"
@@ -313,8 +315,6 @@ static const int interf_y[] = { 51, 51, 51, 51, 83, 83, 83 };
struct RoomHandlers;
-class Console;
-
class DrasculaEngine : public Engine {
protected:
// Engine APIs
@@ -724,11 +724,12 @@ public:
void update_62_pre();
void update_102();
+ Console *_console;
+ GUI::Debugger *getDebugger() { return _console; }
+
private:
int _lang;
- Console *_console;
-
CharInfo *_charMap;
int _charMapSize;
diff --git a/engines/drascula/graphics.cpp b/engines/drascula/graphics.cpp
index b28de669b6..fe954279c3 100644
--- a/engines/drascula/graphics.cpp
+++ b/engines/drascula/graphics.cpp
@@ -336,7 +336,7 @@ void DrasculaEngine::centerText(const char *message, int textX, int textY) {
// original starts printing 4 lines above textY
int y = CLIP<int>(textY - (4 * CHAR_HEIGHT), 0, 320);
- strcpy(msg, message);
+ Common::strlcpy(msg, message, 200);
// If the message fits on screen as-is, just print it here
if (textFitsCentered(msg, textX)) {
@@ -363,8 +363,8 @@ void DrasculaEngine::centerText(const char *message, int textX, int textY) {
while (curWord != NULL) {
// Check if the word and the current line fit on screen
if (tmpMessageLine[0] != '\0')
- strcat(tmpMessageLine, " ");
- strcat(tmpMessageLine, curWord);
+ Common::strlcat(tmpMessageLine, " ", 200);
+ Common::strlcat(tmpMessageLine, curWord, 200);
if (textFitsCentered(tmpMessageLine, textX)) {
// Line fits, so add the word to the current message line
strcpy(messageLine, tmpMessageLine);
@@ -374,8 +374,8 @@ void DrasculaEngine::centerText(const char *message, int textX, int textY) {
// If it goes off screen, print_abc will adjust it
x = CLIP<int>(textX - strlen(messageLine) * CHAR_WIDTH / 2, 60, 255);
print_abc(messageLine, x, y + curLine * CHAR_HEIGHT);
- strcpy(messageLine, curWord);
- strcpy(tmpMessageLine, curWord);
+ Common::strlcpy(messageLine, curWord, 200);
+ Common::strlcpy(tmpMessageLine, curWord, 200);
curLine++;
}
diff --git a/engines/drascula/objects.cpp b/engines/drascula/objects.cpp
index 35dfd3162a..519e919433 100644
--- a/engines/drascula/objects.cpp
+++ b/engines/drascula/objects.cpp
@@ -265,8 +265,9 @@ void DrasculaEngine::updateVisible() {
}
if (_roomNumber == 22 && flags[27] == 1)
visible[3] = 0;
- if (_roomNumber == 26 && flags[21] == 0)
- strcpy(objName[2], _textmisc[0]);
+ if (_roomNumber == 26 && flags[21] == 0) {
+ Common::strlcpy(objName[2], _textmisc[0], 20);
+ }
if (_roomNumber == 26 && flags[18] == 1)
visible[2] = 0;
if (_roomNumber == 26 && flags[12] == 1)
diff --git a/engines/dreamweb/configure.engine b/engines/dreamweb/configure.engine
new file mode 100644
index 0000000000..27506e650f
--- /dev/null
+++ b/engines/dreamweb/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 dreamweb "Dreamweb" yes
diff --git a/engines/dreamweb/dreamweb.cpp b/engines/dreamweb/dreamweb.cpp
index 08838a784a..7323dfc4a8 100644
--- a/engines/dreamweb/dreamweb.cpp
+++ b/engines/dreamweb/dreamweb.cpp
@@ -225,6 +225,49 @@ DreamWebEngine::DreamWebEngine(OSystem *syst, const DreamWebGameDescription *gam
_linePointer = 0;
_lineDirection = 0;
_lineLength = 0;
+
+ _subtitles = 0;
+ _foreignRelease = 0;
+ _wonGame = 0;
+ _hasSpeech = 0;
+ _roomsSample = 0;
+ _copyProtection = 0;
+
+ for (uint i = 0; i < 128; i++)
+ memset(&_setDat[i], 0, sizeof(SetObject));
+
+ for (uint i = 0; i < 80; i++)
+ memset(&_freeDat[i], 0, sizeof(DynObject));
+
+ for (uint i = 0; i < kNumExObjects; i++)
+ memset(&_exData[i], 0, sizeof(DynObject));
+
+ memset(&_vars, 0, sizeof(GameVars));
+
+ for (uint i = 0; i < 96; i++)
+ memset(&_backdropFlags[i], 0, sizeof(BackdropMapFlag));
+
+ for (uint i = 0; i < kNumReelRoutines+1; i++)
+ memset(&_reelRoutines[i], 0, sizeof(ReelRoutine));
+
+ _personData = 0;
+
+ for (uint i = 0; i < 16; i++)
+ memset(&_openInvList[i], 0, sizeof(ObjectRef));
+
+ for (uint i = 0; i < 30; i++)
+ memset(&_ryanInvList[i], 0, sizeof(ObjectRef));
+
+ for (uint i = 0; i < 11*10; i++)
+ memset(&_mapFlags[i], 0, sizeof(MapFlag));
+
+ for (uint i = 0; i < kNumChanges; i++)
+ memset(&_listOfChanges[i], 0, sizeof(Change));
+
+ _currentCharset = 0;
+
+ for (uint i = 0; i < 36; i++)
+ memset(&_pathData[i], 0, sizeof(RoomPaths));
}
DreamWebEngine::~DreamWebEngine() {
diff --git a/engines/dreamweb/dreamweb.h b/engines/dreamweb/dreamweb.h
index 5746568e4e..87a9f5423f 100644
--- a/engines/dreamweb/dreamweb.h
+++ b/engines/dreamweb/dreamweb.h
@@ -110,6 +110,8 @@ protected:
virtual Common::Error run();
virtual bool hasFeature(EngineFeature f) const;
+ GUI::Debugger *getDebugger() { return _console; }
+
public:
DreamWebEngine(OSystem *syst, const DreamWebGameDescription *gameDesc);
virtual ~DreamWebEngine();
@@ -144,8 +146,6 @@ public:
bool loadSpeech(const Common::String &filename);
- void enableSavingOrLoading(bool enable = true) { _enableSavingOrLoading = enable; }
-
Common::Language getLanguage() const;
uint8 modifyChar(uint8 c) const;
Common::String modifyFileName(const char *);
@@ -171,7 +171,6 @@ private:
uint _speed;
bool _turbo;
uint _oldMouseState;
- bool _enableSavingOrLoading;
protected:
GameVars _vars; // saved variables
diff --git a/engines/engine.cpp b/engines/engine.cpp
index c84404cc68..8326a1fe89 100644
--- a/engines/engine.cpp
+++ b/engines/engine.cpp
@@ -154,6 +154,10 @@ Engine::~Engine() {
CursorMan.popCursorPalette();
}
+void Engine::initializePath(const Common::FSNode &gamePath) {
+ SearchMan.addDirectory(gamePath.getPath(), gamePath, 0, 4);
+}
+
void initCommonGFX(bool defaultTo1XScaler) {
const Common::ConfigManager::Domain *transientDomain = ConfMan.getDomain(Common::ConfigManager::kTransientDomain);
const Common::ConfigManager::Domain *gameDomain = ConfMan.getActiveDomain();
@@ -183,7 +187,7 @@ void initCommonGFX(bool defaultTo1XScaler) {
g_system->setGraphicsMode(gfxMode.c_str());
// HACK: For OpenGL modes, we will still honor the graphics scale override
- if (defaultTo1XScaler && (gfxMode.equalsIgnoreCase("gl1") || gfxMode.equalsIgnoreCase("gl2") || gfxMode.equalsIgnoreCase("gl4")))
+ if (defaultTo1XScaler && (gfxMode.equalsIgnoreCase("opengl_linear") || gfxMode.equalsIgnoreCase("opengl_nearest")))
g_system->resetGraphicsScale();
}
}
diff --git a/engines/engine.h b/engines/engine.h
index 4f4223384a..33416dda44 100644
--- a/engines/engine.h
+++ b/engines/engine.h
@@ -37,6 +37,7 @@ class Error;
class EventManager;
class SaveFileManager;
class TimerManager;
+class FSNode;
}
namespace GUI {
class Debugger;
@@ -142,6 +143,16 @@ public:
virtual ~Engine();
/**
+ * Init SearchMan according to the game path.
+ *
+ * By default it adds the directory in non-flat mode with a depth of 4 as
+ * priority 0 to SearchMan.
+ *
+ * @param gamePath The base directory of the game data.
+ */
+ virtual void initializePath(const Common::FSNode &gamePath);
+
+ /**
* Init the engine and start its main loop.
* @return returns kNoError on success, else an error code.
*/
diff --git a/engines/engines.mk b/engines/engines.mk
deleted file mode 100644
index 89f4862bc7..0000000000
--- a/engines/engines.mk
+++ /dev/null
@@ -1,258 +0,0 @@
-ifdef ENABLE_SCUMM
-DEFINES += -DENABLE_SCUMM=$(ENABLE_SCUMM)
-MODULES += engines/scumm
-
-ifdef ENABLE_SCUMM_7_8
-DEFINES += -DENABLE_SCUMM_7_8
-endif
-
-ifdef ENABLE_HE
-DEFINES += -DENABLE_HE
-endif
-
-endif
-
-ifdef ENABLE_AGI
-DEFINES += -DENABLE_AGI=$(ENABLE_AGI)
-MODULES += engines/agi
-endif
-
-ifdef ENABLE_AGOS
-DEFINES += -DENABLE_AGOS=$(ENABLE_AGOS)
-MODULES += engines/agos
-
-ifdef ENABLE_AGOS2
-DEFINES += -DENABLE_AGOS2
-endif
-endif
-
-ifdef ENABLE_BBVS
-DEFINES += -DENABLE_BBVS=$(ENABLE_BBVS)
-MODULES += engines/bbvs
-endif
-
-ifdef ENABLE_CGE
-DEFINES += -DENABLE_CGE=$(ENABLE_CGE)
-MODULES += engines/cge
-endif
-
-ifdef ENABLE_CINE
-DEFINES += -DENABLE_CINE=$(ENABLE_CINE)
-MODULES += engines/cine
-endif
-
-ifdef ENABLE_COMPOSER
-DEFINES += -DENABLE_COMPOSER=$(ENABLE_COMPOSER)
-MODULES += engines/composer
-endif
-
-ifdef ENABLE_CRUISE
-DEFINES += -DENABLE_CRUISE=$(ENABLE_CRUISE)
-MODULES += engines/cruise
-endif
-
-ifdef ENABLE_DRACI
-DEFINES += -DENABLE_DRACI=$(ENABLE_DRACI)
-MODULES += engines/draci
-endif
-
-ifdef ENABLE_DRASCULA
-DEFINES += -DENABLE_DRASCULA=$(ENABLE_DRASCULA)
-MODULES += engines/drascula
-endif
-
-ifdef ENABLE_DREAMWEB
-DEFINES += -DENABLE_DREAMWEB=$(ENABLE_DREAMWEB)
-MODULES += engines/dreamweb
-endif
-
-ifdef ENABLE_FULLPIPE
-DEFINES += -DENABLE_FULLPIPE=$(ENABLE_FULLPIPE)
-MODULES += engines/fullpipe
-endif
-
-ifdef ENABLE_GOB
-DEFINES += -DENABLE_GOB=$(ENABLE_GOB)
-MODULES += engines/gob
-endif
-
-ifdef ENABLE_GROOVIE
-DEFINES += -DENABLE_GROOVIE=$(ENABLE_GROOVIE)
-MODULES += engines/groovie
-
-ifdef ENABLE_GROOVIE2
-DEFINES += -DENABLE_GROOVIE2
-endif
-endif
-
-ifdef ENABLE_HOPKINS
-DEFINES += -DENABLE_HOPKINS=$(ENABLE_HOPKINS)
-MODULES += engines/hopkins
-endif
-
-ifdef ENABLE_HUGO
-DEFINES += -DENABLE_HUGO=$(ENABLE_HUGO)
-MODULES += engines/hugo
-endif
-
-ifdef ENABLE_KYRA
-DEFINES += -DENABLE_KYRA=$(ENABLE_KYRA)
-MODULES += engines/kyra
-
-ifdef ENABLE_LOL
-DEFINES += -DENABLE_LOL
-endif
-
-ifdef ENABLE_EOB
-DEFINES += -DENABLE_EOB
-endif
-endif
-
-ifdef ENABLE_LASTEXPRESS
-DEFINES += -DENABLE_LASTEXPRESS=$(ENABLE_LASTEXPRESS)
-MODULES += engines/lastexpress
-endif
-
-ifdef ENABLE_LURE
-DEFINES += -DENABLE_LURE=$(ENABLE_LURE)
-MODULES += engines/lure
-endif
-
-ifdef ENABLE_MADE
-DEFINES += -DENABLE_MADE=$(ENABLE_MADE)
-MODULES += engines/made
-endif
-
-ifdef ENABLE_MOHAWK
-DEFINES += -DENABLE_MOHAWK=$(ENABLE_MOHAWK)
-MODULES += engines/mohawk
-
-ifdef ENABLE_CSTIME
-DEFINES += -DENABLE_CSTIME
-endif
-
-ifdef ENABLE_MYST
-DEFINES += -DENABLE_MYST
-endif
-
-ifdef ENABLE_RIVEN
-DEFINES += -DENABLE_RIVEN
-endif
-endif
-
-ifdef ENABLE_NEVERHOOD
-DEFINES += -DENABLE_NEVERHOOD=$(ENABLE_NEVERHOOD)
-MODULES += engines/neverhood
-endif
-
-ifdef ENABLE_MORTEVIELLE
-DEFINES += -DENABLE_MORTEVIELLE=$(ENABLE_MORTEVIELLE)
-MODULES += engines/mortevielle
-endif
-
-ifdef ENABLE_PARALLACTION
-DEFINES += -DENABLE_PARALLACTION=$(ENABLE_PARALLACTION)
-MODULES += engines/parallaction
-endif
-
-ifdef ENABLE_PEGASUS
-DEFINES += -DENABLE_PEGASUS=$(ENABLE_PEGASUS)
-MODULES += engines/pegasus
-endif
-
-ifdef ENABLE_QUEEN
-DEFINES += -DENABLE_QUEEN=$(ENABLE_QUEEN)
-MODULES += engines/queen
-endif
-
-ifdef ENABLE_SAGA
-DEFINES += -DENABLE_SAGA=$(ENABLE_SAGA)
-MODULES += engines/saga
-
-ifdef ENABLE_IHNM
-DEFINES += -DENABLE_IHNM
-endif
-
-ifdef ENABLE_SAGA2
-DEFINES += -DENABLE_SAGA2
-endif
-endif
-
-ifdef ENABLE_SCI
-DEFINES += -DENABLE_SCI=$(ENABLE_SCI)
-MODULES += engines/sci
-
-ifdef ENABLE_SCI32
-DEFINES += -DENABLE_SCI32
-endif
-endif
-
-ifdef ENABLE_SKY
-DEFINES += -DENABLE_SKY=$(ENABLE_SKY)
-MODULES += engines/sky
-endif
-
-ifdef ENABLE_SWORD1
-DEFINES += -DENABLE_SWORD1=$(ENABLE_SWORD1)
-MODULES += engines/sword1
-endif
-
-ifdef ENABLE_SWORD2
-DEFINES += -DENABLE_SWORD2=$(ENABLE_SWORD2)
-MODULES += engines/sword2
-endif
-
-ifdef ENABLE_SWORD25
-DEFINES += -DENABLE_SWORD25=$(ENABLE_SWORD25)
-MODULES += engines/sword25
-endif
-
-ifdef ENABLE_TESTBED
-DEFINES += -DENABLE_TESTBED=$(ENABLE_TESTBED)
-MODULES += engines/testbed
-endif
-
-ifdef ENABLE_TEENAGENT
-DEFINES += -DENABLE_TEENAGENT=$(ENABLE_TEENAGENT)
-MODULES += engines/teenagent
-endif
-
-ifdef ENABLE_TINSEL
-DEFINES += -DENABLE_TINSEL=$(ENABLE_TINSEL)
-MODULES += engines/tinsel
-endif
-
-ifdef ENABLE_TOLTECS
-DEFINES += -DENABLE_TOLTECS=$(ENABLE_TOLTECS)
-MODULES += engines/toltecs
-endif
-
-ifdef ENABLE_TONY
-DEFINES += -DENABLE_TONY=$(ENABLE_TONY)
-MODULES += engines/tony
-endif
-
-ifdef ENABLE_TOON
-DEFINES += -DENABLE_TOON=$(ENABLE_TOON)
-MODULES += engines/toon
-endif
-
-ifdef ENABLE_TOUCHE
-DEFINES += -DENABLE_TOUCHE=$(ENABLE_TOUCHE)
-MODULES += engines/touche
-endif
-
-ifdef ENABLE_TSAGE
-DEFINES += -DENABLE_TSAGE=$(ENABLE_TSAGE)
-MODULES += engines/tsage
-endif
-
-ifdef ENABLE_TUCKER
-DEFINES += -DENABLE_TUCKER=$(ENABLE_TUCKER)
-MODULES += engines/tucker
-endif
-
-ifdef ENABLE_WINTERMUTE
-DEFINES += -DENABLE_WINTERMUTE=$(ENABLE_WINTERMUTE)
-MODULES += engines/wintermute
-endif
diff --git a/engines/fullpipe/behavior.cpp b/engines/fullpipe/behavior.cpp
index 1a2b7bb8e2..75cb027d7a 100644
--- a/engines/fullpipe/behavior.cpp
+++ b/engines/fullpipe/behavior.cpp
@@ -132,7 +132,7 @@ void BehaviorManager::updateBehavior(BehaviorInfo *behaviorInfo, BehaviorEntry *
mq->sendNextCommand();
bhi->_flags &= 0xFFFFFFFD;
- } else if (behaviorInfo->_counter >= bhi->_delay && bhi->_percent && g_fullpipe->_rnd->getRandomNumber(32767) <= entry->_items[i]->_percent) {
+ } else if (behaviorInfo->_counter >= bhi->_delay && bhi->_percent && g_fp->_rnd->getRandomNumber(32767) <= entry->_items[i]->_percent) {
MessageQueue *mq = new MessageQueue(bhi->_messageQueue, 0, 1);
mq->sendNextCommand();
@@ -149,7 +149,7 @@ void BehaviorManager::updateStaticAniBehavior(StaticANIObject *ani, int delay, B
MessageQueue *mq = 0;
if (bhe->_flags & 1) {
- uint rnd = g_fullpipe->_rnd->getRandomNumber(32767);
+ uint rnd = g_fp->_rnd->getRandomNumber(32767);
uint runPercent = 0;
for (int i = 0; i < bhe->_itemsCount; i++) {
if (!(bhe->_items[i]->_flags & 1) && bhe->_items[i]->_percent) {
@@ -164,7 +164,7 @@ void BehaviorManager::updateStaticAniBehavior(StaticANIObject *ani, int delay, B
for (int i = 0; i < bhe->_itemsCount; i++) {
if (!(bhe->_items[i]->_flags & 1) && delay >= bhe->_items[i]->_delay) {
if (bhe->_items[i]->_percent) {
- if (g_fullpipe->_rnd->getRandomNumber(32767) <= bhe->_items[i]->_percent) {
+ if (g_fp->_rnd->getRandomNumber(32767) <= bhe->_items[i]->_percent) {
mq = new MessageQueue(bhe->_items[i]->_messageQueue, 0, 1);
break;
}
@@ -179,6 +179,50 @@ void BehaviorManager::updateStaticAniBehavior(StaticANIObject *ani, int delay, B
}
}
+bool BehaviorManager::setBehaviorEnabled(StaticANIObject *obj, int aniId, int quId, int flag) {
+ BehaviorEntryInfo *entry = getBehaviorEntryInfoByMessageQueueDataId(obj, aniId, quId);
+
+ if (entry) {
+ if (flag)
+ entry->_flags &= 0xFFFFFFFE;
+ else
+ entry->_flags |= 1;
+ } else
+ return false;
+
+ return true;
+}
+
+void BehaviorManager::setFlagByStaticAniObject(StaticANIObject *ani, int flag) {
+ for (uint i = 0; i < _behaviors.size(); i++) {
+ BehaviorInfo *beh = _behaviors[i];
+
+ if (ani == beh->_ani) {
+ if (flag)
+ beh->_flags &= 0xfe;
+ else
+ beh->_flags |= 1;
+ }
+ }
+}
+
+BehaviorEntryInfo *BehaviorManager::getBehaviorEntryInfoByMessageQueueDataId(StaticANIObject *ani, int id1, int id2) {
+ for (uint i = 0; i < _behaviors.size(); i++) {
+ if (_behaviors[i]->_ani == ani) {
+ for (uint j = 0; j < _behaviors[i]->_bheItems.size(); j++) {
+ if (_behaviors[i]->_bheItems[j]->_staticsId == id1) {
+ for (int k = 0; k < _behaviors[i]->_bheItems[j]->_itemsCount; k++) {
+ if (_behaviors[i]->_bheItems[j]->_items[k]->_messageQueue->_dataId == id2)
+ return _behaviors[i]->_bheItems[j]->_items[k];
+ }
+ }
+ }
+ }
+ }
+
+ return 0;
+}
+
void BehaviorInfo::clear() {
_ani = 0;
_staticsId = 0;
@@ -227,11 +271,11 @@ void BehaviorInfo::initObjectBehavior(GameVar *var, Scene *sc, StaticANIObject *
if (strcmp(var->_value.stringValue, "ROOT"))
break;
- GameVar *v1 = g_fullpipe->getGameLoaderGameVar()->getSubVarByName("BEHAVIOR")->getSubVarByName(ani->getName());
+ GameVar *v1 = g_fp->getGameLoaderGameVar()->getSubVarByName("BEHAVIOR")->getSubVarByName(ani->getName());
if (v1 == var)
return;
- sc = g_fullpipe->accessScene(ani->_sceneId);
+ sc = g_fp->accessScene(ani->_sceneId);
clear();
var = v1;
_itemsCount = var->getSubVarsCount();
@@ -239,7 +283,7 @@ void BehaviorInfo::initObjectBehavior(GameVar *var, Scene *sc, StaticANIObject *
}
for (int i = 0; i < _itemsCount; i++) {
- int maxDelay;
+ int maxDelay = 0;
_bheItems.push_back(new BehaviorEntry(var->getSubVarByIndex(i), sc, ani, &maxDelay));
@@ -275,7 +319,7 @@ BehaviorEntry::BehaviorEntry(GameVar *var, Scene *sc, StaticANIObject *ani, int
for (int i = 0; i < _itemsCount; i++) {
GameVar *subvar = var->getSubVarByIndex(i);
- int delay;
+ int delay = 0;
_items[i] = new BehaviorEntryInfo(subvar, sc, &delay);
totalPercent += delay;
diff --git a/engines/fullpipe/behavior.h b/engines/fullpipe/behavior.h
index 83a548f486..90bb38dc9b 100644
--- a/engines/fullpipe/behavior.h
+++ b/engines/fullpipe/behavior.h
@@ -77,6 +77,12 @@ class BehaviorManager : public CObject {
void updateBehaviors();
void updateBehavior(BehaviorInfo *behaviorInfo, BehaviorEntry *entry);
void updateStaticAniBehavior(StaticANIObject *ani, int delay, BehaviorEntry *beh);
+
+ bool setBehaviorEnabled(StaticANIObject *obj, int aniId, int quId, int flag);
+
+ void setFlagByStaticAniObject(StaticANIObject *ani, int flag);
+
+ BehaviorEntryInfo *getBehaviorEntryInfoByMessageQueueDataId(StaticANIObject *ani, int id1, int id2);
};
} // End of namespace Fullpipe
diff --git a/engines/fullpipe/configure.engine b/engines/fullpipe/configure.engine
new file mode 100644
index 0000000000..fce5951e26
--- /dev/null
+++ b/engines/fullpipe/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 fullpipe "Full Pipe" no
diff --git a/engines/fullpipe/console.cpp b/engines/fullpipe/console.cpp
new file mode 100644
index 0000000000..2d27fc2ddd
--- /dev/null
+++ b/engines/fullpipe/console.cpp
@@ -0,0 +1,52 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "fullpipe/constants.h"
+#include "fullpipe/fullpipe.h"
+#include "fullpipe/gameloader.h"
+#include "fullpipe/scene.h"
+
+namespace Fullpipe {
+
+Console::Console(FullpipeEngine *vm) : GUI::Debugger(), _vm(vm) {
+ DCmd_Register("scene", WRAP_METHOD(Console, Cmd_Scene));
+}
+
+bool Console::Cmd_Scene(int argc, const char **argv) {
+ if (argc != 2) {
+ int sceneTag = _vm->_currentScene->_sceneId;
+ DebugPrintf("Current scene: %d (scene tag: %d)\n", _vm->getSceneFromTag(sceneTag), sceneTag);
+ DebugPrintf("Use %s <scene> to change the current scene\n", argv[0]);
+ return true;
+ } else {
+ int scene = _vm->convertScene(atoi(argv[1]));
+ _vm->_gameLoader->loadScene(726);
+ _vm->_gameLoader->gotoScene(726, TrubaLeft);
+
+ if (scene != 726)
+ _vm->_gameLoader->preloadScene(726, _vm->getSceneEntrance(scene));
+
+ return false;
+ }
+}
+
+} // End of namespace Fullpipe
diff --git a/engines/fullpipe/console.h b/engines/fullpipe/console.h
new file mode 100644
index 0000000000..af2b5114ac
--- /dev/null
+++ b/engines/fullpipe/console.h
@@ -0,0 +1,42 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef FULLPIPE_CONSOLE_H
+#define FULLPIPE_CONSOLE_H
+
+namespace Fullpipe {
+
+class FullpipeEngine;
+
+class Console : public GUI::Debugger {
+public:
+ Console(FullpipeEngine *vm);
+
+private:
+ FullpipeEngine *_vm;
+
+ bool Cmd_Scene(int argc, const char **argv);
+};
+
+} // End of namespace Fullpipe
+
+#endif /* FULLPIPE_CONSOLE_H */
diff --git a/engines/fullpipe/constants.h b/engines/fullpipe/constants.h
index 796764d0a9..b2ed962b07 100644
--- a/engines/fullpipe/constants.h
+++ b/engines/fullpipe/constants.h
@@ -25,11 +25,12 @@
namespace Fullpipe {
-#define ANI_BOOT_1 4231
-#define ANI_IN1MAN 5110
+// Common
+#define ANI_FLY 4916
#define ANI_INV_MAP 5321
#define ANI_LIFTBUTTON 2751
#define ANI_MAN 322
+#define ANI_PBAR 896
#define MSG_CMN_WINARCADE 4778
#define MSG_DISABLESAVES 5201
#define MSG_ENABLESAVES 5202
@@ -37,21 +38,21 @@ namespace Fullpipe {
#define MSG_HMRKICK_STUCCO 4765
#define MSG_MANSHADOWSOFF 5196
#define MSG_MANSHADOWSON 5197
-#define MSG_RESTARTGAME 4767
-#define MSG_SC1_SHOWOSK 1019
-#define MSG_SC1_SHOWOSK2 468
-#define MSG_SC1_UTRUBACLICK 1100
+#define MV_FLY_FLY 4917
#define MV_MAN_GOLADDER 451
#define MV_MAN_GOLADDER2 2844
+#define MV_MAN_LIFTDOWN 1052
+#define MV_MAN_LIFTUP 1051
#define MV_MAN_LOOKUP 4773
+#define rMV_MAN_LOOKUP 4775
+#define MV_MAN_TOLADDER 448
+#define MV_MAN_TOLADDER2 2841
#define MV_MAN_STARTLADDER 452
#define MV_MAN_STARTLADDER2 2842
#define MV_MAN_STOPLADDER 454
#define MV_MAN_STOPLADDER2 2845
-#define MV_MAN_TOLADDER 448
-#define MV_MAN_TOLADDER2 2841
#define MV_MAN_TURN_LU 486
-#define PIC_CMN_EVAL 3468
+#define MV_PBAR_RUN 897
#define PIC_CSR_DEFAULT 4891
#define PIC_CSR_DEFAULT_INV 4892
#define PIC_CSR_ITN 4893
@@ -84,16 +85,94 @@ namespace Fullpipe {
#define PIC_CSR_ITN_RED 5329
#define PIC_CSR_LIFT 5176
#define PIC_CSR_MAP 5339
+#define PIC_IN1_GAMETITLE 5169
#define PIC_IN1_PIPETITLE 5167
#define PIC_INV_MENU 991
+#define PIC_MAP_A01 5263
+#define PIC_MAP_A02 5264
+#define PIC_MAP_A03 5265
+#define PIC_MAP_A04 5266
+#define PIC_MAP_A05 5267
+#define PIC_MAP_A06 5268
+#define PIC_MAP_A07 5269
+#define PIC_MAP_A08 5270
+#define PIC_MAP_A09 5271
+#define PIC_MAP_A10 5272
+#define PIC_MAP_A11 5273
+#define PIC_MAP_A12 5274
#define PIC_MAP_A13 5275
+#define PIC_MAP_A14 5276
+#define PIC_MAP_I01 5295
+#define PIC_MAP_I02 5296
+#define PIC_MAP_P01 5277
+#define PIC_MAP_P02 5278
+#define PIC_MAP_P03 5279
+#define PIC_MAP_P04 5280
+#define PIC_MAP_P05 5281
+#define PIC_MAP_P06 5282
+#define PIC_MAP_P07 5283
+#define PIC_MAP_P08 5284
+#define PIC_MAP_P09 5285
+#define PIC_MAP_P10 5286
+#define PIC_MAP_P11 5287
+#define PIC_MAP_P12 5288
+#define PIC_MAP_P13 5289
+#define PIC_MAP_P14 5290
+#define PIC_MAP_P15 5291
+#define PIC_MAP_P16 5292
+#define PIC_MAP_P17 5293
+#define PIC_MAP_P18 5294
#define PIC_MAP_S01 5223
-#define PIC_SC1_KUCHKA 1321
-#define PIC_SC1_LADDER 1091
-#define PIC_SC1_OSK 1018
-#define PIC_SC1_OSK2 2932
-#define PIC_SCD_SEL 734
+#define PIC_MAP_S02 5224
+#define PIC_MAP_S03 5225
+#define PIC_MAP_S04 5226
+#define PIC_MAP_S05 5227
+#define PIC_MAP_S06 5228
+#define PIC_MAP_S07 5229
+#define PIC_MAP_S08 5231
+#define PIC_MAP_S09 5230
+#define PIC_MAP_S10 5232
+#define PIC_MAP_S11 5233
+#define PIC_MAP_S12 5234
+#define PIC_MAP_S13 5235
+#define PIC_MAP_S14 5236
+#define PIC_MAP_S15 5237
+#define PIC_MAP_S16 5238
+#define PIC_MAP_S17 5239
+#define PIC_MAP_S1819 5240
+#define PIC_MAP_S20 5241
+#define PIC_MAP_S21 5242
+#define PIC_MAP_S22 5243
+#define PIC_MAP_S23_1 5244
+#define PIC_MAP_S23_2 5245
+#define PIC_MAP_S24 5246
+#define PIC_MAP_S25 5247
+#define PIC_MAP_S26 5248
+#define PIC_MAP_S27 5249
+#define PIC_MAP_S28 5250
+#define PIC_MAP_S29 5251
+#define PIC_MAP_S30 5252
+#define PIC_MAP_S31_1 5253
+#define PIC_MAP_S31_2 5254
+#define PIC_MAP_S32_1 5255
+#define PIC_MAP_S32_2 5256
+#define PIC_MAP_S33 5257
+#define PIC_MAP_S34 5258
+#define PIC_MAP_S35 5259
+#define PIC_MAP_S36 5260
+#define PIC_MAP_S37 5261
+#define PIC_MAP_S38 5262
+#define PIC_TTL_CREDITS 5172
+#define QU_INTR_STARTINTRO 5133
#define SC_1 301
+#define SC_2 302
+#define SC_3 303
+#define SC_4 304
+#define SC_5 305
+#define SC_6 649
+#define SC_7 650
+#define SC_8 651
+#define SC_9 652
#define SC_10 653
#define SC_11 654
#define SC_12 655
@@ -104,7 +183,6 @@ namespace Fullpipe {
#define SC_17 1141
#define SC_18 1142
#define SC_19 1143
-#define SC_2 302
#define SC_20 1144
#define SC_21 1546
#define SC_22 1547
@@ -115,7 +193,6 @@ namespace Fullpipe {
#define SC_27 1552
#define SC_28 2062
#define SC_29 2063
-#define SC_3 303
#define SC_30 2064
#define SC_31 2065
#define SC_32 2066
@@ -125,12 +202,6 @@ namespace Fullpipe {
#define SC_36 2070
#define SC_37 2071
#define SC_38 2072
-#define SC_4 304
-#define SC_5 305
-#define SC_6 649
-#define SC_7 650
-#define SC_8 651
-#define SC_9 652
#define SC_COMMON 321
#define SC_DBGMENU 726
#define SC_FINAL1 4999
@@ -141,39 +212,1215 @@ namespace Fullpipe {
#define SC_INTRO2 3907
#define SC_INV 858
#define SC_LDR 635
-#define SC_MAINMENU 4620
#define SC_MAP 5222
-#define SC_TEST 903
#define SC_TITLES 5166
#define SND_CMN_031 3516
+#define SND_CMN_060 4921
+#define SND_CMN_061 4922
#define SND_CMN_070 5199
+#define SND_INTR_019 5220
+#define ST_EGTR_SLIMSORROW 340
+#define ST_FLY_FLY 4918
+#define ST_LBN_0H 2835
+#define ST_LBN_1H 2791
+#define ST_LBN_2H 2793
+#define ST_LBN_3H 2795
+#define ST_LBN_4H 2797
+#define ST_LBN_5H 2799
+#define ST_LBN_6H 2801
+#define ST_LBN_7H 2803
+#define ST_LBN_8H 2805
+#define ST_LBN_9H 2807
#define ST_LBN_0N 2832
-#define ST_LBN_0P 2833
#define ST_LBN_1N 2753
-#define ST_LBN_1P 2754
#define ST_LBN_2N 2756
-#define ST_LBN_2P 2757
#define ST_LBN_3N 2759
-#define ST_LBN_3P 2760
#define ST_LBN_4N 2762
-#define ST_LBN_4P 2763
#define ST_LBN_5N 2765
-#define ST_LBN_5P 2766
#define ST_LBN_6N 2768
-#define ST_LBN_6P 2769
#define ST_LBN_7N 2771
-#define ST_LBN_7P 2772
#define ST_LBN_8N 2774
-#define ST_LBN_8P 2775
#define ST_LBN_9N 2777
+#define ST_LBN_0P 2833
+#define ST_LBN_1P 2754
+#define ST_LBN_2P 2757
+#define ST_LBN_3P 2760
+#define ST_LBN_4P 2763
+#define ST_LBN_5P 2766
+#define ST_LBN_6P 2769
+#define ST_LBN_7P 2772
+#define ST_LBN_8P 2775
#define ST_LBN_9P 2778
#define ST_MAN_EMPTY 476
+#define ST_MAN_GOU 459
#define ST_MAN_RIGHT 325
#define TrubaDown 697
#define TrubaLeft 474
-#define TrubaRight 696
#define TrubaUp 680
-#define rMV_MAN_LOOKUP 4775
+
+// Intro
+#define ANI_IN1MAN 5110
+#define MSG_INTR_ENDINTRO 5139
+#define MSG_INTR_GETUPMAN 5135
+#define MSG_INTR_SWITCHTO1 5145
+#define MSG_INTR_SWITCHTO2 5134
+#define MV_IN1MAN_SLEEP 5111
+#define QU_IN2_DO 5144
+#define QU_INTR_FINISH 5138
+#define QU_INTR_GETUPMAN 5136
+#define ST_IN1MAN_SLEEP 5112
+
+// Scene 1
+#define ANI_BOOT_1 4231
+#define MSG_SC1_SHOWOSK 1019
+#define MSG_SC1_SHOWOSK2 468
+#define MSG_SC1_UTRUBACLICK 1100
+#define PIC_SC1_KUCHKA 1321
+#define PIC_SC1_LADDER 1091
+#define PIC_SC1_OSK 1018
+#define PIC_SC1_OSK2 2932
+#define TrubaRight 696
+
+// Scene 2
+#define ANI_SC2_BOX 1020
+#define ANI_DADAYASHIK 306
+#define MSG_SC2_HIDELADDER 1023
+#define MSG_SC2_LADDERCLICK 1101
+#define MSG_SC2_PUTMANUP 1026
+#define MSG_SC2_SHOWLADDER 1027
+#define PIC_SC2_DTRUBA 841
+#define PIC_SC2_LADDER 412
+#define ST_DYAS_LIES 318
+
+// Scene 3
+#define ANI_DOMINO_3 2732
+#define ANI_EGGEATER 334
+#define ANI_INV_COIN 875
+#define ANI_INV_EGGAPL 1564
+#define ANI_INV_EGGBOOT 1570
+#define ANI_INV_EGGCOIN 1567
+#define ANI_INV_EGGDOM 1561
+#define ANI_INV_EGGGLS 1573
+#define MSG_LIFT_CLICKBUTTON 2780
+#define MSG_LIFT_CLOSEDOOR 5194
+#define MSG_LIFT_EXITLIFT 5187
+#define MSG_LIFT_GO 1065
+#define MSG_LIFT_STARTEXITQUEUE 5186
+#define MSG_SC3_HIDEDOMINO 3177
+#define MSG_SC3_ONTAKECOIN 5338
+#define MSG_SC3_RELEASEEGG 2681
+#define MSG_SC3_TAKEEGG 1583
+#define MSG_SC3_TESTFAT 1582
+#define MSG_SC3_UTRUBACLICK 1103
+#define MV_EGTR_FATASK 5332
+#define PIC_SC3_DOMIN 5182
+#define PIC_SC3_LADDER 1102
+#define ST_EGTR_MID1 2863
+#define ST_EGTR_MID2 2869
+#define ST_EGTR_SLIM 336
+#define QU_EGTR_MD2_SHOW 4698
+#define QU_EGTR_MD1_SHOW 4697
+#define QU_EGTR_SLIMSHOW 4883
+#define QU_SC3_ENTERLIFT 2779
+#define QU_SC3_EXITLIFT 2808
+
+// Scene 4
+#define ANI_BIGBALL 4923
+#define ANI_BUTTON 598
+#define ANI_CLOCK 588
+#define ANI_HAND 601
+#define ANI_KOZAWKA 495
+#define ANI_MAMASHA_4 660
+#define ANI_PLANK 501
+#define ANI_SC4_BOOT 1035
+#define ANI_SC4_COIN 690
+#define ANI_SPEAKER_4 3275
+#define ANI_SPRING 542
+#define MSG_GOTOLADDER 618
+#define MSG_KOZAWRESTART 546
+#define MSG_SC4_COINOUT 2895
+#define MSG_SC4_COINPUT 1032
+#define MSG_SC4_CLICKLADDER 1439
+#define MSG_SC4_DROPBOTTLE 2896
+#define MSG_SC4_HANDOVER 2960
+#define MSG_SC4_HIDEBOOT 4563
+#define MSG_SC4_KOZAWFALL 2858
+#define MSG_SC4_MANFROMBOTTLE 2854
+#define MSG_SC4_MANTOBOTTLE 2852
+#define MSG_SHAKEBOTTLE 584
+#define MSG_SHOOTKOZAW 557
+#define MSG_STARTHAND 612
+#define MSG_CLICKBOTTLE 569
+#define MSG_CLICKBUTTON 609
+#define MSG_CLICKPLANK 549
+#define MSG_LOWERPLANK 540
+#define MSG_RAISEPLANK 547
+#define MSG_SHOWCOIN 1033
+#define MSG_TAKEBOTTLE 614
+#define MSG_TAKEKOZAW 611
+#define MSG_TESTPLANK 538
+#define MSG_UPDATEBOTTLE 613
+#define MV_BTN_CLICK 599
+#define MV_CLK_GO 589
+#define MV_HND_POINT 602
+#define MV_KZW_GOR 564
+#define rMV_KZW_GOR 566
+#define MV_KZW_JUMP 558
+#define MV_KZW_JUMPROTATE 561
+#define MV_KZW_TOHOLERV 537
+#define MV_KZW_WALKPLANK 500
+#define MV_KZW_JUMPHIT 2857
+#define MV_KZW_JUMPOUT 586
+#define MV_KZW_RAISEHEAD 577
+#define MV_KZW_STANDUP 563
+#define MV_KZW_TURN 562
+#define MV_MAN_FROMLADDER 493
+#define MV_MAN_GOD 481
+#define MV_MAN_GOU 460
+#define MV_MAN_JUMPONPLANK 551
+#define MV_MAN_LOOKLADDER 520
+#define MV_MAN_PLANKTOLADDER 553
+#define MV_MAN_STARTLADDERD 457
+#define MV_PNK_WEIGHTLEFT 541
+#define MV_PNK_WEIGHTRIGHT 502
+#define MV_SC4_COIN_default 1029
+#define MV_SPK4_PLAY 3276
+#define MV_SPR_LOWER 543
+#define PIC_MAP_P03 5279
+#define PIC_SC4_BOTTLE 568
+#define PIC_SC4_BOTTLE2 2936
+#define PIC_SC4_DOWNTRUBA 619
+#define PIC_SC4_LADDER 1438
+#define PIC_SC4_LRTRUBA 616
+#define PIC_SC4_MASK 585
+#define PIC_SC4_PLANK 5183
+#define QU_BALL_WALKL 4920
+#define QU_BALL_WALKR 4919
+#define QU_HND_TAKE0 1440
+#define QU_HND_TAKE1 1441
+#define QU_HND_TAKE2 1442
+#define QU_HND_TAKEBOTTLE 1443
+#define QU_KOZAW_WALK 505
+#define QU_PNK_CLICK 550
+#define QU_SC4_GOCLOCK 595
+#define QU_SC4_MANFROMBOTTLE 2851
+#define QU_SC4_MANTOBOTTLE 2850
+#define SND_4_010 3125
+#define SND_4_012 3127
+#define SND_4_033 4990
+#define ST_CLK_CLOSED 590
+#define ST_HND_EMPTY 603
+#define ST_KZW_EMPTY 498
+#define ST_KZW_JUMPOUT 587
+#define ST_KZW_RIGHT 559
+#define ST_KZW_SIT 560
+#define ST_MAN_GOLADDER 450
+#define ST_MAN_GOLADDER2 2843
+#define MV_MAN_LOOKLADDERRV 556
+#define ST_MAN_LADDERDOWN 521
+#define ST_MAN_LOOKPLANK 555
+#define ST_MAN_ONPLANK 552
+#define ST_MAN_SIT 1164
+#define ST_MAN_STANDLADDER 453
+#define ST_MAN_UP 449
+#define ST_PNK_WEIGHTLEFT 503
+#define ST_PNK_WEIGHTRIGHT 504
+#define ST_SPR_UP 544
+
+// Scene 5
+#define ANI_BIGLUK 909
+#define ANI_HANDLE 622
+#define ANI_OTMOROZ 419
+#define MSG_SC5_BGRSOUNDOFF 5315
+#define MSG_SC5_BGRSOUNDON 5314
+#define MSG_SC5_HANDLEDOWN 916
+#define MSG_SC5_HANDLEUP 915
+#define MSG_SC5_HIDEHANDLE 917
+#define MSG_SC5_MAKEMANFLIGHT 1136
+#define MSG_SC5_MAKEOTMFEEDBACK 1169
+#define MSG_SC5_SHOWHANDLE 918
+#define MSG_SC5_TESTLUK 914
+#define MV_BLK_CLOSE 911
+#define MV_BLK_OPEN 910
+#define MV_MANHDL_HANDLEDOWN 630
+#define MV_MANHDL_HANDLEUP 631
+#define MV_OTM_BOXHANDLEDOWN 626
+#define MV_OTM_BOXHANDLEUP 627
+#define MV_OTM_HANDLEDOWN 620
+#define MV_OTM_HANDLEUP 621
+#define QU_SC5_MANBUMP 1167
+#define QU_SC5_MANFLY 1168
+#define SND_5_026 5316
+#define ST_BLK_CLOSED 912
+#define ST_BLK_OPEN 913
+#define ST_HDL_BROKEN 3342
+#define ST_HDL_DOWN 625
+#define ST_HDL_UP 624
+#define ST_OTM_BOX_LEFT 429
+#define ST_OTM_GLS_LEFT 421
+#define ST_OTM_VNT_LEFT 434
+
+// Scene 6
+#define ANI_BALLDROP 2685
+#define ANI_BUTTON_6 2988
+#define ANI_EGGIE 4929
+#define ANI_INV_HANDLE 893
+#define ANI_MAMASHA 656
+#define ANI_NEWBALL 1073
+#define MSG_SC6_BTNPUSH 1017
+#define MSG_SC6_ENABLEDROPS 687
+#define MSG_SC6_INSTHANDLE 1012
+#define MSG_SC6_JUMPBK 2900
+#define MSG_SC6_JUMPFW 2901
+#define MSG_SC6_RESTORESCROLL 2906
+#define MSG_SC6_SHOWNEXTBALL 790
+#define MSG_SC6_STARTDROPS 2897
+#define MSG_SC6_TAKEBALL 682
+#define MSG_SC6_TESTNUMBALLS 2904
+#define MSG_SC6_UTRUBACLICK 1105
+#define MSG_SPINHANDLE 2398
+#define MV_MAN6_TAKEBALL 2691
+#define MV_MAN6_THROWBALL 2692
+#define MV_MOM_CYCLEBK 3012
+#define MV_MOM_JUMPBK 662
+#define MV_MOM_JUMPFW 661
+#define MV_MOM_STARTBK 3010
+#define MV_MOM_STOPBK 3013
+#define MV_MOM_TAKE1 2885
+#define MV_MOM_TAKE2 2886
+#define MV_MOM_TAKE3 2887
+#define MV_MOM_TAKE4 2888
+#define MV_MOM_TAKE5 2889
+#define PIC_SC6_LADDER 1104
+#define QU_EGG6_GOL 4936
+#define QU_EGG6_GOR 4935
+#define QU_MOM_JUMPBK 671
+#define QU_MOM_JUMPFW 670
+#define QU_MOM_PUTBALL 2903
+#define QU_MOM_SITDOWN 685
+#define QU_MOM_STANDUP 2899
+#define QU_MOM_TOLIFT 2902
+#define QU_SC6_DROPS 2898
+#define QU_SC6_DROPS3 2955
+#define QU_SC6_ENTERLIFT 1054
+#define QU_SC6_EXITLIFT 1055
+#define QU_SC6_FALLBALL 2690
+#define QU_SC6_FALLHANDLE 2995
+#define QU_SC6_SHOWHANDLE 1689
+#define QU_SC6_SHOWNEXTBALL 2689
+#define ST_HDL_PLUGGED 2397
+#define ST_MAN6_BALL 2688
+#define ST_MOM_SITS 659
+#define ST_MOM_STANDS 658
+#define ST_NBL_NORM 1076
+
+// Scene 7
+#define ANI_CORNERSITTER 71
+#define ANI_HOOLIGAN 808
+#define ANI_LUKE 803
+#define ANI_PLUSMINUS 2938
+#define ANI_SC7_BOX 791
+#define MSG_SC7_CLOSELUKE 822
+#define MSG_SC7_HIDEBOX 817
+#define MSG_SC7_HIDELUKE 821
+#define MSG_SC7_OPENLUKE 823
+#define MSG_SC7_PULL 2943
+#define MSG_SC7_SHOWBOX 816
+#define MV_CST_CLOSELUKE 807
+#define MV_SC7_BOX_default 792
+#define QU_CST_CLOSELUKE 820
+#define ST_CST_HANDLELESS 794
+#define ST_HGN_LOOK 811
+#define ST_HGN_LUKE 810
+#define ST_LUK_CLOSED 805
+#define ST_LUK_OPEN 806
+#define ST_PMS_MINUS 2942
+#define ST_PMS_PLUS 2941
+
+// Scene 8
+#define ANI_BATUTA 737
+#define ANI_CLOCK_8 2989
+#define ANI_VMYATS 764
+#define MSG_SC8_ARCADENOW 1044
+#define MSG_SC8_ENTERUP 3037
+#define MSG_SC8_GETHIMUP 789
+#define MSG_SC8_HIDELADDER_D 1107
+#define MSG_SC8_RESUMEFLIGHT 784
+#define MSG_SC8_STANDUP 2976
+#define MSG_STARTARCADE 781
+#define MV_CLK8_GO 2990
+#define MV_MAN_FROMLADDERUP 1522
+#define MV_MAN_TOLADDERD 1524
+#define MV_MAN8_BADLUCK 783
+#define MV_MAN8_DRYGDOWN 770
+#define MV_MAN8_DRYGUP 768
+#define MV_MAN8_HANDSDOWN 772
+#define MV_MAN8_HANDSUP 777
+#define MV_MAN8_JUMP 775
+#define MV_MAN8_JUMPOFF 2969
+#define MV_MAN8_SITDOWN 2968
+#define MV_VMT_DEF 765
+#define PIC_SC8_ARCADENOW 1043
+#define PIC_SC8_LADDER 754
+#define PIC_SC8_LADDER_D 755
+#define PIC_SC8_LADDERD 1106
+#define QU_SC8_FINISH 788
+#define QU_SC8_STANDUP 2975
+#define SND_8_014 3624
+#define ST_BTT_CHESHET 746
+#define ST_BTT_NOSPOON 739
+#define ST_BTT_SLEEPS 748
+#define ST_BTT_SPOON 741
+#define ST_MAN8_FLYDOWN 771
+#define ST_MAN8_FLYUP 769
+#define ST_MAN8_HANDSUP 773
+#define ST_MAN8_STAND 774
+#define ST_VMT_MIN 766
+
+// Scene 10
+#define ANI_GUM 978
+#define ANI_NADUVATEL 944
+#define ANI_PACHKA 975
+#define ANI_PACHKA2 3008
+#define MSG_SC10_CLICKGUM 992
+#define MSG_SC10_HIDEGUM 993
+#define MSG_SC10_LADDERTOBACK 3002
+#define MSG_SC10_LADDERTOFORE 3004
+#define MSG_SC10_SHOWGUM 994
+#define MV_NDV_BLOW2 2855
+#define MV_NDV_DENIES 952
+#define MV_NDV_DENY_NOGUM 3022
+#define PIC_SC10_DTRUBA 974
+#define PIC_SC10_LADDER 995
+#define QU_SC10_ENTERLIFT 1067
+#define QU_SC10_EXITLIFT 2809
+#define QU_SC10_TAKEGUM 3026
+#define ST_NDV_SIT 946
+
+// Scene 11
+#define ANI_BOOTS_11 2704
+#define ANI_KACHELI 1094
+#define ANI_MAN11 1108
+#define ANI_SWINGER 1113
+#define MSG_SC11_HITMAN 3019
+#define MSG_SC11_MANCRY 4691
+#define MSG_SC11_MANTOSWING 1128
+#define MSG_SC11_PUTBOOT 1117
+#define MSG_SC11_RESTARTMAN 1133
+#define MSG_SC11_SHOWSWING 1124
+#define MSG_SC11_SITSWINGER 5198
+#define MV_KCH_MOVE2 1099
+#define MV_KCH_START 1121
+#define MV_MAN11_JUMPHIT 1129
+#define MV_MAN11_JUMPFROMSWING 5209
+#define MV_MAN11_JUMPOVER 1131
+#define MV_MAN11_SWING_0 1109
+#define MV_MAN11_SWING_1 1111
+#define MV_MAN11_SWING_2 1112
+#define PIC_SC11_HINT 5170
+#define QU_SC11_MANFALL 3017
+#define QU_SC11_PUTBOOT1 2709
+#define QU_SC11_PUTBOOT2 2710
+#define QU_SC11_RESTARTMAN 1134
+#define QU_SWR_JUMPDOWN 1123
+#define SND_11_020 3704
+#define SND_11_022 3706
+#define SND_11_024 3708
+#define SND_11_031 5171
+#define ST_BTS11_2 2707
+#define ST_BTS11_ONE 2706
+#define ST_KCH_0 1096
+#define ST_KCH_EMPTY 1132
+#define ST_KCH_STATIC 1122
+#define ST_MAN_1PIX 518
+#define ST_MAN11_EMPTY 1110
+#define ST_MAN11_SWING 1127
+#define ST_SWR_SIT 1147
+#define ST_SWR_SITBALD 1153
+#define ST_SWR_STAND3 3014
+
+// Scene 13
+#define ANI_BRIDGE 1378
+#define ANI_HANDLE_L 1209
+#define ANI_HANDLE_R 1196
+#define ANI_STOROZH 1172
+#define ANI_WHIRLGIG_13 1383
+#define MSG_SC13_CHEW 1220
+#define MSG_SC13_CLOSEBRIDGE 3046
+#define MSG_SC13_CLOSEFAST 1267
+#define MSG_SC13_EATGUM 1219
+#define MSG_SC13_OPENBRIDGE 3064
+#define MSG_SC13_OPENFAST 1266
+#define MSG_SC13_SHOWGUM 1215
+#define MSG_SC13_STARTWHIRLGIG 1388
+#define MSG_SC13_STOPWHIRLGIG 1387
+#define MSG_SC13_TESTCLOSE 3065
+#define MSG_SC13_TESTOPEN 3048
+#define MSG_SC13_UNEATGUM 1218
+#define MSG_SC13_UPDATEBRIDGE 1217
+#define MV_BDG_CLOSE 1382
+#define MV_BDG_OPEN 1379
+#define MV_WHR13_SPIN 1384
+#define QU_SC13_CLOSEFAIL 3063
+#define QU_SC13_CLOSESUCCESS 3062
+#define QU_SC13_OPENFAIL 3042
+#define QU_SC13_OPENSUCCESS 3047
+#define QU_SC13_SHOWGUM 1216
+#define QU_STR_CHEW 1190
+#define QU_STR_LTOR 3054
+#define QU_STR_PLUU 1189
+#define QU_STR_RTOL 3053
+#define QU_STR_TURNR 1186
+#define QU_STR_TURNR_L 3059
+#define SND_13_018 3763
+#define SND_13_033 4685
+#define SND_13_034 4686
+#define SND_13_037 5335
+#define ST_BDG_CLOSED 1380
+#define ST_BDG_OPEN2 1381
+#define ST_HDLL_FIRECAN 1310
+#define ST_HDLL_HAMMER 3205
+#define ST_HDLL_UP 1211
+#define ST_HDLR_DOWN 1199
+#define ST_HDLR_DOWN_GUM 3044
+#define ST_HDLR_GUM 1201
+#define ST_STR_LEFT 1175
+#define ST_STR_RIGHT 1174
+
+// Scene 14
+#define ANI_BALL14 1246
+#define ANI_GRANDMA 1227
+#define MSG_SC14_ENDARCADE 3250
+#define MSG_SC14_GMAJUMP 1250
+#define MSG_SC14_GMATOTRUBA 3249
+#define MSG_SC14_HIDEBALLLAST 3251
+#define MSG_SC14_HIDEPINK 3248
+#define MSG_SC14_MANKICKBALL 1257
+#define MSG_SC14_RESTORESCROLL 4769
+#define MSG_SC14_SCROLLLEFT 4768
+#define MSG_SC14_SHOWBALLFLY 1253
+#define MSG_SC14_SHOWBALLGMADIVE 1260
+#define MSG_SC14_SHOWBALLGMAHIT 1259
+#define MSG_SC14_SHOWBALLGMAHIT2 3245
+#define MSG_SC14_SHOWBALLLAST 3246
+#define MSG_SC14_SHOWBALLMAN 1254
+#define MSG_SC14_STARTARCADE 3252
+#define MV_BAL14_FALL 1258
+#define MV_BAL14_SPIN 1247
+#define MV_BAL14_TOGMA 3214
+#define MV_GMA_BACKOFF 1233
+#define MV_GMA_BACKOFF2 3217
+#define MV_GMA_JUMPFW 1230
+#define MV_GMA_THROW 1232
+#define MV_MAN14_DECLINE 1239
+#define MV_MAN14_FALL 1236
+#define MV_MAN14_KICK 1237
+#define MV_MAN14_KICKAIR 1256
+#define MV_MAN14_STEPFW 1240
+#define PIC_SC14_RTRUBA 1221
+#define ST_GMA_SIT 1229
+#define QU_GMA_BLINK 1252
+#define QU_GMA_JUMPBK 1251
+#define QU_GMA_JUMPFW 1249
+#define QU_GMA_THROW 1255
+#define QU_SC14_ENDARCADE 1391
+#define QU_SC14_ENTERLIFT 1225
+#define QU_SC14_EXITLIFT 1226
+#define QU_SC14_STARTARCADE 1390
+#define QU_SC14_WINARCADE 3247
+
+// Scene 15
+#define ANI_BOOT_15 4779
+#define ANI_INV_BOOT 881
+#define ANI_GRANDMA_ASS 1265
+#define MSG_SC15_ASSDRYG 4755
+#define MSG_SC15_LADDERTOBACK 3259
+#define MSG_SC15_PULL 2940
+#define MSG_SC15_STOPCHANTING 4753
+#define MV_SWR_SWING 1114
+#define PIC_SC15_DTRUBA 1263
+#define PIC_SC15_LADDER 3253
+#define PIC_SC15_LTRUBA 1261
+#define QU_SC15_ENTERLIFT 2811
+#define QU_SC15_EXITLIFT 2812
+#define SND_15_001 3798
+#define SND_15_006 3808
+#define SND_15_011 4754
+#define ST_GMS_BOOT 1270
+#define ST_GMS_BOOTLESS2 3316
+
+// Scene 16
+#define ANI_BEARDED_CMN 3420
+#define ANI_BOOT_16 3285
+#define ANI_BOY 1327
+#define ANI_GIRL 1328
+#define ANI_JETTIE 1392
+#define ANI_MUG 1296
+#define ANI_WIRE16 1344
+#define MSG_SC16_FILLMUG 1363
+#define MSG_SC16_HIDEMAN 1357
+#define MSG_SC16_HIDEMUG 1351
+#define MSG_SC16_HIDEWIRE 1349
+#define MSG_SC16_LAUGHSOUND 4993
+#define MSG_SC16_MUGCLICK 1366
+#define MSG_SC16_SHOWBEARDED 4956
+#define MSG_SC16_SHOWMAN 1358
+#define MSG_SC16_SHOWMUG 1352
+#define MSG_SC16_SHOWMUGFULL 1396
+#define MSG_SC16_SHOWWIRE 1350
+#define MSG_SC16_STARTLAUGH 1374
+#define MV_BOY_DRINK 1333
+#define MV_BT16_FILL 3286
+#define MV_GRL_DRINK 1339
+#define MV_GRL_FALL 3115
+#define MV_GRL_LAUGH_POPA 3278
+#define MV_JTI_FLOWBY 1393
+#define MV_JTI_FLOWIN 1394
+#define MV_MAN16_TAKEMUG 1362
+#define PIC_SC16_TUMBA 1368
+#define QU_BRD16_STARTBEARDED 4948
+#define QU_SC16_BOYKICK 1367
+#define QU_SC16_BOYOUT 1364
+#define QU_SC16_GIRLLAUGH 1375
+#define QU_SC16_GIRLOUT 1365
+#define QU_SC16_GOBOY 1347
+#define QU_SC16_GOGIRL 1348
+#define QU_SC16_MANDRINK 5200
+#define QU_SC16_SHOWMUG 1361
+#define QU_SC16_TAKEMUG 1435
+#define SND_16_034 3854
+#define SND_16_035 3855
+#define SND_16_037 3857
+#define ST_BOY_STAND 1331
+#define ST_GRL_LAUGH 1342
+#define ST_GRL_STAND 1337
+#define ST_MUG_EMPTY 1298
+#define ST_MUG_FULL 1360
+
+// Scene 17
+#define ANI_BOOT_17 4220
+#define ANI_HAND17 1446
+#define ANI_INV_BOTTLE 1418
+#define ANI_INV_SUGAR 1410
+#define ANI_JET_17 2746
+#define ANI_MUG_17 2737
+#define ANI_SAMOGONSHCHIK 1397
+#define MSG_SC17_DROP 3414
+#define MSG_SC17_FILLBOTTLE 1436
+#define MSG_SC17_HIDESUGAR 1417
+#define MSG_SC17_SHOWBOTTLE 1432
+#define MSG_SC17_SHOWSUGAR 1416
+#define MSG_SC17_TESTTRUBA 1458
+#define MSG_SC17_UPDATEHAND 1560
+#define MV_HND17_FIGA 1449
+#define PIC_SC17_RTRUBA 1323
+#define PIC_SC17_RTRUBA2 5297
+#define QU_HND17_ASK 1456
+#define QU_HND17_ATTRACT 1455
+#define QU_HND17_TOCYCLE 1454
+#define QU_JET17_DROP 3295
+#define QU_JET17_FLOW 3294
+#define QU_SC17_FILLBOOT 4237
+#define QU_SC17_FILLBOTTLE 1437
+#define QU_SC17_FILLMUG 2750
+#define QU_SC17_FILLMUG_DROP 3415
+#define QU_SC17_SHOWBOTTLE 1429
+#define QU_SC17_SHOWSUGAR 1415
+#define QU_SMG_FILLBOTTLE 1433
+#define ST_HND17_ATTRACT 1451
+#define ST_HND17_EMPTY 1448
+#define ST_MUG17_EMPTY 2739
+#define ST_SMG_SIT 1399
+
+// Scene 18
+#define PIC_SC18_RTRUBA 1520
+
+// Scene 19
+#define PIC_SC19_RTRUBA3 1515
+
+// Scene 20
+#define ANI_GRANDMA_20 2427
+#define MSG_SC20_UPDATELOCKABLE 5217
+#define ST_GMA20_FLOOR 2429
+#define ST_GMA20_STAND 2436
+#define ST_GMA20_STOOL 2432
+
+// Scene 21
+#define ANI_GIRAFFE_BOTTOM 1633
+#define ANI_INV_BOX 890
+#define ANI_INV_STOOL 1780
+#define MSG_SC21_UPDATEASS 4211
+#define PIC_SC21_DTRUBA 1823
+#define ST_GRFB_SIT 1687
+#define ST_GRFB_HANG 1638
+
+// Scene 22
+#define ANI_GIRAFFE_MIDDLE 1981
+#define ANI_MESHOK 1754
+#define ANI_TABURETTE 1745
+#define MSG_SC22_CHECKGMABOOT 4782
+#define MSG_SC22_CRANEOUT_GMA 5218
+#define MSG_SC22_FROMSTOOL 1799
+#define MSG_SC22_HANDLEDOWN 1796
+#define MSG_SC22_HIDESTOOL 2503
+#define MSG_SC22_ONSTOOL 1798
+#define MSG_SC22_SHOWSTOOL 2495
+#define QU_MSH_CRANEOUT 1811
+#define QU_MSH_CRANEOUT_GMA 5219
+#define QU_SC22_FALLBROOM 1786
+#define QU_SC22_FALLSACK 1791
+#define QU_SC22_FALLSACK_GMA 2613
+#define QU_SC22_FROMSTOOL 1800
+#define QU_SC22_HANDLEDOWN 1804
+#define QU_SC22_PUTSTOOL 1803
+#define QU_SC22_SHOWSTOOL 1793
+#define QU_SC22_TOSTOOL 1801
+#define QU_SC22_TOSTOOL_R 3332
+#define QU_SC22_TRYBOX 5311
+#define QU_SC22_TRYHANDLE 1802
+#define QU_MSH_MOVE 1812
+#define rMV_MAN_TURN_SRL 1090
+#define ST_GRFM_AFTER 3472
+#define ST_GRFM_NORM 1983
+#define ST_MSH_SIT 1756
+
+// Scene 23
+#define ANI_CALENDWHEEL 1702
+#define ANI_GIRAFFE_TOP 1645
+#define ANI_GIRAFFEE 1672
+#define ANI_HANDLE23 1978
+#define ANI_INV_LEVERHANDLE 1777
+#define ANI_LUK23_D 1813
+#define ANI_LUK23_U 1817
+#define MSG_SC23_CLICKBTN1 1736
+#define MSG_SC23_CLICKBTN2 1737
+#define MSG_SC23_CLICKBTN3 1738
+#define MSG_SC23_CLICKBTN4 1739
+#define MSG_SC23_FROMSTOOL 3339
+#define MSG_SC23_HIDEGIRAFFEE 4650
+#define MSG_SC23_ONSTOOL 3334
+#define MSG_SC23_SPINWHEEL1 1740
+#define MSG_SC23_SPINWHEEL2 1741
+#define MSG_SC23_SPINWHEEL3 1742
+#define MSG_SC23_SPINWHEEL4 1743
+#define MV_CND_0_1 1703
+#define MV_CND_1_2 1706
+#define MV_CND_2_3 1708
+#define MV_CND_3_4 1710
+#define MV_CND_4_5 1712
+#define MV_CND_5_6 1714
+#define MV_CND_6_7 1716
+#define MV_CND_7_8 1718
+#define MV_CND_8_9 1720
+#define MV_CND_9_0 1722
+#define MV_MAN23_PUSH1 1724
+#define MV_MAN23_PUSH2 1725
+#define MV_MAN23_PUSH3 1726
+#define MV_MAN23_PUSH4 1727
+#define PIC_SC23_BOXCLOSED 1728
+#define PIC_SC23_BOXOPEN 1723
+#define PIC_SC23_BTN1 1729
+#define PIC_SC23_BTN2 1730
+#define PIC_SC23_BTN3 1731
+#define PIC_SC23_BTN4 1732
+#define PIC_SC23_LADDER 1628
+#define PIC_SC23_LADDERU 3411
+#define QU_GRFU_TURN_UD 1664
+#define QU_GRFU_TURN_UL 1662
+#define QU_SC23_FROMCALENDAR 1734
+#define QU_SC23_FROMCALENDAREXIT 1735
+#define QU_SC23_FROMSTOOL 3338
+#define QU_SC23_SHOWSTOOL 3335
+#define QU_SC23_STARTKISS 1822
+#define QU_SC23_TOCALENDAR 1733
+#define ST_CND_0 1704
+#define ST_CND_1 1705
+#define ST_CND_2 1707
+#define ST_CND_3 1709
+#define ST_CND_4 1711
+#define ST_CND_5 1713
+#define ST_CND_6 1715
+#define ST_CND_7 1717
+#define ST_CND_8 1719
+#define ST_CND_9 1721
+#define ST_GRFG_BALD 1675
+#define ST_GRFG_EMPTY 1674
+#define ST_GRFU_KISS 1681
+#define ST_GRFU_UP 1648
+#define ST_LUK23_OPEN 1816
+#define ST_LUK23_WHANDLE2 1977
+#define ST_LUK23U_CLOSED 1819
+#define ST_LUK23U_OPEN 1820
+
+// Scene 24
+#define ANI_DROP_24 3505
+#define ANI_INV_HAMMER 884
+#define ANI_JET24 1837
+#define ANI_WATER24 1834
+#define MV_MAN_TURN_RL 332
+#define MV_WTR24_FLOW 1835
+#define MV_WTR24_FLOWLOWER 1844
+#define MV_JET24_FLOW 1838
+#define QU_DRP24_TOFLOOR 3510
+#define QU_DRP24_TOWATER 3509
+#define QU_DRP24_TOWATER2 4046
+#define SND_24_006 4041
+#define SND_24_007 4042
+#define ST_DRP24_EMPTY 3507
+#define ST_WTR24_FLOWLOWER 1843
+
+// Scene 25
+#define ANI_BEARDED_CMN 3420
+#define ANI_BOARD25 1898
+#define ANI_DROP_25 3499
+#define ANI_INV_BOARD 1872
+#define ANI_INV_BROOM 1774
+#define ANI_INV_LOPAT 1920
+#define ANI_INV_SWAB 1917
+#define ANI_WATER25 1856
+#define MSG_BRD_TURN 4877
+#define MSG_SC25_ENTERMAN 1861
+#define MSG_SC25_ENTERTRUBA 4214
+#define MSG_SC25_STARTBEARDEDS 3423
+#define MSG_SC25_STOPBEARDEDS 3424
+#define MSG_SC25_TOLADDER 4215
+#define MV_MAN_GOLADDERDOWN 455
+#define MV_MAN25_CHIH 1886
+#define rMV_MAN25_CHIH 3343
+#define MV_BRD25_RIGHT 1899
+#define rMV_BRD25_RIGHT 1903
+#define MV_MAN25_ONBOARD 1885
+#define rMV_MAN25_ONBOARD 1966
+#define MV_WTR25_FLOW 1857
+#define PIC_SC25_LADDERDOWN 1855
+#define PIC_SC25_LADDERUP 1854
+#define PIC_SC25_RTRUBA 1853
+#define QU_DRP25_TOFLOOR 3502
+#define QU_DRP25_TOWATER 3504
+#define QU_SC25_BACKTOLADDER 1955
+#define QU_SC25_BACKTOTRUBA 2061
+#define QU_SC25_BEARDED 3425
+#define QU_SC25_BEARDED2 3426
+#define QU_SC25_BEARDED3 3427
+#define QU_SC25_BOARDTOLADDER 1911
+#define QU_SC25_ENTERUP_FLOOR 1904
+#define QU_SC25_ENTERUP_WATER 1895
+#define QU_SC25_LADDERUP 1925
+#define QU_SC25_MANTOTRUBA 1905
+#define QU_SC25_MANTOTRUBA_R 4218
+#define QU_SC25_PUTBOARD 1896
+#define QU_SC25_ROWTOLADDER 1910
+#define QU_SC25_ROWTOTRUBA 1897
+#define QU_SC25_TRUBATOBOARD 1909
+#define QU_SC25_TRYBROOM 1912
+#define QU_SC25_TRYHAND 4219
+#define QU_SC25_TRYROWHAND 3493
+#define QU_SC25_TRYROWHAND_R 3494
+#define QU_SC25_TRYSPADE 3498
+#define QU_SC25_TRYSWAB 1913
+#define QU_SC25_TRYWATER 1906
+#define SND_25_006 4059
+#define SND_25_025 4874
+#define SND_25_026 4875
+#define SND_25_027 4876
+#define SND_25_028 5173
+#define SND_25_029 5174
+#define SND_25_030 5175
+#define ST_BRD25_RIGHT2 1902
+#define ST_BRDCMN_EMPTY 3422
+#define ST_DRP25_EMPTY 3501
+#define ST_MAN_GOLADDERD 456
+#define ST_MAN_LADDERDOWN_R 3419
+#define ST_MAN25_ONBOARD 1879
+
+// Scene 26
+#define ANI_CHHI 1957
+#define ANI_DROP_26 3345
+#define ANI_INV_SOCK 1698
+#define ANI_INV_VENT 1968
+#define ANI_LUK26 1867
+#define ANI_SOCK_26 4553
+#define ANI_VENT 1927
+#define MSG_SC26_CLICKVENT 1947
+#define MSG_SC26_HIDECHI 1967
+#define MSG_SC26_HIDEVENT 1945
+#define MSG_SC26_SHOWCHI 3495
+#define MSG_SC26_SHOWVENT 1946
+#define MSG_SC26_TESTVENT 1952
+#define MSG_SC26_UPDATEDROP 3496
+#define MSG_SC26_UPDATEPOOL 1956
+#define PIC_SC26_LTRUBA 1864
+#define PIC_SC26_SOCK 5312
+#define QU_CHI_HIDE 1965
+#define QU_CHI_SHOW 1964
+#define QU_SC26_AUTOCLOSE1 1949
+#define QU_SC26_AUTOCLOSE2 1950
+#define QU_SC26_AUTOCLOSE3 1951
+#define QU_SC26_CLOSE1 1936
+#define QU_SC26_CLOSE2 1938
+#define QU_SC26_CLOSE3 1940
+#define QU_SC26_CLOSE4 1942
+#define QU_SC26_CLOSE5 1944
+#define QU_SC26_OPEN1 1935
+#define QU_SC26_OPEN2 1937
+#define QU_SC26_OPEN3 1939
+#define QU_SC26_OPEN4 1941
+#define QU_SC26_OPEN5 1943
+#define SND_26_003 4079
+#define SND_26_018 5340
+#define SND_26_019 5341
+#define SND_26_020 5342
+#define ST_CHI_EMPTY 1959
+#define ST_CHI_NORM 1960
+#define ST_VNT26_RIGHT2 3348
+#define ST_VNT26_UP2 1948
+
+// Scene 28
+#define ANI_LIFT 982
+#define ANI_LIFT_28 4238
+#define ANI_MAN_28 4247
+#define ANI_TIOTIA 4286
+#define MSG_SC28_CLICKLIFT 4258
+#define MSG_SC28_ENDCABIN 3456
+#define MSG_SC28_ENDLIFT1 4259
+#define MSG_SC28_ENDLIFT6 4244
+#define MSG_SC28_LIFT1_SHOWAFTER 4261
+#define MSG_SC28_LIFT6INSIDE 5354
+#define MSG_SC28_LIFT6MUSIC 5355
+#define MSG_SC28_MAKEFACES 4684
+#define MSG_SC28_STARTWORK1 4255
+#define MSG_SC28_TRYVTORPERS 4961
+#define MSG_SC28_TURNOFF_0 4678
+#define MSG_SC28_TURNOFF_1 4279
+#define MSG_SC28_TURNOFF_2 4277
+#define MSG_SC28_TURNOFF_3 4275
+#define MSG_SC28_TURNOFF_4 4282
+#define MSG_SC28_TURNOFF_6 4273
+#define MSG_SC28_TURNON4 4280
+#define MSG_SC28_TURNON_0 4677
+#define MSG_SC28_TURNON_1 4278
+#define MSG_SC28_TURNON_2 4276
+#define MSG_SC28_TURNON_3 4274
+#define MSG_SC28_TURNON_4 4281
+#define MSG_SC28_TURNON_6 4272
+#define MV_WMN28_IN_1 3443
+#define MV_WMN28_IN_2 3445
+#define MV_WMN28_IN_3 3446
+#define MV_WMN28_IN_4 3447
+#define MV_WMN28_IN_5 3448
+#define PIC_SC28_DARK0 4675
+#define PIC_SC28_DARK1 4266
+#define PIC_SC28_DARK2 4267
+#define PIC_SC28_DARK3 4268
+#define PIC_SC28_DARK4 4269
+#define PIC_SC28_DARK5 4270
+#define PIC_SC28_DARK6 4271
+#define QU_BRD28_GOL 4960
+#define QU_BRD28_GOR 4959
+#define QU_GLV28_GOL 4958
+#define QU_GLV28_GOR 4957
+#define QU_SC28_LIFT0_START 4676
+#define QU_SC28_LIFT1_START 4254
+#define QU_SC28_LIFT1_WORK 4256
+#define QU_SC28_LIFT2_START 4246
+#define QU_SC28_LIFT3_START 4245
+#define QU_SC28_LIFT5_START 4674
+#define QU_SC28_LIFT6_END 3563
+#define QU_SC28_LIFT6_START 4243
+#define QU_SC28_LIFT6_START2 4295
+#define QU_SC28_WMN_START 3452
+#define ST_MAN28_RIGHT 4249
+
+// Scene 30
+#define ANI_LEG 2322
+#define MSG_SC30_UPDATEPATH 2358
+#define PIC_SC30_LTRUBA 2354
+#define QU_SC30_ENTERLIFT 2823
+#define QU_SC30_EXITLIFT 2824
+#define ST_LEG_DOWN 2325
+#define ST_LEG_DOWN1 2330
+#define ST_LEG_DOWN2 2334
+#define ST_LEG_EMPTY 2338
+#define ST_LEG_UP 2324
+
+// Scene 31
+#define LiftDown 1058
+#define LiftUp 1057
+#define ANI_CACTUS_31 2456
+#define MSG_SC31_PULL 2944
+#define MSG_SC31_TESTCACTUS 5095
+#define SND_31_001 4377
+#define ST_CTS31_GROWN2 2472
+
+// Scene 32
+#define ANI_BUTTON_32 5347
+#define ANI_CACTUS 2267
+#define ANI_FLAG 2257
+#define ANI_KADKA 2670
+#define ANI_TESTO_BLUE 2659
+#define ANI_TESTO_GREEN 2662
+#define ANI_TESTO_ORANGE 2656
+#define MSG_SC32_ONLADDER 2270
+#define MSG_SC32_SPIN 2405
+#define MSG_SC32_STARTCACTUS 2414
+#define MSG_SC32_STARTFLAGLEFT 2310
+#define MSG_SC32_STARTFLAGRIGHT 2309
+#define MSG_SC32_STOPFLAG 2311
+#define MSG_SC32_TRUBATOBACK 5181
+#define MSG_SC32_TRUBATOFRONT 5180
+#define MSG_SC32_TRYSIT 2294
+#define MV_CTS_DEFAULT 4299
+#define MV_FLG_CYCLEL 2262
+#define MV_FLG_CYCLER 2266
+#define MV_FLG_STARTL 2258
+#define MV_FLG_STARTR 2263
+#define MV_FLG_STOPL 2261
+#define MV_FLG_STOPR 2265
+#define MV_MAN32_SITDOWN 2276
+#define MV_MAN32_STANDUP 2313
+#define MV_TSTG_FLOW 2663
+#define MV_TSTO_FLOW 2657
+#define PIC_SC32_LADDER 4296
+#define PIC_SC32_RTRUBA 2292
+#define QU_CTS_BACK 2415
+#define QU_CTS_GROW 2416
+#define QU_CTS_GROWMAN 2417
+#define QU_KBK32_GO 4977
+#define QU_KBK32_START 4982
+#define QU_KDK_DRIZZLE 4301
+#define QU_SC32_ENTERLIFT 2827
+#define QU_SC32_EXITLIFT 2828
+#define QU_SC32_FALLHANDLE 5351
+#define QU_SC32_FROMLADDER 4300
+#define QU_SC32_SHOWHANDLE 2399
+#define ST_BTN32_OFF 5349
+#define ST_BTN32_ON 5350
+#define ST_CTS_EMPTY 2269
+#define ST_CTS_GROWUP 2467
+#define ST_FLG_LEFT 2260
+#define ST_FLG_NORM 2259
+#define ST_FLG_RIGHT 2264
+#define ST_HDL_LAID 3039
+#define ST_MAN32_SIT 2277
+
+// Scene 33
+#define ANI_KUBIK 4963
+#define ANI_JETTIE_FLOW 2627
+#define ANI_MUG_33 2623
+#define ANI_VENT_33 2637
+#define MSG_SC33_HANDLEDOWN 2643
+#define MSG_SC33_POUR 2645
+#define MSG_SC33_TESTMUG 5185
+#define MSG_SC33_TRYKUBIK 4980
+#define MSG_SC33_UPDATEKUBIK 5346
+#define MV_JTI33_FLOW 2628
+#define MV_JTI33_POUR 2630
+#define MV_JTI33_POURFULL 4455
+#define MV_VNT33_TURND 2638
+#define MV_VNT33_TURNR 2641
+#define PIC_SC33_LTRUBA 2618
+#define PIC_SC33_ZONES 5298
+#define QU_KBK33_GO 4978
+#define QU_KBK33_START 4983
+#define QU_SC33_STARTWATER 2644
+#define ST_MUG33_EMPTY 2625
+#define ST_MUG33_FULL 2626
+#define ST_VNT33_DOWN 2640
+#define ST_VNT33_RIGHT 2639
+
+// Scene 34
+#define ANI_BOOT_34 4560
+#define ANI_BOX_34 2498
+#define ANI_CACTUS_34 2381
+#define ANI_LUK_34 2541
+#define ANI_STOOL_34 2486
+#define ANI_VENT_34 2473
+#define MSG_SC34_CLIMB 2490
+#define MSG_SC34_CLIMBBOX 4571
+#define MSG_SC34_FROMCACTUS 4313
+#define MSG_SC34_LEAVEBOARD 2576
+#define MSG_SC34_ONBOARD 2550
+#define MSG_SC34_ONBUMP 5313
+#define MSG_SC34_ONCACTUS 2482
+#define MSG_SC34_RETRYVENT 5210
+#define MSG_SC34_SHOWBOX 2497
+#define MSG_SC34_SHOWVENT 2481
+#define MSG_SC34_TESTVENT 2557
+#define MSG_SC34_UNCLIMB 2492
+#define MV_MAN34_TRY 2485
+#define MV_MAN34_TRYTABUR 2489
+#define MV_MAN34_TURNVENT_L 4307
+#define MV_MAN34_TURNVENT_R 2500
+#define QU_SC34_ENTERLIFT 2819
+#define QU_SC34_EXITLIFT 2820
+#define QU_SC34_FROMBOX 2494
+#define QU_SC34_FROMBOX_FLOOR 4572
+#define QU_SC34_FROMCACTUS 4312
+#define QU_SC34_FROMSTOOL 2491
+#define QU_SC34_LEAVEBOARD 2575
+#define QU_SC34_SHOWSTOOL 2496
+#define QU_CTS34_FALLEFT 4316
+#define QU_CTS34_FALLRIGHT 4317
+#define QU_LUK34_CLOSE 2547
+#define QU_LUK34_OPEN 2546
+#define ST_CTS34_EMPTY 2383
+#define ST_CTS34_GROWNEMPTY2 2475
+#define ST_LUK34_CLOSED 2543
+#define ST_LUK34_OPEN 2544
+#define ST_STL34_BOX2 4305
+#define ST_VNT34_RIGHT3 4318
+#define ST_VNT34_UP2 4310
+
+// Scene 35
+#define ANI_HOSE 2424
+#define ANI_PUZODUV 2418
+#define MSG_SC35_CHECKPIPESOUND 4761
+#define MSG_SC35_PLUGHOSE 2524
+#define MSG_SC35_SHRINK 2570
+#define MSG_SC35_STARTFLOW 2523
+#define MSG_SC35_STOPFLOW 4864
+#define MSG_SC35_TRYFLY 4985
+#define QU_PDV_SML_BLINK 2553
+#define QU_PDV_SML_TRY 2554
+#define QU_SC35_EATHOZE 2540
+#define QU_SC35_ENTERLIFT 2815
+#define QU_SC35_EXITLIFT 2816
+#define SND_35_011 4509
+#define SND_35_012 4510
+#define SND_35_026 4863
+#define ST_HZE_NORM 2426
+#define ST_PDV_LARGE 2421
+#define ST_PDV_SMALL 2420
+
+// Scene 36
+#define ANI_SCISSORS_36 2647
+#define ANI_ROTOHRUST 2360
+#define PIC_SC36_MASK 5221
+#define ST_RHT_OPEN 2362
+
+// Scene 37
+#define ANI_GUARD_37 2588
+#define ANI_RING 2604
+#define MSG_SC37_EXITLEFT 5006
+#define MSG_SC37_PULL 2945
+#define MV_GRD37_PULL 2589
+#define MV_RNG_CLOSE 2605
+#define MV_RNG_OPEN 4612
+#define PIC_SC37_MASK 2608
+#define SND_37_007 4547
+#define ST_GRD37_STAND 2590
+#define ST_RNG_CLOSED2 4865
+#define ST_RNG_OPEN 2606
+
+// Scene 38
+#define ANI_BOTTLE38 2188
+#define ANI_DOMINO38 2200
+#define ANI_DOMINOS 3317
+#define ANI_DYLDA 2169
+#define ANI_GLAVAR 2154
+#define ANI_MALYSH 2165
+#define MSG_SC38_DRINK 2225
+#define MSG_SC38_HMRKICK 2224
+#define MSG_SC38_POINT 2226
+#define MSG_SC38_POSTHMRKICK 2256
+#define MSG_SC38_PROPOSE 2287
+#define MSG_SC38_TRYTAKEBOTTLE 3179
+#define MV_DMS_FOUR 3322
+#define MV_DMS_THREE 3321
+#define MV_GLV_LOOKMAN 2167
+#define ST_BTL38_FULL 3172
+#define ST_DMN38_6 2288
+#define ST_DMN38_NORM3 2251
+#define ST_DMN38_NORM4 2253
+#define ST_DMS_3 3319
+#define ST_DMS_4 3320
+#define ST_GLV_HAMMER 2156
+#define ST_GLV_NOHAMMER 2159
+#define ST_GLV_SLEEP2 2166
+#define ST_MLS_LEFT2 2291
+#define ST_MLS_RIGHT2 3323
+#define QU_DLD_BLINK 2216
+#define QU_DLD_DENY 2218
+#define QU_DLD_GLOT 2217
+#define QU_DLD_ICK 2219
+#define QU_DLD_TAKE1 2214
+#define QU_DLD_TAKE2 2215
+#define QU_GLV_DRINK 2210
+#define QU_GLV_DRINKBOTTLE 2286
+#define QU_GLV_DRINK_NOHMR 2211
+#define QU_GLV_HMRKICK 2207
+#define QU_GLV_PROPOSE 2280
+#define QU_GLV_PROPOSE_NOHMR 2281
+#define QU_GLV_TAKEDOMINO 2170
+#define QU_GLV_TAKEDOMINO_NOHMR 3182
+#define QU_GLV_TOSMALL 2208
+#define QU_GLV_TOSMALL_NOHMR 2209
+#define QU_MLS_BLINK 2222
+#define QU_MLS_HAND 2223
+#define QU_MLS_TURNL 2220
+#define QU_MLS_TURNR 2221
+#define QU_SC38_SHOWBOTTLE 2199
+#define QU_SC38_SHOWBOTTLE_ONTABLE 2838
+#define QU_SC38_ENTERLIFT 2836
+#define QU_SC38_EXITLIFT 2837
+
+// Final scene
+#define ANI_FIN_COIN 5014
+#define MSG_FIN_ENDFINAL 5109
+#define MSG_FIN_GOTO2 5024
+#define MSG_FIN_GOTO3 5071
+#define MSG_FIN_GOTO4 5075
+#define MSG_FIN_STARTFINAL 5025
+#define MSG_FN4_STARTMUSIC 5356
+#define QU_FIN1_FALLCOIN 5018
+#define QU_FIN1_TAKECOIN 5023
+#define QU_FN2_DOFINAL 5066
+#define QU_FN3_DOFINAL 5072
+#define QU_FN4_DOFINAL 5108
+#define ST_FCN_NORM 5017
+
+// Debug scene
+#define MSG_RESTARTGAME 4767
+#define PIC_SCD_1 727
+#define PIC_SCD_2 728
+#define PIC_SCD_3 729
+#define PIC_SCD_4 730
+#define PIC_SCD_5 731
+#define PIC_SCD_6 732
+#define PIC_SCD_7 733
+#define PIC_SCD_8 756
+#define PIC_SCD_9 907
+#define PIC_SCD_10 981
+#define PIC_SCD_11 1098
+#define PIC_SCD_12 857
+#define PIC_SCD_13 1195
+#define PIC_SCD_14 1224
+#define PIC_SCD_15 1278
+#define PIC_SCD_16 1299
+#define PIC_SCD_17 1305
+#define PIC_SCD_18 1306
+#define PIC_SCD_19 1319
+#define PIC_SCD_20 1622
+#define PIC_SCD_21 1623
+#define PIC_SCD_22 1624
+#define PIC_SCD_23 1625
+#define PIC_SCD_24 1845
+#define PIC_SCD_25 1846
+#define PIC_SCD_26 1847
+#define PIC_SCD_27 1916
+#define PIC_SCD_28 2098
+#define PIC_SCD_29 2099
+#define PIC_SCD_30 2359
+#define PIC_SCD_31 2566
+#define PIC_SCD_32 2312
+#define PIC_SCD_33 2636
+#define PIC_SCD_34 2389
+#define PIC_SCD_35 2412
+#define PIC_SCD_36 2567
+#define PIC_SCD_37 2568
+#define PIC_SCD_38 2228
+#define PIC_SCD_FIN 5026
+#define PIC_SCD_SEL 734
} // End of namespace Fullpipe
diff --git a/engines/fullpipe/floaters.cpp b/engines/fullpipe/floaters.cpp
new file mode 100644
index 0000000000..9e5ca7b3f1
--- /dev/null
+++ b/engines/fullpipe/floaters.cpp
@@ -0,0 +1,255 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public 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 "fullpipe/fullpipe.h"
+#include "fullpipe/floaters.h"
+#include "fullpipe/utils.h"
+#include "fullpipe/objects.h"
+#include "fullpipe/motion.h"
+#include "fullpipe/statics.h"
+#include "fullpipe/scene.h"
+#include "fullpipe/constants.h"
+#include "fullpipe/objectnames.h"
+
+namespace Fullpipe {
+
+Floaters::~Floaters() {
+ delete _hRgn;
+}
+
+void Floaters::init(GameVar *var) {
+ _array1.clear();
+ _array2.clear();
+
+ GameVar *varFliers = var->getSubVarByName(sO_Fliers);
+
+ if (!varFliers)
+ return;
+
+ GameVar *sub = varFliers->getSubVarByName("flyIdleRegion");
+
+ if (sub) {
+ _hRgn = new ReactPolygonal();
+
+ _hRgn->_pointCount = sub->getSubVarsCount();
+ _hRgn->_points = (Common::Point **)malloc(sizeof(Common::Point *) * _hRgn->_pointCount);
+
+ sub = sub->_subVars;
+
+ int idx = 0;
+
+ while (sub) {
+ _hRgn->_points[idx] = new Common::Point;
+ _hRgn->_points[idx]->x = sub->_subVars->_value.intValue;
+ _hRgn->_points[idx]->y = sub->_subVars->_nextVarObj->_value.intValue;
+
+ idx++;
+ sub = sub->_nextVarObj;
+ }
+ }
+
+ sub = varFliers->getSubVarByName("flyIdlePath");
+
+ if (sub) {
+ _array1.reserve(sub->getSubVarsCount());
+
+ sub = sub->_subVars;
+
+ int idx = 0;
+
+ while (sub) {
+ FloaterArray1 *f = new FloaterArray1;
+
+ f->val1 = sub->_subVars->_value.intValue;
+ f->val2 = sub->_subVars->_nextVarObj->_value.intValue;
+
+ _array1.push_back(f);
+
+ idx++;
+ sub = sub->_nextVarObj;
+ }
+
+ }
+}
+
+void Floaters::genFlies(Scene *sc, int x, int y, int priority, int flags) {
+ StaticANIObject *ani = new StaticANIObject(g_fp->accessScene(SC_COMMON)->getStaticANIObject1ById(ANI_FLY, -1));
+
+ ani->_statics = ani->getStaticsById(ST_FLY_FLY);
+ ani->_movement = 0;
+ ani->setOXY(x, y);
+ ani->_flags |= 4;
+ ani->_priority = priority;
+
+ sc->addStaticANIObject(ani, 1);
+
+ ani->startAnim(MV_FLY_FLY, 0, -1);
+
+ int nummoves;
+
+ if (ani->_movement->_currMovement)
+ nummoves = ani->_movement->_currMovement->_dynamicPhases.size();
+ else
+ nummoves = ani->_movement->_dynamicPhases.size();
+
+ ani->_movement->setDynamicPhaseIndex(g_fp->_rnd->getRandomNumber(nummoves - 1));
+
+ FloaterArray2 *arr2 = new FloaterArray2;
+
+ arr2->ani = ani;
+ arr2->val11 = 15.0;
+ arr2->val3 = y;
+ arr2->val5 = y;
+ arr2->val2 = x;
+ arr2->val4 = x;
+ arr2->fflags = flags;
+
+ _array2.push_back(arr2);
+}
+
+void Floaters::update() {
+ for (uint i = 0; i < _array2.size(); ++i) {
+ if (_array2[i]->val13 <= 0) {
+ if (_array2[i]->val4 != _array2[i]->val2 || _array2[i]->val5 != _array2[i]->val3) {
+ if (_array2[i]->val9 < 2.0)
+ _array2[i]->val9 = 2.0;
+
+ int dy = _array2[i]->val3 - _array2[i]->val5;
+ int dx = _array2[i]->val2 - _array2[i]->val4;
+ double dst = sqrt((double)(dy * dy + dx * dx));
+ double at = atan2((double)dx, (double)dy);
+ int newX = (int)(cos(at) * _array2[i]->val9);
+ int newY = (int)(sin(at) * _array2[i]->val9);
+
+ if (dst < _array2[i]->val9) {
+ newX = _array2[i]->val2 - _array2[i]->val4;
+ newY = _array2[i]->val3 - _array2[i]->val5;
+ }
+ if (dst <= 30.0) {
+ if (dst < 30.0) {
+ _array2[i]->val9 = _array2[i]->val9 - _array2[i]->val9 * 0.5;
+
+ if (_array2[i]->val9 < 2.0)
+ _array2[i]->val9 = 2.0;
+ }
+ } else {
+ _array2[i]->val9 = _array2[i]->val9 * 0.5 + _array2[i]->val9;
+
+ if (_array2[i]->val9 > _array2[i]->val11)
+ _array2[i]->val9 = _array2[i]->val11;
+ }
+
+ _array2[i]->val4 += newX;
+ _array2[i]->val5 += newY;
+ _array2[i]->ani->setOXY(newX + _array2[i]->ani->_ox, newY + _array2[i]->ani->_oy);
+
+ if (_array2[i]->val4 == _array2[i]->val2 && _array2[i]->val5 == _array2[i]->val3) {
+ _array2[i]->val9 = 0.0;
+
+ _array2[i]->val13 = g_fp->_rnd->getRandomNumber(200) + 20;
+
+ if (_array2[i]->fflags & 1) {
+ g_fp->_currentScene->deleteStaticANIObject(_array2[i]->ani);
+
+ if (_array2[i]->ani)
+ delete _array2[i]->ani;
+
+ _array2.remove_at(i);
+
+ i--;
+
+ if (!_array2.size())
+ g_fp->stopAllSoundInstances(SND_CMN_060);
+
+ continue;
+ }
+ }
+ } else {
+ if ((_array2[i]->fflags & 4) && _array2[i]->countdown < 1) {
+ _array2[i]->fflags |= 1;
+ _array2[i]->val2 = _array2[i]->val6;
+ _array2[i]->val3 = _array2[i]->val7;
+ } else {
+ if (_array2[i]->fflags & 2) {
+ int idx1 = g_fp->_rnd->getRandomNumber(_array1.size() - 1);
+
+ _array2[i]->val2 = _array1[idx1]->val1;
+ _array2[i]->val3 = _array1[idx1]->val2;
+ } else {
+ Common::Rect rect;
+
+ if (!_hRgn)
+ error("Floaters::update(): empty fliers region");
+
+ _hRgn->getBBox(&rect);
+
+ int x2 = rect.left + g_fp->_rnd->getRandomNumber(rect.right - rect.left);
+ int y2 = rect.top + g_fp->_rnd->getRandomNumber(rect.bottom - rect.top);
+
+ if (_hRgn->pointInRegion(x2, y2)) {
+ int dx = _array2[i]->val2 - x2;
+ int dy = _array2[i]->val3 - y2;
+ double dst = sqrt((double)(dy * dy + dx * dx));
+
+ if (dst < 300.0 || !_hRgn->pointInRegion(_array2[i]->val4, _array2[i]->val5)) {
+ _array2[i]->val2 = x2;
+ _array2[i]->val3 = y2;
+ }
+ }
+ }
+
+ g_fp->playSound(SND_CMN_061, 0);
+
+ if (_array2[i]->fflags & 4)
+ _array2[i]->countdown--;
+ }
+ }
+ } else {
+ _array2[i]->val13--;
+ }
+
+ if (!_array2[i]->ani->_movement && _array2[i]->ani->_statics->_staticsId == ST_FLY_FLY) {
+ if (!_array2[i]->val15) {
+ g_fp->playSound(SND_CMN_060, 1);
+
+ _array2[i]->val15 = 1;
+ }
+
+ _array2[i]->ani->startAnim(MV_FLY_FLY, 0, -1);
+ }
+ }
+}
+
+void Floaters::stopAll() {
+ for (uint i = 0; i < _array2.size(); i++) {
+ g_fp->_currentScene->deleteStaticANIObject(_array2[i]->ani);
+
+ delete _array2[i]->ani;
+ }
+
+ _array2.clear();
+
+ g_fp->stopAllSoundInstances(SND_CMN_060);
+}
+
+
+} // End of namespace Fullpipe
diff --git a/engines/fullpipe/floaters.h b/engines/fullpipe/floaters.h
new file mode 100644
index 0000000000..3ecbbeea9c
--- /dev/null
+++ b/engines/fullpipe/floaters.h
@@ -0,0 +1,75 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public 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 FULLPIPE_FLOATERS_H
+#define FULLPIPE_FLOATERS_H
+
+namespace Fullpipe {
+
+class StaticANIObject;
+class Scene;
+class ReactPolygonal;
+
+struct FloaterArray1 {
+ int val1;
+ int val2;
+
+ FloaterArray1() { val1 = 0; val2 = 0; }
+};
+
+struct FloaterArray2 {
+ StaticANIObject *ani;
+ int val2;
+ int val3;
+ int val4;
+ int val5;
+ int val6;
+ int val7;
+ int val8;
+ double val9;
+ double val11;
+ int val13;
+ int countdown;
+ int val15;
+ int fflags;
+
+ FloaterArray2() : ani(0), val2(0), val3(0), val4(0), val5(0), val6(0), val7(0), val8(0),
+ val9(0.0), val11(0.0), val13(0), countdown(0), val15(0), fflags(0) {}
+};
+
+class Floaters {
+public:
+ ReactPolygonal *_hRgn;
+ Common::Array<FloaterArray1 *> _array1;
+ Common::Array<FloaterArray2 *> _array2;
+
+ Floaters() { _hRgn = 0; }
+ ~Floaters();
+ void init(GameVar *var);
+ void genFlies(Scene *sc, int x, int y, int priority, int flags);
+ void update();
+ void stopAll();
+};
+
+} // End of namespace Fullpipe
+
+#endif /* FULLPIPE_FLOATERS_H */
diff --git a/engines/fullpipe/fullpipe.cpp b/engines/fullpipe/fullpipe.cpp
index 5e1af1227c..b1e366c3a1 100644
--- a/engines/fullpipe/fullpipe.cpp
+++ b/engines/fullpipe/fullpipe.cpp
@@ -33,11 +33,14 @@
#include "fullpipe/behavior.h"
#include "fullpipe/modal.h"
#include "fullpipe/input.h"
+#include "fullpipe/motion.h"
#include "fullpipe/scenes.h"
+#include "fullpipe/floaters.h"
+#include "fullpipe/console.h"
namespace Fullpipe {
-FullpipeEngine *g_fullpipe = 0;
+FullpipeEngine *g_fp = 0;
Vars *g_vars = 0;
FullpipeEngine::FullpipeEngine(OSystem *syst, const ADGameDescription *gameDesc) : Engine(syst), _gameDescription(gameDesc) {
@@ -50,6 +53,7 @@ FullpipeEngine::FullpipeEngine(OSystem *syst, const ADGameDescription *gameDesc)
_mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, ConfMan.getInt("music_volume"));
_rnd = new Common::RandomSource("fullpipe");
+ _console = 0;
_gameProjectVersion = 0;
_pictureScale = 8;
@@ -78,9 +82,16 @@ FullpipeEngine::FullpipeEngine(OSystem *syst, const ADGameDescription *gameDesc)
_modalObject = 0;
+ _liftEnterMQ = 0;
+ _liftExitMQ = 0;
+ _lift = 0;
+ _lastLiftButton = 0;
+ _liftX = 0;
+ _liftY = 0;
+
_gameContinue = true;
_needRestart = false;
- _flgPlayIntro = false;
+ _flgPlayIntro = true;
_gamePaused = false;
_inputArFlag = false;
_recordEvents = false;
@@ -90,12 +101,17 @@ FullpipeEngine::FullpipeEngine(OSystem *syst, const ADGameDescription *gameDesc)
_isProcessingMessages = false;
_musicAllowed = -1;
+ _musicGameVar = 0;
_aniMan = 0;
_aniMan2 = 0;
_currentScene = 0;
+ _loaderScene = 0;
_scene2 = 0;
+ _scene3 = 0;
_movTable = 0;
+ _floaters = 0;
+ _mgm = 0;
_globalMessageQueueList = 0;
_messageHandlers = 0;
@@ -142,14 +158,22 @@ FullpipeEngine::FullpipeEngine(OSystem *syst, const ADGameDescription *gameDesc)
_objectAtCursor = 0;
_objectIdAtCursor = 0;
+ _arcadeOverlay = 0;
+ _arcadeOverlayHelper = 0;
+ _arcadeOverlayX = 0;
+ _arcadeOverlayY = 0;
+ _arcadeOverlayMidX = 0;
+ _arcadeOverlayMidY = 0;
+
_isSaveAllowed = true;
- g_fullpipe = this;
+ g_fp = this;
g_vars = new Vars;
}
FullpipeEngine::~FullpipeEngine() {
delete _rnd;
+ delete _console;
delete _globalMessageQueueList;
}
@@ -161,6 +185,9 @@ void FullpipeEngine::initialize() {
_sceneRect.top = 0;
_sceneRect.right = 799;
_sceneRect.bottom = 599;
+
+ _floaters = new Floaters;
+ _mgm = new MGM;
}
Common::Error FullpipeEngine::run() {
@@ -170,13 +197,15 @@ Common::Error FullpipeEngine::run() {
_backgroundSurface.create(800, 600, format);
+ _console = new Console(this);
+
initialize();
_isSaveAllowed = false;
int scene = 0;
if (ConfMan.hasKey("boot_param"))
- scene = ConfMan.getInt("boot_param");
+ scene = convertScene(ConfMan.getInt("boot_param"));
if (!loadGam("fullpipe.gam", scene))
return Common::kNoGameDataFoundError;
@@ -268,6 +297,11 @@ void FullpipeEngine::updateEvents() {
return;
break;
default:
+ if (event.kbd.keycode == Common::KEYCODE_d && event.kbd.hasFlags(Common::KBD_CTRL)) {
+ // Start the debugger
+ getDebugger()->attach();
+ getDebugger()->onFrame();
+ }
ex = new ExCommand(0, 17, 36, 0, 0, 0, 1, 0, 0, 0);
ex->_keyCode = event.kbd.keycode;
ex->_excFlags |= 3;
@@ -424,21 +458,6 @@ void FullpipeEngine::setObjectState(const char *name, int state) {
var->setSubVarAsInt(name, state);
}
-void FullpipeEngine::updateMapPiece(int mapId, int update) {
- for (int i = 0; i < 200; i++) {
- int hiWord = (_mapTable[i] >> 16) & 0xffff;
-
- if (hiWord == mapId) {
- _mapTable[i] |= update;
- return;
- }
- if (!hiWord) {
- _mapTable[i] = (mapId << 16) | update;
- return;
- }
- }
-}
-
void FullpipeEngine::disableSaves(ExCommand *ex) {
warning("STUB: FullpipeEngine::disableSaves()");
}
diff --git a/engines/fullpipe/fullpipe.h b/engines/fullpipe/fullpipe.h
index 6872dd8356..1e583279f5 100644
--- a/engines/fullpipe/fullpipe.h
+++ b/engines/fullpipe/fullpipe.h
@@ -36,6 +36,9 @@
#include "engines/engine.h"
+#include "gui/debugger.h"
+#include "fullpipe/console.h"
+
struct ADGameDescription;
namespace Fullpipe {
@@ -52,12 +55,17 @@ class Inventory2;
struct CursorInfo;
struct EntranceInfo;
class ExCommand;
+class Floaters;
class GameProject;
class GameObject;
class GlobalMessageQueueList;
struct MessageHandler;
+class MessageQueue;
struct MovTable;
+class MGM;
class NGIArchive;
+class PictureObject;
+struct PreloadItem;
class Scene;
class SoundList;
class StaticANIObject;
@@ -79,6 +87,9 @@ public:
FullpipeEngine(OSystem *syst, const ADGameDescription *gameDesc);
virtual ~FullpipeEngine();
+ Console *_console;
+ GUI::Debugger *getDebugger() { return _console; }
+
void initialize();
void setMusicAllowed(int val) { _musicAllowed = val; }
@@ -119,7 +130,9 @@ public:
int _sceneWidth;
int _sceneHeight;
Scene *_currentScene;
+ Scene *_loaderScene;
Scene *_scene2;
+ Scene *_scene3;
StaticANIObject *_aniMan;
StaticANIObject *_aniMan2;
byte *_globalPalette;
@@ -140,7 +153,12 @@ public:
void stopAllSounds();
void toggleMute();
void playSound(int id, int flag);
+ void playTrack(GameVar *sceneVar, const char *name, bool delayed);
void startSceneTrack();
+ void stopSoundStream2();
+ void stopAllSoundStreams();
+ void stopAllSoundInstances(int id);
+ void updateSoundVolume();
int _sfxVolume;
@@ -163,7 +181,13 @@ public:
MovTable *_movTable;
+ Floaters *_floaters;
+ MGM *_mgm;
+
+ Common::Array<Common::Point *> _arcadeKeys;
+
void initMap();
+ void updateMap(PreloadItem *pre);
void updateMapPiece(int mapId, int update);
void updateScreen();
@@ -202,6 +226,8 @@ public:
int (*_updateScreenCallback)();
int (*_updateCursorCallback)();
+ void drawAlphaRectangle(int x1, int y1, int x2, int y2, int alpha);
+
int _cursorId;
int _minCursorId;
int _maxCursorId;
@@ -210,7 +236,7 @@ public:
int _objectIdAtCursor;
void setCursor(int id);
- void updateCursorsCommon();
+ void updateCursorCommon();
int getObjectState(const char *objname);
void setObjectState(const char *name, int state);
@@ -219,6 +245,9 @@ public:
bool sceneSwitcher(EntranceInfo *entrance);
Scene *accessScene(int sceneId);
void setSceneMusicParameters(GameVar *var);
+ int convertScene(int scene);
+ int getSceneEntrance(int scene);
+ int getSceneFromTag(int tag);
NGIArchive *_currArchive;
@@ -226,11 +255,46 @@ public:
void openHelp();
void openMainMenu();
+ PictureObject *_arcadeOverlay;
+ PictureObject *_arcadeOverlayHelper;
+ int _arcadeOverlayX;
+ int _arcadeOverlayY;
+ int _arcadeOverlayMidX;
+ int _arcadeOverlayMidY;
+
+ void initArcadeKeys(const char *varname);
+ void processArcade(ExCommand *ex);
void winArcade();
+ void setArcadeOverlay(int picId);
+ int drawArcadeOverlay(int adjust);
+
void getAllInventory();
- int lift_getButtonIdP(int objid);
+ StaticANIObject *_lastLiftButton;
+ MessageQueue *_liftEnterMQ;
+ MessageQueue *_liftExitMQ;
+ StaticANIObject *_lift;
+ int _liftX;
+ int _liftY;
+ int lift_getButtonIdP(int objid);
+ int lift_getButtonIdH(int objid);
+ int lift_getButtonIdN(int objid);
+ void lift_setButton(const char *name, int state);
+ void lift_init(Scene *sc, int qu1, int qu2);
+ void lift_setButtonStatics(Scene *sc, int buttonId);
+ void lift_exitSeq(ExCommand *ex);
+ void lift_closedoorSeq();
+ void lift_clickButton();
+ void lift_walkAndGo();
+ void lift_goAnimation();
+ void lift_sub1(StaticANIObject *ani);
+ void lift_startExitQueue();
+ void lift_sub05(ExCommand *ex);
+ bool lift_checkButton(const char *varname);
+
+ GameVar *_musicGameVar;
+ Audio::SoundHandle _sceneTrackHandle;
public:
bool _isSaveAllowed;
@@ -240,7 +304,7 @@ public:
};
-extern FullpipeEngine *g_fullpipe;
+extern FullpipeEngine *g_fp;
extern Vars *g_vars;
} // End of namespace Fullpipe
diff --git a/engines/fullpipe/gameloader.cpp b/engines/fullpipe/gameloader.cpp
index f8ede5cff2..845655dded 100644
--- a/engines/fullpipe/gameloader.cpp
+++ b/engines/fullpipe/gameloader.cpp
@@ -28,23 +28,26 @@
#include "fullpipe/statics.h"
#include "fullpipe/interaction.h"
#include "fullpipe/motion.h"
+#include "fullpipe/constants.h"
+#include "fullpipe/scenes.h"
+#include "fullpipe/floaters.h"
namespace Fullpipe {
Inventory2 *getGameLoaderInventory() {
- return &g_fullpipe->_gameLoader->_inventory;
+ return &g_fp->_gameLoader->_inventory;
}
MctlCompound *getSc2MctlCompoundBySceneId(int16 sceneId) {
- for (uint i = 0; i < g_fullpipe->_gameLoader->_sc2array.size(); i++)
- if (g_fullpipe->_gameLoader->_sc2array[i]._sceneId == sceneId)
- return (MctlCompound *)g_fullpipe->_gameLoader->_sc2array[i]._motionController;
+ for (uint i = 0; i < g_fp->_gameLoader->_sc2array.size(); i++)
+ if (g_fp->_gameLoader->_sc2array[i]._sceneId == sceneId)
+ return (MctlCompound *)g_fp->_gameLoader->_sc2array[i]._motionController;
return 0;
}
InteractionController *getGameLoaderInteractionController() {
- return g_fullpipe->_gameLoader->_interactionController;
+ return g_fp->_gameLoader->_interactionController;
}
GameLoader::GameLoader() {
@@ -68,10 +71,10 @@ GameLoader::GameLoader() {
_preloadEntranceId = 0;
_updateCounter = 0;
- g_fullpipe->_msgX = 0;
- g_fullpipe->_msgY = 0;
- g_fullpipe->_msgObjectId2 = 0;
- g_fullpipe->_msgId = 0;
+ g_fp->_msgX = 0;
+ g_fp->_msgY = 0;
+ g_fp->_msgObjectId2 = 0;
+ g_fp->_msgId = 0;
}
GameLoader::~GameLoader() {
@@ -79,6 +82,8 @@ GameLoader::~GameLoader() {
delete _gameProject;
delete _interactionController;
delete _inputController;
+
+ warning("STUB: GameLoader::~GameLoader()");
}
bool GameLoader::load(MfcArchive &file) {
@@ -91,10 +96,10 @@ bool GameLoader::load(MfcArchive &file) {
_gameProject->load(file);
- g_fullpipe->_gameProject = _gameProject;
+ g_fp->_gameProject = _gameProject;
- if (g_fullpipe->_gameProjectVersion < 12) {
- error("Old gameProjectVersion: %d", g_fullpipe->_gameProjectVersion);
+ if (g_fp->_gameProjectVersion < 12) {
+ error("Old gameProjectVersion: %d", g_fp->_gameProjectVersion);
}
_gameName = file.readPascalString();
@@ -167,7 +172,7 @@ bool GameLoader::gotoScene(int sceneId, int entranceId) {
return false;
if (_sc2array[sc2idx]._entranceDataCount < 1) {
- g_fullpipe->_currentScene = st->_scene;
+ g_fp->_currentScene = st->_scene;
return true;
}
@@ -186,20 +191,20 @@ bool GameLoader::gotoScene(int sceneId, int entranceId) {
if (sg || (sg = _gameVar->getSubVarByName("OBJSTATES")->addSubVarAsInt("SAVEGAME", 0)) != 0)
sg->setSubVarAsInt("Entrance", entranceId);
- if (!g_fullpipe->sceneSwitcher(_sc2array[sc2idx]._entranceData[entranceIdx]))
+ if (!g_fp->sceneSwitcher(_sc2array[sc2idx]._entranceData[entranceIdx]))
return false;
- g_fullpipe->_msgObjectId2 = 0;
- g_fullpipe->_msgY = -1;
- g_fullpipe->_msgX = -1;
+ g_fp->_msgObjectId2 = 0;
+ g_fp->_msgY = -1;
+ g_fp->_msgX = -1;
- g_fullpipe->_currentScene = st->_scene;
+ g_fp->_currentScene = st->_scene;
- MessageQueue *mq1 = g_fullpipe->_currentScene->getMessageQueueById(_sc2array[sc2idx]._entranceData[entranceIdx]->_messageQueueId);
+ MessageQueue *mq1 = g_fp->_currentScene->getMessageQueueById(_sc2array[sc2idx]._entranceData[entranceIdx]->_messageQueueId);
if (mq1) {
MessageQueue *mq = new MessageQueue(mq1, 0, 0);
- StaticANIObject *stobj = g_fullpipe->_currentScene->getStaticANIObject1ById(_field_FA, -1);
+ StaticANIObject *stobj = g_fp->_currentScene->getStaticANIObject1ById(_field_FA, -1);
if (stobj) {
stobj->_flags &= 0x100;
@@ -209,7 +214,7 @@ bool GameLoader::gotoScene(int sceneId, int entranceId) {
ex->_messageNum = 0;
ex->_excFlags |= 3;
- mq->_exCommands.push_back(ex);
+ mq->addExCommandToEnd(ex);
}
mq->setFlags(mq->getFlags() | 1);
@@ -220,7 +225,7 @@ bool GameLoader::gotoScene(int sceneId, int entranceId) {
return false;
}
} else {
- StaticANIObject *stobj = g_fullpipe->_currentScene->getStaticANIObject1ById(_field_FA, -1);
+ StaticANIObject *stobj = g_fp->_currentScene->getStaticANIObject1ById(_field_FA, -1);
if (stobj)
stobj->_flags &= 0xfeff;
}
@@ -228,8 +233,100 @@ bool GameLoader::gotoScene(int sceneId, int entranceId) {
return true;
}
-bool preloadCallback(const PreloadItem &pre, int flag) {
- warning("STUB: preloadCallback");
+bool preloadCallback(PreloadItem &pre, int flag) {
+ if (flag) {
+ if (flag == 50)
+ g_fp->_aniMan->preloadMovements(g_fp->_movTable);
+
+ StaticANIObject *pbar = g_fp->_loaderScene->getStaticANIObject1ById(ANI_PBAR, -1);
+
+ if (pbar) {
+ int sz;
+
+ if (pbar->_movement->_currMovement)
+ sz = pbar->_movement->_currMovement->_dynamicPhases.size();
+ else
+ sz = pbar->_movement->_dynamicPhases.size();
+
+ pbar->_movement->setDynamicPhaseIndex(flag * (sz - 1) / 100);
+ }
+
+ g_fp->updateMap(&pre);
+
+ g_fp->_currentScene = g_fp->_loaderScene;
+
+ g_fp->_loaderScene->draw();
+
+ g_fp->_system->updateScreen();
+ } else {
+ if (g_fp->_scene2) {
+ g_fp->_aniMan = g_fp->_scene2->getAniMan();
+ g_fp->_scene2 = 0;
+ setInputDisabled(1);
+ }
+
+ g_fp->_floaters->stopAll();
+
+ if (g_fp->_soundEnabled) {
+ g_fp->_currSoundListCount = 1;
+ g_fp->_currSoundList1[0] = g_fp->accessScene(SC_COMMON)->_soundList;
+ }
+
+ g_vars->scene18_var01 = 0;
+
+ if ((pre.preloadId1 != SC_18 || pre.sceneId != SC_19) && (pre.preloadId1 != SC_19 || (pre.sceneId != SC_18 && pre.sceneId != SC_19))) {
+ if (g_fp->_scene3) {
+ if (pre.preloadId1 != SC_18)
+ g_fp->_gameLoader->unloadScene(SC_18);
+
+ g_fp->_scene3 = 0;
+ }
+ } else {
+ scene19_preload(g_fp->accessScene(pre.preloadId1), pre.keyCode);
+
+ g_vars->scene18_var01 = 1;
+
+ if (pre.preloadId1 == SC_18) {
+ g_fp->_gameLoader->saveScenePicAniInfos(SC_18);
+
+ scene18_preload();
+ }
+ }
+
+ if (((pre.sceneId == SC_19 && pre.keyCode == TrubaRight) || (pre.sceneId == SC_18 && pre.keyCode == TrubaRight)) && !pre.preloadId2) {
+ pre.sceneId = SC_18;
+ pre.keyCode = TrubaLeft;
+ }
+
+ if (!g_fp->_loaderScene) {
+ g_fp->_gameLoader->loadScene(SC_LDR);
+ g_fp->_loaderScene = g_fp->accessScene(SC_LDR);;
+ }
+
+ StaticANIObject *pbar = g_fp->_loaderScene->getStaticANIObject1ById(ANI_PBAR, -1);
+
+ if (pbar) {
+ pbar->show1(ST_EGTR_SLIMSORROW, ST_MAN_GOU, MV_PBAR_RUN, 0);
+ pbar->startAnim(MV_PBAR_RUN, 0, -1);
+ }
+
+ g_fp->_inventoryScene = 0;
+ g_fp->_updateCursorCallback = 0;
+
+ g_fp->_sceneRect.translate(-g_fp->_sceneRect.left, -g_fp->_sceneRect.top);
+
+ g_fp->_system->delayMillis(10);
+
+ Scene *oldsc = g_fp->_currentScene;
+
+ g_fp->_currentScene = g_fp->_loaderScene;
+
+ g_fp->_loaderScene->draw();
+
+ g_fp->_system->updateScreen();
+
+ g_fp->_currentScene = oldsc;
+ }
return true;
}
@@ -262,8 +359,8 @@ bool GameLoader::preloadScene(int sceneId, int entranceId) {
return false;
}
- if (g_fullpipe->_currentScene && g_fullpipe->_currentScene->_sceneId == sceneId)
- g_fullpipe->_currentScene = 0;
+ if (g_fp->_currentScene && g_fp->_currentScene->_sceneId == sceneId)
+ g_fp->_currentScene = 0;
saveScenePicAniInfos(sceneId);
clearGlobalMessageQueueList1();
@@ -358,7 +455,7 @@ void GameLoader::applyPicAniInfos(Scene *sc, PicAniInfo **picAniInfo, int picAni
if (!(picAniInfo[i]->type & 1))
continue;
- Scene *scNew = g_fullpipe->accessScene(picAniInfo[i]->sceneId);
+ Scene *scNew = g_fp->accessScene(picAniInfo[i]->sceneId);
if (!scNew)
continue;
@@ -386,8 +483,8 @@ void GameLoader::saveScenePicAniInfos(int sceneId) {
}
void GameLoader::updateSystems(int counterdiff) {
- if (g_fullpipe->_currentScene) {
- g_fullpipe->_currentScene->update(counterdiff);
+ if (g_fp->_currentScene) {
+ g_fp->_currentScene->update(counterdiff);
_exCommand._messageKind = 17;
_updateCounter++;
@@ -481,7 +578,7 @@ bool PreloadItems::load(MfcArchive &file) {
int count = file.readCount();
- resize(count);
+ clear();
for (int i = 0; i < count; i++) {
PreloadItem *t = new PreloadItem();
@@ -510,4 +607,8 @@ InputController *FullpipeEngine::getGameLoaderInputController() {
return 0;
}
+MctlCompound *getCurrSceneSc2MotionController() {
+ return getSc2MctlCompoundBySceneId(g_fp->_currentScene->_sceneId);
+}
+
} // End of namespace Fullpipe
diff --git a/engines/fullpipe/gameloader.h b/engines/fullpipe/gameloader.h
index 4f5462671d..85bd6ab0fb 100644
--- a/engines/fullpipe/gameloader.h
+++ b/engines/fullpipe/gameloader.h
@@ -65,7 +65,7 @@ struct PreloadItem {
int keyCode;
};
-bool preloadCallback(const PreloadItem &pre, int flag);
+bool preloadCallback(PreloadItem &pre, int flag);
class PreloadItems : public Common::Array<PreloadItem *>, public CObject {
public:
@@ -95,7 +95,7 @@ class GameLoader : public CObject {
Inventory2 _inventory;
Sc2Array _sc2array;
void *_sceneSwitcher;
- bool (*_preloadCallback)(const PreloadItem &pre, int flag);
+ bool (*_preloadCallback)(PreloadItem &pre, int flag);
void *_readSavegameCallback;
int16 _field_F8;
int16 _field_FA;
@@ -111,6 +111,7 @@ class GameLoader : public CObject {
Inventory2 *getGameLoaderInventory();
InteractionController *getGameLoaderInteractionController();
MctlCompound *getSc2MctlCompoundBySceneId(int16 sceneId);
+MctlCompound *getCurrSceneSc2MotionController();
} // End of namespace Fullpipe
diff --git a/engines/fullpipe/gfx.cpp b/engines/fullpipe/gfx.cpp
index 2e89bd6003..2d68600dbb 100644
--- a/engines/fullpipe/gfx.cpp
+++ b/engines/fullpipe/gfx.cpp
@@ -58,6 +58,8 @@ Bitmap::Bitmap(Bitmap *src) {
Bitmap::~Bitmap() {
if (_pixels)
free(_pixels);
+
+ _pixels = 0;
}
void Bitmap::load(Common::ReadStream *s) {
@@ -87,6 +89,10 @@ Background::Background() {
_palette = 0;
}
+Background::~Background() {
+ warning("STUB: Background::~Background()");
+}
+
bool Background::load(MfcArchive &file) {
debug(5, "Background::load()");
_bgname = file.readPascalString();
@@ -100,11 +106,11 @@ bool Background::load(MfcArchive &file) {
addPictureObject(pct);
}
- assert(g_fullpipe->_gameProjectVersion >= 4);
+ assert(g_fp->_gameProjectVersion >= 4);
_bigPictureArray1Count = file.readUint32LE();
- assert(g_fullpipe->_gameProjectVersion >= 5);
+ assert(g_fp->_gameProjectVersion >= 5);
_bigPictureArray2Count = file.readUint32LE();
@@ -129,8 +135,8 @@ void Background::addPictureObject(PictureObject *pct) {
pct->renumPictures(&_picObjList);
bool inserted = false;
- for (uint i = 0; i < _picObjList.size(); i++) {
- if (((PictureObject *)_picObjList[i])->_priority == pct->_priority) {
+ for (uint i = 1; i < _picObjList.size(); i++) {
+ if (((PictureObject *)_picObjList[i])->_priority <= pct->_priority) {
_picObjList.insert_at(i, pct);
inserted = true;
break;
@@ -152,6 +158,10 @@ PictureObject::PictureObject() {
_objtype = kObjTypePictureObject;
}
+PictureObject::~PictureObject() {
+ warning("STUB: PictureObject::~PictureObject()");
+}
+
PictureObject::PictureObject(PictureObject *src) : GameObject(src) {
_picture = src->_picture;
_ox2 = _ox;
@@ -222,7 +232,7 @@ void PictureObject::drawAt(int x, int y) {
bool PictureObject::setPicAniInfo(PicAniInfo *picAniInfo) {
if (!(picAniInfo->type & 2) || (picAniInfo->type & 1)) {
- error("Picture::setPicAniInfo(): Wrong type: %d", picAniInfo->type);
+ error("PictureObject::setPicAniInfo(): Wrong type: %d", picAniInfo->type);
return false;
}
@@ -269,6 +279,11 @@ bool PictureObject::isPixelHitAtPos(int x, int y) {
return res;
}
+void PictureObject::setOXY2() {
+ _ox2 = _ox;
+ _oy2 = _oy;
+}
+
GameObject::GameObject() {
_okeyCode = 0;
_flags = 0;
@@ -313,7 +328,7 @@ bool GameObject::load(MfcArchive &file) {
_oy = file.readUint32LE();
_priority = file.readUint16LE();
- if (g_fullpipe->_gameProjectVersion >= 11) {
+ if (g_fp->_gameProjectVersion >= 11) {
_field_8 = file.readUint32LE();
}
@@ -329,8 +344,8 @@ void GameObject::renumPictures(PtrList *lst) {
int *buf = (int *)calloc(lst->size() + 2, sizeof(int));
for (uint i = 0; i < lst->size(); i++) {
- if (_id == ((PictureObject *)((*lst)[i]))->_id)
- buf[((PictureObject *)((*lst)[i]))->_okeyCode] = 1;
+ if (_id == ((GameObject *)((*lst)[i]))->_id)
+ buf[((GameObject *)((*lst)[i]))->_okeyCode] = 1;
}
if (buf[_okeyCode]) {
@@ -464,10 +479,12 @@ Picture::~Picture() {
}
void Picture::freePicture() {
+ debug(5, "Picture::freePicture(): file: %s", _memfilename);
+
if (_bitmap) {
if (testFlags() && !_field_54) {
freeData();
- delete _bitmap;
+ free(_bitmap);
_bitmap = 0;
}
}
@@ -484,6 +501,11 @@ void Picture::freePicture() {
}
}
+void Picture::freePixelData() {
+ freePicture();
+ freeData();
+}
+
bool Picture::load(MfcArchive &file) {
debug(5, "Picture::load()");
MemoryObject::load(file);
@@ -492,7 +514,7 @@ bool Picture::load(MfcArchive &file) {
_y = file.readUint32LE();
_field_44 = file.readUint16LE();
- assert(g_fullpipe->_gameProjectVersion >= 2);
+ assert(g_fp->_gameProjectVersion >= 2);
_width = file.readUint32LE();
_height = file.readUint32LE();
@@ -506,7 +528,7 @@ bool Picture::load(MfcArchive &file) {
setAOIDs();
}
- assert (g_fullpipe->_gameProjectVersion >= 12);
+ assert (g_fp->_gameProjectVersion >= 12);
_alpha = file.readUint32LE() & 0xff;
@@ -519,14 +541,14 @@ bool Picture::load(MfcArchive &file) {
getData();
- debug(5, "Picture::load: <%s>", _memfilename);
+ debug(5, "Picture::load: loaded <%s>", _memfilename);
return true;
}
void Picture::setAOIDs() {
- int w = (g_fullpipe->_pictureScale + _width - 1) / g_fullpipe->_pictureScale;
- int h = (g_fullpipe->_pictureScale + _height - 1) / g_fullpipe->_pictureScale;
+ int w = (g_fp->_pictureScale + _width - 1) / g_fp->_pictureScale;
+ int h = (g_fp->_pictureScale + _height - 1) / g_fp->_pictureScale;
_memoryObject2->_rows = (byte **)malloc(w * sizeof(int *));
@@ -539,6 +561,10 @@ void Picture::setAOIDs() {
}
void Picture::init() {
+ debug(5, "Picture::init(), %s", _memfilename);
+
+ MemoryObject::getData();
+
_bitmap = new Bitmap();
getDibInfo();
@@ -567,6 +593,12 @@ void Picture::getDibInfo() {
warning("Uneven data size: 0x%x", _dataSize);
}
+ if (!_data) {
+ warning("Picture::getDibInfo: data is empty <%s>", _memfilename);
+
+ MemoryObject::load();
+ }
+
Common::MemoryReadStream *s = new Common::MemoryReadStream(_data + off - 32, 32);
_bitmap->load(s);
@@ -584,7 +616,7 @@ void Picture::draw(int x, int y, int style, int angle) {
int x1 = x;
int y1 = y;
- debug(0, "Picture::draw(%d, %d, %d, %d) (%s)", x, y, style, angle, _memfilename);
+ debug(7, "Picture::draw(%d, %d, %d, %d) (%s)", x, y, style, angle, _memfilename);
if (x != -1)
x1 = x;
@@ -599,14 +631,14 @@ void Picture::draw(int x, int y, int style, int angle) {
return;
if ((_alpha & 0xff) < 0xff) {
- debug(0, "Picture:draw: alpha = %0x", _alpha);
+ debug(7, "Picture:draw: alpha = %0x", _alpha);
}
byte *pal = _paletteData;
if (!pal) {
//warning("Picture:draw: using global palette");
- pal = g_fullpipe->_globalPalette;
+ pal = g_fp->_globalPalette;
}
Common::Point point;
@@ -638,7 +670,7 @@ void Picture::drawRotated(int x, int y, int angle) {
}
void Picture::displayPicture() {
- if (!g_fullpipe->_gameContinue)
+ if (!g_fp->_gameContinue)
return;
getData();
@@ -647,22 +679,22 @@ void Picture::displayPicture() {
if (!_dataSize)
return;
- g_fullpipe->_backgroundSurface.fillRect(Common::Rect(0, 0, 799, 599), 0);
- g_fullpipe->_system->copyRectToScreen(g_fullpipe->_backgroundSurface.getBasePtr(0, 0), g_fullpipe->_backgroundSurface.pitch, 0, 0, 799, 599);
+ g_fp->_backgroundSurface.fillRect(Common::Rect(0, 0, 800, 600), 0);
+ g_fp->_system->copyRectToScreen(g_fp->_backgroundSurface.getBasePtr(0, 0), g_fp->_backgroundSurface.pitch, 0, 0, 800, 600);
draw(0, 0, 0, 0);
- g_fullpipe->updateEvents();
- g_fullpipe->_system->delayMillis(10);
- g_fullpipe->_system->updateScreen();
+ g_fp->updateEvents();
+ g_fp->_system->delayMillis(10);
+ g_fp->_system->updateScreen();
- while (g_fullpipe->_gameContinue) {
- g_fullpipe->updateEvents();
- g_fullpipe->_system->delayMillis(10);
- g_fullpipe->_system->updateScreen();
+ while (g_fp->_gameContinue) {
+ g_fp->updateEvents();
+ g_fp->_system->delayMillis(10);
+ g_fp->_system->updateScreen();
- if (g_fullpipe->_keyState == ' ') {
- g_fullpipe->_keyState = Common::KEYCODE_INVALID;
+ if (g_fp->_keyState == ' ') {
+ g_fp->_keyState = Common::KEYCODE_INVALID;
break;
}
}
@@ -710,7 +742,7 @@ bool Picture::isPixelHitAtPos(int x, int y) {
}
int Picture::getPixelAtPos(int x, int y) {
- return getPixelAtPosEx(x / g_fullpipe->_pictureScale, y / g_fullpipe->_pictureScale);
+ return getPixelAtPosEx(x / g_fp->_pictureScale, y / g_fp->_pictureScale);
return false;
}
@@ -719,8 +751,8 @@ int Picture::getPixelAtPosEx(int x, int y) {
if (x < 0 || y < 0)
return 0;
- if (x < (g_fullpipe->_pictureScale + _width - 1) / g_fullpipe->_pictureScale &&
- y < (g_fullpipe->_pictureScale + _height - 1) / g_fullpipe->_pictureScale &&
+ if (x < (g_fp->_pictureScale + _width - 1) / g_fp->_pictureScale &&
+ y < (g_fp->_pictureScale + _height - 1) / g_fp->_pictureScale &&
_memoryObject2 != 0 && _memoryObject2->_rows != 0)
return _memoryObject2->_rows[x][2 * y];
@@ -771,10 +803,10 @@ bool Bitmap::isPixelAtHitPosRB(int x, int y) {
}
void Bitmap::putDib(int x, int y, int32 *palette) {
- debug(0, "Bitmap::putDib(%d, %d)", x, y);
+ debug(7, "Bitmap::putDib(%d, %d)", x, y);
- _x = x - g_fullpipe->_sceneRect.left;
- _y = y - g_fullpipe->_sceneRect.top;
+ _x = x - g_fp->_sceneRect.left;
+ _y = y - g_fp->_sceneRect.top;
if (_type == MKTAG('R', 'B', '\0', '\0'))
putDibRB(palette);
@@ -795,7 +827,7 @@ bool Bitmap::putDibRB(int32 *palette, int pX, int pY) {
uint16 *srcPtr;
if (!palette && pX == -1) {
- warning("Bitmap::putDibRB(): Both global and local palettes are empty");
+ debug(2, "Bitmap::putDibRB(): Both global and local palettes are empty");
return false;
}
@@ -867,7 +899,7 @@ bool Bitmap::putDibRB(int32 *palette, int pX, int pY) {
if (y <= endy) {
if (pX == -1) {
int bgcolor = palette[(pixel >> 8) & 0xff];
- curDestPtr = (uint16 *)g_fullpipe->_backgroundSurface.getBasePtr(start1, y);
+ curDestPtr = (uint16 *)g_fp->_backgroundSurface.getBasePtr(start1, y);
colorFill(curDestPtr, fillLen, bgcolor);
} else {
if (y == pY && pX >= start1 && pX < start1 + fillLen)
@@ -898,7 +930,7 @@ bool Bitmap::putDibRB(int32 *palette, int pX, int pY) {
if (y <= endy) {
if (pX == -1) {
- curDestPtr = (uint16 *)g_fullpipe->_backgroundSurface.getBasePtr(start1, y);
+ curDestPtr = (uint16 *)g_fp->_backgroundSurface.getBasePtr(start1, y);
paletteFill(curDestPtr, (byte *)srcPtr2, fillLen, (int32 *)palette);
} else {
if (y == pY && pX >= start1 && pX < start1 + fillLen)
@@ -910,7 +942,7 @@ bool Bitmap::putDibRB(int32 *palette, int pX, int pY) {
}
if (pX == -1)
- g_fullpipe->_system->copyRectToScreen(g_fullpipe->_backgroundSurface.getBasePtr(startx, starty), g_fullpipe->_backgroundSurface.pitch, startx, starty, endx + 1 - startx, endy + 1 - starty);
+ g_fp->_system->copyRectToScreen(g_fp->_backgroundSurface.getBasePtr(startx, starty), g_fp->_backgroundSurface.pitch, startx, starty, endx + 1 - startx, endy + 1 - starty);
return false;
}
@@ -961,17 +993,17 @@ void Bitmap::putDibCB(int32 *palette) {
if (_flags & 0x1000000) {
for (int y = starty; y < endy; srcPtr -= pitch, y++) {
- curDestPtr = (uint16 *)g_fullpipe->_backgroundSurface.getBasePtr(startx, y);
+ curDestPtr = (uint16 *)g_fp->_backgroundSurface.getBasePtr(startx, y);
copierKeyColor(curDestPtr, srcPtr, endx - startx + 1, _flags & 0xff, (int32 *)palette, cb05_format);
}
} else {
for (int y = starty; y <= endy; srcPtr -= pitch, y++) {
- curDestPtr = (uint16 *)g_fullpipe->_backgroundSurface.getBasePtr(startx, y);
+ curDestPtr = (uint16 *)g_fp->_backgroundSurface.getBasePtr(startx, y);
copier(curDestPtr, srcPtr, endx - startx + 1, (int32 *)palette, cb05_format);
}
}
- g_fullpipe->_system->copyRectToScreen(g_fullpipe->_backgroundSurface.getBasePtr(startx, starty), g_fullpipe->_backgroundSurface.pitch, startx, starty, endx + 1 - startx, endy + 1 - starty);
+ g_fp->_system->copyRectToScreen(g_fp->_backgroundSurface.getBasePtr(startx, starty), g_fp->_backgroundSurface.pitch, startx, starty, endx + 1 - startx, endy + 1 - starty);
}
void Bitmap::colorFill(uint16 *dest, int len, int32 color) {
@@ -1166,6 +1198,34 @@ bool BigPicture::load(MfcArchive &file) {
return true;
}
+void BigPicture::draw(int x, int y, int style, int angle) {
+ if (!_bitmap)
+ init();
+
+ if (_bitmap) {
+ _bitmap->_flags &= 0xFEFFFFFF;
+
+ int nx = _x;
+ int ny = _y;
+
+ if (x != -1)
+ nx = x;
+
+ if (y != -1)
+ ny = y;
+
+ if (_alpha < 0xFF) {
+ //vrtSetAlphaBlendMode(g_vrtDrawHandle, 1, v9);
+ }
+
+ _bitmap->putDib(nx, ny, 0);
+
+ if (_alpha < 0xFF) {
+ //vrtSetAlphaBlendMode(g_vrtDrawHandle, 0, 255);
+ }
+ }
+}
+
Shadows::Shadows() {
_staticAniObjectId = 0;
_movementId = 0;
@@ -1182,7 +1242,7 @@ bool Shadows::load(MfcArchive &file) {
}
void Shadows::init() {
- Scene *scene = g_fullpipe->accessScene(_sceneId);
+ Scene *scene = g_fp->accessScene(_sceneId);
StaticANIObject *st;
Movement *mov;
@@ -1235,4 +1295,8 @@ DynamicPhase *Shadows::findSize(int width, int height) {
return _items[idx].dynPhase;
}
+void FullpipeEngine::drawAlphaRectangle(int x1, int y1, int x2, int y2, int alpha) {
+ warning("STUB: FullpipeEngine::drawAlphaRectangle()");
+}
+
} // End of namespace Fullpipe
diff --git a/engines/fullpipe/gfx.h b/engines/fullpipe/gfx.h
index 1f7284a6eb..d640decc80 100644
--- a/engines/fullpipe/gfx.h
+++ b/engines/fullpipe/gfx.h
@@ -88,13 +88,14 @@ class Picture : public MemoryObject {
virtual ~Picture();
void freePicture();
+ void freePixelData();
virtual bool load(MfcArchive &file);
void setAOIDs();
void init();
void getDibInfo();
Bitmap *getPixelData();
- void draw(int x, int y, int style, int angle);
+ virtual void draw(int x, int y, int style, int angle);
void drawRotated(int x, int y, int angle);
byte getAlpha() { return (byte)_alpha; }
@@ -115,7 +116,10 @@ class Picture : public MemoryObject {
class BigPicture : public Picture {
public:
BigPicture() {}
+ virtual ~BigPicture() {}
+
virtual bool load(MfcArchive &file);
+ virtual void draw(int x, int y, int style, int angle);
};
class GameObject : public CObject {
@@ -155,9 +159,13 @@ class PictureObject : public GameObject {
public:
PictureObject();
+
PictureObject(PictureObject *src);
+ virtual ~PictureObject();
+
+ virtual bool load(MfcArchive &file, bool bigPicture);
+ virtual bool load(MfcArchive &file) { assert(0); return false; } // Disable base class
- bool load(MfcArchive &file, bool bigPicture);
Common::Point *getDimensions(Common::Point *p);
void draw();
void drawAt(int x, int y);
@@ -165,6 +173,7 @@ class PictureObject : public GameObject {
bool setPicAniInfo(PicAniInfo *picAniInfo);
bool isPointInside(int x, int y);
bool isPixelHitAtPos(int x, int y);
+ void setOXY2();
};
class Background : public CObject {
@@ -182,6 +191,8 @@ class Background : public CObject {
public:
Background();
+ virtual ~Background();
+
virtual bool load(MfcArchive &file);
void addPictureObject(PictureObject *pct);
diff --git a/engines/fullpipe/init.cpp b/engines/fullpipe/init.cpp
index fb60a4cc57..8de37b5c9e 100644
--- a/engines/fullpipe/init.cpp
+++ b/engines/fullpipe/init.cpp
@@ -45,35 +45,35 @@ void FullpipeEngine::initObjectStates() {
setSwallowedEggsState();
setObjectState(sO_WeirdWacko, getObjectEnumState(sO_WeirdWacko, sO_InGlasses));
- setObjectState(sO_TumyTrampie, getObjectEnumState(sO_TumyTrampie, sO_Drinking));
+ setObjectState(sO_TummyTrampie, getObjectEnumState(sO_TummyTrampie, sO_IsDrinking));
setObjectState(sO_StairsUp_8, getObjectEnumState(sO_StairsUp_8, sO_NotBroken));
setObjectState(sO_HareTheNooksiter, getObjectEnumState(sO_HareTheNooksiter, sO_WithHandle));
setObjectState(sO_Elephantine, getObjectEnumState(sO_Elephantine, sO_WithBoot));
setObjectState(sO_Fly_12, 0);
- setObjectState(sO_ClockAxis, getObjectEnumState(sO_ClockAxis, sO_NotAvailable));
+ setObjectState(sO_ClockAxis, getObjectEnumState(sO_ClockAxis, sO_IsNotAvailable));
setObjectState(sO_ClockHandle, getObjectEnumState(sO_ClockHandle, sO_In_7));
- setObjectState(sO_BigMumsy, getObjectEnumState(sO_BigMumsy, sO_Sleeping));
+ setObjectState(sO_BigMumsy, getObjectEnumState(sO_BigMumsy, sO_IsSleeping));
setObjectState(sO_CoinSlot_1, getObjectEnumState(sO_CoinSlot_1, sO_Empty));
setObjectState(sO_FriesPit, getObjectEnumState(sO_FriesPit, sO_WithApple));
setObjectState(sO_Jug, getObjectEnumState(sO_Jug, sO_Blocked));
- setObjectState(sO_RightStairs_9, getObjectEnumState(sO_RightStairs_9, sO_ClosedShe));
+ setObjectState(sO_RightStairs_9, getObjectEnumState(sO_RightStairs_9, sO_IsClosed));
setObjectState(sO_Pipe_9, getObjectEnumState(sO_Pipe_9, sO_WithJug));
setObjectState(sO_Inflater, getObjectEnumState(sO_Inflater, sO_WithGum));
- setObjectState(sO_Swingie, getObjectEnumState(sO_Swingie, sO_Swinging));
- setObjectState(sO_DudeJumped, getObjectEnumState(sO_DudeJumped, sO_No));
+ setObjectState(sO_Swingie, getObjectEnumState(sO_Swingie, sO_IsSwinging));
+ setObjectState(sO_DudeHasJumped, getObjectEnumState(sO_DudeHasJumped, sO_No));
setObjectState(sO_Bridge, getObjectEnumState(sO_Bridge, sO_Convoluted));
setObjectState(sO_Guardian, getObjectEnumState(sO_Guardian, sO_OnRight));
setObjectState(sO_Grandma, getObjectEnumState(sO_Grandma, sO_In_14));
setObjectState(sO_Boot_15, getObjectEnumState(sO_Boot_15, sO_NotPresent));
- setObjectState(sO_LeftPipe_15, getObjectEnumState(sO_LeftPipe_15, sO_OpenedShe));
+ setObjectState(sO_LeftPipe_15, getObjectEnumState(sO_LeftPipe_15, sO_IsOpened));
setObjectState(sO_Pedestal_16, getObjectEnumState(sO_Pedestal_16, sO_IsFree));
setObjectState(sO_Cup, getObjectEnumState(sO_Cup, sO_InSmokeRoom));
setObjectState(sO_Pedestal_17, getObjectEnumState(sO_Pedestal_17, sO_IsFree));
setObjectState(sO_UsherHand, getObjectEnumState(sO_UsherHand, sO_WithoutCoin));
- setObjectState(sO_RightPipe_17, getObjectEnumState(sO_RightPipe_17, sO_ClosedShe));
+ setObjectState(sO_RightPipe_17, getObjectEnumState(sO_RightPipe_17, sO_IsClosed));
setObjectState(sO_Fly_17, 1);
setObjectState(sO_DudeSwinged, 0);
- setObjectState(sO_Girl, getObjectEnumState(sO_Girl, sO_Swinging));
+ setObjectState(sO_Girl, getObjectEnumState(sO_Girl, sO_IsSwinging));
setObjectState(sO_Sugar, getObjectEnumState(sO_Sugar, sO_Present));
setObjectState(sO_Janitors, getObjectEnumState(sO_Janitors, sO_Together));
setObjectState(sO_Bag_22, getObjectEnumState(sO_Bag_22, sO_NotFallen));
@@ -83,22 +83,22 @@ void FullpipeEngine::initObjectStates() {
setObjectState(sO_LowerHatch_23, getObjectEnumState(sO_LowerHatch_23, sO_Closed));
setObjectState(sO_Lever_23, getObjectEnumState(sO_Lever_23, sO_NotTaken));
setObjectState(sO_LeverHandle_23, getObjectEnumState(sO_LeverHandle_23, sO_WithoutStool));
- setObjectState(sO_LowerPipe_21, getObjectEnumState(sO_LowerPipe_21, sO_ClosedShe));
- setObjectState(sO_StarsDown_24, getObjectEnumState(sO_StarsDown_24, sO_OpenedShe));
+ setObjectState(sO_LowerPipe_21, getObjectEnumState(sO_LowerPipe_21, sO_IsClosed));
+ setObjectState(sO_StairsDown_24, getObjectEnumState(sO_StairsDown_24, sO_IsOpened));
setObjectState(sO_Hatch_26, getObjectEnumState(sO_Hatch_26, sO_Closed));
setObjectState(sO_Sock_26, getObjectEnumState(sO_Sock_26, sO_NotHanging));
- setObjectState(sO_LeftPipe_26, getObjectEnumState(sO_LeftPipe_26, sO_ClosedShe));
+ setObjectState(sO_LeftPipe_26, getObjectEnumState(sO_LeftPipe_26, sO_IsClosed));
setObjectState(sO_Valve1_26, getObjectEnumState(sO_Valve1_26, sO_Opened));
setObjectState(sO_Valve2_26, getObjectEnumState(sO_Valve2_26, sO_Closed));
setObjectState(sO_Valve3_26, getObjectEnumState(sO_Valve3_26, sO_Closed));
setObjectState(sO_Valve4_26, getObjectEnumState(sO_Valve4_26, sO_Closed));
setObjectState(sO_Valve5_26, getObjectEnumState(sO_Valve5_26, sO_Opened));
setObjectState(sO_Pool, getObjectEnumState(sO_Pool, sO_Overfull));
- setObjectState(sO_Plank_25, getObjectEnumState(sO_Plank_25, sO_NearDudesStairs));
+ setObjectState(sO_Board_25, getObjectEnumState(sO_Board_25, sO_NearDudesStairs));
setObjectState(sO_Driver, getObjectEnumState(sO_Driver, sO_WithSteering));
setObjectState(sO_Janitress, getObjectEnumState(sO_Janitress, sO_WithMop));
- setObjectState(sO_LeftPipe_29, getObjectEnumState(sO_LeftPipe_29, sO_ClosedShe));
- setObjectState(sO_LeftPipe_30, getObjectEnumState(sO_LeftPipe_30, sO_ClosedShe));
+ setObjectState(sO_LeftPipe_29, getObjectEnumState(sO_LeftPipe_29, sO_IsClosed));
+ setObjectState(sO_LeftPipe_30, getObjectEnumState(sO_LeftPipe_30, sO_IsClosed));
setObjectState(sO_Leg, getObjectEnumState(sO_Leg, sO_ShowingHeel));
setObjectState(sO_Tub, getObjectEnumState(sO_Tub, sO_EmptyShe));
setObjectState(sO_Cactus, getObjectEnumState(sO_Cactus, sO_NotGrown));
@@ -116,7 +116,7 @@ void FullpipeEngine::initObjectStates() {
setObjectState(sO_BellyInflater, getObjectEnumState(sO_BellyInflater, sO_WithCork));
setObjectState(sO_Jawcrucnher, getObjectEnumState(sO_Jawcrucnher, sO_WithoutCarpet));
setObjectState(sO_Guard_1, getObjectEnumState(sO_Guard_1, sO_On));
- setObjectState(sO_Gurad_2, getObjectEnumState(sO_Gurad_2, sO_On));
+ setObjectState(sO_Guard_2, getObjectEnumState(sO_Guard_2, sO_On));
setObjectState(sO_Guard_3, getObjectEnumState(sO_Guard_3, sO_On));
setObjectState(sO_Bottle_38, getObjectEnumState(sO_Bottle_38, sO_OnTheTable));
setObjectState(sO_Boss, getObjectEnumState(sO_Boss, sO_WithHammer));
diff --git a/engines/fullpipe/input.cpp b/engines/fullpipe/input.cpp
index ee826fd359..5294c4b4ea 100644
--- a/engines/fullpipe/input.cpp
+++ b/engines/fullpipe/input.cpp
@@ -34,7 +34,7 @@
namespace Fullpipe {
InputController::InputController() {
- g_fullpipe->_inputController = this;
+ g_fp->_inputController = this;
_flag = 0;
_cursorHandle = 0;
@@ -55,16 +55,16 @@ InputController::InputController() {
InputController::~InputController() {
removeMessageHandler(126, -1);
- g_fullpipe->_inputController = 0;
+ g_fp->_inputController = 0;
}
void InputController::setInputDisabled(bool state) {
_flag = state;
- g_fullpipe->_inputDisabled = state;
+ g_fp->_inputDisabled = state;
}
void setInputDisabled(bool state) {
- g_fullpipe->_inputController->setInputDisabled(state);
+ g_fp->_inputController->setInputDisabled(state);
}
void InputController::addCursor(CursorInfo *cursor) {
@@ -93,8 +93,8 @@ void InputController::drawCursor(int x, int y) {
if (_cursorIndex == -1)
return;
- _cursorBounds.left = g_fullpipe->_sceneRect.left + x - _cursorsArray[_cursorIndex]->hotspotX;
- _cursorBounds.top = g_fullpipe->_sceneRect.top + y - _cursorsArray[_cursorIndex]->hotspotY;
+ _cursorBounds.left = g_fp->_sceneRect.left + x - _cursorsArray[_cursorIndex]->hotspotX;
+ _cursorBounds.top = g_fp->_sceneRect.top + y - _cursorsArray[_cursorIndex]->hotspotY;
_cursorBounds.right = _cursorBounds.left + _cursorsArray[_cursorIndex]->width;
_cursorBounds.bottom = _cursorBounds.top + _cursorsArray[_cursorIndex]->height;
@@ -211,7 +211,7 @@ void FullpipeEngine::winArcade() {
}
-void FullpipeEngine::updateCursorsCommon() {
+void FullpipeEngine::updateCursorCommon() {
GameObject *ani = _currentScene->getStaticANIObjectAtPos(_mouseVirtX, _mouseVirtY);
GameObject *pic = _currentScene->getPictureObjectAtPos(_mouseVirtX, _mouseVirtY);
@@ -274,4 +274,70 @@ void FullpipeEngine::updateCursorsCommon() {
_cursorId = PIC_CSR_DEFAULT;
}
+void FullpipeEngine::initArcadeKeys(const char *varname) {
+ GameVar *var = getGameLoaderGameVar()->getSubVarByName(varname)->getSubVarByName("KEYPOS");
+
+ if (!var)
+ return;
+
+ int cnt = var->getSubVarsCount();
+
+ for (int i = 0; i < cnt; i++) {
+ Common::Point *point = new Common::Point;
+
+ GameVar *sub = var->getSubVarByIndex(i);
+
+ point->x = sub->getSubVarAsInt("X");
+ point->y = sub->getSubVarAsInt("Y");
+
+ _arcadeKeys.push_back(point);
+ }
+}
+
+void FullpipeEngine::setArcadeOverlay(int picId) {
+ Common::Point point;
+ Common::Point point2;
+
+ _arcadeOverlayX = 800;
+ _arcadeOverlayY = 545;
+
+ _arcadeOverlayHelper = accessScene(SC_INV)->getPictureObjectById(PIC_CSR_HELPERBGR, 0);
+ _arcadeOverlay = accessScene(SC_INV)->getPictureObjectById(picId, 0);
+
+ _arcadeOverlay->getDimensions(&point);
+ _arcadeOverlayHelper->getDimensions(&point2);
+
+ _arcadeOverlayMidX = (point2.x - point.x) / 2;
+ _arcadeOverlayMidY = abs(point2.y - point.y) / 2;
+}
+
+int FullpipeEngine::drawArcadeOverlay(int adjust) {
+ _arcadeOverlayHelper->drawAt(_sceneRect.left + _arcadeOverlayX, _sceneRect.top + _arcadeOverlayY);
+ _arcadeOverlay->drawAt(_sceneRect.left + _arcadeOverlayX + _arcadeOverlayMidX, _sceneRect.top + _arcadeOverlayY + _arcadeOverlayMidY);
+
+ if (adjust) {
+ if (_arcadeOverlayX > 745) {
+ _arcadeOverlayX -= 15;
+
+ if (_arcadeOverlayX < 745)
+ _arcadeOverlayX = 745;
+ }
+
+ return 1;
+ }
+
+ if (_arcadeOverlayX >= 800) {
+ return 0;
+ } else {
+ _arcadeOverlayX += 15;
+
+ if (_arcadeOverlayX <= 800)
+ return 1;
+
+ _arcadeOverlayX = 800;
+ }
+
+ return 1;
+}
+
} // End of namespace Fullpipe
diff --git a/engines/fullpipe/interaction.cpp b/engines/fullpipe/interaction.cpp
index 9fd42c15ae..59b01a1777 100644
--- a/engines/fullpipe/interaction.cpp
+++ b/engines/fullpipe/interaction.cpp
@@ -36,8 +36,8 @@ int handleObjectInteraction(StaticANIObject *subject, GameObject *object, int in
bool canInteractAny(GameObject *obj1, GameObject *obj2, int invId) {
int sceneId = 0;
- if (g_fullpipe->_currentScene)
- sceneId = g_fullpipe->_currentScene->_sceneId;
+ if (g_fp->_currentScene)
+ sceneId = g_fp->_currentScene->_sceneId;
InteractionController *intC = getGameLoaderInteractionController();
for (ObList::iterator i = intC->_interactions.begin(); i != intC->_interactions.end(); ++i) {
@@ -55,6 +55,10 @@ bool canInteractAny(GameObject *obj1, GameObject *obj2, int invId) {
return false;
}
+InteractionController::~InteractionController() {
+ warning("STUB: InteractionController::~InteractionController()");
+}
+
bool InteractionController::load(MfcArchive &file) {
debug(5, "InteractionController::load()");
@@ -137,7 +141,7 @@ bool InteractionController::handleInteraction(StaticANIObject *subj, GameObject
obj->setPicAniInfo(&aniInfo);
if (abs(xpos - subj->_ox) > 1 || abs(ypos - subj->_oy) > 1) {
- mq = getSc2MctlCompoundBySceneId(g_fullpipe->_currentScene->_sceneId)->method4C(subj, xpos, ypos, 1, cinter->_staticsId2);
+ mq = getSc2MctlCompoundBySceneId(g_fp->_currentScene->_sceneId)->doWalkTo(subj, xpos, ypos, 1, cinter->_staticsId2);
if (mq) {
dur = mq->calcDuration(subj);
delete mq;
@@ -186,7 +190,7 @@ bool InteractionController::handleInteraction(StaticANIObject *subj, GameObject
ex->_excFlags = 3;
ex->_field_14 = (obj->_objtype != kObjTypePictureObject);
ex->_field_20 = invId;
- mq->_exCommands.push_back(ex);
+ mq->addExCommandToEnd(ex);
if (mq->_isFinished) {
mq->_isFinished = 0;
@@ -255,7 +259,7 @@ LABEL_38:
ex->_field_14 = 0x100;
ex->_messageNum = 0;
ex->_excFlags = 3;
- mq->_exCommands.push_back(ex);
+ mq->addExCommandToEnd(ex);
}
ex = new ExCommand(obj->_id, 34, 0x100, 0, 0, 0, 1, 0, 0, 0);
@@ -263,19 +267,19 @@ LABEL_38:
ex->_field_14 = 0x100;
ex->_messageNum = 0;
ex->_excFlags = 3;
- mq->_exCommands.push_back(ex);
+ mq->addExCommandToEnd(ex);
ex = new ExCommand(subj->_id, 34, 0x100, 0, 0, 0, 1, 0, 0, 0);
ex->_keyCode = subj->_okeyCode;
ex->_field_14 = 0x100;
ex->_messageNum = 0;
ex->_excFlags = 3;
- mq->_exCommands.push_back(ex);
+ mq->addExCommandToEnd(ex);
ex = new ExCommand(subj->_id, 17, 0x40, 0, 0, 0, 1, 0, 0, 0);
ex->_excFlags |= 3;
ex->_keyCode = 0;
- mq->_exCommands.push_back(ex);
+ mq->addExCommandToEnd(ex);
if (!mq->chain(subj)) {
delete mq;
@@ -305,7 +309,7 @@ LABEL_38:
if (abs(xpos - subj->_ox) > 1 || abs(ypos - subj->_oy) > 1
|| (inter->_staticsId2 != 0 && (subj->_statics == 0 || subj->_statics->_staticsId != inter->_staticsId2))) {
- mq = getSc2MctlCompoundBySceneId(g_fullpipe->_currentScene->_sceneId)->method34(subj, xpos, ypos, 1, inter->_staticsId2);
+ mq = getSc2MctlCompoundBySceneId(g_fp->_currentScene->_sceneId)->method34(subj, xpos, ypos, 1, inter->_staticsId2);
if (!mq)
return false;
@@ -317,7 +321,7 @@ LABEL_38:
ex->_excFlags = 3;
ex->_field_20 = invId;
ex->_field_14 = (obj->_objtype != kObjTypePictureObject);
- mq->_exCommands.push_back(ex);
+ mq->addExCommandToEnd(ex);
someFlag = true;
@@ -357,14 +361,14 @@ LABEL_38:
ex->_field_14 = 0x80;
ex->_keyCode = ani->_okeyCode;
ex->_excFlags = 3;
- mq->_exCommands.push_back(ex);
+ mq->addExCommandToEnd(ex);
}
}
ex = new ExCommand(ani->_id, 34, 0x100, 0, 0, 0, 1, 0, 0, 0);
ex->_keyCode = ani->_okeyCode;
ex->_field_14 = 0x100;
ex->_excFlags = 3;
- mq->_exCommands.push_back(ex);
+ mq->addExCommandToEnd(ex);
} else {
ex = new ExCommand(subj->_id, 55, 0, 0, 0, 0, 1, 0, 0, 0);
ex->_x = ani->_id;
@@ -373,7 +377,7 @@ LABEL_38:
ex->_excFlags = 2;
ex->_field_14 = (obj->_objtype != kObjTypePictureObject);
ex->_field_20 = invId;
- mq->_exCommands.push_back(ex);
+ mq->addExCommandToEnd(ex);
if (!mq->_isFinished)
return true;
@@ -394,6 +398,17 @@ LABEL_38:
return true;
}
+Interaction *InteractionController::getInteractionByObjectIds(int obId, int obId2, int obId3) {
+ for (ObList::iterator i = _interactions.begin(); i != _interactions.end(); ++i) {
+ Interaction *intr = (Interaction *)*i;
+
+ if (intr->_objectId1 == obId && intr->_objectId2 == obId2 && intr->_objectId3 == obId3)
+ return intr;
+ }
+
+ return 0;
+}
+
Interaction::Interaction() {
_objectId1 = 0;
_objectId2 = 0;
@@ -411,6 +426,10 @@ Interaction::Interaction() {
_actionName = 0;
}
+Interaction::~Interaction() {
+ warning("STUB: Interaction::~Interaction()");
+}
+
bool Interaction::load(MfcArchive &file) {
debug(5, "Interaction::load()");
@@ -433,7 +452,7 @@ bool Interaction::load(MfcArchive &file) {
}
bool Interaction::canInteract(GameObject *obj1, GameObject *obj2, int invId) {
- if (_sceneId > 0 && g_fullpipe->_currentScene && g_fullpipe->_currentScene->_sceneId != _sceneId)
+ if (_sceneId > 0 && g_fp->_currentScene && g_fp->_currentScene->_sceneId != _sceneId)
return false;
if (_flags & 0x20000)
@@ -465,20 +484,20 @@ bool Interaction::canInteract(GameObject *obj1, GameObject *obj2, int invId) {
if (_objectState1) {
if (_flags & 0x10) {
- if ((g_fullpipe->getObjectState(obj1->getName()) & _objectState1) == 0)
+ if ((g_fp->getObjectState(obj1->getName()) & _objectState1) == 0)
return false;
} else {
- if (g_fullpipe->getObjectState(obj1->getName()) != _objectState1)
+ if (g_fp->getObjectState(obj1->getName()) != _objectState1)
return false;
}
}
if (_objectState2) {
if (_flags & 0x10) {
- if ((g_fullpipe->getObjectState(obj2->getName()) & _objectState2) == 0)
+ if ((g_fp->getObjectState(obj2->getName()) & _objectState2) == 0)
return false;
} else {
- if (g_fullpipe->getObjectState(obj2->getName()) != _objectState2)
+ if (g_fp->getObjectState(obj2->getName()) != _objectState2)
return false;
}
}
diff --git a/engines/fullpipe/interaction.h b/engines/fullpipe/interaction.h
index f968cca8ee..7d9ee0bd51 100644
--- a/engines/fullpipe/interaction.h
+++ b/engines/fullpipe/interaction.h
@@ -54,6 +54,8 @@ class Interaction : public CObject {
public:
Interaction();
+ virtual ~Interaction();
+
virtual bool load(MfcArchive &file);
bool canInteract(GameObject *obj1, GameObject *obj2, int invId);
bool isOverlapping(StaticANIObject *subj, GameObject *obj);
@@ -70,6 +72,7 @@ class InteractionController : public CObject {
public:
InteractionController() : _field_20(0), _flag24(true) {}
+ virtual ~InteractionController();
virtual bool load(MfcArchive &file);
@@ -79,6 +82,8 @@ class InteractionController : public CObject {
void sortInteractions(int sceneId);
bool handleInteraction(StaticANIObject *subj, GameObject *obj, int invId);
+
+ Interaction *getInteractionByObjectIds(int obId, int obId2, int obId3);
};
struct EntranceInfo {
diff --git a/engines/fullpipe/inventory.cpp b/engines/fullpipe/inventory.cpp
index 18ef3c4d97..f5af0611cb 100644
--- a/engines/fullpipe/inventory.cpp
+++ b/engines/fullpipe/inventory.cpp
@@ -30,6 +30,10 @@
namespace Fullpipe {
+Inventory::~Inventory() {
+ warning("STUB: Inventory::~Inventory()");
+}
+
bool Inventory::load(MfcArchive &file) {
debug(5, "Inventory::load()");
@@ -85,6 +89,10 @@ Inventory2::Inventory2() {
_topOffset = -65;
}
+Inventory2::~Inventory2() {
+ warning("STUB: Inventory2::~Inventory2()");
+}
+
bool Inventory2::loadPartial(MfcArchive &file) { // Inventory2_SerializePartially
int numInvs = file.readUint32LE();
@@ -161,7 +169,7 @@ int Inventory2::getItemFlags(int itemId) {
}
void Inventory2::rebuildItemRects() {
- _scene = g_fullpipe->accessScene(_sceneId);
+ _scene = g_fp->accessScene(_sceneId);
if (!_scene)
return;
@@ -226,11 +234,11 @@ void Inventory2::draw() {
if (!_scene)
return;
- int oldScLeft = g_fullpipe->_sceneRect.left;
- int oldScTop = g_fullpipe->_sceneRect.top;
+ int oldScLeft = g_fp->_sceneRect.left;
+ int oldScTop = g_fp->_sceneRect.top;
- g_fullpipe->_sceneRect.top = -_topOffset;
- g_fullpipe->_sceneRect.left = 0;
+ g_fp->_sceneRect.top = -_topOffset;
+ g_fp->_sceneRect.left = 0;
_picture->draw(-1, -1, 0, 0);
@@ -290,8 +298,8 @@ LABEL_25:
reset:
- g_fullpipe->_sceneRect.top = oldScTop;
- g_fullpipe->_sceneRect.left = oldScLeft;
+ g_fp->_sceneRect.top = oldScTop;
+ g_fp->_sceneRect.left = oldScLeft;
}
@@ -365,7 +373,7 @@ int Inventory2::selectItem(int itemId) {
int idx = getInventoryPoolItemIndexById(itemId);
Picture *pic = _scene->getPictureObjectById(_itemsPool[idx]->pictureObjectId1, 0)->_picture;
- g_fullpipe->getGameLoaderInputController()->setCursorItemPicture(pic);
+ g_fp->getGameLoaderInputController()->setCursorItemPicture(pic);
}
return _selectedId;
@@ -382,7 +390,7 @@ bool Inventory2::unselectItem(bool flag) {
_inventoryIcons[i]->isSelected = false;
}
- g_fullpipe->getGameLoaderInputController()->setCursorItemPicture(0);
+ g_fp->getGameLoaderInputController()->setCursorItemPicture(0);
return true;
}
diff --git a/engines/fullpipe/inventory.h b/engines/fullpipe/inventory.h
index 6d07f069bd..bc5847312b 100644
--- a/engines/fullpipe/inventory.h
+++ b/engines/fullpipe/inventory.h
@@ -49,6 +49,8 @@ class Inventory : public CObject {
public:
Inventory() { _sceneId = 0; }
+ virtual ~Inventory();
+
virtual bool load(MfcArchive &file);
int getInventoryPoolItemIndexById(int itemId);
@@ -96,6 +98,8 @@ class Inventory2 : public Inventory {
public:
Inventory2();
+ virtual ~Inventory2();
+
bool loadPartial(MfcArchive &file);
void addItem(int itemId, int count);
void addItem2(StaticANIObject *obj);
diff --git a/engines/fullpipe/lift.cpp b/engines/fullpipe/lift.cpp
index 25dd2613fe..6484aca30a 100644
--- a/engines/fullpipe/lift.cpp
+++ b/engines/fullpipe/lift.cpp
@@ -22,46 +22,299 @@
#include "fullpipe/fullpipe.h"
+#include "fullpipe/objects.h"
+#include "fullpipe/objectnames.h"
#include "fullpipe/constants.h"
+#include "fullpipe/scene.h"
+#include "fullpipe/statics.h"
+#include "fullpipe/messages.h"
+#include "fullpipe/gameloader.h"
+
namespace Fullpipe {
int FullpipeEngine::lift_getButtonIdP(int objid) {
switch (objid) {
case ST_LBN_0N:
return ST_LBN_0P;
- break;
+
case ST_LBN_1N:
return ST_LBN_1P;
- break;
+
case ST_LBN_2N:
return ST_LBN_2P;
- break;
+
case ST_LBN_3N:
return ST_LBN_3P;
- break;
+
case ST_LBN_4N:
return ST_LBN_4P;
- break;
+
case ST_LBN_5N:
return ST_LBN_5P;
- break;
+
case ST_LBN_6N:
return ST_LBN_6P;
- break;
+
case ST_LBN_7N:
return ST_LBN_7P;
- break;
+
case ST_LBN_8N:
return ST_LBN_8P;
- break;
+
case ST_LBN_9N:
return ST_LBN_9P;
- break;
+
+ default:
+ return 0;
+ }
+}
+
+int FullpipeEngine::lift_getButtonIdH(int objid) {
+ switch (objid) {
+ case ST_LBN_0P:
+ return ST_LBN_0H;
+
+ case ST_LBN_1P:
+ return ST_LBN_1H;
+
+ case ST_LBN_2P:
+ return ST_LBN_2H;
+
+ case ST_LBN_3P:
+ return ST_LBN_3H;
+
+ case ST_LBN_4P:
+ return ST_LBN_4H;
+
+ case ST_LBN_5P:
+ return ST_LBN_5H;
+
+ case ST_LBN_6P:
+ return ST_LBN_6H;
+
+ case ST_LBN_7P:
+ return ST_LBN_7H;
+
+ case ST_LBN_8P:
+ return ST_LBN_8H;
+
+ case ST_LBN_9P:
+ return ST_LBN_9H;
+
+ default:
+ return 0;
+ }
+}
+
+int FullpipeEngine::lift_getButtonIdN(int objid) {
+ switch (objid) {
+ case ST_LBN_0H:
+ case ST_LBN_0N:
+ case ST_LBN_0P:
+ return ST_LBN_0N;
+
+ case ST_LBN_1H:
+ case ST_LBN_1N:
+ case ST_LBN_1P:
+ return ST_LBN_1N;
+
+ case ST_LBN_2H:
+ case ST_LBN_2N:
+ case ST_LBN_2P:
+ return ST_LBN_2N;
+
+ case ST_LBN_3H:
+ case ST_LBN_3N:
+ case ST_LBN_3P:
+ return ST_LBN_3N;
+
+ case ST_LBN_4H:
+ case ST_LBN_4N:
+ case ST_LBN_4P:
+ return ST_LBN_4N;
+
+ case ST_LBN_5H:
+ case ST_LBN_5N:
+ case ST_LBN_5P:
+ return ST_LBN_5N;
+
+ case ST_LBN_6H:
+ case ST_LBN_6N:
+ case ST_LBN_6P:
+ return ST_LBN_6N;
+
+ case ST_LBN_7H:
+ case ST_LBN_7N:
+ case ST_LBN_7P:
+ return ST_LBN_7N;
+
+ case ST_LBN_8H:
+ case ST_LBN_8N:
+ case ST_LBN_8P:
+ return ST_LBN_8N;
+
+ case ST_LBN_9H:
+ case ST_LBN_9N:
+ case ST_LBN_9P:
+ return ST_LBN_9N;
+
default:
return 0;
- break;
}
}
+void FullpipeEngine::lift_setButton(const char *name, int state) {
+ GameVar *var = g_fp->getGameLoaderGameVar()->getSubVarByName("OBJSTATES")->getSubVarByName(sO_LiftButtons);
+
+ if (var)
+ var->setSubVarAsInt(name, state);
+}
+
+void FullpipeEngine::lift_init(Scene *sc, int enterSeq, int exitSeq) {
+ _lastLiftButton = 0;
+
+ _liftEnterMQ = sc->getMessageQueueById(enterSeq);
+ if (!_liftEnterMQ)
+ return;
+
+ _liftExitMQ = sc->getMessageQueueById(exitSeq);
+
+ if (!_liftExitMQ)
+ return;
+
+ ExCommand *ex = _liftEnterMQ->getExCommandByIndex(0);
+
+ if (!ex)
+ return;
+
+ _liftX = ex->_x;
+ _liftY = ex->_y;
+
+ _lift = sc->getStaticANIObject1ById(ANI_LIFT, -1);
+
+ for (uint i = 0; i < sc->_staticANIObjectList1.size(); i++) {
+ StaticANIObject *ani = (StaticANIObject *)sc->_staticANIObjectList1[i];
+
+ if (ani->_id == ANI_LIFTBUTTON)
+ ani->_statics = ani->getStaticsById(lift_getButtonIdP(ani->_statics->_staticsId));
+ }
+
+ GameVar *var = getGameLoaderGameVar()->getSubVarByName("OBJSTATES")->getSubVarByName(sO_LiftButtons);
+ if (var) {
+ for (var = var->_subVars; var; var = var->_nextVarObj) {
+ for (uint i = 0; i < sc->_staticANIObjectList1.size(); i++) {
+ StaticANIObject *ani = (StaticANIObject *)sc->_staticANIObjectList1[i];
+
+ if (ani->_id == ANI_LIFTBUTTON) {
+ int id = lift_getButtonIdN(ani->_statics->_staticsId);
+
+ if (id == var->_value.intValue)
+ ani->_statics = ani->getStaticsById(id);
+ }
+
+ }
+ }
+ }
+}
+
+void FullpipeEngine::lift_exitSeq(ExCommand *ex) {
+ warning("STUB: FullpipeEngine::lift_exitSeq()");
+}
+
+void FullpipeEngine::lift_closedoorSeq() {
+ warning("STUB: FullpipeEngine::lift_closedoorSeq()");
+}
+
+void FullpipeEngine::lift_walkAndGo() {
+ warning("STUB: FullpipeEngine::lift_walkAndGo()");
+}
+
+void FullpipeEngine::lift_clickButton() {
+ if (_lastLiftButton)
+ lift_walkAndGo();
+}
+
+void FullpipeEngine::lift_goAnimation() { if (_lastLiftButton) {
+ int parentId = _currentScene->_sceneId;
+ int buttonId = lift_getButtonIdN(_lastLiftButton->_statics->_staticsId);
+
+ if (!buttonId)
+ return;
+
+ int numItems = _gameLoader->_preloadItems.size();
+
+ for (int i = 0; i < numItems; i++) {
+ PreloadItem *pre = _gameLoader->_preloadItems[i];
+
+ if (pre->preloadId2 == buttonId && pre->preloadId1 == _currentScene->_sceneId) {
+ MessageQueue *mq = new MessageQueue(_globalMessageQueueList->compact());
+
+ ExCommand *ex = new ExCommand(ANI_MAN, 1, (pre->keyCode != LiftDown ? MV_MAN_LIFTDOWN : MV_MAN_LIFTUP), 0, 0, 0, 1, 0, 0, 0);
+
+ ex->_keyCode = -1;
+ ex->_field_24 = 1;
+ ex->_excFlags |= 2;
+
+ mq->addExCommandToEnd(ex);
+
+ ex = new ExCommand(parentId, 17, 61, 0, 0, 0, 1, 0, 0, 0);
+
+ ex->_keyCode = buttonId;
+ ex->_excFlags |= 3;
+
+ mq->addExCommandToEnd(ex);
+
+ _aniMan->_flags &= 0xFEFF;
+
+ if (!mq->chain(_aniMan))
+ delete mq;
+
+ _aniMan->_flags |= 1;
+ }
+ }
+ }
+
+ lift_exitSeq(0);
+
+ if (_lastLiftButton) {
+ _lastLiftButton->_statics = _lastLiftButton->getStaticsById(lift_getButtonIdN(_lastLiftButton->_statics->_staticsId));
+ _lastLiftButton = 0;
+ }
+}
+
+void FullpipeEngine::lift_sub1(StaticANIObject *ani) {
+ warning("STUB: FullpipeEngine::lift_sub1()");
+}
+
+void FullpipeEngine::lift_startExitQueue() {
+ MessageQueue *mq = new MessageQueue(_liftExitMQ, 0, 0);
+
+ mq->chain(0);
+}
+
+void FullpipeEngine::lift_sub05(ExCommand *ex) {
+ warning("STUB: FullpipeEngine::lift_sub05()");
+}
+
+bool FullpipeEngine::lift_checkButton(const char *varname) {
+ warning("STUB: FullpipeEngine::lift_checkButton(%s)", varname);
+
+ return false;
+}
+
+void FullpipeEngine::lift_setButtonStatics(Scene *sc, int buttonId) {
+ for (uint i = 0; i < sc->_staticANIObjectList1.size(); i++) {
+ StaticANIObject *ani = (StaticANIObject *)sc->_staticANIObjectList1[i];
+
+ if (ani->_id == ANI_LIFTBUTTON) {
+ int id = lift_getButtonIdN(ani->_statics->_staticsId);
+
+ if (id == buttonId)
+ ani->_statics = ani->getStaticsById(id);
+ }
+ }
+}
+
+
} // End of namespace Fullpipe
diff --git a/engines/fullpipe/messagehandlers.cpp b/engines/fullpipe/messagehandlers.cpp
new file mode 100644
index 0000000000..44a3e4cb60
--- /dev/null
+++ b/engines/fullpipe/messagehandlers.cpp
@@ -0,0 +1,744 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public 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 "fullpipe/fullpipe.h"
+
+#include "fullpipe/messages.h"
+#include "fullpipe/statics.h"
+#include "fullpipe/gameloader.h"
+#include "fullpipe/interaction.h"
+#include "fullpipe/motion.h"
+#include "fullpipe/input.h"
+
+#include "fullpipe/constants.h"
+
+namespace Fullpipe {
+
+void global_messageHandler_KickStucco() {
+ warning("STUB: global_messageHandler_KickStucco()");
+}
+
+void global_messageHandler_KickMetal() {
+ warning("STUB: global_messageHandler_KickMetal()");
+}
+
+int global_messageHandler1(ExCommand *cmd) {
+ debug(5, "global_messageHandler1: %d %d", cmd->_messageKind, cmd->_messageNum);
+
+ if (cmd->_excFlags & 0x10000) {
+ if (cmd->_messageNum == MV_MAN_TOLADDER)
+ cmd->_messageNum = MV_MAN_TOLADDER2;
+ if (cmd->_messageNum == MV_MAN_STARTLADDER)
+ cmd->_messageNum = MV_MAN_STARTLADDER2;
+ if (cmd->_messageNum == MV_MAN_GOLADDER)
+ cmd->_messageNum = MV_MAN_GOLADDER2;
+ if (cmd->_messageNum == MV_MAN_STOPLADDER)
+ cmd->_messageNum = MV_MAN_STOPLADDER2;
+ }
+
+ if (g_fp->_inputDisabled) {
+ if (cmd->_messageKind == 17) {
+ switch (cmd->_messageNum) {
+ case 29:
+ case 30:
+ case 36:
+ case 106:
+ cmd->_messageKind = 0;
+ break;
+ default:
+ break;
+ }
+ }
+ } else if (cmd->_messageKind == 17) {
+ switch (cmd->_messageNum) {
+ case MSG_MANSHADOWSON:
+ g_fp->_aniMan->_shadowsOn = 1;
+ break;
+ case MSG_HMRKICK_STUCCO:
+ global_messageHandler_KickStucco();
+ break;
+ case MSG_MANSHADOWSOFF:
+ g_fp->_aniMan->_shadowsOn = 0;
+ break;
+ case MSG_DISABLESAVES:
+ g_fp->disableSaves(cmd);
+ break;
+ case MSG_ENABLESAVES:
+ g_fp->enableSaves();
+ break;
+ case MSG_HMRKICK_METAL:
+ global_messageHandler_KickMetal();
+ break;
+ case 29: // left mouse
+ if (g_fp->_inventoryScene) {
+ if (getGameLoaderInventory()->handleLeftClick(cmd))
+ cmd->_messageKind = 0;
+ }
+ break;
+ case 107: // right mouse
+ if (getGameLoaderInventory()->getSelectedItemId()) {
+ getGameLoaderInventory()->unselectItem(0);
+ cmd->_messageKind = 0;
+ }
+ break;
+ case 36: // keydown
+ g_fp->defHandleKeyDown(cmd->_keyCode);
+
+ switch (cmd->_keyCode) {
+ case '\x1B': // ESC
+ if (g_fp->_currentScene) {
+ getGameLoaderInventory()->unselectItem(0);
+ g_fp->openMainMenu();
+ cmd->_messageKind = 0;
+ }
+ break;
+ case 't':
+ g_fp->stopAllSounds();
+ cmd->_messageKind = 0;
+ break;
+ case 'u':
+ g_fp->toggleMute();
+ cmd->_messageKind = 0;
+ break;
+ case ' ':
+ if (getGameLoaderInventory()->getIsLocked()) {
+ if (getGameLoaderInventory()->getIsInventoryOut()) {
+ getGameLoaderInventory()->setIsLocked(0);
+ }
+ } else {
+ getGameLoaderInventory()->slideOut();
+ getGameLoaderInventory()->setIsLocked(1);
+ }
+ break;
+ case '\t':
+ if (g_fp->_flgCanOpenMap)
+ g_fp->openMap();
+ cmd->_messageKind = 0;
+ break;
+ case 'p':
+ if (g_fp->_flgCanOpenMap)
+ g_fp->openHelp();
+ cmd->_messageKind = 0;
+ break;
+ default:
+ break;
+ }
+ break;
+ case 33:
+ if (!g_fp->_inventoryScene)
+ break;
+
+ int invItem;
+
+ if (g_fp->_updateFlag && (invItem = g_fp->_inventory->getHoveredItem(&g_fp->_mouseScreenPos))) {
+ g_fp->_cursorId = PIC_CSR_ITN;
+ if (!g_fp->_currSelectedInventoryItemId && !g_fp->_aniMan->_movement &&
+ !(g_fp->_aniMan->_flags & 0x100) && g_fp->_aniMan->isIdle()) {
+ int st = g_fp->_aniMan->_statics->_staticsId;
+ ExCommand *newex = 0;
+
+ if (st == ST_MAN_RIGHT) {
+ newex = new ExCommand(g_fp->_aniMan->_id, 1, rMV_MAN_LOOKUP, 0, 0, 0, 1, 0, 0, 0);
+ } else if (st == (0x4000 | ST_MAN_RIGHT)) {
+ newex = new ExCommand(g_fp->_aniMan->_id, 1, MV_MAN_LOOKUP, 0, 0, 0, 1, 0, 0, 0);
+ }
+
+ if (newex) {
+ newex->_keyCode = g_fp->_aniMan->_okeyCode;
+ newex->_excFlags |= 3;
+ newex->postMessage();
+ }
+ }
+
+ if (g_fp->_currSelectedInventoryItemId != invItem)
+ g_fp->playSound(SND_CMN_070, 0);
+
+ g_fp->_currSelectedInventoryItemId = invItem;
+ g_fp->setCursor(g_fp->_cursorId);
+ break;
+ }
+ if (g_fp->_updateCursorCallback)
+ g_fp->_updateCursorCallback();
+
+ g_fp->_currSelectedInventoryItemId = 0;
+ g_fp->setCursor(g_fp->_cursorId);
+ break;
+ case 65: // open map
+ if (cmd->_field_2C == 11 && cmd->_field_14 == ANI_INV_MAP && g_fp->_flgCanOpenMap)
+ g_fp->openMap();
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (cmd->_messageKind == 56) {
+ getGameLoaderInventory()->rebuildItemRects();
+
+ ExCommand *newex = new ExCommand(0, 35, SND_CMN_031, 0, 0, 0, 1, 0, 0, 0);
+
+ newex->_field_14 = 1;
+ newex->_excFlags |= 3;
+ newex->postMessage();
+
+ return 1;
+ } else if (cmd->_messageKind == 57) {
+ getGameLoaderInventory()->rebuildItemRects();
+
+ return 1;
+ }
+
+ return 0;
+}
+
+void staticANIObjectCallback(int *arg) {
+ (*arg)--;
+}
+
+int global_messageHandler2(ExCommand *cmd) {
+ if (cmd->_messageKind != 17)
+ return 0;
+
+ int res = 0;
+ StaticANIObject *ani;
+
+ switch (cmd->_messageNum) {
+ case 0x44c8:
+ error("0x44c8");
+ // Unk3_sub_4477A0(&unk3, _parentId, _field_14 != 0);
+ break;
+
+ case 28:
+ ani = g_fp->_currentScene->getStaticANIObject1ById(cmd->_parentId, cmd->_keyCode);
+ if (ani)
+ ani->_priority = cmd->_field_14;
+ break;
+
+ case 25:
+ ani = g_fp->_currentScene->getStaticANIObject1ById(cmd->_parentId, cmd->_keyCode);
+ if (ani) {
+ if (cmd->_field_14) {
+ ani->setFlags40(true);
+ ani->_callback2 = staticANIObjectCallback;
+ } else {
+ ani->setFlags40(false);
+ ani->_callback2 = 0;
+ }
+ }
+ break;
+
+ case 26:
+ ani = g_fp->_currentScene->getStaticANIObject1ById(cmd->_parentId, cmd->_keyCode);
+ if (ani) {
+ Movement *mov = ani->_movement;
+ if (mov)
+ mov->_currDynamicPhase->_field_68 = 0;
+ }
+ break;
+
+ default:
+#if 0
+ // We never put anything into _defMsgArray
+ while (::iterator it = g_fp->_defMsgArray.begin(); it != g_fp->_defMsgArray.end(); ++it)
+ if (((ExCommand *)*it)->_field_24 == _messageNum) {
+ ((ExCommand *)*it)->firef34(v13);
+ res = 1;
+ }
+#endif
+
+ //debug_msg(_messageNum);
+
+ if (!g_fp->_soundEnabled || cmd->_messageNum != 33 || g_fp->_currSoundListCount <= 0)
+ return res;
+
+ for (int snd = 0; snd < g_fp->_currSoundListCount; snd++) {
+ SoundList *s = g_fp->_currSoundList1[snd];
+ int ms = s->getCount();
+ for (int i = 0; i < ms; i++) {
+ s->getSoundByIndex(i)->setPanAndVolumeByStaticAni();
+ }
+ }
+ }
+
+ return res;
+}
+
+int global_messageHandler3(ExCommand *cmd) {
+ int result = 0;
+
+ if (cmd->_messageKind == 17) {
+ switch (cmd->_messageNum) {
+ case 29:
+ case 30:
+ case 31:
+ case 32:
+ case 36:
+ if (g_fp->_inputDisabled)
+ cmd->_messageKind = 0;
+ break;
+ default:
+ break;
+ }
+ }
+
+ StaticANIObject *ani, *ani2;
+
+ switch (cmd->_messageKind) {
+ case 17:
+ switch (cmd->_messageNum) {
+ case 61:
+ debug(0, "preload: { %d, %d },", cmd->_parentId, cmd->_keyCode);
+ return g_fp->_gameLoader->preloadScene(cmd->_parentId, cmd->_keyCode);
+ case 62:
+ return g_fp->_gameLoader->gotoScene(cmd->_parentId, cmd->_keyCode);
+ case 64:
+ if (g_fp->_currentScene && g_fp->_msgObjectId2
+ && (!(cmd->_keyCode & 4) || g_fp->_msgObjectId2 != cmd->_field_14 || g_fp->_msgId != cmd->_field_20)) {
+ ani = g_fp->_currentScene->getStaticANIObject1ById(g_fp->_msgObjectId2, g_fp->_msgId);
+ if (ani) {
+ ani->_flags &= 0xFF7F;
+ ani->_flags &= 0xFEFF;
+ ani->deleteFromGlobalMessageQueue();
+ }
+ }
+ g_fp->_msgX = 0;
+ g_fp->_msgY = 0;
+ g_fp->_msgObjectId2 = 0;
+ g_fp->_msgId = 0;
+ if ((cmd->_keyCode & 1) || (cmd->_keyCode & 2)) {
+ g_fp->_msgX = cmd->_x;
+ g_fp->_msgY = cmd->_y;
+ }
+ if (cmd->_keyCode & 4) {
+ g_fp->_msgObjectId2 = cmd->_field_14;
+ g_fp->_msgId = cmd->_field_20;
+ }
+ return result;
+ case 29:
+ if (!g_fp->_currentScene)
+ return result;
+
+ if (g_fp->_gameLoader->_interactionController->_flag24) {
+ ani = g_fp->_currentScene->getStaticANIObjectAtPos(cmd->_sceneClickX, cmd->_sceneClickY);
+ ani2 = g_fp->_currentScene->getStaticANIObject1ById(g_fp->_gameLoader->_field_FA, -1);
+ if (ani) {
+ if (g_fp->_msgObjectId2 == ani->_id && g_fp->_msgId == ani->_okeyCode) {
+ cmd->_messageKind = 0;
+ return result;
+ }
+ if (canInteractAny(ani2, ani, cmd->_keyCode)) {
+ handleObjectInteraction(ani2, ani, cmd->_keyCode);
+ return 1;
+ }
+ } else {
+ int id = g_fp->_currentScene->getPictureObjectIdAtPos(cmd->_sceneClickX, cmd->_sceneClickY);
+ PictureObject *pic = g_fp->_currentScene->getPictureObjectById(id, 0);
+ if (pic) {
+ if (g_fp->_msgObjectId2 == pic->_id && g_fp->_msgId == pic->_okeyCode) {
+ cmd->_messageKind = 0;
+ return result;
+ }
+ if (!ani2 || canInteractAny(ani2, pic, cmd->_keyCode)) {
+ if (!ani2 || (ani2->isIdle() && !(ani2->_flags & 0x80) && !(ani2->_flags & 0x100)))
+ handleObjectInteraction(ani2, pic, cmd->_keyCode);
+ return 1;
+ }
+ }
+ }
+ }
+ if (getSc2MctlCompoundBySceneId(g_fp->_currentScene->_sceneId)->_isEnabled && cmd->_keyCode <= 0) {
+ if (g_fp->_msgX != cmd->_sceneClickX || g_fp->_msgY != cmd->_sceneClickY) {
+ ani = g_fp->_currentScene->getStaticANIObject1ById(g_fp->_gameLoader->_field_FA, -1);
+ if (!ani || (ani->isIdle() && !(ani->_flags & 0x80) && !(ani->_flags & 0x100))) {
+ result = startWalkTo(g_fp->_gameLoader->_field_FA, -1, cmd->_sceneClickX, cmd->_sceneClickY, 0);
+ if (result) {
+ ExCommand *ex = new ExCommand(g_fp->_gameLoader->_field_FA, 17, 64, 0, 0, 0, 1, 0, 0, 0);
+
+ ex->_keyCode = 1;
+ ex->_excFlags |= 3;
+ ex->_x = cmd->_sceneClickX;
+ ex->_y = cmd->_sceneClickY;
+ ex->postMessage();
+ }
+ }
+ } else {
+ cmd->_messageKind = 0;
+ }
+ }
+ return result;
+ default:
+ return result;
+ }
+ case 58:
+ g_fp->setCursor(cmd->_keyCode);
+ return result;
+ case 59:
+ setInputDisabled(1);
+ return result;
+ case 60:
+ setInputDisabled(0);
+ return result;
+ case 56:
+ if (cmd->_field_2C) {
+ ani = g_fp->_currentScene->getStaticANIObject1ById(cmd->_parentId, cmd->_keyCode);
+ if (ani) {
+ getGameLoaderInventory()->addItem2(ani);
+ result = 1;
+ }
+ } else {
+ result = 1;
+ getGameLoaderInventory()->addItem(cmd->_parentId, 1);
+ }
+ getGameLoaderInventory()->rebuildItemRects();
+ return result;
+ case 57:
+ if (cmd->_field_2C) {
+ if (!cmd->_field_20) {
+ getGameLoaderInventory()->removeItem2(g_fp->_currentScene, cmd->_parentId, cmd->_x, cmd->_y, cmd->_field_14);
+ getGameLoaderInventory()->rebuildItemRects();
+ return 1;
+ }
+ ani = g_fp->_currentScene->getStaticANIObject1ById(g_fp->_gameLoader->_field_FA, -1);
+ if (ani) {
+ getGameLoaderInventory()->removeItem2(g_fp->_currentScene, cmd->_parentId, ani->_ox + cmd->_x, ani->_oy + cmd->_y, ani->_priority + cmd->_field_14);
+ getGameLoaderInventory()->rebuildItemRects();
+ return 1;
+ }
+ } else {
+ getGameLoaderInventory()->removeItem(cmd->_parentId, 1);
+ }
+ getGameLoaderInventory()->rebuildItemRects();
+ return 1;
+ case 55:
+ if (g_fp->_currentScene) {
+ GameObject *obj;
+ if (cmd->_field_14)
+ obj = g_fp->_currentScene->getStaticANIObject1ById(cmd->_x, cmd->_y);
+ else
+ obj = g_fp->_currentScene->getPictureObjectById(cmd->_x, cmd->_y);
+ handleObjectInteraction(g_fp->_currentScene->getStaticANIObject1ById(cmd->_parentId, cmd->_keyCode), obj, cmd->_field_20);
+ result = 1;
+ }
+ return result;
+ case 51:
+ return startWalkTo(cmd->_parentId, cmd->_keyCode, cmd->_x, cmd->_y, cmd->_field_20);
+ case 52:
+ return doSomeAnimation(cmd->_parentId, cmd->_keyCode, cmd->_field_20);
+ case 53:
+ return doSomeAnimation2(cmd->_parentId, cmd->_keyCode);
+ case 63:
+ if (cmd->_objtype == kObjTypeObjstateCommand) {
+ ObjstateCommand *c = (ObjstateCommand *)cmd;
+ result = 1;
+ g_fp->setObjectState(c->_objCommandName, c->_value);
+ }
+ return result;
+ default:
+ return result;
+ }
+}
+
+int global_messageHandler4(ExCommand *cmd) {
+ StaticANIObject *ani = 0;
+
+ switch (cmd->_messageKind) {
+ case 18: {
+ MessageQueue *mq = new MessageQueue(g_fp->_currentScene->getMessageQueueById(cmd->_messageNum), cmd->_parId, 0);
+
+ if (cmd->_excFlags & 1)
+ mq->_flag1 = 1;
+ else
+ mq->_flag1 = 0;
+
+ mq->sendNextCommand();
+ break;
+ }
+ case 2:
+ if (!g_fp->_currentScene)
+ break;
+
+ ani = g_fp->_currentScene->getStaticANIObject1ById(cmd->_parentId, cmd->_keyCode);
+ if (!ani)
+ break;
+
+ ani->trySetMessageQueue(cmd->_messageNum, cmd->_parId);
+ break;
+
+ case 1: {
+ if (!g_fp->_currentScene)
+ break;
+
+ ani = g_fp->_currentScene->getStaticANIObject1ById(cmd->_parentId, cmd->_keyCode);
+ if (!ani)
+ break;
+
+ int flags = cmd->_field_14;
+ if (flags <= 0)
+ flags = -1;
+
+ if (cmd->_excFlags & 1)
+ ani->startAnim(cmd->_messageNum, 0, flags);
+ else
+ ani->startAnim(cmd->_messageNum, cmd->_parId, flags);
+
+ break;
+ }
+ case 8:
+ if (!g_fp->_currentScene)
+ break;
+
+ ani = g_fp->_currentScene->getStaticANIObject1ById(cmd->_parentId, cmd->_keyCode);
+ if (!ani)
+ break;
+
+ ani->startAnimEx(cmd->_messageNum, cmd->_parId, -1, -1);
+ break;
+
+ case 20: {
+ if (!g_fp->_currentScene)
+ break;
+
+ ani = g_fp->_currentScene->getStaticANIObject1ById(cmd->_parentId, cmd->_keyCode);
+ if (!ani)
+ break;
+
+ int flags = cmd->_field_14;
+ if (flags <= 0)
+ flags = -1;
+
+ ExCommand2 *cmd2 = (ExCommand2 *)cmd;
+
+ if (cmd->_excFlags & 1) {
+ ani->startAnimSteps(cmd->_messageNum, 0, cmd->_x, cmd->_y, cmd2->_points, cmd2->_pointsSize >> 3, flags);
+ } else {
+ ani->startAnimSteps(cmd->_messageNum, cmd->_parId, cmd->_x, cmd->_y, cmd2->_points, cmd2->_pointsSize >> 3, flags);
+ }
+ break;
+ }
+ case 21:
+ if (!g_fp->_currentScene)
+ break;
+
+ ani = g_fp->_currentScene->getStaticANIObject1ById(cmd->_parentId, cmd->_keyCode);
+ if (!ani)
+ break;
+
+ ani->queueMessageQueue(0);
+ ani->playIdle();
+ break;
+ case 9:
+ // Nop in original
+ break;
+ case 3:
+ g_fp->_currentScene->_y = cmd->_messageNum - cmd->_messageNum % g_fp->_scrollSpeed;
+ break;
+
+ case 4:
+ g_fp->_currentScene->_x = cmd->_messageNum - cmd->_messageNum % g_fp->_scrollSpeed;
+ break;
+
+ case 19: {
+ if (!g_fp->_currentScene)
+ break;
+ ani = g_fp->_currentScene->getStaticANIObject1ById(cmd->_parentId, cmd->_keyCode);
+ if (!ani)
+ break;
+
+ MessageQueue *mq = ani->getMessageQueue();
+ MessageQueue *mq2 = ani->changeStatics1(cmd->_messageNum);
+
+ if (!mq2 || !mq2->getExCommandByIndex(0) || !mq)
+ break;
+
+ mq2->_parId = mq->_id;
+ mq2->_flag1 = (cmd->_field_24 == 0);
+ break;
+ }
+ case 22:
+ if (!g_fp->_currentScene)
+ break;
+
+ ani = g_fp->_currentScene->getStaticANIObject1ById(cmd->_parentId, cmd->_keyCode);
+ if (!ani)
+ break;
+
+ ani->_flags |= 4;
+ ani->changeStatics2(cmd->_messageNum);
+ break;
+
+ case 6:
+ if (!g_fp->_currentScene)
+ break;
+
+ ani = g_fp->_currentScene->getStaticANIObject1ById(cmd->_parentId, cmd->_keyCode);
+ if (!ani)
+ break;
+
+ ani->hide();
+ break;
+
+ case 27:
+ if (!g_fp->_currentScene || g_fp->_currentScene->getStaticANIObject1ById(cmd->_parentId, cmd->_keyCode) == 0) {
+ ani = g_fp->accessScene(cmd->_field_20)->getStaticANIObject1ById(cmd->_parentId, -1);
+ if (ani) {
+ ani = new StaticANIObject(ani);
+ g_fp->_currentScene->addStaticANIObject(ani, 1);
+ }
+ }
+
+ // fall through
+ case 5:
+ if (g_fp->_currentScene)
+ ani = g_fp->_currentScene->getStaticANIObject1ById(cmd->_parentId, cmd->_keyCode);
+
+ if (!ani)
+ break;
+
+ if (cmd->_field_14 >= 0)
+ ani->_priority = cmd->_field_14;
+
+ ani->show1(cmd->_x, cmd->_y, cmd->_messageNum, cmd->_parId);
+ break;
+
+ case 10:
+ if (!g_fp->_currentScene)
+ break;
+
+ ani = g_fp->_currentScene->getStaticANIObject1ById(cmd->_parentId, cmd->_keyCode);
+ if (!ani)
+ break;
+
+ if (cmd->_field_14 >= 0)
+ ani->_priority = cmd->_field_14;
+
+ ani->show2(cmd->_x, cmd->_y, cmd->_messageNum, cmd->_parId);
+ break;
+
+ case 7: {
+ if (!g_fp->_currentScene->_picObjList.size())
+ break;
+
+ int offX = g_fp->_scrollSpeed * (cmd->_x / g_fp->_scrollSpeed);
+ int offY = g_fp->_scrollSpeed * (cmd->_y / g_fp->_scrollSpeed);
+
+ if (cmd->_messageNum) {
+ g_fp->_currentScene->_x = offX - g_fp->_sceneRect.left;
+ g_fp->_currentScene->_y = offY - g_fp->_sceneRect.top;
+
+ if (cmd->_field_24) {
+ g_fp->_currentScene->_messageQueueId = cmd->_parId;
+ }
+ } else {
+ g_fp->_sceneRect.translate(offX - g_fp->_sceneRect.left, offY - g_fp->_sceneRect.top);
+
+ g_fp->_currentScene->_x = 0;
+ g_fp->_currentScene->_y = 0;
+
+ g_fp->_currentScene->updateScrolling2();
+ }
+ break;
+ }
+ case 34:
+ if (!g_fp->_currentScene)
+ break;
+
+ ani = g_fp->_currentScene->getStaticANIObject1ById(cmd->_parentId, cmd->_keyCode);
+ if (!ani)
+ break;
+
+ ani->_flags = cmd->_messageNum | (ani->_flags & ~cmd->_field_14);
+
+ break;
+
+ case 35:
+ global_messageHandler_handleSound(cmd);
+ break;
+
+ case 11:
+ case 12:
+ break;
+ default:
+ return 0;
+ break;
+ }
+
+ return 1;
+}
+
+int MovGraph_messageHandler(ExCommand *cmd) {
+ if (cmd->_messageKind != 17)
+ return 0;
+
+ if (cmd->_messageNum != 33)
+ return 0;
+
+ StaticANIObject *ani = g_fp->_currentScene->getStaticANIObject1ById(g_fp->_gameLoader->_field_FA, -1);
+
+ if (!getSc2MctlCompoundBySceneId(g_fp->_currentScene->_sceneId))
+ return 0;
+
+ if (getSc2MctlCompoundBySceneId(g_fp->_currentScene->_sceneId)->_objtype != kObjTypeMovGraph || !ani)
+ return 0;
+
+ MovGraph *gr = (MovGraph *)getSc2MctlCompoundBySceneId(g_fp->_currentScene->_sceneId);
+
+ MovGraphLink *link = 0;
+ double mindistance = 1.0e10;
+ Common::Point point;
+
+ for (ObList::iterator i = gr->_links.begin(); i != gr->_links.end(); ++i) {
+ point.x = ani->_ox;
+ point.y = ani->_oy;
+
+ double dst = gr->calcDistance(&point, (MovGraphLink *)(*i), 0);
+ if (dst >= 0.0 && dst < mindistance) {
+ mindistance = dst;
+ link = (MovGraphLink *)(*i);
+ }
+ }
+
+ int top;
+
+ if (link) {
+ MovGraphNode *node = link->_movGraphNode1;
+
+ double sq = (ani->_oy - node->_y) * (ani->_oy - node->_y) + (ani->_ox - node->_x) * (ani->_ox - node->_x);
+ int off = (node->_field_14 >> 16) & 0xFF;
+ double off2 = ((link->_movGraphNode2->_field_14 >> 8) & 0xff) - off;
+
+ top = off + (int)(sqrt(sq) * off2 / link->_distance);
+ } else {
+ top = (gr->calcOffset(ani->_ox, ani->_oy)->_field_14 >> 8) & 0xff;
+ }
+
+ if (ani->_movement) {
+ ani->_movement->_currDynamicPhase->_rect->top = 255 - top;
+ return 0;
+ }
+
+ if (ani->_statics)
+ ani->_statics->_rect->top = 255 - top;
+
+ return 0;
+}
+
+} // End of namespace Fullpipe
diff --git a/engines/fullpipe/messages.cpp b/engines/fullpipe/messages.cpp
index b5f2cb8303..7dfdd06fc8 100644
--- a/engines/fullpipe/messages.cpp
+++ b/engines/fullpipe/messages.cpp
@@ -41,7 +41,10 @@ ExCommand::ExCommand(ExCommand *src) : Message(src) {
_messageNum = src->_messageNum;
_excFlags = src->_excFlags;
_parId = src->_parId;
+}
+ExCommand *ExCommand::createClone() {
+ return new ExCommand(this);
}
ExCommand::ExCommand(int16 parentId, int messageKind, int messageNum, int x, int y, int a7, int a8, int sceneClickX, int sceneClickY, int a11) :
@@ -73,22 +76,24 @@ bool ExCommand::load(MfcArchive &file) {
_field_3C = 0;
- if (g_fullpipe->_gameProjectVersion >= 12) {
+ if (g_fp->_gameProjectVersion >= 12) {
_excFlags = file.readUint32LE();
_parId = file.readUint32LE();
}
+ _objtype = kObjTypeExCommand;
+
return true;
}
bool ExCommand::handleMessage() {
int cnt = 0;
- for (MessageHandler *m = g_fullpipe->_messageHandlers; m; m = m->nextItem)
+ for (MessageHandler *m = g_fp->_messageHandlers; m; m = m->nextItem)
cnt += m->callback(this);
if (_messageKind == 17 || (_excFlags & 1)) {
if (_parId) {
- MessageQueue *mq = g_fullpipe->_globalMessageQueueList->getMessageQueueById(_parId);
+ MessageQueue *mq = g_fp->_globalMessageQueueList->getMessageQueueById(_parId);
if (mq)
mq->update();
}
@@ -101,18 +106,18 @@ bool ExCommand::handleMessage() {
}
void ExCommand::sendMessage() {
- g_fullpipe->_exCommandList.push_back(this);
+ g_fp->_exCommandList.push_back(this);
processMessages();
}
void ExCommand::postMessage() {
- g_fullpipe->_exCommandList.push_back(this);
+ g_fp->_exCommandList.push_back(this);
}
void ExCommand::handle() {
- if (g_fullpipe->_modalObject) {
- g_fullpipe->_modalObject->handleMessage(this);
+ if (g_fp->_modalObject) {
+ g_fp->_modalObject->handleMessage(this);
delete this;
} else {
@@ -120,6 +125,61 @@ void ExCommand::handle() {
}
}
+void ExCommand::setf3c(int val) {
+ if (val != -1)
+ _field_3C = val;
+
+ _field_34 = 1;
+}
+
+void ExCommand::firef34() {
+ if (_field_34) {
+ if (_field_3C >= _keyCode) {
+ _field_34 = 0;
+
+ sendMessage();
+
+ if (!_field_30 )
+ setf3c(_field_2C);
+ }
+ }
+}
+
+ExCommand2::ExCommand2(int messageKind, int parentId, Common::Point **points, int pointsSize) : ExCommand(parentId, messageKind, 0, 0, 0, 0, 1, 0, 0, 0) {
+ _objtype = kObjTypeExCommand2;
+
+ _pointsSize = pointsSize;
+ _points = (Common::Point **)malloc(sizeof(Common::Point *) * pointsSize);
+
+ for (int i = 0; i < pointsSize; i++) {
+ _points[i] = new Common::Point;
+
+ *_points[i] = *points[i];
+ }
+}
+
+ExCommand2::ExCommand2(ExCommand2 *src) : ExCommand(src) {
+ _pointsSize = src->_pointsSize;
+ _points = (Common::Point **)malloc(sizeof(Common::Point *) * _pointsSize);
+
+ for (int i = 0; i < _pointsSize; i++) {
+ _points[i] = new Common::Point;
+
+ *_points[i] = *src->_points[i];
+ }
+}
+
+ExCommand2::~ExCommand2() {
+ for (int i = 0; i < _pointsSize; i++)
+ delete _points[i];
+
+ free(_points);
+}
+
+ExCommand2 *ExCommand2::createClone() {
+ return new ExCommand2(this);
+}
+
Message::Message() {
_messageKind = 0;
_parentId = 0;
@@ -174,12 +234,23 @@ ObjstateCommand::ObjstateCommand() {
_objCommandName = 0;
}
+ObjstateCommand::ObjstateCommand(ObjstateCommand *src) : ExCommand(src) {
+ _value = src->_value;
+ _objCommandName = (char *)calloc(strlen(src->_objCommandName) + 1, 1);
+
+ strncpy(_objCommandName, src->_objCommandName, strlen(src->_objCommandName));
+}
+
+ObjstateCommand::~ObjstateCommand() {
+ free(_objCommandName);
+}
+
bool ObjstateCommand::load(MfcArchive &file) {
debug(5, "ObjStateCommand::load()");
_objtype = kObjTypeObjstateCommand;
- _cmd.load(file);
+ ExCommand::load(file);
_value = file.readUint32LE();
@@ -188,6 +259,10 @@ bool ObjstateCommand::load(MfcArchive &file) {
return true;
}
+ObjstateCommand *ObjstateCommand::createClone() {
+ return new ObjstateCommand(this);
+}
+
MessageQueue::MessageQueue() {
_field_14 = 0;
_parId = 0;
@@ -201,12 +276,25 @@ MessageQueue::MessageQueue() {
_flag1 = 0;
}
+MessageQueue::MessageQueue(int dataId) {
+ _field_14 = 0;
+ _parId = 0;
+ _dataId = dataId;
+ _id = g_fp->_globalMessageQueueList->compact();
+ _isFinished = 0;
+ _flags = 0;
+ _queueName = 0;
+ _counter = 0;
+ _field_38 = 0;
+ _flag1 = 0;
+}
+
MessageQueue::MessageQueue(MessageQueue *src, int parId, int field_38) {
_counter = 0;
_field_38 = (field_38 == 0);
for (Common::List<ExCommand *>::iterator it = src->_exCommands.begin(); it != src->_exCommands.end(); ++it) {
- ExCommand *ex = new ExCommand(*it);
+ ExCommand *ex = (*it)->createClone();
ex->_excFlags |= 2;
_exCommands.push_back(ex);
@@ -218,11 +306,12 @@ MessageQueue::MessageQueue(MessageQueue *src, int parId, int field_38) {
else
_parId = src->_parId;
- _id = g_fullpipe->_globalMessageQueueList->compact();
+ _id = g_fp->_globalMessageQueueList->compact();
_dataId = src->_dataId;
_flags = src->_flags;
+ _queueName = 0;
- g_fullpipe->_globalMessageQueueList->addMessageQueue(this);
+ g_fp->_globalMessageQueueList->addMessageQueue(this);
_isFinished = 0;
_flag1 = 0;
@@ -242,7 +331,7 @@ MessageQueue::~MessageQueue() {
delete _field_14;
if (_flags & 2) {
- g_fullpipe->_globalMessageQueueList->removeQueueById(_id);
+ g_fp->_globalMessageQueueList->removeQueueById(_id);
}
finish();
@@ -257,7 +346,7 @@ bool MessageQueue::load(MfcArchive &file) {
int count = file.readUint16LE();
- assert(g_fullpipe->_gameProjectVersion >= 12);
+ assert(g_fp->_gameProjectVersion >= 12);
_queueName = file.readPascalString();
@@ -278,7 +367,7 @@ bool MessageQueue::load(MfcArchive &file) {
bool MessageQueue::chain(StaticANIObject *ani) {
if (checkGlobalExCommandList1() && checkGlobalExCommandList2()) {
if (!(getFlags() & 2)) {
- g_fullpipe->_globalMessageQueueList->addMessageQueue(this);
+ g_fp->_globalMessageQueueList->addMessageQueue(this);
_flags |= 2;
}
if (ani) {
@@ -296,7 +385,7 @@ void MessageQueue::update() {
if (_counter > 0)
_counter--;
- if (_exCommands.size()) {
+ if (getCount()) {
sendNextCommand();
} else if (_counter == 0) {
_isFinished = 1;
@@ -309,8 +398,25 @@ void MessageQueue::messageQueueCallback1(int par) {
debug(3, "STUB: MessageQueue::messageQueueCallback1()");
}
+void MessageQueue::addExCommand(ExCommand *ex) {
+ _exCommands.push_front(ex);
+}
+
+void MessageQueue::addExCommandToEnd(ExCommand *ex) {
+ _exCommands.push_back(ex);
+}
+
+void MessageQueue::insertExCommandAt(int pos, ExCommand *ex) {
+ Common::List<ExCommand *>::iterator it = _exCommands.begin();
+
+ for (int i = pos; i > 0; i--)
+ ++it;
+
+ _exCommands.insert(it, ex);
+}
+
ExCommand *MessageQueue::getExCommandByIndex(uint idx) {
- if (idx > _exCommands.size())
+ if (idx >= getCount())
return 0;
Common::List<ExCommand *>::iterator it = _exCommands.begin();
@@ -323,8 +429,32 @@ ExCommand *MessageQueue::getExCommandByIndex(uint idx) {
return *it;
}
+void MessageQueue::deleteExCommandByIndex(uint idx, bool doFree) {
+ if (idx >= getCount())
+ return;
+
+ Common::List<ExCommand *>::iterator it = _exCommands.begin();
+
+ while (idx) {
+ ++it;
+ idx--;
+ }
+
+ if (doFree)
+ delete *it;
+
+ _exCommands.erase(it);
+}
+
+void MessageQueue::transferExCommands(MessageQueue *mq) {
+ while (mq->_exCommands.size()) {
+ _exCommands.push_back(mq->_exCommands.front());
+ mq->_exCommands.pop_front();
+ }
+}
+
void MessageQueue::sendNextCommand() {
- if (_exCommands.size()) {
+ if (getCount()) {
if (!(_flags & 4) && (_flags & 1)) {
messageQueueCallback1(16);
}
@@ -353,7 +483,7 @@ bool MessageQueue::checkGlobalExCommandList1() {
if (ex->_messageKind != 1 && ex->_messageKind != 20 && ex->_messageKind != 5 && ex->_messageKind != 27)
continue;
- for (Common::List<ExCommand *>::iterator it = g_fullpipe->_exCommandList.begin(); it != g_fullpipe->_exCommandList.end(); it++) {
+ for (Common::List<ExCommand *>::iterator it = g_fp->_exCommandList.begin(); it != g_fp->_exCommandList.end(); it++) {
ex1 = *it;
if (ex1->_messageKind != 1 && ex1->_messageKind != 20 && ex1->_messageKind != 5 && ex1->_messageKind != 27)
@@ -362,7 +492,7 @@ bool MessageQueue::checkGlobalExCommandList1() {
if (ex1->_keyCode != ex->_keyCode && ex1->_keyCode != -1 && ex->_keyCode != -1)
continue;
- MessageQueue *mq = g_fullpipe->_globalMessageQueueList->getMessageQueueById(ex1->_parId);
+ MessageQueue *mq = g_fp->_globalMessageQueueList->getMessageQueueById(ex1->_parId);
if (mq) {
if (mq->getFlags() & 1)
@@ -382,7 +512,7 @@ bool MessageQueue::checkGlobalExCommandList2() {
if (ex->_messageKind != 1 && ex->_messageKind != 20 && ex->_messageKind != 5 && ex->_messageKind != 27)
continue;
- for (Common::List<ExCommand *>::iterator it = g_fullpipe->_exCommandList.begin(); it != g_fullpipe->_exCommandList.end();) {
+ for (Common::List<ExCommand *>::iterator it = g_fp->_exCommandList.begin(); it != g_fp->_exCommandList.end();) {
ex1 = *it;
if (ex1->_messageKind != 1 && ex1->_messageKind != 20 && ex1->_messageKind != 5 && ex1->_messageKind != 27) {
@@ -395,7 +525,7 @@ bool MessageQueue::checkGlobalExCommandList2() {
continue;
}
- MessageQueue *mq = g_fullpipe->_globalMessageQueueList->getMessageQueueById(ex1->_parId);
+ MessageQueue *mq = g_fp->_globalMessageQueueList->getMessageQueueById(ex1->_parId);
if (mq) {
if (mq->getFlags() & 1)
@@ -404,7 +534,7 @@ bool MessageQueue::checkGlobalExCommandList2() {
delete mq;
}
- it = g_fullpipe->_exCommandList.erase(it);
+ it = g_fp->_exCommandList.erase(it);
if (ex1->_excFlags & 2) {
delete ex1;
@@ -418,7 +548,7 @@ void MessageQueue::finish() {
if (!_parId)
return;
- MessageQueue *mq = g_fullpipe->_globalMessageQueueList->getMessageQueueById(_parId);
+ MessageQueue *mq = g_fp->_globalMessageQueueList->getMessageQueueById(_parId);
_parId = 0;
@@ -451,7 +581,8 @@ int MessageQueue::calcDuration(StaticANIObject *obj) {
ExCommand *ex;
Movement *mov;
- for (uint i = 0; (ex = getExCommandByIndex(i)); i++)
+ for (uint i = 0; i < getCount(); i++) {
+ ex = getExCommandByIndex(i);
if (ex->_parentId == obj->_id) {
if (ex->_messageKind == 1 || ex->_messageKind == 20) {
if ((mov = obj->getMovementById(ex->_messageNum)) != 0) {
@@ -462,12 +593,13 @@ int MessageQueue::calcDuration(StaticANIObject *obj) {
}
}
}
+ }
return res;
}
void MessageQueue::changeParam28ForObjectId(int objId, int oldParam28, int newParam28) {
- for (uint i = 0; i < _exCommands.size(); i++) {
+ for (uint i = 0; i < getCount(); i++) {
ExCommand *ex = getExCommandByIndex(i);
int k = ex->_messageKind;
@@ -516,16 +648,32 @@ void GlobalMessageQueueList::disableQueueById(int id) {
}
int GlobalMessageQueueList::compact() {
+ int *useList = new int[size() + 2];
+
+ for (uint i = 0; i < size() + 2; i++)
+ useList[i] = 0;
+
for (uint i = 0; i < size();) {
if (((MessageQueue *)_storage[i])->_isFinished) {
disableQueueById(_storage[i]->_id);
remove_at(i);
} else {
+ if ((uint)_storage[i]->_id < size() + 2)
+ useList[_storage[i]->_id] = 1;
i++;
}
}
- return size() + 1;
+ uint i;
+
+ for (i = 1; i < size() + 2; i++) {
+ if (!useList[i])
+ break;
+ }
+
+ delete [] useList;
+
+ return i;
}
void GlobalMessageQueueList::addMessageQueue(MessageQueue *msg) {
@@ -535,12 +683,25 @@ void GlobalMessageQueueList::addMessageQueue(MessageQueue *msg) {
}
void clearGlobalMessageQueueList1() {
- warning("STUB: clearGlobalMessageQueueList1()");
+ clearMessages();
+
+ g_fp->_globalMessageQueueList->clear();
+}
+
+void clearMessages() {
+ while (g_fp->_exCommandList.size()) {
+ ExCommand *ex = g_fp->_exCommandList.front();
+
+ g_fp->_exCommandList.pop_front();
+
+ if (ex->_excFlags & 2)
+ delete ex;
+ }
}
bool removeMessageHandler(int16 id, int pos) {
- if (g_fullpipe->_messageHandlers) {
- MessageHandler *curItem = g_fullpipe->_messageHandlers;
+ if (g_fp->_messageHandlers) {
+ MessageHandler *curItem = g_fp->_messageHandlers;
MessageHandler *prevItem = 0;
int curPos = 0;
@@ -574,13 +735,13 @@ void addMessageHandler(int (*callback)(ExCommand *), int16 id) {
if (getMessageHandlerById(id))
return;
- MessageHandler *curItem = g_fullpipe->_messageHandlers;
+ MessageHandler *curItem = g_fp->_messageHandlers;
if (!curItem)
return;
int index = 0;
- for (MessageHandler *i = g_fullpipe->_messageHandlers->nextItem; i; i = i->nextItem) {
+ for (MessageHandler *i = g_fp->_messageHandlers->nextItem; i; i = i->nextItem) {
curItem = i;
index++;
}
@@ -592,7 +753,7 @@ void addMessageHandler(int (*callback)(ExCommand *), int16 id) {
}
MessageHandler *getMessageHandlerById(int16 id) {
- MessageHandler *curItem = g_fullpipe->_messageHandlers;
+ MessageHandler *curItem = g_fp->_messageHandlers;
if (!curItem)
return 0;
@@ -622,7 +783,7 @@ bool allocMessageHandler(MessageHandler *where, int16 id, int (*callback)(ExComm
msg->callback = callback;
msg->index = 0;
- g_fullpipe->_messageHandlers = msg;
+ g_fp->_messageHandlers = msg;
}
return true;
@@ -630,7 +791,7 @@ bool allocMessageHandler(MessageHandler *where, int16 id, int (*callback)(ExComm
int getMessageHandlersCount() {
int result;
- MessageHandler *curItem = g_fullpipe->_messageHandlers;
+ MessageHandler *curItem = g_fp->_messageHandlers;
for (result = 0; curItem; result++)
curItem = curItem->nextItem;
@@ -643,7 +804,7 @@ bool addMessageHandlerByIndex(int (*callback)(ExCommand *), int index, int16 id)
return false;
if (index) {
- MessageHandler *curItem = g_fullpipe->_messageHandlers;
+ MessageHandler *curItem = g_fp->_messageHandlers;
for (int i = index - 1; i > 0; i--)
if (curItem)
@@ -661,13 +822,13 @@ bool addMessageHandlerByIndex(int (*callback)(ExCommand *), int index, int16 id)
} else {
MessageHandler *newItem = new MessageHandler;
- newItem->nextItem = g_fullpipe->_messageHandlers;
+ newItem->nextItem = g_fp->_messageHandlers;
newItem->id = id;
newItem->callback = callback;
newItem->index = 0;
- updateMessageHandlerIndex(g_fullpipe->_messageHandlers, 1);
- g_fullpipe->_messageHandlers = newItem;
+ updateMessageHandlerIndex(g_fp->_messageHandlers, 1);
+ g_fp->_messageHandlers = newItem;
return true;
}
@@ -677,7 +838,7 @@ bool insertMessageHandler(int (*callback)(ExCommand *), int index, int16 id) {
if (getMessageHandlerById(id))
return false;
- MessageHandler *curItem = g_fullpipe->_messageHandlers;
+ MessageHandler *curItem = g_fp->_messageHandlers;
for (int i = index; i > 0; i--)
if (curItem)
@@ -694,7 +855,7 @@ void clearMessageHandlers() {
MessageHandler *curItem;
MessageHandler *nextItem;
- curItem = g_fullpipe->_messageHandlers;
+ curItem = g_fp->_messageHandlers;
if (curItem) {
do {
nextItem = curItem->nextItem;
@@ -704,28 +865,79 @@ void clearMessageHandlers() {
curItem = nextItem;
} while (nextItem);
- g_fullpipe->_messageHandlers = 0;
+ g_fp->_messageHandlers = 0;
}
}
void processMessages() {
- if (!g_fullpipe->_isProcessingMessages) {
- g_fullpipe->_isProcessingMessages = true;
+ if (!g_fp->_isProcessingMessages) {
+ g_fp->_isProcessingMessages = true;
- while (g_fullpipe->_exCommandList.size()) {
- ExCommand *ex = g_fullpipe->_exCommandList.front();
- g_fullpipe->_exCommandList.pop_front();
+ while (g_fp->_exCommandList.size()) {
+ ExCommand *ex = g_fp->_exCommandList.front();
+ g_fp->_exCommandList.pop_front();
ex->handleMessage();
}
- g_fullpipe->_isProcessingMessages = false;
+ g_fp->_isProcessingMessages = false;
}
}
void updateGlobalMessageQueue(int id, int objid) {
- MessageQueue *m = g_fullpipe->_globalMessageQueueList->getMessageQueueById(id);
+ MessageQueue *m = g_fp->_globalMessageQueueList->getMessageQueueById(id);
if (m) {
m->update();
}
}
+bool chainQueue(int queueId, int flags) {
+ MessageQueue *mq = g_fp->_currentScene->getMessageQueueById(queueId);
+
+ if (!mq)
+ return false;
+
+ MessageQueue *nmq = new MessageQueue(mq, 0, 0);
+
+ nmq->_flags |= flags;
+
+ if (!nmq->chain(0)) {
+ delete nmq;
+
+ return false;
+ }
+
+ return true;
+}
+
+bool chainObjQueue(StaticANIObject *obj, int queueId, int flags) {
+ MessageQueue *mq = g_fp->_currentScene->getMessageQueueById(queueId);
+
+ if (!mq)
+ return false;
+
+ MessageQueue *nmq = new MessageQueue(mq, 0, 0);
+
+ nmq->_flags |= flags;
+
+ if (!nmq->chain(obj)) {
+ delete nmq;
+
+ return false;
+ }
+
+ return true;
+}
+
+void postExCommand(int parentId, int keyCode, int x, int y, int f20, int f14) {
+ ExCommand *ex = new ExCommand(parentId, 17, 64, 0, 0, 0, 1, 0, 0, 0);
+
+ ex->_keyCode = keyCode;
+ ex->_excFlags |= 3;
+ ex->_x = x;
+ ex->_y = y;
+ ex->_field_20 = f20;
+ ex->_field_14 = f14;
+
+ ex->postMessage();
+}
+
} // End of namespace Fullpipe
diff --git a/engines/fullpipe/messages.h b/engines/fullpipe/messages.h
index 6b72364323..33bb827888 100644
--- a/engines/fullpipe/messages.h
+++ b/engines/fullpipe/messages.h
@@ -57,7 +57,6 @@ class Message : public CObject {
class ExCommand : public Message {
public:
-
int _messageNum;
int _field_3C;
int _excFlags;
@@ -70,27 +69,42 @@ class ExCommand : public Message {
virtual bool load(MfcArchive &file);
+ virtual ExCommand *createClone();
+
bool handleMessage();
void sendMessage();
void postMessage();
void handle();
+
+ void firef34();
+ void setf3c(int val);
};
class ExCommand2 : public ExCommand {
public:
Common::Point **_points;
int _pointsSize;
+
+ ExCommand2(int messageKind, int parentId, Common::Point **points, int pointsSize);
+ ExCommand2(ExCommand2 *src);
+ virtual ~ExCommand2();
+
+ virtual ExCommand2 *createClone();
};
-class ObjstateCommand : public CObject {
+class ObjstateCommand : public ExCommand {
public:
- ExCommand _cmd;
char *_objCommandName;
int _value;
public:
ObjstateCommand();
+ ObjstateCommand(ObjstateCommand *src);
+ virtual ~ObjstateCommand();
+
virtual bool load(MfcArchive &file);
+
+ virtual ObjstateCommand *createClone();
};
class MessageQueue : public CObject {
@@ -100,15 +114,18 @@ class MessageQueue : public CObject {
char *_queueName;
int16 _dataId;
CObject *_field_14;
- Common::List<ExCommand *> _exCommands;
int _counter;
int _field_38;
int _isFinished;
int _parId;
int _flag1;
+ private:
+ Common::List<ExCommand *> _exCommands;
+
public:
MessageQueue();
+ MessageQueue(int dataId);
MessageQueue(MessageQueue *src, int parId, int field_38);
virtual ~MessageQueue();
@@ -119,7 +136,13 @@ class MessageQueue : public CObject {
uint getCount() { return _exCommands.size(); }
+ void addExCommand(ExCommand *ex);
+ void addExCommandToEnd(ExCommand *ex);
+ void insertExCommandAt(int pos, ExCommand *ex);
ExCommand *getExCommandByIndex(uint idx);
+ void deleteExCommandByIndex(uint idx, bool doFree);
+
+ void transferExCommands(MessageQueue *mq);
void replaceKeyCode(int key1, int key2);
@@ -167,8 +190,13 @@ bool insertMessageHandler(int (*callback)(ExCommand *), int index, int16 id);
void clearMessageHandlers();
void processMessages();
void updateGlobalMessageQueue(int id, int objid);
+void clearMessages();
void clearGlobalMessageQueueList1();
+bool chainQueue(int queueId, int flags);
+bool chainObjQueue(StaticANIObject *obj, int queueId, int flags);
+void postExCommand(int parentId, int keyCode, int x, int y, int f20, int f16);
+
} // End of namespace Fullpipe
#endif /* FULLPIPE_MESSAGEQUEUE_H */
diff --git a/engines/fullpipe/modal.cpp b/engines/fullpipe/modal.cpp
index 26048ced13..f52dc95a7c 100644
--- a/engines/fullpipe/modal.cpp
+++ b/engines/fullpipe/modal.cpp
@@ -24,48 +24,39 @@
#include "fullpipe/modal.h"
#include "fullpipe/messages.h"
#include "fullpipe/constants.h"
+#include "fullpipe/motion.h"
#include "fullpipe/scenes.h"
+#include "fullpipe/gameloader.h"
-namespace Fullpipe {
-
-bool BaseModalObject::handleMessage(ExCommand *message) {
- warning("STUB: BaseModalObject::handleMessage()");
-
- return true;
-}
-
-bool BaseModalObject::init(int counterdiff) {
- warning("STUB: BaseModalObject::init(%d)", counterdiff);
-
- return true;
-}
-
-bool BaseModalObject::update() {
- warning("STUB: BaseModalObject::update()");
-
- return true;
-}
+#include "fullpipe/constants.h"
-void BaseModalObject::saveload() {
- warning("STUB: BaseModalObject::saveload()");
-}
+#include "graphics/palette.h"
+#include "video/avi_decoder.h"
+namespace Fullpipe {
ModalIntro::ModalIntro() {
_field_8 = 0;
_countDown = 0;
- _needRedraw = 0;
+ _stillRunning = 0;
+
if (g_vars->sceneIntro_skipIntro) {
_introFlags = 4;
} else {
_introFlags = 33;
_countDown = 150;
- PictureObject *pict = g_fullpipe->accessScene(SC_INTRO1)->getPictureObjectById(PIC_IN1_PIPETITLE, 0);
+ PictureObject *pict = g_fp->accessScene(SC_INTRO1)->getPictureObjectById(PIC_IN1_PIPETITLE, 0);
pict->setFlags(pict->_flags & 0xFFFB);
}
+
g_vars->sceneIntro_skipIntro = false;
- _sfxVolume = g_fullpipe->_sfxVolume;
+ _sfxVolume = g_fp->_sfxVolume;
+}
+
+ModalIntro::~ModalIntro() {
+ g_fp->stopAllSounds();
+ g_fp->_sfxVolume = _sfxVolume;
}
bool ModalIntro::handleMessage(ExCommand *message) {
@@ -78,7 +69,7 @@ bool ModalIntro::handleMessage(ExCommand *message) {
if (message->_keyCode != 13 && message->_keyCode != 27 && message->_keyCode != 32)
return false;
- if (_needRedraw) {
+ if (_stillRunning) {
if (!(_introFlags & 0x10)) {
_countDown = 0;
g_vars->sceneIntro_needBlackout = true;
@@ -91,8 +82,677 @@ bool ModalIntro::handleMessage(ExCommand *message) {
return true;
}
+bool ModalIntro::init(int counterdiff) {
+ if (!g_vars->sceneIntro_playing) {
+ if (!_stillRunning) {
+ finish();
+ return false;
+ }
+
+ if (_introFlags & 0x10)
+ g_fp->_gameLoader->updateSystems(42);
+
+ _introFlags |= 2;
+
+ return true;
+ }
+
+ if (_introFlags & 4) {
+ ModalVideoPlayer *player = new ModalVideoPlayer();
+
+ g_fp->_modalObject = player;
+ player->_parentObj = this;
+ player->play("intro.avi");
+
+ _countDown--;
+
+ if (_countDown > 0 )
+ return true;
+
+ if (_stillRunning <= 0) {
+ _countDown = 0;
+ _stillRunning = 0;
+ _introFlags = (_introFlags & 0xfb) | 0x40;
+
+ return true;
+ }
+
+ _introFlags |= 2;
+ return true;
+ }
+
+ if (_introFlags & 0x40) {
+ ModalVideoPlayer *player = new ModalVideoPlayer();
+
+ g_fp->_modalObject = player;
+ player->_parentObj = this;
+ player->play("intro2.avi");
+
+ _countDown--;
+ if (_countDown > 0)
+ return true;
+
+ if (_stillRunning <= 0) {
+ _countDown = 50;
+ _stillRunning = 0;
+ _introFlags = (_introFlags & 0xbf) | 9;
+
+ return true;
+ }
+
+ _introFlags |= 2;
+ return true;
+ }
+
+ if (_introFlags & 8) {
+ _countDown--;
+
+ if (_countDown > 0 )
+ return true;
+
+ if (_stillRunning > 0) {
+ _introFlags |= 2;
+ return true;
+ }
+
+ _countDown = 150;
+ _introFlags = (_introFlags & 0xf7) | 0x21;
+ g_fp->accessScene(SC_INTRO1)->getPictureObjectById(PIC_IN1_PIPETITLE, 0)->_flags &= 0xfffb;
+ }
+
+ if (!(_introFlags & 0x20)) {
+ if (_introFlags & 0x10) {
+ if (!_stillRunning) {
+ _introFlags |= 1;
+
+ g_fp->accessScene(SC_INTRO1)->getPictureObjectById(PIC_IN1_PIPETITLE, 0)->_flags &= 0xfffb;
+ g_fp->accessScene(SC_INTRO1)->getPictureObjectById(PIC_IN1_GAMETITLE, 0)->_flags &= 0xfffb;
+
+ chainQueue(QU_INTR_STARTINTRO, 1);
+ }
+ g_fp->_gameLoader->updateSystems(42);
+ }
+ return true;
+ }
+
+ _countDown--;
+
+ if (_countDown <= 0) {
+ if (_stillRunning > 0) {
+ _introFlags |= 2;
+
+ return true;
+ }
+
+ _introFlags = (_introFlags & 0xdf) | 0x10;
+
+ g_fp->accessScene(SC_INTRO1)->getPictureObjectById(PIC_IN1_GAMETITLE, 0)->_flags &= 0xfffb;
+
+ _stillRunning = 0;
+ }
+
+ return true;
+}
+
+void ModalIntro::update() {
+ warning("STUB: ModalIntro::update()");
+
+ if (g_fp->_currentScene) {
+ if (_introFlags & 1) {
+ //sceneFade(virt, g_currentScene, 1);
+ _stillRunning = 255;
+ _introFlags &= 0xfe;
+
+ if (_introFlags & 0x20)
+ g_fp->playSound(SND_INTR_019, 0);
+ } else if (_introFlags & 2) {
+ if (g_vars->sceneIntro_needBlackout) {
+ //vrtRectangle(*(_DWORD *)virt, 0, 0, 0, 800, 600);
+ g_vars->sceneIntro_needBlackout = 0;
+ _stillRunning = 0;
+ _introFlags &= 0xfd;
+ } else {
+ //sceneFade(virt, g_currentScene, 0);
+ _stillRunning = 0;
+ _introFlags &= 0xfd;
+ }
+ } else if (_stillRunning) {
+ g_fp->_currentScene->draw();
+ }
+ }
+}
+
+void ModalIntro::finish() {
+ g_fp->_gameLoader->unloadScene(SC_INTRO2);
+ g_fp->_currentScene = g_fp->accessScene(SC_INTRO1);
+ g_fp->_gameLoader->preloadScene(SC_INTRO1, TrubaDown);
+
+ if (g_fp->_currentScene)
+ g_fp->_gameLoader->updateSystems(42);
+}
+
+void ModalVideoPlayer::play(const char *filename) {
+ // TODO: Videos are encoded using Intel Indeo 5 (IV50), which isn't supported yet
+
+ Video::AVIDecoder *aviDecoder = new Video::AVIDecoder();
+
+ if (!aviDecoder->loadFile(filename))
+ return;
+
+ uint16 x = (g_system->getWidth() - aviDecoder->getWidth()) / 2;
+ uint16 y = (g_system->getHeight() - aviDecoder->getHeight()) / 2;
+ bool skipVideo = false;
+
+ aviDecoder->start();
+
+ while (!g_fp->shouldQuit() && !aviDecoder->endOfVideo() && !skipVideo) {
+ if (aviDecoder->needsUpdate()) {
+ const Graphics::Surface *frame = aviDecoder->decodeNextFrame();
+ if (frame) {
+ g_fp->_system->copyRectToScreen(frame->getPixels(), frame->pitch, x, y, frame->w, frame->h);
+
+ if (aviDecoder->hasDirtyPalette())
+ g_fp->_system->getPaletteManager()->setPalette(aviDecoder->getPalette(), 0, 256);
+
+ g_fp->_system->updateScreen();
+ }
+ }
+
+ Common::Event event;
+ while (g_fp->_system->getEventManager()->pollEvent(event)) {
+ if ((event.type == Common::EVENT_KEYDOWN && (event.kbd.keycode == Common::KEYCODE_ESCAPE ||
+ event.kbd.keycode == Common::KEYCODE_RETURN ||
+ event.kbd.keycode == Common::KEYCODE_SPACE))
+ || event.type == Common::EVENT_LBUTTONUP)
+ skipVideo = true;
+ }
+
+ g_fp->_system->delayMillis(aviDecoder->getTimeToNextFrame());
+ }
+}
+
+ModalMap::ModalMap() {
+ _mapScene = 0;
+ _pic = 0;
+ _isRunning = false;
+ _rect1 = g_fp->_sceneRect;
+ _x = g_fp->_currentScene->_x;
+ _y = g_fp->_currentScene->_y;
+ _flag = 0;
+ _mouseX = 0;
+ _mouseY = 0;
+ _field_38 = 0;
+ _field_3C = 0;
+ _field_40 = 12;
+ _rect2.top = 0;
+ _rect2.left = 0;
+ _rect2.bottom = 600;
+ _rect2.right = 800;
+}
+
+ModalMap::~ModalMap() {
+ g_fp->_gameLoader->unloadScene(SC_MAP);
+
+ g_fp->_sceneRect = _rect1;
+
+ g_fp->_currentScene->_x = _x;
+ g_fp->_currentScene->_y = _y;
+}
+
+bool ModalMap::init(int counterdiff) {
+ g_fp->setCursor(PIC_CSR_ITN);
+
+ if (_flag) {
+ _rect2.left = _mouseX + _field_38 - g_fp->_mouseScreenPos.x;
+ _rect2.top = _mouseY + _field_3C - g_fp->_mouseScreenPos.y;;
+ _rect2.right = _rect2.left + 800;
+ _rect2.bottom = _rect2.top + 600;
+
+ g_fp->_sceneRect =_rect2;
+
+ _mapScene->updateScrolling2();
+
+ _rect2 = g_fp->_sceneRect;
+ }
+
+ _field_40--;
+
+ if (_field_40 <= 0) {
+ _field_40 = 12;
+
+ if (_pic)
+ _pic->_flags ^= 4;
+ }
+
+ return _isRunning;
+}
+
+void ModalMap::update() {
+ g_fp->_sceneRect = _rect2;
+
+ _mapScene->draw();
+
+ g_fp->drawArcadeOverlay(1);
+}
+
+bool ModalMap::handleMessage(ExCommand *cmd) {
+ if (cmd->_messageKind != 17)
+ return false;
+
+ switch (cmd->_messageNum) {
+ case 29:
+ _flag = 1;
+ _mouseX = g_fp->_mouseScreenPos.x;
+ _mouseY = g_fp->_mouseScreenPos.x;
+
+ _field_3C = _rect2.top;
+ _field_38 = _rect2.left;
+
+ break;
+
+ case 30:
+ _flag = 0;
+ break;
+
+ case 36:
+ if (cmd->_keyCode != 9 && cmd->_keyCode != 27 )
+ return false;
+
+ break;
+
+ case 107:
+ break;
+
+ default:
+ return false;
+ }
+
+ _isRunning = 0;
+
+ return true;
+}
+
+void ModalMap::initMap() {
+ _isRunning = 1;
+
+ _mapScene = g_fp->accessScene(SC_MAP);
+
+ if (!_mapScene)
+ error("ModalMap::initMap(): error accessing scene SC_MAP");
+
+ PictureObject *pic;
+
+ for (int i = 0; i < 200; i++) {
+ if (!(g_fp->_mapTable[i] >> 16))
+ break;
+
+ pic = _mapScene->getPictureObjectById(g_fp->_mapTable[i] >> 16, 0);
+
+ if ((g_fp->_mapTable[i] & 0xffff) == 1)
+ pic->_flags |= 4;
+ else
+ pic->_flags &= 0xfffb;
+ }
+
+ pic = getScenePicture();
+
+ Common::Point point;
+ Common::Point point2;
+
+ if (pic) {
+ pic->getDimensions(&point);
+
+ _rect2.left = point.x / 2 + pic->_ox - 400;
+ _rect2.top = point.y / 2 + pic->_oy - 300;
+ _rect2.right = _rect2.left + 800;
+ _rect2.bottom = _rect2.top + 600;
+
+ _mapScene->updateScrolling2();
+
+ _pic = _mapScene->getPictureObjectById(PIC_MAP_I02, 0);
+ _pic->getDimensions(&point2);
+
+ _pic->setOXY(pic->_ox + point.x / 2 - point2.x / 2, point.y - point2.y / 2 + pic->_oy - 24);
+ _pic->_flags |= 4;
+
+ _pic = _mapScene->getPictureObjectById(PIC_MAP_I01, 0);
+ _pic->getDimensions(&point2);
+
+ _pic->setOXY(pic->_ox + point.x / 2 - point2.x / 2, point.y - point2.y / 2 + pic->_oy - 25);
+ _pic->_flags |= 4;
+ }
+
+ g_fp->setArcadeOverlay(PIC_CSR_MAP);
+}
+
+PictureObject *ModalMap::getScenePicture() {
+ int picId = 0;
+
+ switch (g_fp->_currentScene->_sceneId) {
+ case SC_1:
+ picId = PIC_MAP_S01;
+ break;
+ case SC_2:
+ picId = PIC_MAP_S02;
+ break;
+ case SC_3:
+ picId = PIC_MAP_S03;
+ break;
+ case SC_4:
+ picId = PIC_MAP_S04;
+ break;
+ case SC_5:
+ picId = PIC_MAP_S05;
+ break;
+ case SC_6:
+ picId = PIC_MAP_S06;
+ break;
+ case SC_7:
+ picId = PIC_MAP_S07;
+ break;
+ case SC_8:
+ picId = PIC_MAP_S08;
+ break;
+ case SC_9:
+ picId = PIC_MAP_S09;
+ break;
+ case SC_10:
+ picId = PIC_MAP_S10;
+ break;
+ case SC_11:
+ picId = PIC_MAP_S11;
+ break;
+ case SC_12:
+ picId = PIC_MAP_S12;
+ break;
+ case SC_13:
+ picId = PIC_MAP_S13;
+ break;
+ case SC_14:
+ picId = PIC_MAP_S14;
+ break;
+ case SC_15:
+ picId = PIC_MAP_S15;
+ break;
+ case SC_16:
+ picId = PIC_MAP_S16;
+ break;
+ case SC_17:
+ picId = PIC_MAP_S17;
+ break;
+ case SC_18:
+ case SC_19:
+ picId = PIC_MAP_S1819;
+ break;
+ case SC_20:
+ picId = PIC_MAP_S20;
+ break;
+ case SC_21:
+ picId = PIC_MAP_S21;
+ break;
+ case SC_22:
+ picId = PIC_MAP_S22;
+ break;
+ case SC_23:
+ picId = PIC_MAP_S23_1;
+ break;
+ case SC_24:
+ picId = PIC_MAP_S24;
+ break;
+ case SC_25:
+ picId = PIC_MAP_S25;
+ break;
+ case SC_26:
+ picId = PIC_MAP_S26;
+ break;
+ case SC_27:
+ picId = PIC_MAP_S27;
+ break;
+ case SC_28:
+ picId = PIC_MAP_S28;
+ break;
+ case SC_29:
+ picId = PIC_MAP_S29;
+ break;
+ case SC_30:
+ picId = PIC_MAP_S30;
+ break;
+ case SC_31:
+ picId = PIC_MAP_S31_1;
+ break;
+ case SC_32:
+ picId = PIC_MAP_S32_1;
+ break;
+ case SC_33:
+ picId = PIC_MAP_S33;
+ break;
+ case SC_34:
+ picId = PIC_MAP_S34;
+ break;
+ case SC_35:
+ picId = PIC_MAP_S35;
+ break;
+ case SC_36:
+ picId = PIC_MAP_S36;
+ break;
+ case SC_37:
+ picId = PIC_MAP_S37;
+ break;
+ case SC_38:
+ picId = PIC_MAP_S38;
+ break;
+ case SC_FINAL1:
+ picId = PIC_MAP_S38;
+ break;
+ }
+
+ if (picId)
+ return _mapScene->getPictureObjectById(picId, 0);
+
+ error("ModalMap::getScenePicture(): Unknown scene id: %d", g_fp->_currentScene->_sceneId);
+}
+
void FullpipeEngine::openMap() {
- warning("STUB: FullpipeEngine::openMap()");
+ if (!_modalObject) {
+ ModalMap *map = new ModalMap;
+
+ _modalObject = map;
+
+ map->initMap();
+ }
+}
+
+ModalFinal::ModalFinal() {
+ _flags = 0;
+ _counter = 255;
+ _sfxVolume = g_fp->_sfxVolume;
+}
+
+ModalFinal::~ModalFinal() {
+ if (g_vars->sceneFinal_var01) {
+ g_fp->_gameLoader->unloadScene(SC_FINAL2);
+ g_fp->_gameLoader->unloadScene(SC_FINAL3);
+ g_fp->_gameLoader->unloadScene(SC_FINAL4);
+
+ g_fp->_currentScene = g_fp->accessScene(SC_FINAL1);
+
+ g_fp->stopAllSounds();
+
+ g_vars->sceneFinal_var01 = 0;
+ }
+
+ g_fp->_sfxVolume = _sfxVolume;
+}
+
+bool ModalFinal::init(int counterdiff) {
+ if (g_vars->sceneFinal_var01) {
+ g_fp->_gameLoader->updateSystems(42);
+
+ return true;
+ }
+
+ if (_counter > 0) {
+ _flags |= 2u;
+
+ g_fp->_gameLoader->updateSystems(42);
+
+ return true;
+ }
+
+ unloadScenes();
+
+ g_fp->_modalObject = new ModalCredits();
+
+ return true;
+}
+
+void ModalFinal::unloadScenes() {
+ g_fp->_gameLoader->unloadScene(SC_FINAL2);
+ g_fp->_gameLoader->unloadScene(SC_FINAL3);
+ g_fp->_gameLoader->unloadScene(SC_FINAL4);
+
+ g_fp->_currentScene = g_fp->accessScene(SC_FINAL1);
+
+ g_fp->stopAllSounds();
+}
+
+bool ModalFinal::handleMessage(ExCommand *cmd) {
+ if (cmd->_messageKind == 17 && cmd->_messageNum == 36 && cmd->_keyCode == 27) {
+ g_fp->_modalObject = new ModalMainMenu();
+ g_fp->_modalObject->_parentObj = this;
+
+ return true;
+ }
+
+ return false;
+}
+
+void ModalFinal::update() {
+ if (g_fp->_currentScene) {
+ g_fp->_currentScene->draw();
+
+ if (_flags & 1) {
+ g_fp->drawAlphaRectangle(0, 0, 800, 600, 0xff - _counter);
+
+ _counter += 10;
+
+ if (_counter >= 255) {
+ _counter = 255;
+ _flags &= 0xfe;
+ }
+ } else {
+ if (!(_flags & 2))
+ return;
+
+ g_fp->drawAlphaRectangle(0, 0, 800, 600, 0xff - _counter);
+ _counter -= 10;
+
+ if (_counter <= 0) {
+ _counter = 0;
+ _flags &= 0xFD;
+ }
+ }
+
+ g_fp->_sfxVolume = _counter * (_sfxVolume + 3000) / 255 - 3000;
+
+ g_fp->updateSoundVolume();
+ }
+}
+
+ModalCredits::ModalCredits() {
+ Common::Point point;
+
+ _sceneTitles = g_fp->accessScene(SC_TITLES);
+
+ _creditsPic = _sceneTitles->getPictureObjectById(PIC_TTL_CREDITS, 0);
+ _creditsPic->_flags |= 4;
+
+ _fadeIn = true;
+ _fadeOut = false;
+
+ _creditsPic->getDimensions(&point);
+
+ _countdown = point.y / 2 + 470;
+ _sfxVolume = g_fp->_sfxVolume;
+
+ _currY = 630;
+ _maxY = -1000 - point.y;
+
+ _currX = 400 - point.x / 2;
+
+ _creditsPic->setOXY(_currX, _currY);
+}
+
+ModalCredits::~ModalCredits() {
+ g_fp->_gameLoader->unloadScene(SC_TITLES);
+
+ g_fp->_sfxVolume = _sfxVolume;
+}
+
+bool ModalCredits::handleMessage(ExCommand *cmd) {
+ if (cmd->_messageKind == 17 && cmd->_messageNum == 36 && cmd->_keyCode == 27) {
+ _fadeIn = false;
+
+ return true;
+ }
+
+ return false;
+}
+
+bool ModalCredits::init(int counterdiff) {
+ if (_fadeIn || _fadeOut) {
+ _countdown--;
+
+ if (_countdown < 0)
+ _fadeIn = false;
+
+ _creditsPic->setOXY(_currX, _currY);
+
+ if (_currY > _maxY)
+ _currY -= 2;
+ } else {
+ if (_parentObj)
+ return 0;
+
+ ModalMainMenu *menu = new ModalMainMenu;
+
+ g_fp->_modalObject = menu;
+
+ menu->_field_34 = 1;
+ }
+
+ return true;
+}
+
+void ModalCredits::update() {
+ warning("STUB: ModalCredits::update()");
+
+ if (_fadeOut) {
+ if (_fadeIn) {
+ _sceneTitles->draw();
+
+ return;
+ }
+ } else if (_fadeIn) {
+ //sceneFade(virt, this->_sceneTitles, 1); // TODO
+ _fadeOut = 1;
+
+ return;
+ }
+
+ if (_fadeOut) {
+ //sceneFade(virt, this->_sceneTitles, 0); // TODO
+ _fadeOut = 0;
+ return;
+ }
+
+ _sceneTitles->draw();
+}
+
+ModalMainMenu::ModalMainMenu() {
+ warning("STUB: ModalMainMenu::ModalMainMenu()");
+
+ _field_34 = 0;
}
void FullpipeEngine::openHelp() {
@@ -100,7 +760,11 @@ void FullpipeEngine::openHelp() {
}
void FullpipeEngine::openMainMenu() {
- warning("STUB: FullpipeEngine::openMainMenu()");
+ ModalMainMenu *menu = new ModalMainMenu;
+
+ menu->_parentObj = g_fp->_modalObject;
+
+ g_fp->_modalObject = menu;
}
} // End of namespace Fullpipe
diff --git a/engines/fullpipe/modal.h b/engines/fullpipe/modal.h
index 7d98427e20..438e341c1c 100644
--- a/engines/fullpipe/modal.h
+++ b/engines/fullpipe/modal.h
@@ -25,6 +25,8 @@
namespace Fullpipe {
+class PictureObject;
+
class BaseModalObject {
public:
@@ -34,26 +36,132 @@ class BaseModalObject {
BaseModalObject() : _parentObj(0) {}
virtual ~BaseModalObject() {}
- virtual bool handleMessage(ExCommand *message);
- virtual bool init(int counterdiff);
- virtual bool update();
- void saveload();
+ virtual bool pollEvent() = 0;
+ virtual bool handleMessage(ExCommand *message) = 0;
+ virtual bool init(int counterdiff) = 0;
+ virtual void update() = 0;
+
+ virtual void saveload() = 0;
};
class ModalIntro : public BaseModalObject {
int _field_8;
int _introFlags;
int _countDown;
- int _needRedraw;
+ int _stillRunning;
int _sfxVolume;
public:
ModalIntro();
+ virtual ~ModalIntro();
+
+ virtual bool pollEvent() { return true; }
+ virtual bool handleMessage(ExCommand *message);
+ virtual bool init(int counterdiff);
+ virtual void update();
+ virtual void saveload() {}
+
+ void finish();
+};
+
+class ModalVideoPlayer : public BaseModalObject {
+public:
+
+ virtual bool pollEvent() { return true; }
+ virtual bool handleMessage(ExCommand *message) { return true; }
+ virtual bool init(int counterdiff) { return false; }
+ virtual void update() {}
+ virtual void saveload() {}
+
+ void play(const char *fname);
+};
+
+class ModalMap : public BaseModalObject {
+ Scene *_mapScene;
+ PictureObject *_pic;
+ bool _isRunning;
+ Common::Rect _rect1;
+ int _x;
+ int _y;
+ int _flag;
+ int _mouseX;
+ int _mouseY;
+ int _field_38;
+ int _field_3C;
+ int _field_40;
+ Common::Rect _rect2;
+
+ public:
+ ModalMap();
+ virtual ~ModalMap();
+
+ virtual bool pollEvent() { return true; }
+ virtual bool handleMessage(ExCommand *message);
+ virtual bool init(int counterdiff);
+ virtual void update();
+ virtual void saveload() {}
+
+ void initMap();
+ PictureObject *getScenePicture();
+};
+
+class ModalFinal : public BaseModalObject {
+ int _flags;
+ int _counter;
+ int _sfxVolume;
+
+ public:
+ ModalFinal();
+ virtual ~ModalFinal();
+
+ virtual bool pollEvent() { return true; }
+ virtual bool handleMessage(ExCommand *message);
+ virtual bool init(int counterdiff);
+ virtual void update();
+ virtual void saveload() {}
+
+ void unloadScenes();
+};
+class ModalCredits : public BaseModalObject {
+ Scene *_sceneTitles;
+ PictureObject *_creditsPic;
+ bool _fadeIn;
+ bool _fadeOut;
+ int _countdown;
+ int _sfxVolume;
+ int _currX;
+ int _currY;
+ int _maxY;
+
+ public:
+ ModalCredits();
+ virtual ~ModalCredits();
+
+ virtual bool pollEvent() { return true; }
virtual bool handleMessage(ExCommand *message);
+ virtual bool init(int counterdiff);
+ virtual void update();
+ virtual void saveload() {}
};
+class ModalMainMenu : public BaseModalObject {
+public:
+ int _field_34;
+
+public:
+ ModalMainMenu();
+ virtual ~ModalMainMenu() {}
+
+ virtual bool pollEvent() { return true; }
+ virtual bool handleMessage(ExCommand *message) { return false; }
+ virtual bool init(int counterdiff) { return true; }
+ virtual void update() {}
+ virtual void saveload() {}
+};
+
+
} // End of namespace Fullpipe
#endif /* FULLPIPE_MODAL_H */
diff --git a/engines/fullpipe/module.mk b/engines/fullpipe/module.mk
index 380f582c08..f6a94de421 100644
--- a/engines/fullpipe/module.mk
+++ b/engines/fullpipe/module.mk
@@ -2,7 +2,9 @@ MODULE := engines/fullpipe
MODULE_OBJS = \
behavior.o \
+ console.o \
detection.o \
+ floaters.o \
fullpipe.o \
gameloader.o \
gfx.o \
@@ -11,6 +13,7 @@ MODULE_OBJS = \
interaction.o \
inventory.o \
lift.o \
+ messagehandlers.o \
messages.o \
modal.o \
motion.o \
@@ -20,7 +23,44 @@ MODULE_OBJS = \
sound.o \
stateloader.o \
statics.o \
- utils.o
+ utils.o \
+ scenes/sceneIntro.o \
+ scenes/scene01.o \
+ scenes/scene02.o \
+ scenes/scene03.o \
+ scenes/scene04.o \
+ scenes/scene05.o \
+ scenes/scene06.o \
+ scenes/scene07.o \
+ scenes/scene08.o \
+ scenes/scene10.o \
+ scenes/scene11.o \
+ scenes/scene12.o \
+ scenes/scene13.o \
+ scenes/scene14.o \
+ scenes/scene15.o \
+ scenes/scene16.o \
+ scenes/scene17.o \
+ scenes/scene18and19.o \
+ scenes/scene20.o \
+ scenes/scene21.o \
+ scenes/scene22.o \
+ scenes/scene23.o \
+ scenes/scene24.o \
+ scenes/scene25.o \
+ scenes/scene26.o \
+ scenes/scene28.o \
+ scenes/scene30.o \
+ scenes/scene31.o \
+ scenes/scene32.o \
+ scenes/scene33.o \
+ scenes/scene34.o \
+ scenes/scene35.o \
+ scenes/scene36.o \
+ scenes/scene37.o \
+ scenes/scene38.o \
+ scenes/sceneFinal.o \
+ scenes/sceneDbg.o
# This module can be built as a plugin
ifeq ($(ENABLE_FULLPIPE), DYNAMIC_PLUGIN)
diff --git a/engines/fullpipe/motion.cpp b/engines/fullpipe/motion.cpp
index b63267c572..f0318581f1 100644
--- a/engines/fullpipe/motion.cpp
+++ b/engines/fullpipe/motion.cpp
@@ -27,9 +27,10 @@
#include "common/list.h"
#include "fullpipe/objects.h"
+#include "fullpipe/statics.h"
+#include "fullpipe/gameloader.h"
#include "fullpipe/motion.h"
#include "fullpipe/messages.h"
-#include "fullpipe/gameloader.h"
namespace Fullpipe {
@@ -41,6 +42,48 @@ bool MotionController::load(MfcArchive &file) {
return true;
}
+void MotionController::enableLinks(const char *linkName, bool enable) {
+ warning("STUB: MotionController::enableLinks()");
+}
+
+MovGraphLink *MotionController::getLinkByName(const char *name) {
+ if (_objtype == kObjTypeMctlCompound) {
+ MctlCompound *obj = (MctlCompound *)this;
+
+ for (uint i = 0; i < obj->getMotionControllerCount(); i++) {
+ MotionController *con = obj->getMotionController(i);
+
+ if (con->_objtype == kObjTypeMovGraph) {
+ MovGraph *gr = (MovGraph *)con;
+
+ for (ObList::iterator l = gr->_links.begin(); l != gr->_links.end(); ++l) {
+ assert(((CObject *)*l)->_objtype == kObjTypeMovGraphLink);
+
+ MovGraphLink *lnk = (MovGraphLink *)*l;
+
+ if (!strcmp(lnk->_name, name))
+ return lnk;
+ }
+ }
+ }
+ }
+
+ if (_objtype == kObjTypeMovGraph) {
+ MovGraph *gr = (MovGraph *)this;
+
+ for (ObList::iterator l = gr->_links.begin(); l != gr->_links.end(); ++l) {
+ assert(((CObject *)*l)->_objtype == kObjTypeMovGraphLink);
+
+ MovGraphLink *lnk = (MovGraphLink *)*l;
+
+ if (!strcmp(lnk->_name, name))
+ return lnk;
+ }
+ }
+
+ return 0;
+}
+
bool MctlCompound::load(MfcArchive &file) {
debug(5, "MctlCompound::load()");
@@ -50,7 +93,9 @@ bool MctlCompound::load(MfcArchive &file) {
for (int i = 0; i < count; i++) {
debug(6, "CompoundArray[%d]", i);
- MctlCompoundArrayItem *obj = (MctlCompoundArrayItem *)file.readClass();
+ MctlCompoundArrayItem *obj = new MctlCompoundArrayItem();
+
+ obj->_motionControllerObj = (MotionController *)file.readClass();
int count1 = file.readUint32LE();
@@ -59,7 +104,7 @@ bool MctlCompound::load(MfcArchive &file) {
debug(6, "ConnectionPoint[%d]", j);
MctlConnectionPoint *obj1 = (MctlConnectionPoint *)file.readClass();
- obj->_connectionPoints.push_back(*obj1);
+ obj->_connectionPoints.push_back(obj1);
}
obj->_field_20 = file.readUint32LE();
@@ -68,16 +113,15 @@ bool MctlCompound::load(MfcArchive &file) {
debug(6, "graphReact");
obj->_movGraphReactObj = (MovGraphReact *)file.readClass();
- _motionControllers.push_back(*obj);
+ _motionControllers.push_back(obj);
}
return true;
}
-int MctlCompound::addObject(StaticANIObject *obj) {
- warning("STUB: MctlCompound::addObject()");
-
- return 0;
+void MctlCompound::addObject(StaticANIObject *obj) {
+ for (uint i = 0; i < _motionControllers.size(); i++)
+ _motionControllers[i]->_motionControllerObj->addObject(obj);
}
int MctlCompound::removeObject(StaticANIObject *obj) {
@@ -87,7 +131,6 @@ int MctlCompound::removeObject(StaticANIObject *obj) {
}
void MctlCompound::initMovGraph2() {
-#if 0
if (_objtype != kObjTypeMctlCompound)
return;
@@ -97,10 +140,10 @@ void MctlCompound::initMovGraph2() {
MovGraph *gr = (MovGraph *)_motionControllers[i]->_motionControllerObj;
- CMovGraph2 *newgr = new MovGraph2();
+ MovGraph2 *newgr = new MovGraph2();
- newgr->_links.push_back(gr->_links);
- newgr->_nodes.push_back(gr->_nodes);
+ newgr->_links = gr->_links;
+ newgr->_nodes = gr->_nodes;
gr->_links.clear();
gr->_nodes.clear();
@@ -109,25 +152,270 @@ void MctlCompound::initMovGraph2() {
_motionControllers[i]->_motionControllerObj = newgr;
}
-#endif
}
void MctlCompound::freeItems() {
- warning("STUB: MctlCompound::freeItems()");
+ for (uint i = 0; i < _motionControllers.size(); i++)
+ _motionControllers[i]->_motionControllerObj->freeItems();
}
-MessageQueue *MctlCompound::method34(StaticANIObject *subj, int xpos, int ypos, int flag, int staticsId) {
+MessageQueue *MctlCompound::method34(StaticANIObject *subj, int xpos, int ypos, int fuzzyMatch, int staticsId) {
warning("STUB: MctlCompound::method34()");
return 0;
}
-MessageQueue *MctlCompound::method4C(StaticANIObject *subj, int xpos, int ypos, int flag, int staticsId) {
- warning("STUB: MctlCompound::method4C()");
+MessageQueue *MctlCompound::doWalkTo(StaticANIObject *subj, int xpos, int ypos, int fuzzyMatch, int staticsId) {
+ int match1 = -1;
+ int match2 = -1;
+
+ if (!subj)
+ return 0;
+
+ for (uint i = 0; i < _motionControllers.size(); i++) {
+ if (_motionControllers[i]->_movGraphReactObj) {
+ if (_motionControllers[i]->_movGraphReactObj->pointInRegion(subj->_ox, subj->_oy)) {
+ match1 = i;
+ break;
+ }
+ }
+ }
+
+ if (match1 == -1)
+ return 0;
+
+ for (uint i = 0; i < _motionControllers.size(); i++) {
+ if (_motionControllers[i]->_movGraphReactObj) {
+ if (_motionControllers[i]->_movGraphReactObj->pointInRegion(xpos, ypos)) {
+ match2 = i;
+ break;
+ }
+ }
+ }
+
+ if (match2 == -1)
+ return 0;
+
+ if (match1 == match2)
+ return _motionControllers[match1]->_motionControllerObj->doWalkTo(subj, xpos, ypos, fuzzyMatch, staticsId);
+
+ MctlConnectionPoint *closestP = findClosestConnectionPoint(subj->_ox, subj->_oy, match1, xpos, ypos, match2, &match2);
+
+ if (!closestP)
+ return 0;
+
+ MessageQueue *mq = _motionControllers[match1]->_motionControllerObj->doWalkTo(subj, closestP->_connectionX, closestP->_connectionY, 1, closestP->_field_14);
+
+ ExCommand *ex;
+
+ if (mq) {
+ for (uint i = 0; i < closestP->_messageQueueObj->getCount(); i++) {
+ ex = closestP->_messageQueueObj->getExCommandByIndex(i)->createClone();
+ ex->_excFlags |= 2;
+ mq->addExCommandToEnd(ex);
+ }
+
+ ex = new ExCommand(subj->_id, 51, 0, xpos, ypos, 0, 1, 0, 0, 0);
+
+ ex->_field_20 = fuzzyMatch;
+ ex->_keyCode = subj->_okeyCode;
+ ex->_excFlags |= 2;
+
+ mq->addExCommandToEnd(ex);
+ }
+
+ return mq;
+}
+
+MctlCompoundArrayItem::~MctlCompoundArrayItem() {
+ delete _movGraphReactObj;
+ delete _motionControllerObj;
+}
+
+MctlLadder::MctlLadder() {
+ _width = 0;
+ _ladderX = 0;
+ _height = 0;
+ _ladderY = 0;
+ _ladder_field_14 = 0;
+
+ _ladder_field_20 = 0;
+ _ladder_field_24 = 0;
+}
+
+MctlLadder::~MctlLadder() {
+ freeItems();
+}
+
+int MctlLadder::collisionDetection(StaticANIObject *man) {
+ if (findObjectPos(man) < 0)
+ return 0;
+
+ double delta;
+
+ if ((double)(man->_oy - _ladderY) / (double)_height < 0.0)
+ delta = -0.5;
+ else
+ delta = 0.5;
+
+ int res = (int)((double)(man->_oy - _ladderY) / (double)_height + delta);
+
+ if (res < 0)
+ return 0;
+
+ return res;
+}
+
+void MctlLadder::addObject(StaticANIObject *obj) {
+ if (findObjectPos(obj) < 0) {
+ MctlLadderMovement *movement = new MctlLadderMovement;
+
+ if (initMovement(obj, movement)) {
+ _mgm.addItem(obj->_id);
+ _movements.push_back(movement);
+ } else {
+ delete movement;
+ }
+ }
+}
+
+int MctlLadder::findObjectPos(StaticANIObject *obj) {
+ int res = -1;
+
+ for (Common::List<MctlLadderMovement *>::iterator it = _movements.begin(); it != _movements.end(); ++it, ++res)
+ if ((*it)->objId == obj->_id)
+ break;
+
+ return res;
+}
+
+bool MctlLadder::initMovement(StaticANIObject *ani, MctlLadderMovement *movement) {
+ GameVar *v = g_fp->getGameLoaderGameVar()->getSubVarByName(ani->getName());
+
+ if (!v)
+ return false;
+
+ v = v->getSubVarByName("Test_Ladder");
+
+ if (!v)
+ return false;
+
+ movement->staticIdsSize = 6;
+ movement->movVars = new MctlLadderMovementVars;
+ movement->staticIds = new int[movement->staticIdsSize];
+
+ v = v->getSubVarByName("Up");
+
+ if (!v)
+ return false;
+
+ movement->movVars->varUpStart = v->getSubVarAsInt("Start");
+ movement->movVars->varUpGo = v->getSubVarAsInt("Go");
+ movement->movVars->varUpStop = v->getSubVarAsInt("Stop");
+
+ movement->staticIds[0] = ani->getMovementById(movement->movVars->varUpStart)->_staticsObj1->_staticsId;
+ movement->staticIds[2] = ani->getMovementById(movement->movVars->varUpGo)->_staticsObj1->_staticsId;
+
+ v = v->getSubVarByName("Down");
+
+ if (!v)
+ return false;
+
+ movement->movVars->varDownStart = v->getSubVarAsInt("Start");
+ movement->movVars->varDownGo = v->getSubVarAsInt("Go");
+ movement->movVars->varDownStop = v->getSubVarAsInt("Stop");
+
+ movement->staticIds[1] = ani->getMovementById(movement->movVars->varDownStart)->_staticsObj1->_staticsId;
+ movement->staticIds[3] = ani->getMovementById(movement->movVars->varDownGo)->_staticsObj1->_staticsId;
+
+ movement->objId = ani->_id;
+
+ return true;
+}
+
+void MctlLadder::freeItems() {
+ _mgm.clear();
+
+ for (Common::List<MctlLadderMovement *>::iterator it = _movements.begin(); it != _movements.end(); ++it) {
+ delete (*it)->movVars;
+ delete [] (*it)->staticIds;
+ }
+
+ _movements.clear();
+}
+
+MessageQueue *MctlLadder::method34(StaticANIObject *subj, int xpos, int ypos, int fuzzyMatch, int staticsId) {
+ MessageQueue *mq = doWalkTo(subj, xpos, ypos, fuzzyMatch, staticsId);
+
+ if (mq) {
+ if (mq->chain(subj))
+ return mq;
+ }
+
+ return 0;
+}
+
+MessageQueue *MctlLadder::doWalkTo(StaticANIObject *subj, int xpos, int ypos, int fuzzyMatch, int staticsId) {
+ warning("STUB: MctlLadder::doWalkTo()");
+
+ return 0;
+}
+
+MessageQueue *MctlLadder::controllerWalkTo(StaticANIObject *ani, int off) {
+ return doWalkTo(ani, _ladderX + off * _width, _ladderY + off * _height, 1, 0);
+}
+
+MctlConnectionPoint *MctlCompound::findClosestConnectionPoint(int ox, int oy, int destIndex, int connectionX, int connectionY, int sourceIndex, int *minDistancePtr) {
+ warning("STUB: MctlCompound::findClosestConnectionPoint()");
return 0;
}
+void MctlCompound::replaceNodeX(int from, int to) {
+ warning("STUB: MctlCompound::replaceNodeX()");
+}
+
+MctlConnectionPoint::MctlConnectionPoint() {
+ _connectionX = 0;
+ _connectionY = 0;
+ _field_C = 0;
+ _field_10 = 0;
+ _field_14 = 0;
+ _field_16 = 0;
+ _messageQueueObj = 0;
+ _motionControllerObj = 0;
+}
+
+MctlConnectionPoint::~MctlConnectionPoint() {
+ delete _messageQueueObj;
+}
+
+MovInfo1::MovInfo1(MovInfo1 *src) {
+ index = src->index;
+ pt1 = src->pt1;
+ pt2 = src->pt2;
+ distance1 = src->distance1;
+ distance2 = src->distance2;
+ subIndex = src->subIndex;
+ item1Index = src->item1Index;
+ items = src->items;
+ itemsCount = src->itemsCount;
+ flags = src->flags;
+}
+
+void MovInfo1::clear() {
+ index = 0;
+ pt1.x = pt1.y = 0;
+ pt2.x = pt2.y = 0;
+ distance1 = 0;
+ distance2 = 0;
+ subIndex = 0;
+ item1Index = 0;
+ items.clear();
+ itemsCount = 0;
+ flags = 0;
+}
+
bool MctlCompoundArray::load(MfcArchive &file) {
debug(5, "MctlCompoundArray::load()");
@@ -140,6 +428,25 @@ bool MctlCompoundArray::load(MfcArchive &file) {
return true;
}
+MovGraphItem::MovGraphItem() {
+ ani = 0;
+ field_4 = 0;
+ field_8 = 0;
+ field_C = 0;
+ field_10 = 0;
+ field_14 = 0;
+ field_18 = 0;
+ field_1C = 0;
+ field_20 = 0;
+ field_24 = 0;
+ items = 0;
+ count = 0;
+ field_30 = 0;
+ field_34 = 0;
+ field_38 = 0;
+ field_3C = 0;
+}
+
int MovGraph_messageHandler(ExCommand *cmd);
int MovGraphCallback(int a1, int a2, int a3) {
@@ -149,8 +456,6 @@ int MovGraphCallback(int a1, int a2, int a3) {
}
MovGraph::MovGraph() {
- _itemsCount = 0;
- _items = 0;
_callback1 = MovGraphCallback;
_field_44 = 0;
insertMessageHandler(MovGraph_messageHandler, getMessageHandlersCount() - 1, 129);
@@ -158,6 +463,10 @@ MovGraph::MovGraph() {
_objtype = kObjTypeMovGraph;
}
+MovGraph::~MovGraph() {
+ warning("STUB: MovGraph::~MovGraph()");
+}
+
bool MovGraph::load(MfcArchive &file) {
debug(5, "MovGraph::load()");
@@ -167,24 +476,1582 @@ bool MovGraph::load(MfcArchive &file) {
return true;
}
-int MovGraph::addObject(StaticANIObject *obj) {
- warning("STUB: MovGraph::addObject()");
+void MovGraph::addObject(StaticANIObject *obj) {
+ _mgm.clear();
+ _mgm.addItem(obj->_id);
+
+ for (uint i = 0; i < _items.size(); i++)
+ if (_items[i]->ani == obj)
+ return;
+
+ MovGraphItem *item = new MovGraphItem();
+
+ item->ani = obj;
+
+ _items.push_back(item);
+
+ _mgm.addItem(obj->_id); // FIXME: Is it really needed?
+}
+
+int MovGraph::removeObject(StaticANIObject *obj) {
+ warning("STUB: MovGraph::removeObject()");
+
+ return 0;
+}
+
+void MovGraph::freeItems() {
+ warning("STUB: MovGraph::freeItems()");
+}
+
+int MovGraph::method28() {
+ warning("STUB: MovGraph::method28()");
+
+ return 0;
+}
+
+int MovGraph::method2C(StaticANIObject *obj, int x, int y) {
+ obj->setOXY(x, y);
+ return method3C(obj, 1);
+}
+
+MessageQueue *MovGraph::method34(StaticANIObject *subj, int xpos, int ypos, int fuzzyMatch, int staticsId) {
+ warning("STUB: MovGraph::method34()");
+
+ return 0;
+}
+
+int MovGraph::changeCallback() {
+ warning("STUB: MovGraph::changeCallback()");
+
+ return 0;
+}
+
+int MovGraph::method3C(StaticANIObject *ani, int flag) {
+ warning("STUB: MovGraph::method3C()");
+
+ return 0;
+}
+
+int MovGraph::method44() {
+ warning("STUB: MovGraph::method44()");
+
+ return 0;
+}
+
+MessageQueue *MovGraph::doWalkTo(StaticANIObject *subj, int xpos, int ypos, int fuzzyMatch, int staticsId) {
+ warning("STUB: MovGraph::doWalkTo()");
+
+ return 0;
+}
+
+int MovGraph::method50() {
+ warning("STUB: MovGraph::method50()");
+
+ return 0;
+}
+
+double MovGraph::calcDistance(Common::Point *point, MovGraphLink *link, int fuzzyMatch) {
+ int n1x = link->_movGraphNode1->_x;
+ int n1y = link->_movGraphNode1->_y;
+ int n2x = link->_movGraphNode2->_x;
+ int n2y = link->_movGraphNode2->_y;
+ double dist1x = (double)(point->x - n1x);
+ double dist1y = (double)(n1y - point->y);
+ double dist2x = (double)(n2x - n1x);
+ double dist2y = (double)(n2y - n1y);
+ double dist1 = sqrt(dist1y * dist1y + dist1x * dist1x);
+ double dist2 = ((double)(n1y - n2y) * dist1y + dist2x * dist1x) / link->_distance / dist1;
+ double distm = dist2 * dist1;
+ double res = sqrt(1.0 - dist2 * dist2) * dist1;
+
+ if (dist2 <= 0.0 || distm >= link->_distance) {
+ if (fuzzyMatch) {
+ if (dist2 > 0.0) {
+ if (distm >= link->_distance) {
+ point->x = n2x;
+ point->y = n2y;
+ }
+ } else {
+ point->x = n1x;
+ point->y = n1y;
+ }
+ } else {
+ return -1.0;
+ }
+ } else {
+ point->x = (int)(n1x + (dist2x * distm / link->_distance));
+ point->y = (int)(n1y + (dist2y * distm / link->_distance));
+ }
+
+ return res;
+}
+
+void MovGraph::calcNodeDistancesAndAngles() {
+ for (ObList::iterator i = _links.begin(); i != _links.end(); ++i) {
+ assert(((CObject *)*i)->_objtype == kObjTypeMovGraphLink);
+
+ MovGraphLink *lnk = (MovGraphLink *)*i;
+
+ lnk->_flags &= 0x7FFFFFFF;
+
+ lnk->calcNodeDistanceAndAngle();
+ }
+}
+
+int MovGraph2::getItemIndexByGameObjectId(int objectId) {
+ for (uint i = 0; i < _items2.size(); i++)
+ if (_items2[i]->_objectId == objectId)
+ return i;
+
+ return -1;
+}
+
+int MovGraph2::getItemSubIndexByStaticsId(int idx, int staticsId) {
+ for (int i = 0; i < 4; i++)
+ if (_items2[idx]->_subItems[i]._staticsId1 == staticsId || _items2[idx]->_subItems[i]._staticsId2 == staticsId)
+ return i;
+
+ return -1;
+}
+
+int MovGraph2::getItemSubIndexByMovementId(int idx, int movId) {
+ for (int i = 0; i < 4; i++)
+ if (_items2[idx]->_subItems[i]._walk[0]._movementId == movId || _items2[idx]->_subItems[i]._turn[0]._movementId == movId ||
+ _items2[idx]->_subItems[i]._turnS[0]._movementId == movId)
+ return i;
+
+ return -1;
+}
+
+int MovGraph2::getItemSubIndexByMGM(int idx, StaticANIObject *ani) {
+ warning("STUB: MovGraph2::getItemSubIndexByMGM()");
+
+ return -1;
+}
+
+bool MovGraph2::initDirections(StaticANIObject *obj, MovGraph2Item *item) {
+ item->_obj = obj;
+ item->_objectId = obj->_id;
+
+ GameVar *var = g_fp->getGameLoaderGameVar()->getSubVarByName(obj->_objectName);
+ if (!var)
+ return false;
+
+ var = var->getSubVarByName("Test_walk");
+
+ if (!var)
+ return false;
+
+ GameVar *varD = 0;
+ Common::Point point;
+
+ for (int dir = 0; dir < 4; dir++) {
+ switch (dir) {
+ case 0:
+ varD = var->getSubVarByName("Right");
+ break;
+ case 1:
+ varD = var->getSubVarByName("Left");
+ break;
+ case 2:
+ varD = var->getSubVarByName("Up");
+ break;
+ case 3:
+ varD = var->getSubVarByName("Down");
+ break;
+ }
+
+ if (!varD)
+ return false;
+
+ for (int act = 0; act < 3; act++) {
+ int idx = 0;
+
+ switch(act) {
+ case 0:
+ idx = varD->getSubVarAsInt("Start");
+ break;
+ case 1:
+ idx = varD->getSubVarAsInt("Go");
+ break;
+ case 2:
+ idx = varD->getSubVarAsInt("Stop");
+ break;
+ }
+
+ item->_subItems[dir]._walk[act]._movementId = idx;
+
+ Movement *mov = obj->getMovementById(idx);
+
+ item->_subItems[dir]._walk[act]._mov = mov;
+ if (mov) {
+ mov->calcSomeXY(point, 0);
+ item->_subItems[dir]._walk[act]._mx = point.x;
+ item->_subItems[dir]._walk[act]._my = point.y;
+ }
+ }
+
+ for (int act = 0; act < 4; act++) {
+ int idx = 0;
+
+ switch(act) {
+ case 0:
+ idx = varD->getSubVarAsInt("TurnR");
+ break;
+ case 1:
+ idx = varD->getSubVarAsInt("TurnL");
+ break;
+ case 2:
+ idx = varD->getSubVarAsInt("TurnU");
+ break;
+ case 3:
+ idx = varD->getSubVarAsInt("TurnD");
+ break;
+ }
+
+ item->_subItems[dir]._turn[act]._movementId = idx;
+
+ Movement *mov = obj->getMovementById(idx);
+
+ item->_subItems[dir]._turn[act]._mov = mov;
+ if (mov) {
+ mov->calcSomeXY(point, 0);
+ item->_subItems[dir]._turn[act]._mx = point.x;
+ item->_subItems[dir]._turn[act]._my = point.y;
+ }
+ }
+
+ for (int act = 0; act < 4; act++) {
+ int idx = 0;
+
+ switch(act) {
+ case 0:
+ idx = varD->getSubVarAsInt("TurnSR");
+ break;
+ case 1:
+ idx = varD->getSubVarAsInt("TurnSL");
+ break;
+ case 2:
+ idx = varD->getSubVarAsInt("TurnSU");
+ break;
+ case 3:
+ idx = varD->getSubVarAsInt("TurnSD");
+ break;
+ }
+
+ item->_subItems[dir]._turnS[act]._movementId = idx;
+
+ Movement *mov = obj->getMovementById(idx);
+
+ item->_subItems[dir]._turnS[act]._mov = mov;
+ if (mov) {
+ mov->calcSomeXY(point, 0);
+ item->_subItems[dir]._turnS[act]._mx = point.x;
+ item->_subItems[dir]._turnS[act]._my = point.y;
+ }
+ }
+
+ item->_subItems[dir]._staticsId1 = item->_subItems[dir]._walk[0]._mov->_staticsObj1->_staticsId;
+ item->_subItems[dir]._staticsId2 = item->_subItems[dir]._walk[0]._mov->_staticsObj2->_staticsId;
+
+ }
+ return true;
+}
+
+void MovGraph2::addObject(StaticANIObject *obj) {
+ MovGraph::addObject(obj);
+
+ int id = getItemIndexByGameObjectId(obj->_id);
+
+ if (id >= 0) {
+ _items2[id]->_obj = obj;
+ } else {
+ MovGraph2Item *item = new MovGraph2Item;
+
+ if (initDirections(obj, item)) {
+ _items2.push_back(item);
+ } else {
+ delete item;
+ }
+ }
+}
+
+void MovGraph2::buildMovInfo1SubItems(MovInfo1 *movinfo, Common::Array<MovGraphLink *> *linkList, LinkInfo *lnkSrc, LinkInfo *lnkDst) {
+ MovInfo1Sub *elem;
+ Common::Point point;
+ Common::Rect rect;
+
+ int subIndex = movinfo->subIndex;
+
+ movinfo->items.clear();
+
+ elem = new MovInfo1Sub;
+ elem->subIndex = subIndex;
+ elem->x = movinfo->pt1.x;
+ elem->y = movinfo->pt1.y;
+ elem->distance = -1;
+
+ movinfo->items.push_back(elem);
+
+ int prevSubIndex = movinfo->subIndex;
+
+ for (uint i = 0; i < linkList->size(); i++) {
+ int idx1;
+
+ if (linkList->size() <= 1) {
+ if (linkList->size() == 1)
+ idx1 = getShortSide((*linkList)[0], movinfo->pt2.x - movinfo->pt1.x, movinfo->pt2.y - movinfo->pt1.y);
+ else
+ idx1 = getShortSide(0, movinfo->pt2.x - movinfo->pt1.x, movinfo->pt2.y - movinfo->pt1.y);
+
+ point.y = -1;
+ rect.bottom = -1;
+ rect.right = -1;
+ rect.top = -1;
+ rect.left = -1;
+ } else {
+ idx1 = findLink(linkList, i, &rect, &point);
+ }
+
+ if (idx1 != prevSubIndex) {
+ prevSubIndex = idx1;
+ subIndex = idx1;
+
+ elem = new MovInfo1Sub;
+ elem->subIndex = subIndex;
+ elem->x = rect.left;
+ elem->y = rect.top;
+ elem->distance = -1;
+
+ movinfo->items.push_back(elem);
+ }
+
+ if (i != linkList->size() - 1) {
+ while (1) {
+ i++;
+ if (findLink(linkList, i, &rect, 0) != prevSubIndex) {
+ i--;
+ findLink(linkList, i, &rect, &point);
+
+ break;
+ }
+
+ if (i == linkList->size() - 1)
+ break;
+ }
+ }
+
+ if (movinfo->items.back()->subIndex != 10) {
+ subIndex = prevSubIndex;
+
+ elem = new MovInfo1Sub;
+ elem->subIndex = 10;
+ elem->x = -1;
+ elem->y = -1;
+ elem->distance = -1;
+
+ movinfo->items.push_back(elem);
+
+ if (i == linkList->size()) {
+ elem = new MovInfo1Sub;
+ elem->subIndex = prevSubIndex;
+ elem->x = movinfo->pt2.x;
+ elem->y = movinfo->pt2.y;
+ elem->distance = movinfo->distance2;
+
+ movinfo->items.push_back(elem);
+ } else {
+ elem = new MovInfo1Sub;
+ elem->subIndex = prevSubIndex;
+ elem->x = rect.right;
+ elem->y = rect.bottom;
+ elem->distance = point.y;
+
+ movinfo->items.push_back(elem);
+ }
+ }
+ }
+
+ if (subIndex != movinfo->item1Index) {
+ elem = new MovInfo1Sub;
+ elem->subIndex = movinfo->item1Index;
+ elem->x = movinfo->pt2.x;
+ elem->y = movinfo->pt2.y;
+ elem->distance = movinfo->distance2;
+
+ movinfo->items.push_back(elem);
+ }
+
+ movinfo->itemsCount = movinfo->items.size();
+}
+
+MessageQueue *MovGraph2::buildMovInfo1MessageQueue(MovInfo1 *movInfo) {
+ MovInfo1 movinfo(movInfo);
+
+ int curX = movInfo->pt1.x;
+ int curY = movInfo->pt1.y;
+ int curDistance = movInfo->distance1;
+
+ MessageQueue *mq = new MessageQueue(g_fp->_globalMessageQueueList->compact());
+
+ for (int i = 0; i < movInfo->itemsCount - 1; i++) {
+ if (movInfo->items[i + 1]->subIndex != 10) {
+ MG2I *mg2i;
+
+ if (i >= movInfo->itemsCount - 2 || movInfo->items[i + 2]->subIndex != 10) {
+ movinfo.flags = 0;
+ mg2i = &_items2[movInfo->index]->_subItems[movInfo->items[i]->subIndex]._turnS[movInfo->items[i + 1]->subIndex];
+ } else {
+ movinfo.flags = 2;
+ mg2i = &_items2[movInfo->index]->_subItems[movInfo->items[i]->subIndex]._turn[movInfo->items[i + 1]->subIndex];
+ }
+ if (i < movInfo->itemsCount - 2
+ || (movInfo->items[i]->x == movInfo->items[i + 1]->x
+ && movInfo->items[i]->y == movInfo->items[i + 1]->y)
+ || movInfo->items[i]->x == -1
+ || movInfo->items[i]->y == -1
+ || movInfo->items[i + 1]->x == -1
+ || movInfo->items[i + 1]->y == -1) {
+
+ ExCommand *ex = new ExCommand(_items2[movInfo->index]->_objectId, 1, mg2i->_movementId, 0, 0, 0, 1, 0, 0, 0);
+
+ ex->_excFlags |= 2;
+ ex->_keyCode = _items2[movInfo->index]->_obj->_okeyCode;
+ ex->_field_24 = 1;
+ ex->_field_14 = -1;
+ mq->addExCommandToEnd(ex);
+
+ curX += mg2i->_mx;
+ curY += mg2i->_my;
+ } else {
+ MGMInfo mgminfo;
+
+ memset(&mgminfo, 0, sizeof(mgminfo));
+
+ mgminfo.ani = _items2[movInfo->index]->_obj;
+ mgminfo.staticsId2 = mg2i->_mov->_staticsObj2->_staticsId;
+ mgminfo.x1 = movInfo->items[i + 1]->x;
+ mgminfo.y1 = movInfo->items[i + 1]->y;
+ mgminfo.field_1C = movInfo->items[i + 1]->distance;
+ mgminfo.staticsId1 = mg2i->_mov->_staticsObj1->_staticsId;
+
+ mgminfo.x2 = movInfo->items[i]->x;
+ mgminfo.y2 = movInfo->items[i]->y;
+ mgminfo.field_10 = 1;
+ mgminfo.flags = 0x7f;
+ mgminfo.movementId = mg2i->_movementId;
+
+ MessageQueue *mq2 = _mgm.genMovement(&mgminfo);
+ mq->transferExCommands(mq2);
+
+ delete mq2;
+
+ curX = movInfo->items[i + 1]->x;
+ curY = movInfo->items[i + 1]->y;
+ }
+ } else {
+ movinfo.item1Index = movInfo->items[i]->subIndex;
+ movinfo.subIndex = movinfo.item1Index;
+ movinfo.pt1.y = curY;
+ movinfo.pt1.x = curX;
+
+ movinfo.distance1 = curDistance;
+ movinfo.pt2.x = movInfo->items[i + 2]->x;
+ movinfo.pt2.y = movInfo->items[i + 2]->y;
+ movinfo.distance2 = movInfo->items[i + 2]->distance;
+
+ if (i >= movInfo->itemsCount - 4
+ || movInfo->items[i + 2]->subIndex == 10
+ || movInfo->items[i + 3]->subIndex == 10
+ || movInfo->items[i + 2]->subIndex == movInfo->items[i + 3]->subIndex
+ || movInfo->items[i + 4]->subIndex != 10) {
+ if (i >= movInfo->itemsCount - 3
+ || movInfo->items[i + 2]->subIndex == 10
+ || movInfo->items[i + 3]->subIndex == 10
+ || movInfo->items[i + 2]->subIndex == movInfo->items[i + 3]->subIndex) {
+ movinfo.flags &= 3;
+ } else {
+ MG2I *m = &_items2[movInfo->index]->_subItems[movInfo->items[i + 2]->subIndex]._turnS[movInfo->items[i + 3]->subIndex];
+ movinfo.pt2.x -= m->_mx;
+ movinfo.pt2.y -= m->_my;
+ movinfo.flags &= 3;
+ }
+ } else {
+ MG2I *m = &_items2[movInfo->index]->_subItems[movInfo->items[i + 2]->subIndex]._turn[movInfo->items[i + 3]->subIndex];
+
+ if (movinfo.item1Index && movinfo.item1Index != 1) {
+ movinfo.pt2.y -= m->_my;
+ movinfo.flags = (movinfo.flags & 2) | 1;
+ } else {
+ movinfo.pt2.x -= m->_mx;
+ movinfo.flags = (movinfo.flags & 2) | 1;
+ }
+ }
+ i++; // intentional
+
+ MessageQueue *mq2 = genMovement(&movinfo);
+
+ if (!mq2) {
+ delete mq;
+ return 0;
+ }
+
+ mq->transferExCommands(mq2);
+
+ delete mq2;
+
+ curX = movinfo.pt2.x;
+ curY = movinfo.pt2.y;
+ curDistance = movinfo.distance2;
+ }
+ }
+
+ movInfo->pt2.x = movinfo.pt2.x;
+ movInfo->pt2.y = movinfo.pt2.y;
+
+ return mq;
+}
+
+int MovGraph2::removeObject(StaticANIObject *obj) {
+ warning("STUB: MovGraph2::removeObject()");
return 0;
}
-double MovGraph::calcDistance(Common::Point *point, MovGraphLink *link, int flag) {
- warning("STUB: MovGraph::calcDistance()");
+void MovGraph2::freeItems() {
+ warning("STUB: MovGraph2::freeItems()");
+}
+
+MessageQueue *MovGraph2::method34(StaticANIObject *ani, int xpos, int ypos, int fuzzyMatch, int staticsId) {
+ if (!ani->isIdle())
+ return 0;
+
+ if (ani->_flags & 0x100)
+ return 0;
+
+ MessageQueue *mq = doWalkTo(ani, xpos, ypos, fuzzyMatch, staticsId);
+
+ if (!mq)
+ return 0;
+
+ if (ani->_movement) {
+ if (mq->getCount() <= 1 || mq->getExCommandByIndex(0)->_messageKind != 22) {
+ PicAniInfo picAniInfo;
+
+ ani->getPicAniInfo(&picAniInfo);
+ ani->updateStepPos();
+ MessageQueue *mq1 = doWalkTo(ani, xpos, ypos, fuzzyMatch, staticsId);
+
+ ani->setPicAniInfo(&picAniInfo);
+
+ if (mq1) {
+ delete mq;
+
+ mq = mq1;
+ }
+ } else {
+ ani->_movement = 0;
+ }
+ }
+
+ if (!mq->chain(ani)) {
+ delete mq;
+
+ return 0;
+ }
+
+ return mq;
+}
+
+MessageQueue *MovGraph2::doWalkTo(StaticANIObject *obj, int xpos, int ypos, int fuzzyMatch, int staticsId) {
+ LinkInfo linkInfoDest;
+ LinkInfo linkInfoSource;
+ MovInfo1 movInfo1;
+ PicAniInfo picAniInfo;
+ Common::Point point;
+
+ int idx = getItemIndexByGameObjectId(obj->_id);
+
+ if (idx < 0)
+ return 0;
+
+ linkInfoSource.link = 0;
+ linkInfoSource.node = 0;
+
+ linkInfoDest.link = 0;
+ linkInfoDest.node = 0;
+
+ point.x = 0;
+
+ obj->getPicAniInfo(&picAniInfo);
+
+ int idxsub;
+
+ if (obj->_movement)
+ idxsub = getItemSubIndexByMovementId(idx, obj->_movement->_id);
+ else
+ idxsub = getItemSubIndexByStaticsId(idx, obj->_statics->_staticsId);
+
+ bool subMgm = false;
+
+ if (idxsub == -1) {
+ idxsub = getItemSubIndexByMGM(idx, obj);
+ subMgm = true;
+
+ if (idxsub == -1)
+ return 0;
+ }
+
+ if (obj->_movement) {
+ int newx, newy;
+
+ if (subMgm) {
+ obj->_messageQueueId = 0;
+ obj->changeStatics2(_items2[idx]->_subItems[idxsub]._staticsId1);
+ newx = obj->_ox;
+ newy = obj->_oy;
+ } else {
+ obj->_movement->calcSomeXY(point, 0);
+ newx = obj->_movement->_ox - point.x;
+ newy = obj->_movement->_oy - point.y;
+ if (idxsub != 1 && idxsub) {
+ if (idxsub == 2 || idxsub == 3) {
+ newy = obj->_movement->_oy;
+ }
+ } else {
+ newx = obj->_movement->_ox;
+ }
+ }
+
+ obj->_movement = 0;
+ obj->setOXY(newx, newy);
+ }
+
+ if (obj->_ox == xpos && obj->_oy == ypos) {
+ g_fp->_globalMessageQueueList->compact();
+
+ MessageQueue *mq = new MessageQueue();
+
+ if (staticsId && obj->_statics->_staticsId != staticsId) {
+ int idxwalk = getItemSubIndexByStaticsId(idx, staticsId);
+ if (idxwalk == -1) {
+ obj->setPicAniInfo(&picAniInfo);
+
+ delete mq;
+
+ return 0;
+ }
+
+ ExCommand *ex = new ExCommand(picAniInfo.objectId, 1, _items2[idx]->_subItems[idxsub]._walk[idxwalk]._movementId, 0, 0, 0, 1, 0, 0, 0);
+
+ ex->_field_24 = 1;
+ ex->_keyCode = picAniInfo.field_8;
+ ex->_excFlags |= 2;
+
+ mq->addExCommandToEnd(ex);
+ } else {
+ ExCommand *ex = new ExCommand(picAniInfo.objectId, 22, obj->_statics->_staticsId, 0, 0, 0, 1, 0, 0, 0);
+
+ ex->_keyCode = picAniInfo.field_8;
+ ex->_excFlags |= 3;
+ mq->addExCommandToEnd(ex);
+
+ ex = new ExCommand(picAniInfo.objectId, 5, -1, obj->_ox, obj->_oy, 0, 1, 0, 0, 0);
+
+ ex->_field_14 = -1;
+ ex->_keyCode = picAniInfo.field_8;
+ ex->_excFlags |= 3;
+ mq->addExCommandToEnd(ex);
+ }
+
+ obj->setPicAniInfo(&picAniInfo);
+
+ return mq;
+ }
+
+ linkInfoSource.node = findNode(obj->_ox, obj->_oy, 0);
+
+ if (!linkInfoSource.node) {
+ linkInfoSource.link = findLink1(obj->_ox, obj->_oy, idxsub, 0);
+
+ if (!linkInfoSource.link) {
+ linkInfoSource.link = findLink2(obj->_ox, obj->_oy);
+
+ if (!linkInfoSource.link) {
+ obj->setPicAniInfo(&picAniInfo);
+
+ return 0;
+ }
+ }
+ }
+
+ linkInfoDest.node = findNode(xpos, ypos, fuzzyMatch);
+
+ if (!linkInfoDest.node) {
+ linkInfoDest.link = findLink1(xpos, ypos, idxsub, fuzzyMatch);
+
+ if (!linkInfoDest.link) {
+ obj->setPicAniInfo(&picAniInfo);
+
+ return 0;
+ }
+ }
+
+ Common::Array<MovGraphLink *> tempLinkList;
+ double minPath = findMinPath(&linkInfoSource, &linkInfoDest, &tempLinkList);
+
+ debug(0, "MovGraph2::doWalkTo(): path: %g parts: %d", minPath, tempLinkList.size());
+
+ if (minPath < 0.0 || ((linkInfoSource.node != linkInfoDest.node || !linkInfoSource.node) && !tempLinkList.size()))
+ return 0;
+
+ movInfo1.clear();
+
+ movInfo1.subIndex = idxsub;
+ movInfo1.pt1.x = obj->_ox;
+ movInfo1.pt1.y = obj->_oy;
+
+ int dx1 = obj->_ox;
+ int dy1 = obj->_oy;
+ int dx2, dy2;
+
+ if (linkInfoSource.node)
+ movInfo1.distance1 = linkInfoSource.node->_distance;
+ else
+ movInfo1.distance1 = linkInfoSource.link->_movGraphNode1->_distance;
+
+ if (linkInfoDest.node) {
+ dx2 = linkInfoDest.node->_x;
+ dy2 = linkInfoDest.node->_y;
+
+ movInfo1.pt2.x = linkInfoDest.node->_x;
+ movInfo1.pt2.y = linkInfoDest.node->_y;
+
+ movInfo1.distance2 = linkInfoDest.node->_distance;
+ } else {
+ movInfo1.pt2.x = xpos;
+ movInfo1.pt2.y = ypos;
+
+ MovGraphNode *nod = linkInfoDest.link->_movGraphNode1;
+ double dst1 = sqrt((double)((ypos - nod->_y) * (ypos - nod->_y) + (xpos - nod->_x) * (xpos - nod->_x)));
+ int dst = linkInfoDest.link->_movGraphNode2->_distance - nod->_distance;
+
+ movInfo1.distance2 = (int)(nod->_distance + (dst1 * (double)dst / linkInfoDest.link->_distance));
+
+ calcDistance(&movInfo1.pt2, linkInfoDest.link, 1);
+
+ dx1 = movInfo1.pt1.x;
+ dy1 = movInfo1.pt1.y;
+ dx2 = movInfo1.pt2.x;
+ dy2 = movInfo1.pt2.y;
+ }
+
+ if (staticsId) {
+ movInfo1.item1Index = getItemSubIndexByStaticsId(idx, staticsId);
+ } else if (tempLinkList.size() <= 1) {
+ if (tempLinkList.size() == 1)
+ movInfo1.item1Index = getShortSide(tempLinkList[0], dx2 - dx1, dy2 - dy1);
+ else
+ movInfo1.item1Index = getShortSide(0, dx2 - dx1, dy2 - dy1);
+ } else {
+ movInfo1.item1Index = findLink(&tempLinkList, tempLinkList.size() - 1, 0, 0);
+ }
+
+ movInfo1.flags = fuzzyMatch != 0;
+
+ if (_items2[idx]->_subItems[idxsub]._staticsId1 != obj->_statics->_staticsId)
+ movInfo1.flags |= 2;
+
+ buildMovInfo1SubItems(&movInfo1, &tempLinkList, &linkInfoSource, &linkInfoDest);
+
+ MessageQueue *mq = buildMovInfo1MessageQueue(&movInfo1);
+
+ linkInfoDest.node = findNode(movInfo1.pt2.x, movInfo1.pt2.y, fuzzyMatch);
+
+ if (!linkInfoDest.node)
+ linkInfoDest.link = findLink1(movInfo1.pt2.x, movInfo1.pt2.y, movInfo1.item1Index, fuzzyMatch);
+
+ if (fuzzyMatch || linkInfoDest.link || linkInfoDest.node) {
+ if (mq && mq->getCount() > 0 && picAniInfo.movementId) {
+ ExCommand *ex = mq->getExCommandByIndex(0);
+
+ if (ex && (ex->_messageKind == 1 || ex->_messageKind == 20)
+ && picAniInfo.movementId == ex->_messageNum
+ && picAniInfo.someDynamicPhaseIndex == ex->_field_14) {
+ mq->deleteExCommandByIndex(0, 1);
+ } else {
+ ex = new ExCommand(picAniInfo.objectId, 5, ex->_messageNum, obj->_ox, obj->_oy, 0, 1, 0, 0, 0);
+ ex->_field_14 = -1;
+ ex->_keyCode = picAniInfo.field_8;
+ ex->_excFlags |= 2;
+ mq->addExCommand(ex);
+
+ ex = new ExCommand(picAniInfo.objectId, 22, _items2[idx]->_subItems[idxsub]._staticsId1, 0, 0, 0, 1, 0, 0, 0);
+
+ ex->_keyCode = picAniInfo.field_8;
+ ex->_excFlags |= 3;
+ mq->addExCommand(ex);
+ }
+ }
+ } else {
+ if (mq)
+ delete mq;
+ mq = 0;
+ }
+
+ obj->setPicAniInfo(&picAniInfo);
+
+ return mq;
+}
+
+MovGraphNode *MovGraph2::findNode(int x, int y, int fuzzyMatch) {
+ for (ObList::iterator i = _nodes.begin(); i != _nodes.end(); ++i) {
+ assert(((CObject *)*i)->_objtype == kObjTypeMovGraphNode);
+
+ MovGraphNode *node = (MovGraphNode *)*i;
+
+ if (fuzzyMatch) {
+ if (abs(node->_x - x) < 15 && abs(node->_y - y) < 15)
+ return node;
+ } else {
+ if (node->_x == x && node->_y == y)
+ return node;
+ }
+ }
return 0;
}
+int MovGraph2::getShortSide(MovGraphLink *lnk, int x, int y) {
+ bool cond;
+
+ if (lnk)
+ cond = abs(lnk->_movGraphNode2->_x - lnk->_movGraphNode1->_x) > abs(lnk->_movGraphNode2->_y - lnk->_movGraphNode1->_y);
+ else
+ cond = abs(x) > abs(y);
+
+ if (cond)
+ return x <= 0;
+ else
+ return ((y > 0) + 2);
+}
+
+int MovGraph2::findLink(Common::Array<MovGraphLink *> *linkList, int idx, Common::Rect *rect, Common::Point *point) {
+ MovGraphNode *node1 = (*linkList)[idx]->_movGraphNode1;
+ MovGraphNode *node2 = (*linkList)[idx]->_movGraphNode2;
+ MovGraphNode *node3 = node1;
+
+ if (idx != 0) {
+ MovGraphLink *lnk = (*linkList)[idx - 1];
+
+ if (lnk->_movGraphNode2 != node1) {
+ if (lnk->_movGraphNode1 != node1) {
+ if (lnk->_movGraphNode2 == node2 || lnk->_movGraphNode1 == node2) {
+ node3 = node2;
+ node2 = node1;
+ }
+ goto LABEL_7;
+ }
+ }
+ node3 = node1;
+ } else if (idx != (int)(linkList->size() - 1)) {
+ MovGraphLink *lnk = (*linkList)[idx + 1];
+
+ if (lnk->_movGraphNode2 == node1 || lnk->_movGraphNode1 == node1) {
+ node3 = node2;
+ node2 = node1;
+ } else if (lnk->_movGraphNode2 == node2 || lnk->_movGraphNode1 == node2) {
+ node3 = node1;
+ }
+ }
+
+ LABEL_7:
+ if (rect) {
+ rect->left = node3->_x;
+ rect->top = node3->_y;
+ rect->right = node2->_x;
+ rect->bottom = node2->_y;
+ }
+ if (point) {
+ point->x = node3->_distance;
+ point->y = node2->_distance;
+ }
+
+ if (abs(node3->_x - node2->_x) <= abs(node3->_y - node2->_y))
+ return (node3->_y < node2->_x) + 2;
+ else
+ return node3->_x >= node2->_x;
+}
+
+MessageQueue *MovGraph2::genMovement(MovInfo1 *info) {
+ int mx1 = 0;
+ int my1 = 0;
+
+ if (!(info->flags & 2)) {
+ mx1 = _items2[info->index]->_subItems[info->subIndex]._walk[0]._mx;
+ my1 = _items2[info->index]->_subItems[info->subIndex]._walk[0]._my;
+ }
+
+ int mx2 = 0;
+ int my2 = 0;
+
+ if (!(info->flags & 4)) {
+ mx2 = _items2[info->index]->_subItems[info->subIndex]._walk[2]._mx;
+ my2 = _items2[info->index]->_subItems[info->subIndex]._walk[2]._my;
+ }
+
+ Common::Point point;
+
+ int y = info->pt2.y - info->pt1.y - my2 - my1;
+ int x = info->pt2.x - info->pt1.x - mx2 - mx1;
+ int a2;
+ int mgmLen;
+
+ _mgm.calcLength(&point, _items2[info->index]->_subItems[info->subIndex]._walk[1]._mov, x, y, &mgmLen, &a2, info->flags & 1);
+
+ int x1 = point.x;
+ int y1 = point.y;
+
+ if (!(info->flags & 1)) {
+ if (info->subIndex == 1 || info->subIndex == 0) {
+ a2 = -1;
+ x1 = mgmLen * _items2[info->index]->_subItems[info->subIndex]._walk[1]._mx;
+ x = x1;
+ info->pt2.x = x1 + info->pt1.x + mx1 + mx2;
+ }
+ }
+
+ if (!(info->flags & 1)) {
+ if (info->subIndex == 2 || info->subIndex == 3) {
+ a2 = -1;
+ y1 = mgmLen * _items2[info->index]->_subItems[info->subIndex]._walk[1]._my;
+ y = y1;
+ info->pt2.y = y1 + info->pt1.y + my1 + my2;
+ }
+ }
+
+ int cntX = 0;
+ int cntY = 0;
+
+ if (!(info->flags & 2)) {
+ cntX = _items2[info->index]->_subItems[info->subIndex]._walk[0]._mov->countPhasesWithFlag(-1, 1);
+ cntY = _items2[info->index]->_subItems[info->subIndex]._walk[0]._mov->countPhasesWithFlag(-1, 2);
+ }
+
+ if (mgmLen > 1) {
+ cntX += (mgmLen - 1) * _items2[info->index]->_subItems[info->subIndex]._walk[1]._mov->countPhasesWithFlag(-1, 1);
+ cntY += (mgmLen - 1) * _items2[info->index]->_subItems[info->subIndex]._walk[1]._mov->countPhasesWithFlag(-1, 2);
+ }
+
+ if (mgmLen > 0) {
+ cntX += _items2[info->index]->_subItems[info->subIndex]._walk[1]._mov->countPhasesWithFlag(a2, 1);
+ cntY += _items2[info->index]->_subItems[info->subIndex]._walk[1]._mov->countPhasesWithFlag(a2, 2);
+ }
+
+ if (!(info->flags & 4)) {
+ cntX += _items2[info->index]->_subItems[info->subIndex]._walk[2]._mov->countPhasesWithFlag(-1, 1);
+ cntY += _items2[info->index]->_subItems[info->subIndex]._walk[2]._mov->countPhasesWithFlag(-1, 2);
+ }
+
+ int dx1 = x - x1;
+ int dy1 = y - y1;
+
+ if (cntX)
+ x1 = (int)((double)dx1 / (double)cntX);
+ else
+ x1 = 0;
+
+ if (cntY)
+ y1 = (int)((double)dy1 / (double)cntY);
+ else
+ y1 = 0;
+
+ int v34 = dx1 - cntX * x1;
+ int v35 = dy1 - cntY * y1;
+ Common::Point x2;
+ Common::Point y2(v34, v35);
+
+ if (v34)
+ x2.x = v34 / abs(v34);
+ else
+ x2.x = 0;
+
+ if (v35)
+ x2.y = v35 / abs(v35);
+ else
+ x2.y = 0;
+
+ MessageQueue *mq = new MessageQueue(g_fp->_globalMessageQueueList->compact());
+ ExCommand *ex;
+
+ if (info->flags & 2) {
+ ex = new ExCommand(
+ _items2[info->index]->_objectId,
+ 5,
+ _items2[info->index]->_subItems[info->subIndex]._walk[1]._movementId,
+ info->pt1.x,
+ info->pt1.y,
+ 0,
+ 1,
+ 0,
+ 0,
+ 0);
+
+ ex->_field_14 = info->distance1;
+
+ ex->_keyCode = _items2[info->index]->_obj->_okeyCode;
+ ex->_field_24 = 1;
+ ex->_excFlags |= 2;
+ } else {
+ ex = new ExCommand(
+ _items2[info->index]->_objectId,
+ 5,
+ _items2[info->index]->_subItems[info->subIndex]._walk[0]._movementId,
+ info->pt1.x,
+ info->pt1.y,
+ 0,
+ 1,
+ 0,
+ 0,
+ 0);
+
+ ex->_field_14 = info->distance1;
+
+ ex->_keyCode = _items2[info->index]->_obj->_okeyCode;
+ ex->_field_24 = 1;
+ ex->_excFlags |= 2;
+ mq->addExCommandToEnd(ex);
+
+ ex = _mgm.buildExCommand2(
+ _items2[info->index]->_subItems[info->subIndex]._walk[0]._mov,
+ _items2[info->index]->_objectId,
+ x1,
+ y1,
+ &x2,
+ &y2,
+ -1);
+ ex->_parId = mq->_id;
+ ex->_keyCode = _items2[info->index]->_obj->_okeyCode;
+ }
+
+ mq->addExCommandToEnd(ex);
+
+ for (int i = 0; i < mgmLen; ++i) {
+ int par;
+
+ if (i == mgmLen - 1)
+ par = a2;
+ else
+ par = -1;
+
+ ex = _mgm.buildExCommand2(
+ _items2[info->index]->_subItems[info->subIndex]._walk[1]._mov,
+ _items2[info->index]->_objectId,
+ x1,
+ y1,
+ &x2,
+ &y2,
+ par);
+ ex->_parId = mq->_id;
+ ex->_keyCode = _items2[info->index]->_obj->_okeyCode;
+ mq->addExCommandToEnd(ex);
+ }
+
+ if (!(info->flags & 4)) {
+ ex = _mgm.buildExCommand2(
+ _items2[info->index]->_subItems[info->subIndex]._walk[2]._mov,
+ _items2[info->index]->_objectId,
+ x1,
+ y1,
+ &x2,
+ &y2,
+ -1);
+ ex->_parId = mq->_id;
+ ex->_keyCode = _items2[info->index]->_obj->_okeyCode;
+
+ mq->addExCommandToEnd(ex);
+ }
+
+ ex = new ExCommand(_items2[info->index]->_objectId, 5, -1, info->pt2.x, info->pt2.y, 0, 1, 0, 0, 0);
+ ex->_field_14 = info->distance2;
+
+ ex->_keyCode = _items2[info->index]->_obj->_okeyCode;
+ ex->_field_24 = 0;
+ ex->_excFlags |= 2;
+
+ mq->addExCommandToEnd(ex);
+
+ return mq;
+}
+
+MovGraphLink *MovGraph2::findLink1(int x, int y, int idx, int fuzzyMatch) {
+ Common::Point point;
+ MovGraphLink *res = 0;
+
+ for (ObList::iterator i = _links.begin(); i != _links.end(); ++i) {
+ assert(((CObject *)*i)->_objtype == kObjTypeMovGraphLink);
+
+ MovGraphLink *lnk = (MovGraphLink *)*i;
+
+ if (fuzzyMatch) {
+ point.x = x;
+ point.y = y;
+ double dst = calcDistance(&point, lnk, 0);
+
+ if (dst >= 0.0 && dst < 2.0)
+ return lnk;
+ } else if (!(lnk->_flags & 0x20000000)) {
+ if (lnk->_movGraphReact->pointInRegion(x, y)) {
+ if (abs(lnk->_movGraphNode1->_x - lnk->_movGraphNode2->_x) <= abs(lnk->_movGraphNode1->_y - lnk->_movGraphNode2->_y)) {
+ if (idx == 2 || idx == 3)
+ return lnk;
+ res = lnk;
+ } else {
+ if (idx == 1 || !idx)
+ return lnk;
+ res = lnk;
+ }
+ }
+ }
+ }
+
+ return res;
+}
+
+MovGraphLink *MovGraph2::findLink2(int x, int y) {
+ double mindist = 1.0e20;
+ MovGraphLink *res = 0;
+
+ for (ObList::iterator i = _links.begin(); i != _links.end(); ++i) {
+ assert(((CObject *)*i)->_objtype == kObjTypeMovGraphLink);
+
+ MovGraphLink *lnk = (MovGraphLink *)*i;
+
+ if (!(lnk->_flags & 0x20000000)) {
+ double n1x = lnk->_movGraphNode1->_x;
+ double n1y = lnk->_movGraphNode1->_y;
+ double n2x = lnk->_movGraphNode2->_x;
+ double n2y = lnk->_movGraphNode2->_y;
+ double n1dx = n1x - x;
+ double n1dy = n1y - y;
+ double dst1 = sqrt(n1dy * n1dy + n1dx * n1dx);
+ double coeff1 = ((n1y - n2y) * n1dy + (n2x - n1x) * n1dx) / lnk->_distance / dst1;
+ double dst3 = coeff1 * dst1;
+ double dst2 = sqrt(1.0 - coeff1 * coeff1) * dst1;
+
+ if (coeff1 * dst1 < 0.0) {
+ dst3 = 0.0;
+ dst2 = sqrt(n1dy * n1dy + n1dx * n1dx);
+ }
+ if (dst3 > lnk->_distance) {
+ dst3 = lnk->_distance;
+ dst2 = sqrt((n2x - x) * (n2x - x) + (n2y - y) * (n2y - y));
+ }
+ if (dst3 >= 0.0 && dst3 <= lnk->_distance && dst2 < mindist) {
+ mindist = dst2;
+ res = lnk;
+ }
+ }
+ }
+
+ if (mindist < 1.0e20)
+ return res;
+ else
+ return 0;
+}
+
+double MovGraph2::findMinPath(LinkInfo *linkInfoSource, LinkInfo *linkInfoDest, Common::Array<MovGraphLink *> *listObj) {
+ LinkInfo linkInfoWorkSource;
+
+ if (linkInfoSource->link != linkInfoDest->link || linkInfoSource->node != linkInfoDest->node) {
+ double minDistance = -1.0;
+
+ if (linkInfoSource->node) {
+ for (ObList::iterator i = _links.begin(); i != _links.end(); ++i) {
+ MovGraphLink *lnk = (MovGraphLink *)*i;
+
+ if ((lnk->_movGraphNode1 == linkInfoSource->node || lnk->_movGraphNode2 == linkInfoSource->node) && !(lnk->_flags & 0xA0000000)) {
+ linkInfoWorkSource.node = 0;
+ linkInfoWorkSource.link = lnk;
+
+ Common::Array<MovGraphLink *> tmpList;
+
+ lnk->_flags |= 0x80000000;
+
+ double newDistance = findMinPath(&linkInfoWorkSource, linkInfoDest, &tmpList);
+
+ if (newDistance >= 0.0 && (minDistance < 0.0 || newDistance + lnk->_distance < minDistance)) {
+ listObj->clear();
+ listObj->push_back(tmpList);
+
+ minDistance = newDistance + lnk->_distance;
+ }
+
+ lnk->_flags &= 0x7FFFFFFF;
+ }
+ }
+ } else if (linkInfoSource->link) {
+ linkInfoWorkSource.node = linkInfoSource->link->_movGraphNode1;
+ linkInfoWorkSource.link = 0;
+
+ Common::Array<MovGraphLink *> tmpList;
+
+ double newDistance = findMinPath(&linkInfoWorkSource, linkInfoDest, &tmpList);
+
+ if (newDistance >= 0.0) {
+ listObj->clear();
+
+ listObj->push_back(linkInfoSource->link);
+ listObj->push_back(tmpList);
+
+ minDistance = newDistance;
+ }
+
+ linkInfoWorkSource.link = 0;
+ linkInfoWorkSource.node = linkInfoSource->link->_movGraphNode2;
+
+ tmpList.clear();
+
+ newDistance = findMinPath(&linkInfoWorkSource, linkInfoDest, &tmpList);
+
+ if (newDistance >= 0 && (minDistance < 0.0 || newDistance < minDistance)) {
+ listObj->push_back(linkInfoSource->link);
+ listObj->push_back(tmpList);
+
+ minDistance = newDistance;
+ }
+ }
+
+ return minDistance;
+ } else {
+ if (linkInfoSource->link)
+ listObj->push_back(linkInfoSource->link);
+
+ return 0.0;
+ }
+}
+
MovGraphNode *MovGraph::calcOffset(int ox, int oy) {
- warning("STUB: MovGraph::calcOffset()");
+ MovGraphNode *res = 0;
+ double mindist = 1.0e10;
+
+ for (ObList::iterator i = _nodes.begin(); i != _nodes.end(); ++i) {
+ assert(((CObject *)*i)->_objtype == kObjTypeMovGraphNode);
+
+ MovGraphNode *node = (MovGraphNode *)*i;
+
+ double dist = sqrt((double)((node->_x - oy) * (node->_x - oy) + (node->_x - ox) * (node->_x - ox)));
+ if (dist < mindist) {
+ mindist = dist;
+ res = node;
+ }
+ }
+
+ return res;
+}
+
+void MGM::clear() {
+ _items.clear();
+}
+
+MGMItem::MGMItem() {
+ objId = 0;
+}
+
+MGMSubItem::MGMSubItem() {
+ movement = 0;
+ staticsIndex = 0;
+ field_8 = 0;
+ field_C = 0;
+ x = 0;
+ y = 0;
+}
+
+void MGM::addItem(int objId) {
+ if (getItemIndexById(objId) == -1) {
+ MGMItem *item = new MGMItem();
+
+ item->objId = objId;
+ _items.push_back(item);
+ }
+ rebuildTables(objId);
+}
+
+void MGM::rebuildTables(int objId) {
+ int idx = getItemIndexById(objId);
+
+ if (idx == -1)
+ return;
+
+ _items[idx]->subItems.clear();
+ _items[idx]->statics.clear();
+ _items[idx]->movements1.clear();
+ _items[idx]->movements2.clear();
+
+ StaticANIObject *obj = g_fp->_currentScene->getStaticANIObject1ById(objId, -1);
+
+ if (!obj)
+ return;
+
+ for (uint i = 0; i < obj->_staticsList.size(); i++)
+ _items[idx]->statics.push_back((Statics *)obj->_staticsList[i]);
+
+ 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) {
+ for (uint i = 0; i < _items.size(); i++)
+ if (_items[i]->objId == objId)
+ return i;
+
+ return -1;
+}
+
+MessageQueue *MGM::genMovement(MGMInfo *mgminfo) {
+ warning("STUB: MGM::genMovement()");
return 0;
}
+void MGM::updateAnimStatics(StaticANIObject *ani, int staticsId) {
+ if (getItemIndexById(ani->_id) == -1)
+ return;
+
+ if (ani->_movement) {
+ ani->queueMessageQueue(0);
+ ani->_movement->gotoLastFrame();
+ ani->_statics = ani->_movement->_staticsObj2;
+
+ int x = ani->_movement->_ox;
+ int y = ani->_movement->_oy;
+
+ ani->_movement = 0;
+
+ ani->setOXY(x, y);
+ }
+
+ if (ani->_statics) {
+ Common::Point point;
+
+ getPoint(&point, ani->_id, ani->_statics->_staticsId, staticsId);
+
+ ani->setOXY(ani->_ox + point.x, ani->_oy + point.y);
+
+ ani->_statics = ani->getStaticsById(staticsId);
+ }
+}
+
+Common::Point *MGM::getPoint(Common::Point *point, int objectId, int staticsId1, int staticsId2) {
+ int idx = getItemIndexById(objectId);
+
+ if (idx == -1) {
+ point->x = -1;
+ point->y = -1;
+ } else {
+ int st1idx = getStaticsIndexById(idx, staticsId1);
+ int st2idx = getStaticsIndexById(idx, staticsId2);
+
+ if (st1idx == st2idx) {
+ point->x = 0;
+ point->y = 0;
+ } else {
+ int subidx = st1idx + st2idx * _items[idx]->statics.size();
+
+ if (!_items[idx]->subItems[subidx]->movement) {
+ clearMovements2(idx);
+ recalcOffsets(idx, st1idx, st2idx, false, true);
+
+ if (!_items[idx]->subItems[subidx]->movement) {
+ clearMovements2(idx);
+ recalcOffsets(idx, st1idx, st2idx, true, false);
+ }
+ }
+
+ MGMSubItem *sub = _items[idx]->subItems[subidx];
+
+ if (sub->movement) {
+ point->x = sub->x;
+ point->y = sub->y;
+ } else {
+ point->x = 0;
+ point->y = 0;
+ }
+ }
+ }
+
+ return point;
+}
+
+int MGM::getStaticsIndexById(int idx, int16 id) {
+ if (!_items[idx]->statics.size())
+ return -1;
+
+ for (uint i = 0; i < _items[idx]->statics.size(); i++) {
+ if (_items[idx]->statics[i]->_staticsId == id)
+ return i;
+ }
+
+ return 0;
+}
+
+int MGM::getStaticsIndex(int idx, Statics *st) {
+ if (!_items[idx]->statics.size())
+ return -1;
+
+ for (uint i = 0; i < _items[idx]->statics.size(); i++) {
+ if (_items[idx]->statics[i] == st)
+ return i;
+ }
+
+ return 0;
+}
+
+void MGM::clearMovements2(int idx) {
+ _items[idx]->movements2.clear();
+}
+
+int MGM::recalcOffsets(int idx, int st1idx, int st2idx, bool flip, bool flop) {
+ warning("STUB: MGM::recalcOffsets()");
+
+ return 0;
+}
+
+Common::Point *MGM::calcLength(Common::Point *pRes, Movement *mov, int x, int y, int *x1, int *y1, int flag) {
+ Common::Point point;
+
+ mov->calcSomeXY(point, 0);
+ int p1x = point.x;
+ int p1y = point.y;
+
+ int newx1 = 0;
+ int oldy1 = *y1;
+
+ if (abs(p1y) > abs(p1x)) {
+ if (mov->calcSomeXY(point, 0)->y)
+ newx1 = (int)((double)y / point.y);
+ } else if (mov->calcSomeXY(point, 0)->x) {
+ newx1 = (int)((double)x / point.y);
+ }
+
+ if (newx1 < 0)
+ newx1 = 0;
+
+ *x1 = newx1;
+
+ int phase = 1;
+ int sz;
+
+ if (flag) {
+ if (abs(p1y) > abs(p1x)) {
+ while (abs(p1y * newx1 + mov->calcSomeXY(point, 0)->y) < abs(y)) {
+ sz = mov->_currMovement ? mov->_currMovement->_dynamicPhases.size() : mov->_dynamicPhases.size();
+
+ if (phase >= sz) {
+ phase--;
+
+ break;
+ }
+
+ phase++;
+ }
+ } else {
+ while (abs(p1x * newx1 + mov->calcSomeXY(point, 0)->x) < abs(x)) {
+ sz = mov->_currMovement ? mov->_currMovement->_dynamicPhases.size() : mov->_dynamicPhases.size();
+
+ if (phase >= sz) {
+ phase--;
+
+ break;
+ }
+
+ phase++;
+ }
+ }
+
+ *y1 = phase - 1;
+ } else {
+ *y1 = -1;
+ }
+
+ int p2x = 0;
+ int p2y = 0;
+
+ if (!oldy1)
+ oldy1 = -1;
+
+ if (oldy1 > 0) {
+ ++*x1;
+
+ mov->calcSomeXY(point, 0);
+ p2x = point.x;
+ p2y = point.y;
+
+ if (abs(p1y) > abs(p1x))
+ p2x = p1x;
+ else
+ p2y = p1y;
+ }
+
+ pRes->x = p2x + p1x * newx1;
+ pRes->y = p2y + p1y * newx1;
+
+ return pRes;
+}
+
+ExCommand2 *MGM::buildExCommand2(Movement *mov, int objId, int x1, int y1, Common::Point *x2, Common::Point *y2, int len) {
+ uint cnt;
+
+ if (mov->_currMovement)
+ cnt = mov->_currMovement->_dynamicPhases.size();
+ else
+ cnt = mov->_dynamicPhases.size();
+
+ if (len > 0 && cnt > (uint)len)
+ cnt = len;
+
+ Common::Point **points = (Common::Point **)malloc(sizeof(Common::Point *) * cnt);
+
+ for (uint i = 0; i < cnt; i++) {
+ int flags = mov->getDynamicPhaseByIndex(i)->getDynFlags();
+
+ points[i] = new Common::Point;
+
+ if (flags & 1) {
+ points[i]->x = x1 + x2->x;
+
+ y2->x -= x2->x;
+
+ if (!y2->x)
+ x2->x = 0;
+ }
+
+ if (flags & 2) {
+ points[i]->y = y1 + x2->y;
+
+ y2->y -= x2->y;
+
+ if (!y2->y)
+ x2->y = 0;
+ }
+ }
+
+ ExCommand2 *ex = new ExCommand2(20, objId, points, cnt);
+ ex->_excFlags = 2;
+ ex->_messageNum = mov->_id;
+ ex->_field_14 = len;
+ ex->_field_24 = 1;
+ ex->_keyCode = -1;
+
+ for (uint i = 0; i < cnt; i++)
+ delete points[i];
+
+ free(points);
+
+ return ex;
+}
MovGraphLink::MovGraphLink() {
_distance = 0;
@@ -196,8 +2063,15 @@ MovGraphLink::MovGraphLink() {
_field_38 = 0;
_movGraphReact = 0;
_name = 0;
+
+ _objtype = kObjTypeMovGraphLink;
+}
+
+MovGraphLink::~MovGraphLink() {
+ warning("STUB: MovGraphLink::~MovGraphLink()");
}
+
bool MovGraphLink::load(MfcArchive &file) {
debug(5, "MovGraphLink::load()");
@@ -222,6 +2096,16 @@ bool MovGraphLink::load(MfcArchive &file) {
return true;
}
+void MovGraphLink::calcNodeDistanceAndAngle() {
+ if (_movGraphNode1) {
+ double dx = _movGraphNode2->_x - _movGraphNode1->_x;
+ double dy = _movGraphNode2->_y - _movGraphNode1->_y;
+
+ _distance = sqrt(dy * dy + dx * dx);
+ _angle = atan2(dx, dy);
+ }
+}
+
bool MovGraphNode::load(MfcArchive &file) {
debug(5, "MovGraphNode::load()");
@@ -238,7 +2122,6 @@ ReactParallel::ReactParallel() {
_x2 = 0;
_dy = 0;
_dx = 0;
- _points = 0;
_y1 = 0;
_y2 = 0;
}
@@ -264,7 +2147,7 @@ void ReactParallel::createRegion() {
for (int i = 0; i < 4; i++)
_points[i] = new Common::Point;
- double at = atan2((double)(_x1 - _x2), (double)(_y1 - _y2)) + 1.570796;
+ double at = atan2((double)(_x1 - _x2), (double)(_y1 - _y2)) + 1.570796; // pi/2
double sn = sin(at);
double cs = cos(at);
@@ -274,27 +2157,38 @@ void ReactParallel::createRegion() {
_points[1]->x = (int16)(_x2 - _dx * cs);
_points[1]->y = (int16)(_y2 - _dx * sn);
- _points[2]->x = (int16)(_x1 + _dy * cs);
+ _points[2]->x = (int16)(_x2 + _dy * cs);
_points[2]->y = (int16)(_y2 + _dy * sn);
_points[3]->x = (int16)(_x1 + _dy * cs);
_points[3]->y = (int16)(_y1 + _dy * sn);
+ _pointCount = 4;
// GdiObject::Attach(_rgn, CreatePolygonRgn(_points, 4, 2);
}
+void ReactParallel::setCenter(int x1, int y1, int x2, int y2) {
+ _x1 = x1;
+ _y1 = y1;
+ _x2 = x2;
+ _y2 = y2;
+}
+
ReactPolygonal::ReactPolygonal() {
- _field_C = 0;
- _points = 0;
- _pointCount = 0;
- _field_10 = 0;
+ _centerX = 0;
+ _centerY = 0;
+ _bbox = 0;
+}
+
+ReactPolygonal::~ReactPolygonal() {
+ delete _bbox;
}
bool ReactPolygonal::load(MfcArchive &file) {
debug(5, "ReactPolygonal::load()");
- _field_C = file.readUint32LE();
- _field_10 = file.readUint32LE();
+ _centerX = file.readUint32LE();
+ _centerY = file.readUint32LE();
_pointCount = file.readUint32LE();
if (_pointCount > 0) {
@@ -321,17 +2215,110 @@ void ReactPolygonal::createRegion() {
}
}
+void ReactPolygonal::setCenter(int x1, int y1, int x2, int y2) {
+ int cX = (x2 + x1) / 2;
+ int cY = (y2 + y1) / 2;
+
+ if (_points) {
+ for (int i = 0; i < _pointCount; i++) {
+ _points[i]->x += cX - _centerX;
+ _points[i]->y += cY - _centerY;
+ }
+ }
+
+ _centerX = cX;
+ _centerY = cY;
+}
+
+void ReactPolygonal::getBBox(Common::Rect *rect) {
+ if (!_pointCount)
+ return;
+
+ if (_bbox) {
+ *rect = *_bbox;
+ return;
+ }
+
+ rect->left = _points[0]->x;
+ rect->top = _points[0]->y;
+ rect->right = _points[0]->x;
+ rect->bottom = _points[0]->y;
+
+ for (int i = 1; i < _pointCount; i++) {
+ if (rect->left > _points[i]->x)
+ rect->left = _points[i]->x;
+
+ if (rect->top < _points[i]->y)
+ rect->top = _points[i]->y;
+
+ if (rect->right < _points[i]->x)
+ rect->right = _points[i]->x;
+
+ if (rect->bottom > _points[i]->y)
+ rect->bottom = _points[i]->y;
+ }
+
+ _bbox = new Common::Rect;
+ *_bbox = *rect;
+}
+
+
+bool MovGraphReact::pointInRegion(int x, int y) {
+ if (_pointCount < 3) {
+ return false;
+ }
+
+ int counter = 0;
+ double xinters;
+ Common::Point p, p1, p2;
+
+ p.x = x;
+ p.y = y;
+
+ p1.x = _points[0]->x;
+ p1.y = _points[0]->y;
+
+ for (int i = 1; i <= _pointCount; i++) {
+ p2.x = _points[i % _pointCount]->x;
+ p2.y = _points[i % _pointCount]->y;
+
+ if (p.y > MIN(p1.y, p2.y)) {
+ if (p.y <= MAX(p1.y, p2.y)) {
+ if (p.x <= MAX(p1.x, p2.x)) {
+ if (p1.y != p2.y) {
+ xinters = (p.y - p1.y) * (p2.x - p1.x) / (p2.y - p1.y) + p1.x;
+ if (p1.x == p2.x || p.x <= xinters) {
+ counter++;
+ }
+ }
+ }
+ }
+ }
+ p1 = p2;
+ }
+
+ if (counter % 2 == 0) {
+ return false;
+ } else {
+ return true;
+ }
+}
+
int startWalkTo(int objId, int objKey, int x, int y, int a5) {
- MctlCompound *mc = getSc2MctlCompoundBySceneId(g_fullpipe->_currentScene->_sceneId);
+ MctlCompound *mc = getSc2MctlCompoundBySceneId(g_fp->_currentScene->_sceneId);
if (mc)
- return (mc->method34(g_fullpipe->_currentScene->getStaticANIObject1ById(objId, objKey), x, y, a5, 0) != 0);
+ return (mc->method34(g_fp->_currentScene->getStaticANIObject1ById(objId, objKey), x, y, a5, 0) != 0);
return 0;
}
int doSomeAnimation(int objId, int objKey, int a3) {
- warning("STUB: doSomeAnimation(%d, %d, %d)", objId, objKey, a3);
+ StaticANIObject *ani = g_fp->_currentScene->getStaticANIObject1ById(objId, objKey);
+ MctlCompound *cmp = getCurrSceneSc2MotionController();
+
+ if (ani && cmp)
+ return cmp->method3C(ani, a3);
return 0;
}
diff --git a/engines/fullpipe/motion.h b/engines/fullpipe/motion.h
index b0bfe92d1f..6ad46e719a 100644
--- a/engines/fullpipe/motion.h
+++ b/engines/fullpipe/motion.h
@@ -25,6 +25,13 @@
namespace Fullpipe {
+class Statics;
+class Movement;
+class MctlConnectionPoint;
+class MovGraphLink;
+class MessageQueue;
+class ExCommand2;
+
int startWalkTo(int objId, int objKey, int x, int y, int a5);
int doSomeAnimation(int objId, int objKey, int a3);
int doSomeAnimation2(int objId, int objKey);
@@ -42,88 +49,196 @@ public:
virtual void method10() {}
virtual void clearEnabled() { _isEnabled = false; }
virtual void setEnabled() { _isEnabled = true; }
- virtual int addObject(StaticANIObject *obj) { return 0; }
+ virtual void addObject(StaticANIObject *obj) {}
virtual int removeObject(StaticANIObject *obj) { return 0; }
virtual void freeItems() {}
virtual int method28() { return 0; }
- virtual int method2C() { return 0; }
+ virtual int method2C(StaticANIObject *obj, int x, int y) { return 0; }
virtual int method30() { return 0; }
- virtual MessageQueue *method34(StaticANIObject *subj, int xpos, int ypos, int flag, int staticsId) { return 0; }
+ virtual MessageQueue *method34(StaticANIObject *subj, int xpos, int ypos, int fuzzyMatch, int staticsId) { return 0; }
virtual int changeCallback() { return 0; }
- virtual int method3C() { return 0; }
+ virtual int method3C(StaticANIObject *ani, int flag) { return 0; }
virtual int method40() { return 0; }
virtual int method44() { return 0; }
virtual int method48() { return -1; }
- virtual MessageQueue *method4C(StaticANIObject *subj, int xpos, int ypos, int flag, int staticsId) { return 0; }
+ virtual MessageQueue *doWalkTo(StaticANIObject *subj, int xpos, int ypos, int fuzzyMatch, int staticsId) { return 0; }
+
+ void enableLinks(const char *linkName, bool enable);
+ MovGraphLink *getLinkByName(const char *name);
};
-class MctlCompoundArray : public Common::Array<CObject>, public CObject {
- public:
- virtual bool load(MfcArchive &file);
+class MovGraphReact : public CObject {
+public:
+ int _pointCount;
+ Common::Point **_points;
+
+public:
+ MovGraphReact() : _pointCount(0), _points(0) {}
+ ~MovGraphReact() { free(_points); }
+
+ virtual void setCenter(int x1, int y1, int x2, int y2) {}
+ virtual void createRegion() {}
+ virtual bool pointInRegion(int x, int y);
+};
+
+class MctlCompoundArrayItem : public CObject {
+public:
+ MotionController *_motionControllerObj;
+ MovGraphReact *_movGraphReactObj;
+ Common::Array<MctlConnectionPoint *> _connectionPoints;
+ int _field_20;
+ int _field_24;
+ int _field_28;
+
+public:
+ MctlCompoundArrayItem() : _movGraphReactObj(0), _motionControllerObj(0), _field_20(0), _field_24(0), _field_28(0) {}
+ ~MctlCompoundArrayItem();
};
-class MctlConnectionPointsArray : public Common::Array<CObject>, public CObject {
+class MctlCompoundArray : public Common::Array<MctlCompoundArrayItem *>, public CObject {
public:
virtual bool load(MfcArchive &file);
};
class MctlCompound : public MotionController {
+public:
MctlCompoundArray _motionControllers;
- public:
MctlCompound() { _objtype = kObjTypeMctlCompound; }
virtual bool load(MfcArchive &file);
- virtual int addObject(StaticANIObject *obj);
+ virtual void addObject(StaticANIObject *obj);
virtual int removeObject(StaticANIObject *obj);
virtual void freeItems();
- virtual MessageQueue *method34(StaticANIObject *subj, int xpos, int ypos, int flag, int staticsId);
- virtual MessageQueue *method4C(StaticANIObject *subj, int xpos, int ypos, int flag, int staticsId);
+ virtual MessageQueue *method34(StaticANIObject *subj, int xpos, int ypos, int fuzzyMatch, int staticsId);
+ virtual MessageQueue *doWalkTo(StaticANIObject *subj, int xpos, int ypos, int fuzzyMatch, int staticsId);
void initMovGraph2();
+ MctlConnectionPoint *findClosestConnectionPoint(int ox, int oy, int destIndex, int connectionX, int connectionY, int sourceIndex, int *minDistancePtr);
+ void replaceNodeX(int from, int to);
+
+ uint getMotionControllerCount() { return _motionControllers.size(); }
+ MotionController *getMotionController(int num) { return _motionControllers[num]->_motionControllerObj; }
};
-class Unk2 : public CObject {
- int _items;
- int _count;
+struct MGMSubItem {
+ Movement *movement;
+ int staticsIndex;
+ int field_8;
+ int field_C;
+ int x;
+ int y;
- public:
- Unk2() : _items(0), _count(0) {}
+ MGMSubItem();
+};
+
+struct MGMItem {
+ int16 objId;
+ Common::Array<MGMSubItem *> subItems;
+ Common::Array<Statics *> statics;
+ Common::Array<Movement *> movements1;
+ Common::Array<Movement *> movements2;
+
+ MGMItem();
+};
+
+struct MGMInfo {
+ StaticANIObject *ani;
+ int staticsId1;
+ int staticsId2;
+ int movementId;
+ int field_10;
+ int x1;
+ int y1;
+ int field_1C;
+ int x2;
+ int y2;
+ int flags;
+
+ MGMInfo() { memset(this, 0, sizeof(MGMInfo)); }
+};
+
+class MGM : public CObject {
+public:
+ Common::Array<MGMItem *> _items;
+
+public:
+ void clear();
+ void addItem(int objId);
+ void rebuildTables(int objId);
+ int getItemIndexById(int objId);
+
+ MessageQueue *genMovement(MGMInfo *mgminfo);
+ void updateAnimStatics(StaticANIObject *ani, int staticsId);
+ Common::Point *getPoint(Common::Point *point, int aniId, int staticsId1, int staticsId2);
+ int getStaticsIndexById(int idx, int16 id);
+ int getStaticsIndex(int idx, Statics *st);
+ void clearMovements2(int idx);
+ int recalcOffsets(int idx, int st1idx, int st2idx, bool flip, bool flop);
+ Common::Point *calcLength(Common::Point *point, Movement *mov, int x, int y, int *x1, int *y1, int flag);
+ ExCommand2 *buildExCommand2(Movement *mov, int objId, int x1, int y1, Common::Point *x2, Common::Point *y2, int len);
+};
+
+struct MctlLadderMovementVars {
+ int varUpGo;
+ int varDownGo;
+ int varUpStop;
+ int varDownStop;
+ int varUpStart;
+ int varDownStart;
+};
+
+struct MctlLadderMovement {
+ int objId;
+ int staticIdsSize;
+ MctlLadderMovementVars *movVars;
+ int *staticIds;
+};
+
+class MctlLadder : public MotionController {
+public:
+ int _ladderX;
+ int _ladderY;
+ int _ladder_field_14;
+ int _width;
+ int _height;
+ int _ladder_field_20;
+ int _ladder_field_24;
+ Common::List<MctlLadderMovement *> _movements;
+ MGM _mgm;
+
+public:
+ MctlLadder();
+ virtual ~MctlLadder();
+ int collisionDetection(StaticANIObject *man);
+
+ virtual void addObject(StaticANIObject *obj);
+ virtual int removeObject(StaticANIObject *obj) { return 1; }
+ virtual void freeItems();
+ virtual MessageQueue *method34(StaticANIObject *subj, int xpos, int ypos, int fuzzyMatch, int staticsId);
+ virtual MessageQueue *doWalkTo(StaticANIObject *subj, int xpos, int ypos, int fuzzyMatch, int staticsId);
+
+ MessageQueue *controllerWalkTo(StaticANIObject *ani, int off);
+
+private:
+ int findObjectPos(StaticANIObject *obj);
+ bool initMovement(StaticANIObject *ani, MctlLadderMovement *movement);
};
class MovGraphNode : public CObject {
- public:
+public:
int _x;
int _y;
int _distance;
int16 _field_10;
int _field_14;
- public:
- MovGraphNode() : _x(0), _y(0), _distance(0), _field_10(0), _field_14(0) {}
+public:
+ MovGraphNode() : _x(0), _y(0), _distance(0), _field_10(0), _field_14(0) { _objtype = kObjTypeMovGraphNode; }
virtual bool load(MfcArchive &file);
};
-class MovGraphReact : public CObject {
- // Empty
-};
-
-class MctlCompoundArrayItem : public CObject {
- friend class MctlCompound;
-
- protected:
- MotionController *_motionControllerObj;
- MovGraphReact *_movGraphReactObj;
- MctlConnectionPointsArray _connectionPoints;
- int _field_20;
- int _field_24;
- int _field_28;
-
- public:
- MctlCompoundArrayItem() : _movGraphReactObj(0) {}
-};
-
class ReactParallel : public MovGraphReact {
//CRgn _rgn;
int _x1;
@@ -132,25 +247,30 @@ class ReactParallel : public MovGraphReact {
int _y2;
int _dx;
int _dy;
- Common::Point **_points;
- public:
+public:
ReactParallel();
virtual bool load(MfcArchive &file);
- void createRegion();
+
+ virtual void setCenter(int x1, int y1, int x2, int y2);
+ virtual void createRegion();
};
class ReactPolygonal : public MovGraphReact {
- //CRgn _rgn;
- int _field_C;
- int _field_10;
- int _pointCount;
- Common::Point **_points;
+ Common::Rect *_bbox;
+ int _centerX;
+ int _centerY;
- public:
+public:
ReactPolygonal();
+ ~ReactPolygonal();
+
virtual bool load(MfcArchive &file);
- void createRegion();
+
+ virtual void setCenter(int x1, int y1, int x2, int y2);
+ virtual void createRegion();
+
+ void getBBox(Common::Rect *rect);
};
class MovGraphLink : public CObject {
@@ -169,38 +289,162 @@ class MovGraphLink : public CObject {
public:
MovGraphLink();
+ virtual ~MovGraphLink();
+
virtual bool load(MfcArchive &file);
+
+ void calcNodeDistanceAndAngle();
+};
+
+struct MovGraphItem {
+ StaticANIObject *ani;
+ int field_4;
+ int field_8;
+ int field_C;
+ int field_10;
+ int field_14;
+ int field_18;
+ int field_1C;
+ int field_20;
+ int field_24;
+ int items;
+ int count;
+ int field_30;
+ int field_34;
+ int field_38;
+ int field_3C;
+
+ MovGraphItem();
};
class MovGraph : public MotionController {
- public:
+public:
ObList _nodes;
ObList _links;
int _field_44;
- int _items;
- int _itemsCount;
+ Common::Array<MovGraphItem *> _items;
int (*_callback1)(int, int, int);
- Unk2 _unk2;
+ MGM _mgm;
- public:
+public:
MovGraph();
- virtual bool load(MfcArchive &file);
+ virtual ~MovGraph();
- virtual int addObject(StaticANIObject *obj);
+ virtual bool load(MfcArchive &file);
- double calcDistance(Common::Point *point, MovGraphLink *link, int flag);
+ virtual void addObject(StaticANIObject *obj);
+ virtual int removeObject(StaticANIObject *obj);
+ virtual void freeItems();
+ virtual int method28();
+ virtual int method2C(StaticANIObject *obj, int x, int y);
+ virtual MessageQueue *method34(StaticANIObject *subj, int xpos, int ypos, int fuzzyMatch, int staticsId);
+ virtual int changeCallback();
+ virtual int method3C(StaticANIObject *ani, int flag);
+ virtual int method44();
+ virtual MessageQueue *doWalkTo(StaticANIObject *subj, int xpos, int ypos, int fuzzyMatch, int staticsId);
+ virtual int method50();
+
+ double calcDistance(Common::Point *point, MovGraphLink *link, int fuzzyMatch);
+ void calcNodeDistancesAndAngles();
MovGraphNode *calcOffset(int ox, int oy);
};
+class Movement;
+
+struct MG2I {
+ int _movementId;
+ Movement *_mov;
+ int _mx;
+ int _my;
+};
+
+struct MovGraph2ItemSub {
+ int _staticsId2;
+ int _staticsId1;
+ MG2I _walk[3];
+ MG2I _turn[4];
+ MG2I _turnS[4];
+};
+
+struct LinkInfo {
+ MovGraphLink *link;
+ MovGraphNode *node;
+};
+
+struct MovInfo1Sub {
+ int subIndex;
+ int x;
+ int y;
+ int distance;
+};
+
+struct MovInfo1 {
+ int index;
+ Common::Point pt1;
+ Common::Point pt2;
+ int distance1;
+ int distance2;
+ int subIndex;
+ int item1Index;
+ Common::Array<MovInfo1Sub *> items;
+ int itemsCount;
+ int flags;
+
+ MovInfo1() { clear(); }
+ MovInfo1(MovInfo1 *src);
+ void clear();
+};
+
+struct MovGraph2Item { // 744
+ int _objectId;
+ StaticANIObject *_obj;
+ MovGraph2ItemSub _subItems[4]; // 184
+};
+
+class MovGraph2 : public MovGraph {
+public:
+ Common::Array<MovGraph2Item *> _items2;
+
+public:
+ virtual void addObject(StaticANIObject *obj);
+ virtual int removeObject(StaticANIObject *obj);
+ virtual void freeItems();
+ virtual MessageQueue *method34(StaticANIObject *subj, int xpos, int ypos, int fuzzyMatch, int staticsId);
+ virtual MessageQueue *doWalkTo(StaticANIObject *subj, int xpos, int ypos, int fuzzyMatch, int staticsId);
+
+ int getItemIndexByGameObjectId(int objectId);
+ int getItemSubIndexByStaticsId(int index, int staticsId);
+ int getItemSubIndexByMovementId(int index, int movId);
+ int getItemSubIndexByMGM(int idx, StaticANIObject *ani);
+
+ int getShortSide(MovGraphLink *lnk, int x, int y);
+ int findLink(Common::Array<MovGraphLink *> *linkList, int idx, Common::Rect *a3, Common::Point *a4);
+
+ bool initDirections(StaticANIObject *obj, MovGraph2Item *item);
+ void buildMovInfo1SubItems(MovInfo1 *movinfo, Common::Array<MovGraphLink *> *linkList, LinkInfo *lnkSrc, LinkInfo *lnkDst);
+ MessageQueue *buildMovInfo1MessageQueue(MovInfo1 *movInfo);
+
+ MovGraphNode *findNode(int x, int y, int fuzzyMatch);
+ MovGraphLink *findLink1(int x, int y, int idx, int fuzzyMatch);
+ MovGraphLink *findLink2(int x, int y);
+ double findMinPath(LinkInfo *linkInfoSource, LinkInfo *linkInfoDest, Common::Array<MovGraphLink *> *listObj);
+
+ MessageQueue *genMovement(MovInfo1 *movinfo);
+};
+
class MctlConnectionPoint : public CObject {
+public:
int _connectionX;
int _connectionY;
int _field_C;
int _field_10;
int16 _field_14;
int16 _field_16;
- int _messageQueueObj;
+ MessageQueue *_messageQueueObj;
int _motionControllerObj;
+
+ MctlConnectionPoint();
+ ~MctlConnectionPoint();
};
} // End of namespace Fullpipe
diff --git a/engines/fullpipe/ngiarchive.cpp b/engines/fullpipe/ngiarchive.cpp
index 5d895c17a0..132f4758d3 100644
--- a/engines/fullpipe/ngiarchive.cpp
+++ b/engines/fullpipe/ngiarchive.cpp
@@ -91,7 +91,7 @@ NGIArchive::NGIArchive(const Common::String &filename) : _ngiFilename(filename)
free(fat);
- g_fullpipe->_currArchive = this;
+ g_fp->_currArchive = this;
debug(0, "NGIArchive::NGIArchive(%s): Located %d files", filename.c_str(), _headers.size());
}
@@ -103,7 +103,7 @@ NGIArchive::~NGIArchive() {
delete it->_value;
}
- g_fullpipe->_currArchive = 0;
+ g_fp->_currArchive = 0;
}
bool NGIArchive::hasFile(const Common::String &name) const {
diff --git a/engines/fullpipe/objectnames.h b/engines/fullpipe/objectnames.h
index 015df727e9..eafdb2a8e7 100644
--- a/engines/fullpipe/objectnames.h
+++ b/engines/fullpipe/objectnames.h
@@ -30,15 +30,16 @@ namespace Fullpipe {
#define sO_Grandma "\xc1\xe0\xe1\xf3\xeb\xff" // "БабулÑ"
#define sO_Jar_4 "\xc1\xe0\xed\xea\xe0_4" // "Банка_4"
#define sO_Pool "\xc1\xe0\xf1\xf1\xe5\xe9\xed" // "БаÑÑейн"
-#define sO_TumyTrampie "\xc1\xe0\xf2\xf3\xf2\xe0" // "Батута"
+#define sO_TummyTrampie "\xc1\xe0\xf2\xf3\xf2\xe0" // "Батута"
#define sO_WithoutBoot "\xc1\xe5\xe7 \xe1\xee\xf2\xe8\xed\xea\xe0" // "Без ботинка"
-#define sO_WithoutJug "\xc1\xe5\xe7 \xe3\xee\xf0\xf8\xea\xee\xe2" // "Без горшков"
+#define sO_WithoutJugs "\xc1\xe5\xe7 \xe3\xee\xf0\xf8\xea\xee\xe2" // "Без горшков"
#define sO_WithoutCarpet "\xc1\xe5\xe7 \xea\xee\xe2\xf0\xe8\xea\xe0" // "Без коврика"
#define sO_WithoutCoin "\xc1\xe5\xe7 \xec\xee\xed\xe5\xf2\xfb" // "Без монеты"
#define sO_WithNothing "\xc1\xe5\xe7 \xed\xe8\xf7\xe5\xe3\xee" // "Без ничего"
#define sO_WithoutHandle "\xc1\xe5\xe7 \xf0\xf3\xf7\xea\xe8" // "Без ручки"
#define sO_WithoutStool "\xc1\xe5\xe7 \xf2\xe0\xe1\xf3\xf0\xe5\xf2\xea\xe8" // "Без табуретки"
#define sO_WithoutDrawer "\xc1\xe5\xe7 \xff\xf9\xe8\xea\xe0" // "Без Ñщика"
+#define sO_Nearby "\xc1\xeb\xe8\xe7\xea\xee" // "Близко"
#define sO_Blocked "\xc1\xeb\xee\xea\xe8\xf0\xee\xe2\xe0\xed" // "Блокирован"
#define sO_BlockedShe "\xc1\xeb\xee\xea\xe8\xf0\xee\xe2\xe0\xed\xe0" // "Блокирована"
#define sO_Awaken "\xc1\xee\xe4\xf0\xf1\xf2\xe2\xf3\xe5\xf2" // "БодрÑтвует"
@@ -48,8 +49,14 @@ namespace Fullpipe {
#define sO_InSock "\xc2 \xed\xee\xf1\xea\xe5" // "Ð’ ноÑке"
#define sO_InGlasses "\xc2 \xee\xf7\xea\xe0\xf5" // "В очках"
#define sO_In_14 "\xc2_14" // "Ð’_14"
+#define sO_In_15 "\xc2_15" // "Ð’_15"
+#define sO_In_15_1 "\xc2_15_1" // "Ð’_15_1"
+#define sO_In_15_2 "\xc2_15_2" // "Ð’_15_2"
+#define sO_In_15_3 "\xc2_15_3" // "Ð’_15_3"
+#define sO_In_16 "\xc2_16" // "Ð’_16"
+#define sO_In_32 "\xc2_32" // "Ð’_32"
#define sO_In_32_Lies "\xc2_32 \xeb\xe5\xe6\xe8\xf2" // "В_32 лежит"
-#define sO_In_32_Stands "\xc2_32 \xf2\xee\xf0\xf7\xe8\xf2" // "В_32 торчит"
+#define sO_In_32_Sticks "\xc2_32 \xf2\xee\xf0\xf7\xe8\xf2" // "В_32 торчит"
#define sO_In_33 "\xc2_33" // "Ð’_33"
#define sO_In_7 "\xc2_7" // "Ð’_7"
#define sO_Together "\xc2\xe4\xe2\xee\xe5\xec" // "Вдвоем"
@@ -73,16 +80,17 @@ namespace Fullpipe {
#define sO_Jug "\xc3\xee\xf0\xf8\xee\xea" // "Горшок"
#define sO_Strolling "\xc3\xf3\xeb\xff\xe5\xf2" // "ГулÑет"
#define sO_Yes "\xc4\xe0" // "Да"
+#define sO_FarAway "\xc4\xe0\xeb\xe5\xea\xee" // "Далеко"
#define sO_Girl "\xc4\xe5\xe2\xee\xf7\xea\xe0" // "Девочка"
#define sO_Elephantine "\xc4\xe5\xe2\xee\xf7\xea\xe0-\xf1\xeb\xee\xed\xe8\xea" // "Девочка-Ñлоник"
#define sO_Grandpa "\xc4\xe5\xe4\xf3\xf8\xea\xe0" // "Дедушка"
-#define sO_Plank_25 "\xc4\xee\xf1\xea\xe0_25" // "ДоÑка_25"
+#define sO_Board_25 "\xc4\xee\xf1\xea\xe0_25" // "ДоÑка_25"
#define sO_Plank_34 "\xc4\xee\xf1\xea\xe0_34" // "ДоÑка_34"
-#define sO_DudeJumped "\xc4\xff\xe4\xff \xef\xf0\xfb\xe3\xe0\xeb" // "ДÑÐ´Ñ Ð¿Ñ€Ñ‹Ð³Ð°Ð»"
+#define sO_DudeHasJumped "\xc4\xff\xe4\xff \xef\xf0\xfb\xe3\xe0\xeb" // "ДÑÐ´Ñ Ð¿Ñ€Ñ‹Ð³Ð°Ð»"
#define sO_Dude "\xc4\xff\xe4\xff" // "ДÑдÑ"
#define sO_GuvTheDrawer "\xc4\xff\xe4\xff-\xff\xf9\xe8\xea" // "ДÑдÑ-Ñщик"
#define sO_DudeSwinged "\xc4\xff\xe4\xff_\xea\xe0\xf2\xe0\xeb\xf1\xff" // "ДÑдÑ_каталÑÑ"
-#define sO_Eats "\xc5\xf1\xf2" // "ЕÑÑ‚"
+#define sO_IsEating "\xc5\xf1\xf2" // "ЕÑÑ‚"
#define sO_Present "\xc5\xf1\xf2\xfc" // "ЕÑÑ‚ÑŒ"
#define sO_CloseThing1 "\xc7\xe0\xea\xf0\xfb\xe2\xe0\xe5\xec\xee\xe5 1" // "Закрываемое 1"
#define sO_CloseThing2 "\xc7\xe0\xea\xf0\xfb\xe2\xe0\xe5\xec\xee\xe5 2" // "Закрываемое 2"
@@ -90,15 +98,15 @@ namespace Fullpipe {
#define sO_CloseThing "\xc7\xe0\xea\xf0\xfb\xe2\xe0\xe5\xec\xee\xe5" // "Закрываемое"
#define sO_Closed "\xc7\xe0\xea\xf0\xfb\xf2" // "Закрыт"
#define sO_ClosedWithBoot "\xc7\xe0\xea\xf0\xfb\xf2\xe0 \xf1 \xe1\xee\xf2\xe8\xed\xea\xee\xec" // "Закрыта Ñ Ð±Ð¾Ñ‚Ð¸Ð½ÐºÐ¾Ð¼"
-#define sO_ClosedShe "\xc7\xe0\xea\xf0\xfb\xf2\xe0" // "Закрыта"
+#define sO_IsClosed "\xc7\xe0\xea\xf0\xfb\xf2\xe0" // "Закрыта"
#define sO_HalfFull "\xc7\xe0\xef\xee\xeb\xed\xe5\xed \xed\xe0\xef\xee\xeb\xee\xe2\xe8\xed\xf3" // "Заполнен наполовину"
#define sO_Full "\xc7\xe0\xef\xee\xeb\xed\xe5\xed \xf6\xe5\xeb\xe8\xea\xee\xec" // "Заполнен целиком"
#define sO_MirroredTo "\xc7\xe5\xf0\xea\xe0\xeb\xfc\xed\xe0\xff \xea" // "Ð—ÐµÑ€ÐºÐ°Ð»ÑŒÐ½Ð°Ñ Ðº"
-#define sO_Playing "\xc8\xe3\xf0\xe0\xe5\xf2" // "Играет"
+#define sO_IsPlaying "\xc8\xe3\xf0\xe0\xe5\xf2" // "Играет"
#define sO_Tub "\xca\xe0\xe4\xea\xe0" // "Кадка"
#define sO_Cactus "\xca\xe0\xea\xf2\xf3\xf1" // "КактуÑ"
-#define sO_SwingingWithBoot "\xca\xe0\xf2\xe0\xe5\xf2\xf1\xff \xf1 \xe1\xee\xf2\xe8\xed\xea\xee\xec" // "КатаетÑÑ Ñ Ð±Ð¾Ñ‚Ð¸Ð½ÐºÐ¾Ð¼"
-#define sO_Swinging "\xca\xe0\xf2\xe0\xe5\xf2\xf1\xff" // "КатаетÑÑ"
+#define sO_IsSwingingWithBoot "\xca\xe0\xf2\xe0\xe5\xf2\xf1\xff \xf1 \xe1\xee\xf2\xe8\xed\xea\xee\xec" // "КатаетÑÑ Ñ Ð±Ð¾Ñ‚Ð¸Ð½ÐºÐ¾Ð¼"
+#define sO_IsSwinging "\xca\xe0\xf2\xe0\xe5\xf2\xf1\xff" // "КатаетÑÑ"
#define sO_Swingie "\xca\xe0\xf7\xe5\xeb\xe5\xed\xff" // "КачеленÑ"
#define sO_LiftButtons "\xca\xed\xee\xef\xea\xe8 \xeb\xe8\xf4\xf2\xe0" // "Кнопки лифта"
#define sO_Carpet_35 "\xca\xee\xe2\xf0\xe8\xea_35" // "Коврик_35"
@@ -110,7 +118,7 @@ namespace Fullpipe {
#define sO_LeftPipe_29 "\xcb\xe5\xe2\xe0\xff \xf2\xf0\xf3\xe1\xe0_29" // "Ð›ÐµÐ²Ð°Ñ Ñ‚Ñ€ÑƒÐ±Ð°_29"
#define sO_LeftPipe_30 "\xcb\xe5\xe2\xe0\xff \xf2\xf0\xf3\xe1\xe0_30" // "Ð›ÐµÐ²Ð°Ñ Ñ‚Ñ€ÑƒÐ±Ð°_30"
#define sO_LeftPipe_37 "\xcb\xe5\xe2\xe0\xff \xf2\xf0\xf3\xe1\xe0_37" // "Ð›ÐµÐ²Ð°Ñ Ñ‚Ñ€ÑƒÐ±Ð°_37"
-#define sO_StarsDown_24 "\xcb\xe5\xf1\xf2\xed\xe8\xf6\xe0 \xe2\xed\xe8\xe7_24" // "ЛеÑтница вниз_24"
+#define sO_StairsDown_24 "\xcb\xe5\xf1\xf2\xed\xe8\xf6\xe0 \xe2\xed\xe8\xe7_24" // "ЛеÑтница вниз_24"
#define sO_StairsUp_8 "\xcb\xe5\xf1\xf2\xed\xe8\xf6\xe0 \xf1\xe2\xe5\xf0\xf5\xf3_8" // "ЛеÑтница Ñверху_8"
#define sO_Stairway "\xcb\xe5\xf1\xf2\xed\xe8\xf6\xe0" // "ЛеÑтница"
#define sO_Fliers "\xcb\xe5\xf2\xf3\xed\xfb" // "Летуны"
@@ -135,7 +143,7 @@ namespace Fullpipe {
#define sO_NotGrown "\xcd\xe5 \xe2\xfb\xf0\xee\xf1" // "Ðе выроÑ"
#define sO_DidNotCrackEgg "\xcd\xe5 \xea\xee\xeb\xee\xeb \xff\xe9\xf6\xee" // "Ðе колол Ñйцо"
#define sO_NotFallen "\xcd\xe5 \xef\xe0\xe4\xe0\xeb" // "Ðе падал"
-#define sO_NotAvailable "\xcd\xe5\xe4\xee\xf1\xf2\xf3\xef\xed\xe0" // "ÐедоÑтупна"
+#define sO_IsNotAvailable "\xcd\xe5\xe4\xee\xf1\xf2\xf3\xef\xed\xe0" // "ÐедоÑтупна"
#define sO_CannotTake "\xcd\xe5\xeb\xfc\xe7\xff \xe2\xe7\xff\xf2\xfc" // "ÐÐµÐ»ÑŒÐ·Ñ Ð²Ð·ÑÑ‚ÑŒ"
#define sO_No "\xcd\xe5\xf2" // "Ðет"
#define sO_LowerHatch_23 "\xcd\xe8\xe6\xed\xe8\xe9 \xeb\xfe\xea_23" // "Ðижний люк_23"
@@ -148,7 +156,7 @@ namespace Fullpipe {
#define sO_ClockAxis "\xce\xf1\xfc \xf7\xe0\xf1\xee\xe2" // "ОÑÑŒ чаÑов"
#define sO_Opened "\xce\xf2\xea\xf0\xfb\xf2" // "Открыт"
#define sO_OpenedWithBoot "\xce\xf2\xea\xf0\xfb\xf2\xe0 \xf1 \xe1\xee\xf2\xe8\xed\xea\xee\xec" // "Открыта Ñ Ð±Ð¾Ñ‚Ð¸Ð½ÐºÐ¾Ð¼"
-#define sO_OpenedShe "\xce\xf2\xea\xf0\xfb\xf2\xe0" // "Открыта"
+#define sO_IsOpened "\xce\xf2\xea\xf0\xfb\xf2\xe0" // "Открыта"
#define sO_WeirdWacko "\xce\xf2\xec\xee\xf0\xee\xe6\xe5\xed\xed\xfb\xe9" // "Отмороженный"
#define sO_NotPresent "\xce\xf2\xf1\xf3\xf2\xf1\xf2\xe2\xf3\xe5\xf2" // "ОтÑутÑтвует"
#define sO_Error "\xce\xf8\xe8\xe1\xea\xe0" // "Ошибка"
@@ -161,17 +169,17 @@ namespace Fullpipe {
#define sO_FullPipe "\xcf\xee\xeb\xed\xe0\xff \xd2\xf0\xf3\xe1\xe0" // "ÐŸÐ¾Ð»Ð½Ð°Ñ Ð¢Ñ€ÑƒÐ±Ð°"
#define sO_RightStairs_9 "\xcf\xf0\xe0\xe2\xe0\xff \xeb\xe5\xf1\xf2\xed\xe8\xf6\xe0_9" // "ÐŸÑ€Ð°Ð²Ð°Ñ Ð»ÐµÑтница_9"
#define sO_RightPipe_17 "\xcf\xf0\xe0\xe2\xe0\xff \xf2\xf0\xf3\xe1\xe0_17" // "ÐŸÑ€Ð°Ð²Ð°Ñ Ñ‚Ñ€ÑƒÐ±Ð°_17"
-#define sO_Available "\xcf\xf0\xe8\xf1\xf3\xf2\xf1\xf2\xe2\xf3\xe5\xf2" // "ПриÑутÑтвует"
+#define sO_IsPresent "\xcf\xf0\xe8\xf1\xf3\xf2\xf1\xf2\xe2\xf3\xe5\xf2" // "ПриÑутÑтвует"
#define sO_GulpedEgg "\xcf\xf0\xee\xe3\xeb\xee\xf7\xe5\xed\xed\xee\xe5 \xff\xe9\xf6\xee" // "Проглоченное Ñйцо"
#define sO_GulpedEggs "\xcf\xf0\xee\xe3\xeb\xee\xf7\xe5\xed\xed\xfb\xe5 \xff\xe9\xf6\xe0" // "Проглоченные Ñйца"
#define sO_BellyInflater "\xcf\xf3\xe7\xee\xe4\xf3\xe2" // "Пузодув"
#define sO_Empty "\xcf\xf3\xf1\xf2" // "ПуÑÑ‚"
#define sO_EmptyShe "\xcf\xf3\xf1\xf2\xe0\xff" // "ПуÑтаÑ"
#define sO_WayToPipe "\xcf\xf3\xf2\xfc \xea \xf2\xf0\xf3\xe1\xe5" // "Путь к трубе"
-#define sO_Drinking "\xcf\xfc\xe5\xf2" // "Пьет"
-#define sO_BrokenInPieces "\xd0\xe0\xe7\xe1\xe8\xf2\xe0" // "Разбита"
+#define sO_IsDrinking "\xcf\xfc\xe5\xf2" // "Пьет"
+#define sO_Broken "\xd0\xe0\xe7\xe1\xe8\xf2\xe0" // "Разбита"
#define sO_Unblocked "\xd0\xe0\xe7\xe1\xeb\xee\xea\xe8\xf0\xee\xe2\xe0\xed" // "Разблокирован"
-#define sO_Unfolded "\xd0\xe0\xe7\xe2\xe5\xf0\xed\xf3\xf2" // "Развернут"
+#define sO_Unconvoluted "\xd0\xe0\xe7\xe2\xe5\xf0\xed\xf3\xf2" // "Развернут"
#define sO_Jawcrucnher "\xd0\xee\xf2\xee\xf5\xf0\xf3\xf1" // "РотохруÑ"
#define sO_UsherHand "\xd0\xf3\xea\xe0 \xc1\xe8\xeb\xe5\xf2\xe5\xf0\xf8\xe8" // "Рука Билетерши"
#define sO_LeverHandle_23 "\xd0\xf3\xea\xee\xff\xf2\xea\xe0 \xf0\xfb\xf7\xe0\xe3\xe0_23" // "РукоÑтка рычага_23"
@@ -185,7 +193,7 @@ namespace Fullpipe {
#define sO_WithJug "\xd1 \xe3\xee\xf0\xf8\xea\xee\xec" // "С горшком"
#define sO_WithGum "\xd1 \xe6\xe2\xe0\xf7\xea\xee\xe9" // "С жвачкой"
#define sO_WithShovel "\xd1 \xeb\xee\xef\xe0\xf2\xee\xe9" // "С лопатой"
-#define sO_WithTiny "\xd1 \xec\xe0\xeb\xfb\xec" // "С малым"
+#define sO_WithSmall "\xd1 \xec\xe0\xeb\xfb\xec" // "С малым"
#define sO_WithHammer "\xd1 \xec\xee\xeb\xee\xf2\xea\xee\xec" // "С молотком"
#define sO_WithCoin "\xd1 \xec\xee\xed\xe5\xf2\xee\xe9" // "С монетой"
#define sO_WithSock "\xd1 \xed\xee\xf1\xea\xee\xec" // "С ноÑком"
@@ -197,19 +205,19 @@ namespace Fullpipe {
#define sO_Sugar "\xd1\xe0\xf5\xe0\xf0\xee\xea" // "Сахарок"
#define sO_Convoluted "\xd1\xe2\xe5\xf0\xed\xf3\xf2" // "Свернут"
#define sO_IsFree "\xd1\xe2\xee\xe1\xee\xe4\xed\xe0" // "Свободна"
-#define sO_Sitting "\xd1\xe8\xe4\xe8\xf2" // "Сидит"
-#define sO_Laughing "\xd1\xec\xe5\xe5\xf2\xf1\xff" // "СмеетÑÑ"
-#define sO_WithEveryone "\xd1\xee \xe2\xf1\xe5\xec\xe8" // "Со вÑеми"
+#define sO_IsSitting "\xd1\xe8\xe4\xe8\xf2" // "Сидит"
+#define sO_IsLaughing "\xd1\xec\xe5\xe5\xf2\xf1\xff" // "СмеетÑÑ"
+#define sO_WithAll "\xd1\xee \xe2\xf1\xe5\xec\xe8" // "Со вÑеми"
#define sO_WithMop "\xd1\xee \xf8\xe2\xe0\xe1\xf0\xee\xe9" // "Со шваброй"
#define sO_WithHose "\xd1\xee \xf8\xeb\xe0\xed\xe3\xee\xec" // "Со шлангом"
#define sO_WithBrush "\xd1\xee \xf9\xe5\xf2\xea\xee\xe9" // "Со щеткой"
-#define sO_Sleeping "\xd1\xef\xe8\xf2" // "Спит"
+#define sO_IsSleeping "\xd1\xef\xe8\xf2" // "Спит"
#define sO_OnRight "\xd1\xef\xf0\xe0\xe2\xe0" // "Справа"
-#define sO_StandsInBoots "\xd1\xf2\xee\xe8\xf2 \xe2 \xe1\xee\xf2\xe8\xed\xea\xe0\xf5" // "Стоит в ботинках"
-#define sO_StandsInCorner "\xd1\xf2\xee\xe8\xf2 \xe2 \xf3\xe3\xeb\xf3" // "Стоит в углу"
+#define sO_IsStandingInBoots "\xd1\xf2\xee\xe8\xf2 \xe2 \xe1\xee\xf2\xe8\xed\xea\xe0\xf5" // "Стоит в ботинках"
+#define sO_IsStandingInCorner "\xd1\xf2\xee\xe8\xf2 \xe2 \xf3\xe3\xeb\xf3" // "Стоит в углу"
#define sO_Guardian "\xd1\xf2\xee\xf0\xee\xe6" // "Сторож"
#define sO_Guard_1 "\xd1\xf2\xf0\xe0\xe6 1" // "Страж 1"
-#define sO_Gurad_2 "\xd1\xf2\xf0\xe0\xe6 2" // "Страж 2"
+#define sO_Guard_2 "\xd1\xf2\xf0\xe0\xe6 2" // "Страж 2"
#define sO_Guard_3 "\xd1\xf2\xf0\xe0\xe6 3" // "Страж 3"
#define sO_Stool_34 "\xd2\xe0\xe1\xf3\xf0\xe5\xf2_34" // "Табурет_34"
#define sO_Pipe_9 "\xd2\xf0\xf3\xe1\xe0_9" // "Труба_9"
@@ -217,16 +225,17 @@ namespace Fullpipe {
#define sO_Pedestal_17 "\xd2\xf3\xec\xe1\xe0_17" // "Тумба_17"
#define sO_Pedestal_33 "\xd2\xf3\xec\xe1\xe0_33" // "Тумба_33"
#define sO_NearDudesStairs "\xd3 \xc4\xff\xe4\xe8 \xed\xe0 \xeb\xe5\xf1\xf2\xed\xe8\xf6\xe5" // "У ДÑди на леÑтнице"
-#define sO_NearDude "\xd3 \xc4\xff\xe4\xe8" // "У ДÑди"
+#define sO_DudeHas "\xd3 \xc4\xff\xe4\xe8" // "У ДÑди"
#define sO_NearPipeWithStool "\xd3 \xf2\xf0\xf3\xe1\xfb \xf1 \xf2\xe0\xe1\xf3\xf0\xe5\xf2\xea\xee\xe9" // "У трубы Ñ Ñ‚Ð°Ð±ÑƒÑ€ÐµÑ‚ÐºÐ¾Ð¹"
#define sO_NearPipe "\xd3 \xf2\xf0\xf3\xe1\xfb" // "У трубы"
#define sO_Janitors "\xd3\xe1\xee\xf0\xf9\xe8\xea\xe8" // "Уборщики"
#define sO_Janitress "\xd3\xe1\xee\xf0\xf9\xe8\xf6\xe0" // "Уборщица"
-#define sO_Gone "\xd3\xe5\xf5\xe0\xeb\xe0" // "Уехала"
+#define sO_IsGone "\xd3\xe5\xf5\xe0\xeb\xe0" // "Уехала"
+#define sO_FallenTwice "\xd3\xef\xe0\xeb \xe4\xe2\xe0" // "Упал два"
#define sO_FallenOnce "\xd3\xef\xe0\xeb \xf0\xe0\xe7" // "Упал раз"
-#define sO_FallenBrush "\xd3\xef\xe0\xeb\xe0 \xf9\xe5\xf2\xea\xe0" // "Упала щетка"
+#define sO_BrushHasFallen "\xd3\xef\xe0\xeb\xe0 \xf9\xe5\xf2\xea\xe0" // "Упала щетка"
#define sO_NotBroken "\xd6\xe5\xeb\xe0" // "Цела"
-#define sO_ScratchingBelly "\xd7\xe5\xf8\xe5\xf2 \xef\xf3\xe7\xee" // "Чешет пузо"
+#define sO_IsScratchingBelly "\xd7\xe5\xf8\xe5\xf2 \xef\xf3\xe7\xee" // "Чешет пузо"
#define sO_Level0 "\xdd\xf2\xe0\xe6 0" // "Этаж 0"
#define sO_Level1 "\xdd\xf2\xe0\xe6 1" // "Этаж 1"
#define sO_Level2 "\xdd\xf2\xe0\xe6 2" // "Этаж 2"
diff --git a/engines/fullpipe/objects.h b/engines/fullpipe/objects.h
index a12851e63b..d13559429a 100644
--- a/engines/fullpipe/objects.h
+++ b/engines/fullpipe/objects.h
@@ -82,6 +82,8 @@ class GameVar : public CObject {
public:
GameVar();
+ virtual ~GameVar();
+
virtual bool load(MfcArchive &file);
GameVar *getSubVarByName(const char *name);
bool setSubVarAsInt(const char *name, int value);
diff --git a/engines/fullpipe/scene.cpp b/engines/fullpipe/scene.cpp
index cc93363786..997d92ae1c 100644
--- a/engines/fullpipe/scene.cpp
+++ b/engines/fullpipe/scene.cpp
@@ -92,6 +92,9 @@ bool SceneTag::load(MfcArchive &file) {
SceneTag::~SceneTag() {
free(_tag);
+
+ delete _scene;
+ delete _field_4;
}
void SceneTag::loadScene() {
@@ -114,7 +117,7 @@ void SceneTag::loadScene() {
delete file;
- g_fullpipe->_currArchive = 0;
+ g_fp->_currArchive = 0;
free(fname);
free(archname);
@@ -129,6 +132,10 @@ Scene::Scene() {
_sceneName = 0;
}
+Scene::~Scene() {
+ warning("STUB: Scene::~Scene()");
+}
+
bool Scene::load(MfcArchive &file) {
debug(5, "Scene::load()");
@@ -146,7 +153,7 @@ bool Scene::load(MfcArchive &file) {
int aniNum = file.readUint16LE();
char *aniname = genFileName(0, aniNum, "ani");
- Common::SeekableReadStream *f = g_fullpipe->_currArchive->createReadStreamForMember(aniname);
+ Common::SeekableReadStream *f = g_fp->_currArchive->createReadStreamForMember(aniname);
StaticANIObject *ani = new StaticANIObject();
@@ -168,7 +175,7 @@ bool Scene::load(MfcArchive &file) {
int qNum = file.readUint16LE();
char *qname = genFileName(0, qNum, "qu");
- Common::SeekableReadStream *f = g_fullpipe->_currArchive->createReadStreamForMember(qname);
+ Common::SeekableReadStream *f = g_fp->_currArchive->createReadStreamForMember(qname);
MfcArchive archive(f);
archive.readUint16LE(); // Skip 2 bytes
@@ -191,7 +198,7 @@ bool Scene::load(MfcArchive &file) {
assert(0);
}
- _libHandle = g_fullpipe->_currArchive;
+ _libHandle = g_fp->_currArchive;
if (_picObjList.size() > 0 && _bgname && strlen(_bgname) > 1) {
char fname[260];
@@ -216,10 +223,10 @@ bool Scene::load(MfcArchive &file) {
char *slsname = genFileName(0, _sceneId, "sls");
- if (g_fullpipe->_soundEnabled) {
+ if (g_fp->_soundEnabled) {
_soundList = new SoundList();
- if (g_fullpipe->_flgSoundList) {
+ if (g_fp->_flgSoundList) {
char *nlname = genFileName(17, _sceneId, "nl");
_soundList->loadFile(slsname, nlname);
@@ -249,7 +256,7 @@ void Scene::init() {
_x = 0;
_y = 0;
- g_fullpipe->_sceneRect.moveTo(0, 0);
+ g_fp->_sceneRect.moveTo(0, 0);
for (uint i = 0; i < _picObjList.size(); i++)
((PictureObject *)_picObjList[i])->clearFlags();
@@ -328,7 +335,7 @@ void Scene::setPictureObjectsFlag4() {
}
PictureObject *Scene::getPictureObjectById(int objId, int flags) {
- for (uint i = 1; i < _picObjList.size(); i++) {
+ for (uint i = 0; i < _picObjList.size(); i++) {
if (((PictureObject *)_picObjList[i])->_id == objId && ((PictureObject *)_picObjList[i])->_okeyCode == flags)
return (PictureObject *)_picObjList[i];
}
@@ -398,7 +405,7 @@ void Scene::preloadMovements(GameVar *var) {
}
void Scene::initObjectCursors(const char *varname) {
- GameVar *cursorsVar = g_fullpipe->getGameLoaderGameVar()->getSubVarByName(varname)->getSubVarByName("CURSORS");
+ GameVar *cursorsVar = g_fp->getGameLoaderGameVar()->getSubVarByName(varname)->getSubVarByName("CURSORS");
if (!cursorsVar || !cursorsVar->_subVars)
return;
@@ -417,10 +424,10 @@ void Scene::initObjectCursors(const char *varname) {
}
}
- g_fullpipe->_minCursorId = minId;
- g_fullpipe->_maxCursorId = maxId;
+ g_fp->_minCursorId = minId;
+ g_fp->_maxCursorId = maxId;
- g_fullpipe->_objectIdCursors.resize(maxId - minId + 1);
+ g_fp->_objectIdCursors.resize(maxId - minId + 1);
for (GameVar *sub = cursorsVar->_subVars; sub; sub = sub->_nextVarObj) {
GameObject *obj = getPictureObjectByName(sub->_varName, -1);
@@ -431,7 +438,7 @@ void Scene::initObjectCursors(const char *varname) {
PictureObject *pic = getGameLoaderInventory()->getScene()->getPictureObjectByName(sub->_value.stringValue, -1);
if (obj && pic)
- g_fullpipe->_objectIdCursors[obj->_id - minId] = pic->_id;
+ g_fp->_objectIdCursors[obj->_id - minId] = pic->_id;
}
}
@@ -442,14 +449,25 @@ bool Scene::compareObjPriority(const void *p1, const void *p2) {
return false;
}
-void Scene::objectList_sortByPriority(PtrList &list) {
- Common::sort(list.begin(), list.end(), Scene::compareObjPriority);
+void Scene::objectList_sortByPriority(PtrList &list, bool skipFirst) {
+ if (skipFirst) {
+ PtrList::iterator s = list.begin();
+
+ ++s;
+
+ Common::sort(s, list.end(), Scene::compareObjPriority);
+ } else {
+ Common::sort(list.begin(), list.end(), Scene::compareObjPriority);
+ }
}
void Scene::draw() {
- debug(0, ">>>>> Scene::draw()");
+ debug(6, ">>>>> Scene::draw()");
updateScrolling();
+ // Clean previous stuff
+ g_fp->_backgroundSurface.fillRect(Common::Rect(0, 0, 800, 600), 0);
+
drawContent(60000, 0, true);
objectList_sortByPriority(_staticANIObjectList2);
@@ -470,11 +488,74 @@ void Scene::draw() {
}
void Scene::updateScrolling() {
- debug(0, "STUB Scene::updateScrolling()");
+ if (_messageQueueId && !_x && !_y) {
+ MessageQueue *mq = g_fp->_globalMessageQueueList->getMessageQueueById(_messageQueueId);
+
+ if (mq)
+ mq->update();
+
+ _messageQueueId = 0;
+ }
+
+ if (_x || _y) {
+ int offsetX = 0;
+ int offsetY = 0;
+
+ if (_x < 0) {
+ if (!g_fp->_sceneRect.left && !(((PictureObject *)_picObjList[0])->_flags & 2))
+ _x = 0;
+
+ if (_x <= -g_fp->_scrollSpeed) {
+ offsetX = -g_fp->_scrollSpeed;
+ _x += g_fp->_scrollSpeed;
+ }
+ } else if (_x >= g_fp->_scrollSpeed) {
+ offsetX = g_fp->_scrollSpeed;
+ _x -= g_fp->_scrollSpeed;
+ } else {
+ _x = 0;
+ }
+
+ if (_y > 0) {
+ offsetY = g_fp->_scrollSpeed;
+ _y -= g_fp->_scrollSpeed;
+ }
+
+ if (_y < 0) {
+ offsetY -= g_fp->_scrollSpeed;
+ _y += g_fp->_scrollSpeed;
+ }
+
+ g_fp->_sceneRect.translate(offsetX, offsetY);
+ }
+
+ updateScrolling2();
}
void Scene::updateScrolling2() {
- warning("STUB Scene::updateScrolling2()");
+ if (_picObjList.size()) {
+ Common::Point point;
+ int offsetY = 0;
+ int offsetX = 0;
+
+ ((PictureObject *)_picObjList[0])->getDimensions(&point);
+
+ int flags = ((PictureObject *)_picObjList[0])->_flags;
+
+ if (g_fp->_sceneRect.left < 0 && !(flags & 2))
+ offsetX = -g_fp->_sceneRect.left;
+
+ if (g_fp->_sceneRect.top < 0 && !(flags & 0x20))
+ offsetY = -g_fp->_sceneRect.top;
+
+ if (g_fp->_sceneRect.right > point.x - 1 && g_fp->_sceneRect.left > 0 && !(flags & 2))
+ offsetX = point.x - g_fp->_sceneRect.right - 1;
+
+ if (g_fp->_sceneRect.bottom > point.y - 1 && g_fp->_sceneRect.top > 0 && !(flags & 0x20))
+ offsetY = point.y - g_fp->_sceneRect.bottom - 1;
+
+ g_fp->_sceneRect.translate(offsetX, offsetY);
+ }
}
StaticANIObject *Scene::getStaticANIObjectAtPos(int x, int y) {
@@ -525,7 +606,7 @@ int Scene::getPictureObjectIdAtPos(int x, int y) {
}
void Scene::update(int counterdiff) {
- debug(0, "Scene::update(%d)", counterdiff);
+ debug(6, "Scene::update(%d)", counterdiff);
for (PtrList::iterator s = _staticANIObjectList2.begin(); s != _staticANIObjectList2.end(); ++s)
((StaticANIObject *)*s)->update(counterdiff);
@@ -536,13 +617,13 @@ void Scene::drawContent(int minPri, int maxPri, bool drawBg) {
return;
if (_palette) {
- g_fullpipe->_globalPalette = _palette->_data;
+ g_fp->_globalPalette = _palette->_data;
}
debug(8, "Scene::drawContent(>%d, <%d, %d)", minPri, maxPri, drawBg);
if (_picObjList.size() > 2) { // We need to z-sort them
- objectList_sortByPriority(_picObjList);
+ objectList_sortByPriority(_picObjList, true);
}
if (minPri == -1 && _picObjList.size())
@@ -569,7 +650,7 @@ void Scene::drawContent(int minPri, int maxPri, bool drawBg) {
debug(8, "w2: %d h2:%d", point.x, point.y);
- int bgStX = g_fullpipe->_sceneRect.left % point.x;
+ int bgStX = g_fp->_sceneRect.left % point.x;
if (bgStX < 0)
bgStX += point.x;
@@ -577,7 +658,7 @@ void Scene::drawContent(int minPri, int maxPri, bool drawBg) {
int bgNumX = bgStX / width;
int bgOffsetX = bgStX % width;
- int bgStY = g_fullpipe->_sceneRect.top % point.y;
+ int bgStY = g_fp->_sceneRect.top % point.y;
if (bgStY < 0)
bgStY += point.y;
@@ -585,12 +666,12 @@ void Scene::drawContent(int minPri, int maxPri, bool drawBg) {
int bgNumY = bgStY / height;
int bgOffsetY = bgStY % height;
- int bgPosX = g_fullpipe->_sceneRect.left - bgOffsetX;
+ int bgPosX = g_fp->_sceneRect.left - bgOffsetX;
- if (bgPosX < g_fullpipe->_sceneRect.right - 1) {
+ if (bgPosX < g_fp->_sceneRect.right - 1) {
while (1) {
int v25 = bgNumY;
- for (int y = g_fullpipe->_sceneRect.top - bgOffsetY; y < g_fullpipe->_sceneRect.bottom - 1;) {
+ for (int y = g_fp->_sceneRect.top - bgOffsetY; y < g_fp->_sceneRect.bottom - 1;) {
BigPicture *v27 = _bigPictureArray[bgNumX][v25];
v27->draw(bgPosX, y, 0, 0);
y += v27->getDimensions(&point)->y;
@@ -603,7 +684,7 @@ void Scene::drawContent(int minPri, int maxPri, bool drawBg) {
}
}
_bigPictureArray[bgNumX][0]->getDimensions(&point);
- int v32 = point.x + bgPosX;
+ int oldx = point.x + bgPosX;
bgPosX += point.x;
bgNumX++;
@@ -612,7 +693,7 @@ void Scene::drawContent(int minPri, int maxPri, bool drawBg) {
break;
bgNumX = 0;
}
- if (v32 >= g_fullpipe->_sceneRect.right - 1)
+ if (oldx >= g_fp->_sceneRect.right - 1)
break;
}
}
@@ -637,22 +718,22 @@ void Scene::drawContent(int minPri, int maxPri, bool drawBg) {
int height = point.y;
if (obj->_flags & 8) {
- while (objX > g_fullpipe->_sceneRect.right) {
+ while (objX > g_fp->_sceneRect.right) {
objX -= width;
obj->setOXY(objX, objY);
}
- for (int j = width + objX; width + objX < g_fullpipe->_sceneRect.left; j = width + objX) {
+ for (int j = width + objX; width + objX < g_fp->_sceneRect.left; j = width + objX) {
objX = j;
obj->setOXY(j, objY);
}
}
if (obj->_flags & 0x10) {
- while (objY > g_fullpipe->_sceneRect.bottom) {
+ while (objY > g_fp->_sceneRect.bottom) {
objY -= height;
obj->setOXY(objX, objY);
}
- for (int j = objY + height; objY + height < g_fullpipe->_sceneRect.top; j = objY + height) {
+ for (int j = objY + height; objY + height < g_fp->_sceneRect.top; j = objY + height) {
objY = j;
obj->setOXY(objX, j);
}
@@ -661,12 +742,12 @@ void Scene::drawContent(int minPri, int maxPri, bool drawBg) {
obj->draw();
if (obj->_flags & 2) {
- if (objX > g_fullpipe->_sceneRect.left) {
+ if (objX > g_fp->_sceneRect.left) {
obj->setOXY(objX - width, objY);
obj->draw();
obj->setOXY(objX, objY);
}
- if (width + objX < g_fullpipe->_sceneRect.right) {
+ if (width + objX < g_fp->_sceneRect.right) {
obj->setOXY(width + objX, objY);
obj->draw();
obj->setOXY(objX, objY);
@@ -674,12 +755,12 @@ void Scene::drawContent(int minPri, int maxPri, bool drawBg) {
}
if (obj->_flags & 0x20) {
- if (objY > g_fullpipe->_sceneRect.top) {
+ if (objY > g_fp->_sceneRect.top) {
obj->setOXY(objX, objY - height);
obj->draw();
obj->setOXY(objX, objY);
}
- if (height + objY < g_fullpipe->_sceneRect.bottom) {
+ if (height + objY < g_fp->_sceneRect.bottom) {
obj->setOXY(objX, height + objY);
obj->draw();
obj->setOXY(objX, objY);
diff --git a/engines/fullpipe/scene.h b/engines/fullpipe/scene.h
index db0da5db31..fc04a877f5 100644
--- a/engines/fullpipe/scene.h
+++ b/engines/fullpipe/scene.h
@@ -44,6 +44,7 @@ class Scene : public Background {
public:
Scene();
+ virtual ~Scene();
virtual bool load(MfcArchive &file);
@@ -79,12 +80,12 @@ class Scene : public Background {
private:
static bool compareObjPriority(const void *p1, const void *p2);
- void objectList_sortByPriority(PtrList &list);
+ void objectList_sortByPriority(PtrList &list, bool skipFirst = false);
};
class SceneTag : public CObject {
public:
- int _field_4;
+ CObject *_field_4;
char *_tag;
Scene *_scene;
int16 _sceneId;
diff --git a/engines/fullpipe/scenes.cpp b/engines/fullpipe/scenes.cpp
index 7bc8f68fa5..71c8b1efb5 100644
--- a/engines/fullpipe/scenes.cpp
+++ b/engines/fullpipe/scenes.cpp
@@ -23,39 +23,19 @@
#include "fullpipe/fullpipe.h"
#include "fullpipe/utils.h"
-#include "fullpipe/gfx.h"
#include "fullpipe/objects.h"
#include "fullpipe/statics.h"
-#include "fullpipe/scene.h"
#include "fullpipe/gameloader.h"
-#include "fullpipe/sound.h"
#include "fullpipe/motion.h"
#include "fullpipe/input.h"
-#include "fullpipe/messages.h"
#include "fullpipe/behavior.h"
#include "fullpipe/constants.h"
-#include "fullpipe/objectnames.h"
#include "fullpipe/scenes.h"
-#include "fullpipe/modal.h"
#include "fullpipe/interaction.h"
namespace Fullpipe {
-int defaultUpdateCursor();
-void setElevatorButton(const char *name, int state);
-
-int sceneIntro_updateCursor();
-void sceneIntro_initScene(Scene *sc);
-int sceneHandlerIntro(ExCommand *cmd);
-
-void scene01_fixEntrance();
-void scene01_initScene(Scene *sc, int entrance);
-int sceneHandler01(ExCommand *cmd);
-
-void sceneDbgMenu_initScene(Scene *sc);
-int sceneHandlerDbgMenu(ExCommand *cmd);
-
Vars::Vars() {
sceneIntro_aniin1man = 0;
sceneIntro_needSleep = true;
@@ -71,9 +51,385 @@ Vars::Vars() {
scene01_picSc01Osk = 0;
scene01_picSc01Osk2 = 0;
+ scene02_guvTheDrawer = 0;
+ scene02_boxDelay = 0;
+ scene02_boxOpen = false;
+
+ scene03_eggeater = 0;
+ scene03_domino = 0;
+
+ scene04_bottle = 0;
+ scene04_hand = 0;
+ scene04_plank = 0;
+ scene04_clock = 0;
+ scene04_hand = 0;
+ scene04_spring = 0;
+ scene04_mamasha = 0;
+ scene04_boot = 0;
+ scene04_speaker = 0;
+
+ scene04_ladder = 0;
+ scene04_coinPut = false;
+ scene04_soundPlaying = false;
+ scene04_dynamicPhaseIndex = 0;
+ scene04_dudeOnLadder = false;
+
+ scene04_sceneClickX = 0;
+ scene04_sceneClickY = 0;
+
+ scene04_dudePosX = 0;
+ scene04_dudePosY = 0;
+
+ scene04_bottleIsTaken = false;
+ scene04_kozyawkaOnLadder = false;
+ scene04_walkingKozyawka = 0;
+ scene04_bottleWeight = 0;
+ scene04_var07 = false;
+ scene04_ladderClickable = false;
+ scene04_handIsDown = false;
+ scene04_dudeInBottle = false;
+ scene04_kozHeadRaised = false;
+ scene04_bottleIsDropped = false;
+ scene04_bigBallIn = false;
+ scene04_bigBallCounter = 0;
+ scene04_bigBallFromLeft = false;
+ scene04_speakerVariant = 0;
+ scene04_speakerPhase = 0;
+ scene04_clockCanGo = false;
+ scene04_objectIsTaken = false;
+ scene04_springOffset = 0;
+ scene04_lastKozyawka = 0;
+ scene04_springDelay = 0;
+ scene04_bottleY = 0;
+ scene04_ladderOffset = 0;
+
+ scene05_handle = 0;
+ scene05_wacko = 0;
+ scene05_bigHatch = 0;
+ scene05_wackoTicker = 0;
+ scene05_handleFlipper = 0;
+ scene05_floatersTicker = 0;
+
+ scene06_manX = 0;
+ scene06_manY = 0;
+ scene06_ballX = 0;
+ scene06_ballY = 0;
+ scene06_mumsy = 0;
+ scene06_someBall = 0;
+ scene06_invHandle = 0;
+ scene06_liftButton = 0;
+ scene06_ballDrop = 0;
+ scene06_arcadeEnabled = false;
+ scene06_aimingBall = false;
+ scene06_currentBall = 0;
+ scene06_ballInHands = 0;
+ scene06_flyingBall = 0;
+ scene06_numBallsGiven = 0;
+ scene06_mumsyNumBalls = 0;
+ scene06_eggieTimeout = 0;
+ scene06_eggieDirection = true;
+ scene06_mumsyGotBall = 0;
+ scene06_ballDeltaX = 0;
+ scene06_ballDeltaY = 0;
+ scene06_sceneClickX = 0;
+ scene06_sceneClickY = 0;
+ scene06_mumsyPos = 0;
+ scene06_mumsyJumpBk = 0;
+ scene06_mumsyJumpFw = 0;
+ scene06_mumsyJumpBkPercent = 0;
+ scene06_mumsyJumpFwPercent = 0;
+
+ scene07_lukeAnim = 0;
+ scene07_lukePercent = 0;
+ scene07_plusMinus = 0;
+
+ scene08_batuta = 0;
+ scene08_vmyats = 0;
+ scene08_clock = 0;
+ scene08_inAir = false;
+ scene08_flyingUp = false;
+ scene08_onBelly = false;
+ scene08_stairsOffset = -37;
+ scene08_snoringCountdown = -1;
+ scene08_inArcade = false;
+ scene08_stairsVisible = true;
+ scene08_manOffsetY = 0;
+
+ scene10_gum = 0;
+ scene10_packet = 0;
+ scene10_packet2 = 0;
+ scene10_inflater = 0;
+ scene10_ladder = 0;
+ scene10_hasGum = 0;
+
+ scene11_swingie = 0;
+ scene11_boots = 0;
+ scene11_dudeOnSwing = 0;
+ scene11_hint = 0;
+ scene11_arcadeIsOn = false;
+ scene11_scrollIsEnabled = false;
+ scene11_scrollIsMaximized = false;
+ scene11_hintCounter = 0;
+ scene11_swingieScreenEdge = 0;
+ scene11_crySound = 0;
+ scene11_swingAngle = 1.0;
+ scene11_swingOldAngle = 1.0;
+ scene11_swingSpeed = 1.0;
+ scene11_swingAngleDiff = 1.0;
+ scene11_swingInertia = 0.0;
+ scene11_swingCounter = 0;
+ scene11_swingCounterPrevTurn = 0;
+ scene11_swingDirection = 0;
+ scene11_swingDirectionPrevTurn = 0;
+ scene11_swingIsSwinging = false;
+ scene11_swingieStands = false;
+ scene11_dudeX = 0;
+ scene11_dudeY = 0;
+ scene11_swingMaxAngle = 45;
+
+ scene12_fly = 0;
+ scene12_flyCountdown = 0;
+
+ scene13_whirlgig = 0;
+ scene13_guard = 0;
+ scene13_handleR = 0;
+ scene13_handleL = 0;
+ scene13_bridge = 0;
+ scene13_guardDirection = false;
+ scene13_dudeX = 0;
+
+ scene14_grandma = 0;
+ scene14_sceneDeltaX = 0;
+ scene14_sceneDeltaY = 0;
+ scene14_arcadeIsOn = false;
+ scene14_dudeIsKicking = false;
+ scene14_ballIsFlying = false;
+ scene14_dudeCanKick = false;
+ scene14_sceneDiffX = 0;
+ scene14_sceneDiffY = 0;
+ scene14_pink = 0;
+ scene14_flyingBall = 0;
+ scene14_balls.clear();
+ scene14_grandmaIsHere = false;
+ scene14_dudeX = 0;
+ scene14_dudeY = 0;
+ scene14_grandmaX = 0;
+ scene14_grandmaY = 0;
+ scene14_dude2X = 0;
+ scene14_ballDeltaX = 0;
+ scene14_ballDeltaY = 0;
+ scene14_ballX = 0;
+ scene14_ballY = 0;
+ scene14_hitsLeft = 0;
+
+ scene15_chantingCountdown = 0;
+ scene15_plusminus = 0;
+ scene15_ladder = 0;
+ scene15_boot = 0;
+
+ scene16_figures.clear();
+ scene16_walkingBoy = 0;
+ scene16_walkingGirl = 0;
+ scene16_walkingCount = 0;
+ scene16_wire = 0;
+ scene16_mug = 0;
+ scene16_jettie = 0;
+ scene16_boot = 0;
+ scene16_girlIsLaughing = false;
+ scene16_sound = 0;
+ scene16_placeIsOccupied = false;
+
+ scene17_flyState = 0;
+ scene17_sugarIsShown = false;
+ scene17_sceneOldEdgeX = 0;
+ scene17_flyCountdown = 0;
+ scene17_hand = 0;
+ scene17_handPhase = false;
+ scene17_sceneEdgeX = 0;
+
+ scene18_var01 = 0;
+
+ scene20_fliesCountdown = 0;
+ scene20_grandma = 0;
+
+ scene21_giraffeBottom = 0;
+ scene21_giraffeBottomX = 0;
+ scene21_giraffeBottomY = 0;
+ scene21_pipeIsOpen = false;
+ scene21_wigglePos = 0.0;
+ scene21_wiggleTrigger = 0;
+
+ scene22_bag = 0;
+ scene22_giraffeMiddle = 0;
+ scene22_dudeIsOnStool = false;
+ scene22_interactionIsDisabled = false;
+ scene22_craneIsOut = true;
+ scene22_numBagFalls = 1;
+
+ scene23_calend0 = 0;
+ scene23_calend1 = 0;
+ scene23_calend2 = 0;
+ scene23_calend3 = 0;
+ scene23_topReached = false;
+ scene23_isOnStool = false;
+ scene23_someVar = 0;
+ scene23_giraffeTop = 0;
+ scene23_giraffee = 0;
+
+ scene24_jetIsOn = false;
+ scene24_flowIsLow = false;
+ scene24_waterIsOn = false;
+ scene24_water = 0;
+ scene24_jet = 0;
+ scene24_drop = 0;
+
+ scene25_water = 0;
+ scene25_board = 0;
+ scene25_drop = 0;
+ scene25_dudeIsOnBoard = false;
+ scene25_waterIsPresent = false;
+ scene25_boardIsSelectable = false;
+ scene25_beardersAreThere = false;
+ scene25_beardersCounter = 0;
+ scene25_bearders.clear();
+ scene25_sneezeFlipper = false;
+
+ scene26_chhi = 0;
+ scene26_drop = 0;
+ scene26_sockPic = 0;
+ scene26_sock = 0;
+ scene26_activeVent = 0;
+
+ scene28_fliesArePresent = true;
+ scene28_beardedDirection = true;
+ scene28_darkeningObject = 0;
+ scene28_lighteningObject = 0;
+ scene28_headDirection = false;
+ scene28_headBeardedFlipper = false;
+ scene28_lift6inside = false;
+
+ scene30_leg = 0;
+ scene30_liftFlag = 1;
+
+ scene31_chantingCountdown = 0;
+ scene31_cactus = 0;
+ scene31_plusMinus = 0;
+
+ scene32_flagIsWaving = false;
+ scene32_flagNeedsStopping = false;
+ scene32_dudeIsSitting = false;
+ scene32_cactusCounter = -1;
+ scene32_dudeOnLadder = false;
+ scene32_cactusIsGrowing = false;
+ scene32_flag = 0;
+ scene32_cactus = 0;
+ scene32_massOrange = 0;
+ scene32_massBlue = 0;
+ scene32_massGreen = 0;
+ scene32_button = 0;
+
+ scene33_mug = 0;
+ scene33_jettie = 0;
+ scene33_cube = 0;
+ scene33_cubeX = -1;
+ scene33_handleIsDown = false;
+
+ for (int i = 0; i < 9; i++) {
+ scene33_ventsX[i] = 0;
+ scene33_ventsState[i] = 0;
+ }
+
+ scene34_cactus = 0;
+ scene34_vent = 0;
+ scene34_hatch = 0;
+ scene34_boot = 0;
+ scene34_dudeClimbed = false;
+ scene34_dudeOnBoard = false;
+ scene34_dudeOnCactus = false;
+ scene34_fliesCountdown = 0;
+
+ scene35_hose = 0;
+ scene35_bellyInflater = 0;
+ scene35_flowCounter = 0;
+ scene35_fliesCounter = 0;
+
+ scene36_rotohrust = 0;
+ scene36_scissors = 0;
+
+ scene37_rings.clear();
+ scene37_lastDudeX = -1;
+ scene37_cursorIsLocked = 0;
+ scene37_plusMinus1 = 0;
+ scene37_plusMinus2 = 0;
+ scene37_plusMinus3 = 0;
+ scene37_soundFlipper = 0;
+ scene37_dudeX = 0;
+
+ scene38_boss = 0;
+ scene38_tally = 0;
+ scene38_shorty = 0;
+ scene38_domino0 = 0;
+ scene38_dominos = 0;
+ scene38_domino1 = 0;
+ scene38_bottle = 0;
+ scene38_bossCounter = 0;
+ scene38_lastBossAnim = 0;
+ scene38_bossAnimCounter = 0;
+ scene38_tallyCounter = 0;
+ scene38_lastTallyAnim = 0;
+ scene38_tallyAnimCounter = 0;
+ scene38_shortyCounter = 0;
+ scene38_lastShortyAnim = 0;
+ scene38_shortyAnimCounter = 0;
+
+ sceneFinal_var01 = 0;
+ sceneFinal_var02 = 0;
+ sceneFinal_var03 = 0;
+
selector = 0;
}
+static int scenes[] = {
+ SC_1, SC_2, SC_3, SC_4, SC_5, SC_6, SC_7, SC_8, SC_9, SC_10,
+ SC_11, SC_12, SC_13, SC_14, SC_15, SC_16, SC_17, SC_18, SC_19, SC_20,
+ SC_21, SC_22, SC_23, SC_24, SC_25, SC_26, SC_27, SC_28, SC_29, SC_30,
+ SC_31, SC_32, SC_33, SC_34, SC_35, SC_36, SC_37, SC_38, SC_FINAL1, SC_DBGMENU
+};
+
+static int scenesD[] = {
+ PIC_SCD_1, PIC_SCD_2, PIC_SCD_3, PIC_SCD_4, PIC_SCD_5, PIC_SCD_6, PIC_SCD_7, PIC_SCD_8, PIC_SCD_9, PIC_SCD_10,
+ PIC_SCD_11, PIC_SCD_12, PIC_SCD_13, PIC_SCD_14, PIC_SCD_15, PIC_SCD_16, PIC_SCD_17, PIC_SCD_18, PIC_SCD_19, PIC_SCD_20,
+ PIC_SCD_21, PIC_SCD_22, PIC_SCD_23, PIC_SCD_24, PIC_SCD_25, PIC_SCD_26, PIC_SCD_27, PIC_SCD_28, PIC_SCD_29, PIC_SCD_30,
+ PIC_SCD_31, PIC_SCD_32, PIC_SCD_33, PIC_SCD_34, PIC_SCD_35, PIC_SCD_36, PIC_SCD_37, PIC_SCD_38, PIC_SCD_FIN, 0
+};
+
+int FullpipeEngine::convertScene(int scene) {
+ if (!scene || scene >= SC_1)
+ return scene;
+
+ if (scene < 1 || scene > 40)
+ return SC_1;
+
+ return scenes[scene - 1];
+}
+
+int FullpipeEngine::getSceneEntrance(int scene) {
+ for (int i = 0; i < 40; i++)
+ if (scenes[i] == scene)
+ return scenesD[i];
+
+ return 0;
+}
+
+int FullpipeEngine::getSceneFromTag(int tag) {
+ for (int i = 0; i < ARRAYSIZE(scenes); i++) {
+ if (scenes[i] == tag)
+ return i + 1;
+ }
+
+ return 1;
+}
+
bool FullpipeEngine::sceneSwitcher(EntranceInfo *entrance) {
GameVar *sceneVar;
Common::Point sceneDim;
@@ -182,7 +538,6 @@ bool FullpipeEngine::sceneSwitcher(EntranceInfo *entrance) {
_updateCursorCallback = defaultUpdateCursor;
break;
-#if 0
case SC_2:
sceneVar = _gameLoader->_gameVar->getSubVarByName("SC_2");
scene->preloadMovements(sceneVar);
@@ -202,7 +557,7 @@ bool FullpipeEngine::sceneSwitcher(EntranceInfo *entrance) {
scene->initObjectCursors("SC_3");
setSceneMusicParameters(sceneVar);
addMessageHandler(sceneHandler03, 2);
- j_Scene_sc03_sub_40F160(scene);
+ scene03_setEaterState();
_updateCursorCallback = scene03_updateCursor;
break;
@@ -235,7 +590,7 @@ bool FullpipeEngine::sceneSwitcher(EntranceInfo *entrance) {
_behaviorManager->initBehavior(scene, sceneVar);
scene->initObjectCursors("SC_6");
setSceneMusicParameters(sceneVar);
- sub_415300();
+ scene06_initMumsy();
insertMessageHandler(sceneHandler06, 2, 2);
_updateCursorCallback = scene06_updateCursor;
break;
@@ -258,11 +613,12 @@ bool FullpipeEngine::sceneSwitcher(EntranceInfo *entrance) {
_behaviorManager->initBehavior(scene, sceneVar);
scene->initObjectCursors("SC_8");
setSceneMusicParameters(sceneVar);
- sub_416890();
+ scene08_setupMusic();
addMessageHandler(sceneHandler08, 2);
_updateCursorCallback = scene08_updateCursor;
break;
+#if 0
case SC_9:
sceneVar = _gameLoader->_gameVar->getSubVarByName("SC_9");
scene->preloadMovements(sceneVar);
@@ -273,6 +629,7 @@ bool FullpipeEngine::sceneSwitcher(EntranceInfo *entrance) {
insertMessageHandler(sceneHandler09, 2, 2);
_updateCursorCallback = scene09_updateCursor;
break;
+#endif
case SC_10:
sceneVar = _gameLoader->_gameVar->getSubVarByName("SC_10");
@@ -293,7 +650,7 @@ bool FullpipeEngine::sceneSwitcher(EntranceInfo *entrance) {
scene->initObjectCursors("SC_11");
setSceneMusicParameters(sceneVar);
insertMessageHandler(sceneHandler11, 2, 2);
- scene11_sub_41A980();
+ scene11_setupMusic();
_updateCursorCallback = scene11_updateCursor;
break;
@@ -327,7 +684,7 @@ bool FullpipeEngine::sceneSwitcher(EntranceInfo *entrance) {
scene->initObjectCursors("SC_14");
setSceneMusicParameters(sceneVar);
insertMessageHandler(sceneHandler14, 2, 2);
- scene14_sub_41D2B0();
+ scene14_setupMusic();
_updateCursorCallback = scene14_updateCursor;
break;
@@ -361,10 +718,11 @@ bool FullpipeEngine::sceneSwitcher(EntranceInfo *entrance) {
scene->initObjectCursors("SC_17");
setSceneMusicParameters(sceneVar);
addMessageHandler(sceneHandler17, 2);
- scene17_sub_41F060();
+ scene17_restoreState();
_updateCursorCallback = scene17_updateCursor;
break;
+#if 0
case SC_18:
sub_40E1B0();
sceneVar = _gameLoader->_gameVar->getSubVarByName("SC_18");
@@ -405,6 +763,7 @@ bool FullpipeEngine::sceneSwitcher(EntranceInfo *entrance) {
scene19_sub_4211D0(scene);
_updateCursorCallback = scene19_updateCursor;
break;
+#endif
case SC_20:
sceneVar = _gameLoader->_gameVar->getSubVarByName("SC_20");
@@ -435,7 +794,7 @@ bool FullpipeEngine::sceneSwitcher(EntranceInfo *entrance) {
_behaviorManager->initBehavior(scene, sceneVar);
scene->initObjectCursors("SC_22");
setSceneMusicParameters(sceneVar);
- scene22_sub_4228A0();
+ scene22_setBagState();
insertMessageHandler(sceneHandler22, 2, 2);
_updateCursorCallback = scene22_updateCursor;
break;
@@ -448,7 +807,7 @@ bool FullpipeEngine::sceneSwitcher(EntranceInfo *entrance) {
scene->initObjectCursors("SC_23");
setSceneMusicParameters(sceneVar);
insertMessageHandler(sceneHandler23, 2, 2);
- scene23_sub_423B00();
+ scene23_setGiraffeState();
_updateCursorCallback = scene23_updateCursor;
break;
@@ -460,19 +819,19 @@ bool FullpipeEngine::sceneSwitcher(EntranceInfo *entrance) {
scene->initObjectCursors("SC_24");
setSceneMusicParameters(sceneVar);
addMessageHandler(sceneHandler24, 2);
- scene24_sub_423DD0();
+ scene24_setPoolState();
_updateCursorCallback = defaultUpdateCursor;
break;
case SC_25:
sceneVar = _gameLoader->_gameVar->getSubVarByName("SC_25");
scene->preloadMovements(sceneVar);
- scene25_initScene(scene, entrance->field_4);
+ scene25_initScene(scene, entrance->_field_4);
_behaviorManager->initBehavior(scene, sceneVar);
scene->initObjectCursors("SC_25");
setSceneMusicParameters(sceneVar);
addMessageHandler(sceneHandler25, 2);
- scene25_sub_4253B0(scene, entrance->field_4);
+ scene25_setupWater(scene, entrance->_field_4);
_updateCursorCallback = scene25_updateCursor;
break;
@@ -484,10 +843,11 @@ bool FullpipeEngine::sceneSwitcher(EntranceInfo *entrance) {
scene->initObjectCursors("SC_26");
setSceneMusicParameters(sceneVar);
insertMessageHandler(sceneHandler26, 2, 2);
- scene26_sub_426140(scene);
+ scene26_setupDrop(scene);
_updateCursorCallback = scene26_updateCursor;
break;
+#if 0
case SC_27:
sceneVar = _gameLoader->_gameVar->getSubVarByName("SC_27");
scene->preloadMovements(sceneVar);
@@ -498,6 +858,7 @@ bool FullpipeEngine::sceneSwitcher(EntranceInfo *entrance) {
addMessageHandler(sceneHandler27, 2);
_updateCursorCallback = scene27_updateCursor;
break;
+#endif
case SC_28:
sceneVar = _gameLoader->_gameVar->getSubVarByName("SC_28");
@@ -510,6 +871,7 @@ bool FullpipeEngine::sceneSwitcher(EntranceInfo *entrance) {
_updateCursorCallback = scene28_updateCursor;
break;
+#if 0
case SC_29:
sceneVar = _gameLoader->_gameVar->getSubVarByName("SC_29");
scene->preloadMovements(sceneVar);
@@ -520,11 +882,12 @@ bool FullpipeEngine::sceneSwitcher(EntranceInfo *entrance) {
addMessageHandler(sceneHandler29, 2);
_updateCursorCallback = scene29_updateCursor;
break;
+#endif
case SC_30:
sceneVar = _gameLoader->_gameVar->getSubVarByName("SC_30");
scene->preloadMovements(sceneVar);
- scene30_initScene(scene, entrance->field_4);
+ scene30_initScene(scene, entrance->_field_4);
_behaviorManager->initBehavior(scene, sceneVar);
scene->initObjectCursors("SC_30");
setSceneMusicParameters(sceneVar);
@@ -551,7 +914,7 @@ bool FullpipeEngine::sceneSwitcher(EntranceInfo *entrance) {
scene->initObjectCursors("SC_32");
setSceneMusicParameters(sceneVar);
insertMessageHandler(sceneHandler32, 2, 2);
- scene32_sub_42C5C0();
+ scene32_setupMusic();
_updateCursorCallback = scene32_updateCursor;
break;
@@ -563,7 +926,7 @@ bool FullpipeEngine::sceneSwitcher(EntranceInfo *entrance) {
scene->initObjectCursors("SC_33");
setSceneMusicParameters(sceneVar);
insertMessageHandler(sceneHandler33, 2, 2);
- scene33_sub_42CEF0();
+ scene33_setupMusic();
_updateCursorCallback = scene33_updateCursor;
break;
@@ -575,7 +938,7 @@ bool FullpipeEngine::sceneSwitcher(EntranceInfo *entrance) {
scene->initObjectCursors("SC_34");
setSceneMusicParameters(sceneVar);
insertMessageHandler(sceneHandler34, 2, 2);
- scene34_sub_42DEE0();
+ scene34_initBeh();
_updateCursorCallback = scene34_updateCursor;
break;
@@ -626,14 +989,13 @@ bool FullpipeEngine::sceneSwitcher(EntranceInfo *entrance) {
case SC_FINAL1:
sceneVar = _gameLoader->_gameVar->getSubVarByName("SC_FINAL1");
scene->preloadMovements(sceneVar);
- sceneFinal1_initScene();
+ sceneFinal_initScene();
_behaviorManager->initBehavior(scene, sceneVar);
scene->initObjectCursors("SC_FINAL1");
setSceneMusicParameters(sceneVar);
- addMessageHandler(sceneHandlerFinal1, 2);
- _updateCursorCallback = sceneFinal1_updateCursor;
+ addMessageHandler(sceneHandlerFinal, 2);
+ _updateCursorCallback = sceneFinal_updateCursor;
break;
-#endif
case SC_DBGMENU:
sceneVar = _gameLoader->_gameVar->getSubVarByName("SC_DBGMENU");
@@ -645,920 +1007,354 @@ bool FullpipeEngine::sceneSwitcher(EntranceInfo *entrance) {
break;
default:
- _behaviorManager->initBehavior(0, 0);
+ error("Unknown scene %d", entrance->_sceneId);
break;
}
return true;
}
-void setElevatorButton(const char *name, int state) {
- GameVar *var = g_fullpipe->getGameLoaderGameVar()->getSubVarByName("OBJSTATES")->getSubVarByName(sO_LiftButtons);
-
- if (var)
- var->setSubVarAsInt(name, state);
-}
+int defaultUpdateCursor() {
+ g_fp->updateCursorCommon();
-void global_messageHandler_KickStucco() {
- warning("STUB: global_messageHandler_KickStucco()");
+ return g_fp->_cursorId;
}
-void global_messageHandler_KickMetal() {
- warning("STUB: global_messageHandler_KickMetal()");
+void FullpipeEngine::processArcade(ExCommand *ex) {
+ warning("STUB: FullpipeEngine::processArcade()");
}
-int global_messageHandler1(ExCommand *cmd) {
- debug(0, "global_messageHandler1: %d %d", cmd->_messageKind, cmd->_messageNum);
-
- if (cmd->_excFlags & 0x10000) {
- if (cmd->_messageNum == MV_MAN_TOLADDER)
- cmd->_messageNum = MV_MAN_TOLADDER2;
- if (cmd->_messageNum == MV_MAN_STARTLADDER)
- cmd->_messageNum = MV_MAN_STARTLADDER2;
- if (cmd->_messageNum == MV_MAN_GOLADDER)
- cmd->_messageNum = MV_MAN_GOLADDER2;
- if (cmd->_messageNum == MV_MAN_STOPLADDER)
- cmd->_messageNum = MV_MAN_STOPLADDER2;
- }
+void FullpipeEngine::updateMapPiece(int mapId, int update) {
+ for (int i = 0; i < 200; i++) {
+ int hiWord = (_mapTable[i] >> 16) & 0xffff;
- if (g_fullpipe->_inputDisabled) {
- if (cmd->_messageKind == 17) {
- switch (cmd->_messageNum) {
- case 29:
- case 30:
- case 36:
- case 106:
- cmd->_messageKind = 0;
- break;
- default:
- break;
- }
+ if (hiWord == mapId) {
+ _mapTable[i] |= update;
+ return;
}
- } else if (cmd->_messageKind == 17) {
- switch (cmd->_messageNum) {
- case MSG_MANSHADOWSON:
- g_fullpipe->_aniMan->_shadowsOn = 1;
- break;
- case MSG_HMRKICK_STUCCO:
- global_messageHandler_KickStucco();
- break;
- case MSG_MANSHADOWSOFF:
- g_fullpipe->_aniMan->_shadowsOn = 0;
- break;
- case MSG_DISABLESAVES:
- g_fullpipe->disableSaves(cmd);
- break;
- case MSG_ENABLESAVES:
- g_fullpipe->enableSaves();
- break;
- case MSG_HMRKICK_METAL:
- global_messageHandler_KickMetal();
- break;
- case 29: // left mouse
- if (g_fullpipe->_inventoryScene) {
- if (getGameLoaderInventory()->handleLeftClick(cmd))
- cmd->_messageKind = 0;
- }
- break;
- case 107: // right mouse
- if (getGameLoaderInventory()->getSelectedItemId()) {
- getGameLoaderInventory()->unselectItem(0);
- cmd->_messageKind = 0;
- }
- break;
- case 36: // keydown
- g_fullpipe->defHandleKeyDown(cmd->_keyCode);
-
- switch (cmd->_keyCode) {
- case '\x1B': // ESC
- if (g_fullpipe->_currentScene) {
- getGameLoaderInventory()->unselectItem(0);
- g_fullpipe->openMainMenu();
- cmd->_messageKind = 0;
- }
- break;
- case 't':
- g_fullpipe->stopAllSounds();
- cmd->_messageKind = 0;
- break;
- case 'u':
- g_fullpipe->toggleMute();
- cmd->_messageKind = 0;
- break;
- case ' ':
- if (getGameLoaderInventory()->getIsLocked()) {
- if (getGameLoaderInventory()->getIsInventoryOut()) {
- getGameLoaderInventory()->setIsLocked(0);
- }
- } else {
- getGameLoaderInventory()->slideOut();
- getGameLoaderInventory()->setIsLocked(1);
- }
- break;
- case '\t':
- if (g_fullpipe->_flgCanOpenMap)
- g_fullpipe->openMap();
- cmd->_messageKind = 0;
- break;
- case 'p':
- if (g_fullpipe->_flgCanOpenMap)
- g_fullpipe->openHelp();
- cmd->_messageKind = 0;
- break;
- default:
- break;
- }
- break;
- case 33:
- if (!g_fullpipe->_inventoryScene)
- break;
-
- int invItem;
-
- if (g_fullpipe->_updateFlag && (invItem = g_fullpipe->_inventory->getHoveredItem(&g_fullpipe->_mouseScreenPos))) {
- g_fullpipe->_cursorId = PIC_CSR_ITN;
- if (!g_fullpipe->_currSelectedInventoryItemId && !g_fullpipe->_aniMan->_movement &&
- !(g_fullpipe->_aniMan->_flags & 0x100) && g_fullpipe->_aniMan->isIdle()) {
- int st = g_fullpipe->_aniMan->_statics->_staticsId;
- ExCommand *newex = 0;
-
- if (st == ST_MAN_RIGHT) {
- newex = new ExCommand(g_fullpipe->_aniMan->_id, 1, rMV_MAN_LOOKUP, 0, 0, 0, 1, 0, 0, 0);
- } else if (st == (0x4000 | ST_MAN_RIGHT)) {
- newex = new ExCommand(g_fullpipe->_aniMan->_id, 1, MV_MAN_LOOKUP, 0, 0, 0, 1, 0, 0, 0);
- }
-
- if (newex) {
- newex->_keyCode = g_fullpipe->_aniMan->_okeyCode;
- newex->_excFlags |= 3;
- newex->postMessage();
- }
- }
-
- if (g_fullpipe->_currSelectedInventoryItemId != invItem)
- g_fullpipe->playSound(SND_CMN_070, 0);
-
- g_fullpipe->_currSelectedInventoryItemId = invItem;
- g_fullpipe->setCursor(g_fullpipe->_cursorId);
- break;
- }
- if (g_fullpipe->_updateCursorCallback)
- g_fullpipe->_updateCursorCallback();
-
- g_fullpipe->_currSelectedInventoryItemId = 0;
- g_fullpipe->setCursor(g_fullpipe->_cursorId);
- break;
- case 65: // open map
- if (cmd->_field_2C == 11 && cmd->_field_14 == ANI_INV_MAP && g_fullpipe->_flgCanOpenMap)
- g_fullpipe->openMap();
- break;
- default:
- break;
+ if (!hiWord) {
+ _mapTable[i] = (mapId << 16) | update;
+ return;
}
}
+}
- if (cmd->_messageKind == 56) {
- getGameLoaderInventory()->rebuildItemRects();
-
- ExCommand *newex = new ExCommand(0, 35, SND_CMN_031, 0, 0, 0, 1, 0, 0, 0);
-
- newex->_field_14 = 1;
- newex->_excFlags |= 3;
- newex->postMessage();
-
- return 1;
- } else if (cmd->_messageKind == 57) {
- getGameLoaderInventory()->rebuildItemRects();
-
- return 1;
- }
+void FullpipeEngine::updateMap(PreloadItem *pre) {
+ switch (pre->sceneId) {
+ case SC_1:
+ updateMapPiece(PIC_MAP_S01, 1);
- return 0;
-}
+ if (pre->keyCode == TrubaUp)
+ updateMapPiece(PIC_MAP_P01, 1);
-void staticANIObjectCallback(int *arg) {
- (*arg)--;
-}
+ if (pre->keyCode == TrubaLeft)
+ updateMapPiece(PIC_MAP_A13, 1);
+ break;
-int global_messageHandler2(ExCommand *cmd) {
- if (cmd->_messageKind != 17)
- return 0;
+ case SC_2:
+ updateMapPiece(PIC_MAP_S02, 1);
- int res = 0;
- StaticANIObject *ani;
+ if (pre->keyCode == TrubaLeft)
+ updateMapPiece(PIC_MAP_P01, 1);
- switch (cmd->_messageNum) {
- case 0x44c8:
- error("0x44c8");
- // Unk3_sub_4477A0(&unk3, _parentId, _field_14 != 0);
break;
- case 28:
- ani = g_fullpipe->_currentScene->getStaticANIObject1ById(cmd->_parentId, cmd->_keyCode);
- if (ani)
- ani->_priority = cmd->_field_14;
+ case SC_3:
+ updateMapPiece(PIC_MAP_S03, 1);
break;
- case 25:
- ani = g_fullpipe->_currentScene->getStaticANIObject1ById(cmd->_parentId, cmd->_keyCode);
- if (ani) {
- if (cmd->_field_14) {
- ani->setFlags40(true);
- ani->_callback2 = staticANIObjectCallback;
- } else {
- ani->setFlags40(false);
- ani->_callback2 = 0;
- }
- }
- break;
+ case SC_4:
+ updateMapPiece(PIC_MAP_S04, 1);
- case 26:
- ani = g_fullpipe->_currentScene->getStaticANIObject1ById(cmd->_parentId, cmd->_keyCode);
- if (ani) {
- Movement *mov = ani->_movement;
- if (mov)
- mov->_currDynamicPhase->_field_68 = 0;
- }
- break;
+ if (pre->keyCode == TrubaRight)
+ updateMapPiece(PIC_MAP_P04, 1);
- default:
-#if 0
- // We never put anything into _defMsgArray
- while (::iterator it = g_fullpipe->_defMsgArray.begin(); it != g_fullpipe->_defMsgArray.end(); ++it)
- if (((ExCommand *)*it)->_field_24 == _messageNum) {
- ((ExCommand *)*it)->firef34(v13);
- res = 1;
- }
-#endif
+ break;
- //debug_msg(_messageNum);
+ case SC_5:
+ updateMapPiece(PIC_MAP_S05, 1);
- if (!g_fullpipe->_soundEnabled || cmd->_messageNum != 33 || g_fullpipe->_currSoundListCount <= 0)
- return res;
+ if (pre->keyCode == TrubaLeft) {
+ updateMapPiece(PIC_MAP_P04, 1);
+ }
- for (int snd = 0; snd < g_fullpipe->_currSoundListCount; snd++) {
- SoundList *s = g_fullpipe->_currSoundList1[snd];
- int ms = s->getCount();
- for (int i = 0; i < ms; i++) {
- s->getSoundByIndex(i)->setPanAndVolumeByStaticAni();
- }
- }
- }
+ if (pre->keyCode == TrubaUp) {
+ updateMapPiece(PIC_MAP_P05, 1);
+ updateMapPiece(PIC_MAP_A11, 1);
+ }
- return res;
-}
+ break;
-int global_messageHandler3(ExCommand *cmd) {
- int result = 0;
-
- if (cmd->_messageKind == 17) {
- switch (cmd->_messageNum) {
- case 29:
- case 30:
- case 31:
- case 32:
- case 36:
- if (g_fullpipe->_inputDisabled)
- cmd->_messageKind = 0;
- break;
- default:
- break;
- }
- }
+ case SC_6:
+ updateMapPiece(PIC_MAP_S06, 1);
- StaticANIObject *ani, *ani2;
-
- switch (cmd->_messageKind) {
- case 17:
- switch (cmd->_messageNum) {
- case 61:
- return g_fullpipe->_gameLoader->preloadScene(cmd->_parentId, cmd->_keyCode);
- case 62:
- return g_fullpipe->_gameLoader->gotoScene(cmd->_parentId, cmd->_keyCode);
- case 64:
- if (g_fullpipe->_currentScene && g_fullpipe->_msgObjectId2
- && (!(cmd->_keyCode & 4) || g_fullpipe->_msgObjectId2 != cmd->_field_14 || g_fullpipe->_msgId != cmd->_field_20)) {
- ani = g_fullpipe->_currentScene->getStaticANIObject1ById(g_fullpipe->_msgObjectId2, g_fullpipe->_msgId);
- if (ani) {
- ani->_flags &= 0xFF7F;
- ani->_flags &= 0xFEFF;
- ani->deleteFromGlobalMessageQueue();
- }
- }
- g_fullpipe->_msgX = 0;
- g_fullpipe->_msgY = 0;
- g_fullpipe->_msgObjectId2 = 0;
- g_fullpipe->_msgId = 0;
- if ((cmd->_keyCode & 1) || (cmd->_keyCode & 2)) {
- g_fullpipe->_msgX = cmd->_x;
- g_fullpipe->_msgY = cmd->_y;
- }
- if (cmd->_keyCode & 4) {
- g_fullpipe->_msgObjectId2 = cmd->_field_14;
- g_fullpipe->_msgId = cmd->_field_20;
- }
- return result;
- case 29:
- if (!g_fullpipe->_currentScene)
- return result;
-
- if (g_fullpipe->_gameLoader->_interactionController->_flag24) {
- ani = g_fullpipe->_currentScene->getStaticANIObjectAtPos(cmd->_sceneClickX, cmd->_sceneClickY);
- ani2 = g_fullpipe->_currentScene->getStaticANIObject1ById(g_fullpipe->_gameLoader->_field_FA, -1);
- if (ani) {
- if (g_fullpipe->_msgObjectId2 == ani->_id && g_fullpipe->_msgId == ani->_okeyCode) {
- cmd->_messageKind = 0;
- return result;
- }
- if (canInteractAny(ani2, ani, cmd->_keyCode)) {
- handleObjectInteraction(ani2, ani, cmd->_keyCode);
- return 1;
- }
- } else {
- int id = g_fullpipe->_currentScene->getPictureObjectIdAtPos(cmd->_sceneClickX, cmd->_sceneClickY);
- PictureObject *pic = g_fullpipe->_currentScene->getPictureObjectById(id, 0);
- if (pic) {
- if (g_fullpipe->_msgObjectId2 == pic->_id && g_fullpipe->_msgId == pic->_okeyCode) {
- cmd->_messageKind = 0;
- return result;
- }
- if (!ani2 || canInteractAny(ani2, pic, cmd->_keyCode)) {
- if (!ani2 || (ani2->isIdle() && !(ani2->_flags & 0x80) && !(ani2->_flags & 0x100)))
- handleObjectInteraction(ani2, pic, cmd->_keyCode);
- return 1;
- }
- }
- }
- }
- if (getSc2MctlCompoundBySceneId(g_fullpipe->_currentScene->_sceneId)->_isEnabled && cmd->_keyCode <= 0) {
- if (g_fullpipe->_msgX != cmd->_sceneClickX || g_fullpipe->_msgY != cmd->_sceneClickY) {
- ani = g_fullpipe->_currentScene->getStaticANIObject1ById(g_fullpipe->_gameLoader->_field_FA, -1);
- if (!ani || (ani->isIdle() && !(ani->_flags & 0x80) && !(ani->_flags & 0x100))) {
- result = startWalkTo(g_fullpipe->_gameLoader->_field_FA, -1, cmd->_sceneClickX, cmd->_sceneClickY, 0);
- if (result) {
- ExCommand *ex = new ExCommand(g_fullpipe->_gameLoader->_field_FA, 17, 64, 0, 0, 0, 1, 0, 0, 0);
-
- ex->_keyCode = 1;
- ex->_excFlags |= 3;
- ex->_x = cmd->_sceneClickX;
- ex->_y = cmd->_sceneClickY;
- ex->postMessage();
- }
- }
- } else {
- cmd->_messageKind = 0;
- }
- }
- return result;
- default:
- return result;
- }
- case 58:
- g_fullpipe->setCursor(cmd->_keyCode);
- return result;
- case 59:
- setInputDisabled(1);
- return result;
- case 60:
- setInputDisabled(0);
- return result;
- case 56:
- if (cmd->_field_2C) {
- ani = g_fullpipe->_currentScene->getStaticANIObject1ById(cmd->_parentId, cmd->_keyCode);
- if (ani) {
- getGameLoaderInventory()->addItem2(ani);
- result = 1;
- }
- } else {
- result = 1;
- getGameLoaderInventory()->addItem(cmd->_parentId, 1);
- }
- getGameLoaderInventory()->rebuildItemRects();
- return result;
- case 57:
- if (cmd->_field_2C) {
- if (!cmd->_field_20) {
- getGameLoaderInventory()->removeItem2(g_fullpipe->_currentScene, cmd->_parentId, cmd->_x, cmd->_y, cmd->_field_14);
- getGameLoaderInventory()->rebuildItemRects();
- return 1;
- }
- ani = g_fullpipe->_currentScene->getStaticANIObject1ById(g_fullpipe->_gameLoader->_field_FA, -1);
- if (ani) {
- getGameLoaderInventory()->removeItem2(g_fullpipe->_currentScene, cmd->_parentId, ani->_ox + cmd->_x, ani->_oy + cmd->_y, ani->_priority + cmd->_field_14);
- getGameLoaderInventory()->rebuildItemRects();
- return 1;
- }
- } else {
- getGameLoaderInventory()->removeItem(cmd->_parentId, 1);
- }
- getGameLoaderInventory()->rebuildItemRects();
- return 1;
- case 55:
- if (g_fullpipe->_currentScene) {
- GameObject *obj;
- if (cmd->_field_14)
- obj = g_fullpipe->_currentScene->getStaticANIObject1ById(cmd->_x, cmd->_y);
- else
- obj = g_fullpipe->_currentScene->getPictureObjectById(cmd->_x, cmd->_y);
- handleObjectInteraction(g_fullpipe->_currentScene->getStaticANIObject1ById(cmd->_parentId, cmd->_keyCode), obj, cmd->_field_20);
- result = 1;
- }
- return result;
- case 51:
- return startWalkTo(cmd->_parentId, cmd->_keyCode, cmd->_x, cmd->_y, cmd->_field_20);
- case 52:
- return doSomeAnimation(cmd->_parentId, cmd->_keyCode, cmd->_field_20);
- case 53:
- return doSomeAnimation2(cmd->_parentId, cmd->_keyCode);
- case 63:
- if (cmd->_objtype == kObjTypeObjstateCommand) {
- ObjstateCommand *c = (ObjstateCommand *)cmd;
- result = 1;
- g_fullpipe->setObjectState(c->_objCommandName, c->_value);
- }
- return result;
- default:
- return result;
- }
-}
+ if (pre->keyCode == TrubaUp)
+ updateMapPiece(PIC_MAP_A12, 1);
-int global_messageHandler4(ExCommand *cmd) {
- StaticANIObject *ani = 0;
+ break;
- switch (cmd->_messageKind) {
- case 18: {
- MessageQueue *mq = new MessageQueue(g_fullpipe->_currentScene->getMessageQueueById(cmd->_messageNum), cmd->_parId, 0);
+ case SC_7:
+ updateMapPiece(PIC_MAP_S07, 1);
- if (cmd->_excFlags & 1)
- mq->_flag1 = 1;
- else
- mq->_flag1 = 0;
+ if (pre->keyCode == TrubaLeft)
+ updateMapPiece(PIC_MAP_P18, 1);
- mq->sendNextCommand();
break;
- }
- case 2:
- if (!g_fullpipe->_currentScene)
- break;
- ani = g_fullpipe->_currentScene->getStaticANIObject1ById(cmd->_parentId, cmd->_keyCode);
- if (!ani)
- break;
+ case SC_8:
+ updateMapPiece(PIC_MAP_S08, 1);
- ani->trySetMessageQueue(cmd->_messageNum, cmd->_parId);
- break;
+ if (pre->keyCode == TrubaUp)
+ updateMapPiece(PIC_MAP_P11, 1);
- case 1: {
- if (!g_fullpipe->_currentScene)
- break;
+ if (pre->keyCode == TrubaRight)
+ updateMapPiece(PIC_MAP_P18, 1);
- ani = g_fullpipe->_currentScene->getStaticANIObject1ById(cmd->_parentId, cmd->_keyCode);
- if (!ani)
- break;
+ return;
- int flags = cmd->_field_14;
- if (flags <= 0)
- flags = -1;
+ case SC_9:
+ updateMapPiece(PIC_MAP_S09, 1);
- if (cmd->_excFlags & 1)
- ani->startAnim(cmd->_messageNum, 0, flags);
- else
- ani->startAnim(cmd->_messageNum, cmd->_parId, flags);
+ if (pre->keyCode == TrubaDown)
+ updateMapPiece(PIC_MAP_P11, 1);
- break;
- }
- case 8:
- if (!g_fullpipe->_currentScene)
- break;
+ return;
- ani = g_fullpipe->_currentScene->getStaticANIObject1ById(cmd->_parentId, cmd->_keyCode);
- if (!ani)
- break;
+ case SC_10:
+ updateMapPiece(PIC_MAP_S10, 1);
- ani->startAnimEx(cmd->_messageNum, cmd->_parId, -1, -1);
- break;
+ if (pre->keyCode == TrubaRight)
+ updateMapPiece(PIC_MAP_P02, 1);
- case 20: {
- if (!g_fullpipe->_currentScene)
- break;
+ break;
- ani = g_fullpipe->_currentScene->getStaticANIObject1ById(cmd->_parentId, cmd->_keyCode);
- if (!ani)
- break;
+ case SC_11:
+ updateMapPiece(PIC_MAP_S11, 1);
- int flags = cmd->_field_14;
- if (flags <= 0)
- flags = -1;
+ if (pre->keyCode == TrubaLeft)
+ updateMapPiece(PIC_MAP_P02, 1);
- ExCommand2 *cmd2 = (ExCommand2 *)cmd;
+ break;
- if (cmd->_excFlags & 1) {
- ani->startAnimSteps(cmd->_messageNum, 0, cmd->_x, cmd->_y, cmd2->_points, cmd2->_pointsSize >> 3, flags);
- } else {
- ani->startAnimSteps(cmd->_messageNum, cmd->_parId, cmd->_x, cmd->_y, cmd2->_points, cmd2->_pointsSize >> 3, flags);
- }
+ case SC_12:
+ updateMapPiece(PIC_MAP_S12, 1);
break;
- }
- case 21:
- if (!g_fullpipe->_currentScene)
- break;
- ani = g_fullpipe->_currentScene->getStaticANIObject1ById(cmd->_parentId, cmd->_keyCode);
- if (!ani)
- break;
+ case SC_13:
+ updateMapPiece(PIC_MAP_S13, 1);
- ani->queueMessageQueue(0);
- ani->playIdle();
- break;
- case 9:
- // Nop in original
- break;
- case 3:
- g_fullpipe->_currentScene->_y = cmd->_messageNum - cmd->_messageNum % g_fullpipe->_scrollSpeed;
+ if (pre->keyCode == TrubaUp) {
+ updateMapPiece(PIC_MAP_P06, 1);
+ updateMapPiece(PIC_MAP_A10, 1);
+ }
break;
- case 4:
- g_fullpipe->_currentScene->_x = cmd->_messageNum - cmd->_messageNum % g_fullpipe->_scrollSpeed;
+ case SC_14:
+ updateMapPiece(PIC_MAP_S14, 1);
break;
- case 19: {
- if (!g_fullpipe->_currentScene)
- break;
- ani = g_fullpipe->_currentScene->getStaticANIObject1ById(cmd->_parentId, cmd->_keyCode);
- if (!ani)
- break;
-
- MessageQueue *mq = ani->getMessageQueue();
- MessageQueue *mq2 = ani->changeStatics1(cmd->_messageNum);
+ case SC_15:
+ updateMapPiece(PIC_MAP_S15, 1);
- if (!mq2 || !mq2->getExCommandByIndex(0) || !mq)
- break;
+ if (pre->keyCode == TrubaUp) {
+ updateMapPiece(PIC_MAP_P08, 1);
+ updateMapPiece(PIC_MAP_A14, 1);
+ }
- mq2->_parId = mq->_id;
- mq2->_flag1 = (cmd->_field_24 == 0);
break;
- }
- case 22:
- if (!g_fullpipe->_currentScene)
- break;
- ani = g_fullpipe->_currentScene->getStaticANIObject1ById(cmd->_parentId, cmd->_keyCode);
- if (!ani)
- break;
+ case SC_16:
+ updateMapPiece(PIC_MAP_S16, 1);
+ break;
- ani->_flags |= 4;
- ani->changeStatics2(cmd->_messageNum);
+ case SC_17:
+ updateMapPiece(PIC_MAP_S17, 1);
break;
- case 6:
- if (!g_fullpipe->_currentScene)
- break;
+ case SC_18:
+ updateMapPiece(PIC_MAP_S1819, 1);
- ani = g_fullpipe->_currentScene->getStaticANIObject1ById(cmd->_parentId, cmd->_keyCode);
- if (!ani)
- break;
+ if (pre->keyCode == PIC_SC18_RTRUBA)
+ updateMapPiece(PIC_MAP_P14, 1);
- ani->hide();
break;
- case 27:
- if (!g_fullpipe->_currentScene || g_fullpipe->_currentScene->getStaticANIObject1ById(cmd->_parentId, cmd->_keyCode) == 0) {
- ani = g_fullpipe->accessScene(cmd->_field_20)->getStaticANIObject1ById(cmd->_parentId, -1);
- if (ani) {
- ani = new StaticANIObject(ani);
- g_fullpipe->_currentScene->addStaticANIObject(ani, 1);
- }
- }
-
- // fall through
- case 5:
- if (g_fullpipe->_currentScene)
- ani = g_fullpipe->_currentScene->getStaticANIObject1ById(cmd->_parentId, cmd->_keyCode);
+ case SC_19:
+ updateMapPiece(PIC_MAP_S1819, 1);
- if (!ani)
- break;
+ if (pre->keyCode == PIC_SC19_RTRUBA3) {
+ updateMapPiece(PIC_MAP_P15, 1);
+ updateMapPiece(PIC_MAP_A09, 1);
+ }
- if (cmd->_field_14 >= 0)
- ani->_priority = cmd->_field_14;
+ break;
- ani->show1(cmd->_x, cmd->_y, cmd->_messageNum, cmd->_parId);
+ case SC_20:
+ updateMapPiece(PIC_MAP_S20, 1);
break;
- case 10:
- if (!g_fullpipe->_currentScene)
- break;
+ case SC_21:
+ updateMapPiece(PIC_MAP_S21, 1);
- ani = g_fullpipe->_currentScene->getStaticANIObject1ById(cmd->_parentId, cmd->_keyCode);
- if (!ani)
- break;
+ if (pre->keyCode == TrubaLeft) {
+ updateMapPiece(PIC_MAP_P15, 1);
+ updateMapPiece(PIC_MAP_A09, 1);
+ }
- if (cmd->_field_14 >= 0)
- ani->_priority = cmd->_field_14;
+ if (pre->keyCode == TrubaDown)
+ updateMapPiece(PIC_MAP_A08, 1);
- ani->show2(cmd->_x, cmd->_y, cmd->_messageNum, cmd->_parId);
break;
- case 7: {
- if (!g_fullpipe->_currentScene->_picObjList.size())
- break;
-
- int offX = g_fullpipe->_scrollSpeed * (cmd->_x / g_fullpipe->_scrollSpeed);
- int offY = g_fullpipe->_scrollSpeed * (cmd->_y / g_fullpipe->_scrollSpeed);
-
- if (cmd->_messageNum) {
- g_fullpipe->_currentScene->_x = offX - g_fullpipe->_sceneRect.left;
- g_fullpipe->_currentScene->_y = offY - g_fullpipe->_sceneRect.top;
+ case SC_22:
+ updateMapPiece(PIC_MAP_S22, 1);
+ break;
- if (cmd->_field_24) {
- g_fullpipe->_currentScene->_messageQueueId = cmd->_parId;
- }
+ case SC_23:
+ if (getObjectState("Верхний люк_23") == getObjectEnumState("Верхний люк_23", "Открыт")) {
+ updateMapPiece(PIC_MAP_S23_1, 0);
+ updateMapPiece(PIC_MAP_S23_2, 1);
+ updateMapPiece(PIC_MAP_P07, 1);
} else {
- g_fullpipe->_sceneRect.moveTo(offX, offY);
-
- g_fullpipe->_currentScene->_x = 0;
- g_fullpipe->_currentScene->_y = 0;
-
- g_fullpipe->_currentScene->updateScrolling2();
+ updateMapPiece(PIC_MAP_S23_1, 1);
+ updateMapPiece(PIC_MAP_S23_2, 0);
}
break;
- }
- case 34:
- if (!g_fullpipe->_currentScene)
- break;
- ani = g_fullpipe->_currentScene->getStaticANIObject1ById(cmd->_parentId, cmd->_keyCode);
- if (!ani)
- break;
-
- ani->_flags = cmd->_messageNum | (ani->_flags & ~cmd->_field_14);
+ case SC_24:
+ updateMapPiece(PIC_MAP_S24, 1);
- break;
+ if (pre->keyCode == TrubaUp)
+ updateMapPiece(PIC_MAP_A08, 1);
- case 35:
- global_messageHandler_handleSound(cmd);
+ if (pre->keyCode == TrubaDown) {
+ updateMapPiece(PIC_MAP_P13, 1);
+ updateMapPiece(PIC_MAP_A07, 1);
+ }
break;
- case 11:
- case 12:
- break;
- default:
- return 0;
+ case SC_25:
+ updateMapPiece(PIC_MAP_S25, 1);
break;
- }
-
- return 1;
-}
-
-int MovGraph_messageHandler(ExCommand *cmd) {
- if (cmd->_messageKind != 17)
- return 0;
- if (cmd->_messageNum != 33)
- return 0;
-
- StaticANIObject *ani = g_fullpipe->_currentScene->getStaticANIObject1ById(g_fullpipe->_gameLoader->_field_FA, -1);
-
- if (!getSc2MctlCompoundBySceneId(g_fullpipe->_currentScene->_sceneId))
- return 0;
-
- if (getSc2MctlCompoundBySceneId(g_fullpipe->_currentScene->_sceneId)->_objtype != kObjTypeMovGraph || !ani)
- return 0;
-
- MovGraph *gr = (MovGraph *)getSc2MctlCompoundBySceneId(g_fullpipe->_currentScene->_sceneId);
-
- MovGraphLink *link = 0;
- double mindistance = 1.0e10;
- Common::Point point;
+ case SC_26:
+ updateMapPiece(PIC_MAP_S26, 1);
- for (ObList::iterator i = gr->_links.begin(); i != gr->_links.end(); ++i) {
- point.x = ani->_ox;
- point.y = ani->_oy;
+ if (pre->keyCode == TrubaLeft)
+ updateMapPiece(PIC_MAP_A06, 1);
- double dst = gr->calcDistance(&point, (MovGraphLink *)(*i), 0);
- if (dst >= 0.0 && dst < mindistance) {
- mindistance = dst;
- link = (MovGraphLink *)(*i);
+ if (pre->keyCode == TrubaUp) {
+ updateMapPiece(PIC_MAP_P13, 1);
+ updateMapPiece(PIC_MAP_A07, 1);
}
- }
-
- int top;
-
- if (link) {
- MovGraphNode *node = link->_movGraphNode1;
-
- double sq = (ani->_oy - node->_y) * (ani->_oy - node->_y) + (ani->_ox - node->_x) * (ani->_ox - node->_x);
- int off = (node->_field_14 >> 16) & 0xFF;
- double off2 = (link->_movGraphNode2->_field_14 >> 8) & 0xff - off;
-
- top = off + (int)(sqrt(sq) * off2 / link->_distance);
- } else {
- top = (gr->calcOffset(ani->_ox, ani->_oy)->_field_14 >> 8) & 0xff;
- }
-
- if (ani->_movement) {
- ani->_movement->_currDynamicPhase->_rect->top = 255 - top;
- return 0;
- }
-
- if (ani->_statics)
- ani->_statics->_rect->top = 255 - top;
-
- return 0;
-}
-
-int defaultUpdateCursor() {
- g_fullpipe->updateCursorsCommon();
-
- return g_fullpipe->_cursorId;
-}
-int sceneIntro_updateCursor() {
- g_fullpipe->_cursorId = 0;
-
- return 0;
-}
-
-void FullpipeEngine::setSwallowedEggsState() {
- GameVar *v = _gameLoader->_gameVar->getSubVarByName("OBJSTATES")->getSubVarByName(sO_GulpedEggs);
-
- g_vars->swallowedEgg1 = v->getSubVarByName(sO_Egg1);
- g_vars->swallowedEgg2 = v->getSubVarByName(sO_Egg2);
- g_vars->swallowedEgg3 = v->getSubVarByName(sO_Egg3);
+ break;
- g_vars->swallowedEgg1->_value.intValue = 0;
- g_vars->swallowedEgg2->_value.intValue = 0;
- g_vars->swallowedEgg3->_value.intValue = 0;
-}
+ case SC_27:
+ updateMapPiece(PIC_MAP_S27, 1);
+ break;
-void sceneIntro_initScene(Scene *sc) {
- g_fullpipe->_gameLoader->loadScene(SC_INTRO2);
+ case SC_28:
+ updateMapPiece(PIC_MAP_S28, 1);
- g_vars->sceneIntro_aniin1man = sc->getStaticANIObject1ById(ANI_IN1MAN, -1);
- g_vars->sceneIntro_needSleep = true;
- g_vars->sceneIntro_needGetup = false;
- g_vars->sceneIntro_playing = true;
- g_vars->sceneIntro_needBlackout = false;
+ if (pre->keyCode == TrubaRight)
+ updateMapPiece(PIC_MAP_A06, 1);
- if (g_fullpipe->_recordEvents || g_fullpipe->_inputArFlag)
- g_vars->sceneIntro_skipIntro = false;
+ break;
- g_fullpipe->_modalObject = new ModalIntro;
-}
+ case SC_29:
+ updateMapPiece(PIC_MAP_S29, 1);
-int sceneHandlerIntro(ExCommand *cmd) {
- warning("STUB: sceneHandlerIntro()");
+ if (pre->keyCode == TrubaUp)
+ updateMapPiece(PIC_MAP_A05, 1);
- return 0;
-}
+ break;
-void scene01_fixEntrance() {
- GameVar *var = g_fullpipe->getGameLoaderGameVar()->getSubVarByName("OBJSTATES")->getSubVarByName("SAVEGAME");
- if (var->getSubVarAsInt("Entrance") == TrubaLeft)
- var->setSubVarAsInt("Entrance", TrubaRight);
-}
+ case SC_30:
+ updateMapPiece(PIC_MAP_S30, 1);
-void scene01_initScene(Scene *sc, int entrance) {
- g_vars->scene01_picSc01Osk = sc->getPictureObjectById(PIC_SC1_OSK, 0);
- g_vars->scene01_picSc01Osk->_flags &= 0xFFFB;
+ if (pre->keyCode == TrubaLeft)
+ updateMapPiece(PIC_MAP_P09, 1);
- g_vars->scene01_picSc01Osk2 = sc->getPictureObjectById(PIC_SC1_OSK2, 0);
- g_vars->scene01_picSc01Osk2->_flags &= 0xFFFB;
+ if (pre->keyCode == TrubaRight)
+ updateMapPiece(PIC_MAP_A04, 1);
- if (g_fullpipe->getObjectState(sO_EggCracker) == g_fullpipe->getObjectEnumState(sO_EggCracker, sO_DidNotCrackEgg)) {
- PictureObject *pic = sc->getPictureObjectById(PIC_SC1_KUCHKA, 0);
- if (pic)
- pic->_flags &= 0xFFFB;
- }
+ break;
- if (entrance != TrubaLeft) {
- StaticANIObject *bootAnim = sc->getStaticANIObject1ById(ANI_BOOT_1, -1);
- if (bootAnim)
- bootAnim->_flags &= ~0x04;
- }
+ case SC_31:
+ updateMapPiece(PIC_MAP_S31_2, 1);
- setElevatorButton(sO_Level2, ST_LBN_2N);
-}
+ if (getObjectState("КактуÑ") == getObjectEnumState("КактуÑ", "ВыроÑ"))
+ updateMapPiece(PIC_MAP_S31_1, 1);
-int sceneHandler01(ExCommand *cmd) {
- int res = 0;
+ if (pre->keyCode == TrubaRight)
+ updateMapPiece(PIC_MAP_P09, 1);
- if (cmd->_messageKind != 17)
- return 0;
+ break;
- if (cmd->_messageNum > MSG_SC1_SHOWOSK) {
- if (cmd->_messageNum == MSG_SC1_UTRUBACLICK)
- handleObjectInteraction(g_fullpipe->_aniMan, g_fullpipe->_currentScene->getPictureObjectById(PIC_SC1_LADDER, 0), 0);
+ case SC_32:
+ updateMapPiece(PIC_MAP_S32_2, 1);
- return 0;
- }
+ if (getObjectState("КактуÑ") == getObjectEnumState("КактуÑ", "ВыроÑ"))
+ updateMapPiece(PIC_MAP_S32_1, 1);
- if (cmd->_messageNum == MSG_SC1_SHOWOSK) {
- g_vars->scene01_picSc01Osk->_flags |= 4;
+ break;
- g_vars->scene01_picSc01Osk->_priority = 20;
- g_vars->scene01_picSc01Osk2->_priority = 21;
+ case SC_33:
+ updateMapPiece(PIC_MAP_S33, 1);
+ break;
- return 0;
- }
+ case SC_34:
+ updateMapPiece(PIC_MAP_S34, 1);
- if (cmd->_messageNum != 0x21) {
- if (cmd->_messageNum == MSG_SC1_SHOWOSK2) {
- g_vars->scene01_picSc01Osk2->_flags |= 4;
- g_vars->scene01_picSc01Osk2->_priority = 20;
- g_vars->scene01_picSc01Osk->_priority = 21;
+ if (pre->keyCode == TrubaUp)
+ updateMapPiece(PIC_MAP_A03, 1);
- return 0;
- }
+ break;
- return 0;
- }
+ case SC_35:
+ updateMapPiece(PIC_MAP_S35, 1);
- if (g_fullpipe->_aniMan2) {
- if (g_fullpipe->_aniMan2->_ox < g_fullpipe->_sceneRect.left + 200) {
- g_fullpipe->_currentScene->_x = g_fullpipe->_aniMan2->_ox - g_fullpipe->_sceneRect.left - 300;
- }
+ if (pre->keyCode == TrubaLeft)
+ updateMapPiece(PIC_MAP_A02, 1);
- if (g_fullpipe->_aniMan2->_ox > g_fullpipe->_sceneRect.right - 200)
- g_fullpipe->_currentScene->_x = g_fullpipe->_aniMan2->_ox - g_fullpipe->_sceneRect.right + 300;
+ if (pre->keyCode == TrubaDown)
+ updateMapPiece(PIC_MAP_A03, 1);
- res = 1;
- }
- g_fullpipe->_behaviorManager->updateBehaviors();
+ break;
- g_fullpipe->startSceneTrack();
+ case SC_36:
+ updateMapPiece(PIC_MAP_S36, 1);
+ break;
- return res;
-}
+ case SC_37:
+ updateMapPiece(PIC_MAP_S37, 1);
+ updateMapPiece(PIC_MAP_A01, 1);
+ break;
-void sceneDbgMenu_initScene(Scene *sc) {
- g_vars->selector = sc->getPictureObjectById(PIC_SCD_SEL, 0);
- getGameLoaderInteractionController()->disableFlag24();
- setInputDisabled(0);
-}
+ case SC_38:
+ updateMapPiece(PIC_MAP_S38, 1);
-GameObject *sceneHandlerDbgMenu_getObjectAtXY(int x, int y) {
- if (g_fullpipe->_currentScene)
- for (uint i = 0; i < g_fullpipe->_currentScene->_picObjList.size(); i++) {
- PictureObject *pic = (PictureObject *)g_fullpipe->_currentScene->_picObjList[i];
+ switch (pre->preloadId1) {
+ case SC_15:
+ updateMapPiece(PIC_MAP_P16, 1);
+ break;
- if (x >= pic->_ox && y >= pic->_oy) {
- Common::Point point;
+ case SC_1:
+ updateMapPiece(PIC_MAP_P10, 1);
+ break;
- pic->getDimensions(&point);
+ case SC_10:
+ updateMapPiece(PIC_MAP_P17, 1);
+ break;
- if (x <= pic->_ox + point.x && y <= pic->_oy + point.y && pic != g_vars->selector)
- return pic;
- }
+ case SC_19:
+ updateMapPiece(PIC_MAP_P12, 1);
+ break;
}
-
- return 0;
+ break;
+ }
}
-int sceneHandlerDbgMenu(ExCommand *ex) {
- if (ex->_messageKind != 17)
- return 0;
-
- int mx = g_fullpipe->_mouseScreenPos.x + g_fullpipe->_sceneRect.left;
- int my = g_fullpipe->_mouseScreenPos.y + g_fullpipe->_sceneRect.top;
-
- if (ex->_messageNum == 29) {
- GameObject *obj = sceneHandlerDbgMenu_getObjectAtXY(mx, my);
- if (obj && canInteractAny(0, obj, -3) ) {
- getGameLoaderInteractionController()->enableFlag24();
- handleObjectInteraction(0, obj, 0);
- }
- return 0;
- }
- if (ex->_messageNum != 33) {
- if (ex->_messageNum == MSG_RESTARTGAME) {
- g_fullpipe->_needRestart = true;
- return 0;
- }
- return 0;
- }
-
- g_fullpipe->_cursorId = PIC_CSR_DEFAULT;
- GameObject *obj = g_fullpipe->_currentScene->getStaticANIObjectAtPos(mx, my);
- if (obj) {
- if (canInteractAny(0, obj, -3)) {
- g_fullpipe->_cursorId = PIC_CSR_DEFAULT;
- g_fullpipe->setCursor(PIC_CSR_DEFAULT);
- return 0;
- }
- } else {
- obj = sceneHandlerDbgMenu_getObjectAtXY(mx, my);
- if (obj && canInteractAny(0, obj, -3) ) {
- g_vars->selector->_flags |= 4;
- g_vars->selector->setOXY(obj->_ox, obj->_oy);
- g_fullpipe->_cursorId = PIC_CSR_DEFAULT;
- g_fullpipe->setCursor(PIC_CSR_DEFAULT);
- return 0;
- }
- g_vars->selector->_flags &= 0xFFFB;
- }
- g_fullpipe->setCursor(g_fullpipe->_cursorId);
-
- return 0;
-}
} // End of namespace Fullpipe
diff --git a/engines/fullpipe/scenes.h b/engines/fullpipe/scenes.h
index 5597612aa6..5f77f74706 100644
--- a/engines/fullpipe/scenes.h
+++ b/engines/fullpipe/scenes.h
@@ -25,10 +25,166 @@
namespace Fullpipe {
+struct BehaviorEntryInfo;
+class MGM;
+class MctlLadder;
+struct Ring;
class StaticANIObject;
+int defaultUpdateCursor();
+
+int sceneIntro_updateCursor();
+void sceneIntro_initScene(Scene *sc);
+int sceneHandlerIntro(ExCommand *cmd);
+
+void scene01_fixEntrance();
+void scene01_initScene(Scene *sc, int entrance);
+int sceneHandler01(ExCommand *cmd);
+
+void scene02_initScene(Scene *sc);
+int sceneHandler02(ExCommand *ex);
+
+void scene03_setEaterState();
+int scene03_updateCursor();
+void scene03_initScene(Scene *sc);
+int sceneHandler03(ExCommand *cmd);
+
+int scene04_updateCursor();
+void scene04_initScene(Scene *sc);
+int sceneHandler04(ExCommand *cmd);
+
+void scene05_initScene(Scene *sc);
+int sceneHandler05(ExCommand *cmd);
+
+void scene06_initScene(Scene *sc);
+void scene06_initMumsy();
+int sceneHandler06(ExCommand *cmd);
+int scene06_updateCursor();
+
+void scene07_initScene(Scene *sc);
+int sceneHandler07(ExCommand *cmd);
+
+void scene08_initScene(Scene *sc);
+void scene08_setupMusic();
+int sceneHandler08(ExCommand *cmd);
+int scene08_updateCursor();
+
+void scene10_initScene(Scene *sc);
+int sceneHandler10(ExCommand *cmd);
+int scene10_updateCursor();
+
+void scene11_initScene(Scene *sc);
+void scene11_setupMusic();
+int sceneHandler11(ExCommand *cmd);
+int scene11_updateCursor();
+
+void scene12_initScene(Scene *sc);
+int sceneHandler12(ExCommand *ex);
+
+void scene13_initScene(Scene *sc);
+int sceneHandler13(ExCommand *ex);
+
+void scene14_initScene(Scene *sc);
+void scene14_setupMusic();
+int sceneHandler14(ExCommand *cmd);
+int scene14_updateCursor();
+
+int scene15_updateCursor();
+void scene15_initScene(Scene *sc);
+int sceneHandler15(ExCommand *cmd);
+
+void scene16_initScene(Scene *sc);
+int sceneHandler16(ExCommand *cmd);
+int scene16_updateCursor();
+
+void scene17_initScene(Scene *sc);
+void scene17_restoreState();
+int sceneHandler17(ExCommand *cmd);
+int scene17_updateCursor();
+
+void scene18_preload();
+void scene19_preload(Scene *sc, int key);
+
+void scene20_initScene(Scene *sc);
+int sceneHandler20(ExCommand *ex);
+
+int scene21_updateCursor();
+void scene21_initScene(Scene *sc);
+int sceneHandler21(ExCommand *cmd);
+
+void scene22_initScene(Scene *sc);
+void scene22_setBagState();
+int sceneHandler22(ExCommand *cmd);
+int scene22_updateCursor();
+
+void scene23_initScene(Scene *sc);
+void scene23_setGiraffeState();
+int sceneHandler23(ExCommand *cmd);
+int scene23_updateCursor();
+
+void scene24_initScene(Scene *sc);
+void scene24_setPoolState();
+int sceneHandler24(ExCommand *cmd);
+
+void scene25_initScene(Scene *sc, int entrance);
+void scene25_setupWater(Scene *sc, int entrance);
+int sceneHandler25(ExCommand *cmd);
+int scene25_updateCursor();
+
+void scene26_initScene(Scene *sc);
+void scene26_setupDrop(Scene *sc);
+int sceneHandler26(ExCommand *cmd);
+int scene26_updateCursor();
+
+void scene28_initScene(Scene *sc);
+ int sceneHandler28(ExCommand *ex);
+int scene28_updateCursor();
+
+int scene30_updateCursor();
+void scene30_initScene(Scene *sc, int flag);
+int sceneHandler30(ExCommand *cmd);
+
+void scene31_initScene(Scene *sc);
+int sceneHandler31(ExCommand *ex);
+
+void scene32_initScene(Scene *sc);
+void scene32_setupMusic();
+int sceneHandler32(ExCommand *cmd);
+int scene32_updateCursor();
+
+void scene33_initScene(Scene *sc);
+void scene33_setupMusic();
+int sceneHandler33(ExCommand *cmd);
+int scene33_updateCursor();
+
+void scene34_initScene(Scene *sc);
+void scene34_initBeh();
+int sceneHandler34(ExCommand *cmd);
+int scene34_updateCursor();
+
+void scene35_initScene(Scene *sc);
+int sceneHandler35(ExCommand *cmd);
+
+int scene36_updateCursor();
+void scene36_initScene(Scene *sc);
+int sceneHandler36(ExCommand *cmd);
+
+void scene37_initScene(Scene *sc);
+int sceneHandler37(ExCommand *ex);
+int scene37_updateCursor();
+
+void scene38_initScene(Scene *sc);
+int sceneHandler38(ExCommand *ex);
+
+int sceneFinal_updateCursor();
+void sceneFinal_initScene();
+int sceneHandlerFinal(ExCommand *cmd);
+
+void sceneDbgMenu_initScene(Scene *sc);
+int sceneHandlerDbgMenu(ExCommand *cmd);
+
class Vars {
- public:
+public:
Vars();
GameVar *swallowedEgg1;
@@ -45,7 +201,361 @@ class Vars {
PictureObject *scene01_picSc01Osk;
PictureObject *scene01_picSc01Osk2;
- GameObject *selector;
+ StaticANIObject *scene02_guvTheDrawer;
+ int scene02_boxDelay;
+ bool scene02_boxOpen;
+
+ StaticANIObject *scene03_eggeater;
+ StaticANIObject *scene03_domino;
+
+ PictureObject *scene04_bottle;
+ StaticANIObject *scene04_hand;
+ StaticANIObject *scene04_plank;
+ StaticANIObject *scene04_clock;
+ StaticANIObject *scene04_spring;
+ StaticANIObject *scene04_mamasha;
+ StaticANIObject *scene04_boot;
+ StaticANIObject *scene04_speaker;
+
+ Common::Point scene04_jumpingKozyawki[20];
+ Common::Point scene04_jumpRotateKozyawki[20];
+
+ Common::List<StaticANIObject *> scene04_kozyawkiObjList;
+ Common::List<GameObject *> scene04_bottleObjList;
+ Common::List<StaticANIObject *> scene04_kozyawkiAni;
+
+ MctlLadder *scene04_ladder;
+ int scene04_ladderOffset;
+
+ bool scene04_coinPut;
+ bool scene04_soundPlaying;
+ bool scene04_dudeOnLadder;
+
+ int scene04_dynamicPhaseIndex;
+ int scene04_sceneClickX;
+ int scene04_sceneClickY;
+ int scene04_dudePosX;
+ int scene04_dudePosY;
+ int scene04_bottleY;
+
+ StaticANIObject *scene04_walkingKozyawka;
+
+ int scene04_speakerVariant;
+ int scene04_speakerPhase;
+
+ bool scene04_bottleIsTaken;
+ bool scene04_kozyawkaOnLadder;
+ int scene04_bottleWeight;
+ bool scene04_var07;
+ bool scene04_ladderClickable;
+ bool scene04_handIsDown;
+ bool scene04_dudeInBottle;
+ bool scene04_kozHeadRaised;
+ bool scene04_bottleIsDropped;
+ bool scene04_bigBallIn;
+ int scene04_bigBallCounter;
+ bool scene04_bigBallFromLeft;
+ bool scene04_clockCanGo;
+ bool scene04_objectIsTaken;
+ int scene04_springOffset;
+ StaticANIObject *scene04_lastKozyawka;
+ int scene04_springDelay;
+
+ StaticANIObject *scene05_handle;
+ StaticANIObject *scene05_wacko;
+ StaticANIObject *scene05_bigHatch;
+ int scene05_wackoTicker;
+ int scene05_handleFlipper;
+ int scene05_floatersTicker;
+
+ StaticANIObject *scene06_mumsy;
+ int scene06_manX;
+ int scene06_manY;
+ int scene06_ballX;
+ int scene06_ballY;
+ StaticANIObject *scene06_someBall;
+ StaticANIObject *scene06_invHandle;
+ StaticANIObject *scene06_liftButton;
+ StaticANIObject *scene06_ballDrop;
+ bool scene06_arcadeEnabled;
+ bool scene06_aimingBall;
+ StaticANIObject *scene06_currentBall;
+ StaticANIObject *scene06_ballInHands;
+ StaticANIObject *scene06_flyingBall;
+ Common::Array<StaticANIObject *> scene06_balls;
+ int scene06_numBallsGiven;
+ int scene06_mumsyNumBalls;
+ int scene06_eggieTimeout;
+ int scene06_eggieDirection;
+ int scene06_mumsyGotBall;
+ int scene06_ballDeltaX;
+ int scene06_ballDeltaY;
+ int scene06_sceneClickX;
+ int scene06_sceneClickY;
+ int scene06_mumsyPos;
+ BehaviorEntryInfo *scene06_mumsyJumpBk;
+ BehaviorEntryInfo *scene06_mumsyJumpFw;
+ int scene06_mumsyJumpBkPercent;
+ int scene06_mumsyJumpFwPercent;
+
+ BehaviorEntryInfo *scene07_lukeAnim;
+ int scene07_lukePercent;
+ StaticANIObject *scene07_plusMinus;
+
+ StaticANIObject *scene08_batuta;
+ StaticANIObject *scene08_vmyats;
+ StaticANIObject *scene08_clock;
+ bool scene08_inAir;
+ bool scene08_flyingUp;
+ int scene08_onBelly;
+ int scene08_stairsOffset;
+ int scene08_snoringCountdown;
+ bool scene08_inArcade;
+ bool scene08_stairsVisible;
+ int scene08_manOffsetY;
+
+ StaticANIObject *scene10_gum;
+ StaticANIObject *scene10_packet;
+ StaticANIObject *scene10_packet2;
+ StaticANIObject *scene10_inflater;
+ PictureObject *scene10_ladder;
+ int scene10_hasGum;
+
+ StaticANIObject *scene11_swingie;
+ StaticANIObject *scene11_boots;
+ StaticANIObject *scene11_dudeOnSwing;
+ PictureObject *scene11_hint;
+ MGM scene11_mgm;
+ bool scene11_arcadeIsOn;
+ bool scene11_scrollIsEnabled;
+ bool scene11_scrollIsMaximized;
+ int scene11_hintCounter;
+ int scene11_swingieScreenEdge;
+ int scene11_crySound;
+ double scene11_swingAngle;
+ double scene11_swingOldAngle;
+ double scene11_swingSpeed;
+ double scene11_swingAngleDiff;
+ double scene11_swingInertia;
+ int scene11_swingCounter;
+ int scene11_swingCounterPrevTurn;
+ int scene11_swingDirection;
+ int scene11_swingDirectionPrevTurn;
+ bool scene11_swingIsSwinging;
+ bool scene11_swingieStands;
+ int scene11_dudeX;
+ int scene11_dudeY;
+ int scene11_swingMaxAngle;
+
+ int scene12_fly;
+ int scene12_flyCountdown;
+
+ StaticANIObject *scene13_whirlgig;
+ StaticANIObject *scene13_guard;
+ StaticANIObject *scene13_handleR;
+ StaticANIObject *scene13_handleL;
+ StaticANIObject *scene13_bridge;
+ bool scene13_guardDirection;
+ int scene13_dudeX;
+
+ StaticANIObject *scene14_grandma;
+ int scene14_sceneDeltaX;
+ int scene14_sceneDeltaY;
+ bool scene14_arcadeIsOn;
+ bool scene14_dudeIsKicking;
+ bool scene14_ballIsFlying;
+ bool scene14_dudeCanKick;
+ int scene14_sceneDiffX;
+ int scene14_sceneDiffY;
+ StaticANIObject *scene14_pink;
+ StaticANIObject *scene14_flyingBall;
+ Common::List<StaticANIObject *> scene14_balls;
+ bool scene14_grandmaIsHere;
+ int scene14_dudeX;
+ int scene14_dudeY;
+ int scene14_grandmaX;
+ int scene14_grandmaY;
+ int scene14_dude2X;
+ int scene14_ballDeltaX;
+ int scene14_ballDeltaY;
+ int scene14_ballX;
+ int scene14_ballY;
+ int scene14_hitsLeft;
+ Common::Point scene14_mouseCursorPos;
+
+ int scene15_chantingCountdown;
+ StaticANIObject *scene15_plusminus;
+ PictureObject *scene15_ladder;
+ StaticANIObject *scene15_boot;
+
+ Common::List<StaticANIObject *> scene16_figures;
+ StaticANIObject *scene16_walkingBoy;
+ StaticANIObject *scene16_walkingGirl;
+ int scene16_walkingCount;
+ StaticANIObject *scene16_wire;
+ StaticANIObject *scene16_mug;
+ StaticANIObject *scene16_jettie;
+ StaticANIObject *scene16_boot;
+ bool scene16_girlIsLaughing;
+ int scene16_sound;
+ bool scene16_placeIsOccupied;
+
+ int scene17_flyState;
+ bool scene17_sugarIsShown;
+ int scene17_sceneOldEdgeX;
+ int scene17_flyCountdown;
+ StaticANIObject *scene17_hand;
+ bool scene17_handPhase;
+ int scene17_sceneEdgeX;
+
+ int scene18_var01;
+
+ int scene20_fliesCountdown;
+ StaticANIObject *scene20_grandma;
+
+ StaticANIObject *scene21_giraffeBottom;
+ int scene21_giraffeBottomX;
+ int scene21_giraffeBottomY;
+ int scene21_pipeIsOpen;
+ double scene21_wigglePos;
+ bool scene21_wiggleTrigger;
+
+ StaticANIObject *scene22_bag;
+ StaticANIObject *scene22_giraffeMiddle;
+ bool scene22_dudeIsOnStool;
+ bool scene22_interactionIsDisabled;
+ bool scene22_craneIsOut;
+ int scene22_numBagFalls;
+
+ StaticANIObject *scene23_calend0;
+ StaticANIObject *scene23_calend1;
+ StaticANIObject *scene23_calend2;
+ StaticANIObject *scene23_calend3;
+ bool scene23_topReached;
+ bool scene23_isOnStool;
+ int scene23_someVar;
+ StaticANIObject *scene23_giraffeTop;
+ StaticANIObject *scene23_giraffee;
+
+ bool scene24_jetIsOn;
+ bool scene24_flowIsLow;
+ bool scene24_waterIsOn;
+ StaticANIObject *scene24_water;
+ StaticANIObject *scene24_jet;
+ StaticANIObject *scene24_drop;
+
+ StaticANIObject *scene25_water;
+ StaticANIObject *scene25_board;
+ StaticANIObject *scene25_drop;
+ bool scene25_dudeIsOnBoard;
+ bool scene25_waterIsPresent;
+ bool scene25_boardIsSelectable;
+ bool scene25_beardersAreThere;
+ int scene25_beardersCounter;
+ Common::Array<StaticANIObject *> scene25_bearders;
+ bool scene25_sneezeFlipper;
+
+ StaticANIObject *scene26_chhi;
+ StaticANIObject *scene26_drop;
+ PictureObject *scene26_sockPic;
+ StaticANIObject *scene26_sock;
+ StaticANIObject *scene26_activeVent;
+
+ bool scene28_fliesArePresent;
+ bool scene28_beardedDirection;
+ PictureObject *scene28_darkeningObject;
+ PictureObject *scene28_lighteningObject;
+ bool scene28_headDirection;
+ bool scene28_headBeardedFlipper;
+ bool scene28_lift6inside;
+
+ StaticANIObject *scene30_leg;
+ int scene30_liftFlag;
+
+ int scene31_chantingCountdown;
+ StaticANIObject *scene31_cactus;
+ StaticANIObject *scene31_plusMinus;
+
+ bool scene32_flagIsWaving;
+ bool scene32_flagNeedsStopping;
+ bool scene32_dudeIsSitting;
+ int scene32_cactusCounter;
+ bool scene32_dudeOnLadder;
+ bool scene32_cactusIsGrowing;
+ StaticANIObject *scene32_flag;
+ StaticANIObject *scene32_cactus;
+ StaticANIObject *scene32_massOrange;
+ StaticANIObject *scene32_massBlue;
+ StaticANIObject *scene32_massGreen;
+ StaticANIObject *scene32_button;
+
+ StaticANIObject *scene33_mug;
+ StaticANIObject *scene33_jettie;
+ StaticANIObject *scene33_cube;
+ int scene33_cubeX;
+ bool scene33_handleIsDown;
+ int scene33_ventsX[9];
+ int scene33_ventsState[9];
+
+ StaticANIObject *scene34_cactus;
+ StaticANIObject *scene34_vent;
+ StaticANIObject *scene34_hatch;
+ StaticANIObject *scene34_boot;
+ bool scene34_dudeClimbed;
+ bool scene34_dudeOnBoard;
+ bool scene34_dudeOnCactus;
+ int scene34_fliesCountdown;
+
+ StaticANIObject *scene35_hose;
+ StaticANIObject *scene35_bellyInflater;
+ int scene35_flowCounter;
+ int scene35_fliesCounter;
+
+ StaticANIObject *scene36_rotohrust;
+ StaticANIObject *scene36_scissors;
+
+ Common::Array<Ring *> scene37_rings;
+ int scene37_lastDudeX;
+ bool scene37_cursorIsLocked;
+ StaticANIObject *scene37_plusMinus1;
+ StaticANIObject *scene37_plusMinus2;
+ StaticANIObject *scene37_plusMinus3;
+ int scene37_soundFlipper;
+ int scene37_dudeX;
+
+ StaticANIObject *scene38_boss;
+ StaticANIObject *scene38_tally;
+ StaticANIObject *scene38_shorty;
+ StaticANIObject *scene38_domino0;
+ StaticANIObject *scene38_dominos;
+ StaticANIObject *scene38_domino1;
+ StaticANIObject *scene38_bottle;
+ int scene38_bossCounter;
+ int scene38_lastBossAnim;
+ int scene38_bossAnimCounter;
+ int scene38_tallyCounter;
+ int scene38_lastTallyAnim;
+ int scene38_tallyAnimCounter;
+ int scene38_shortyCounter;
+ int scene38_lastShortyAnim;
+ int scene38_shortyAnimCounter;
+
+ int sceneFinal_var01;
+ int sceneFinal_var02;
+ int sceneFinal_var03;
+
+ PictureObject *selector;
+};
+
+struct Ring {
+ StaticANIObject *ani;
+ int x;
+ int y;
+ int numSubRings;
+ int subRings[10];
+ bool state;
+
+ Ring();
};
} // End of namespace Fullpipe
diff --git a/engines/fullpipe/scenes/scene01.cpp b/engines/fullpipe/scenes/scene01.cpp
new file mode 100644
index 0000000000..6c8f26d209
--- /dev/null
+++ b/engines/fullpipe/scenes/scene01.cpp
@@ -0,0 +1,118 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public 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 "fullpipe/fullpipe.h"
+
+#include "fullpipe/objectnames.h"
+#include "fullpipe/constants.h"
+
+#include "fullpipe/gameloader.h"
+#include "fullpipe/motion.h"
+#include "fullpipe/scenes.h"
+#include "fullpipe/statics.h"
+
+#include "fullpipe/interaction.h"
+#include "fullpipe/behavior.h"
+
+
+namespace Fullpipe {
+
+void scene01_fixEntrance() {
+ GameVar *var = g_fp->getGameLoaderGameVar()->getSubVarByName("OBJSTATES")->getSubVarByName("SAVEGAME");
+ if (var->getSubVarAsInt("Entrance") == TrubaLeft)
+ var->setSubVarAsInt("Entrance", TrubaRight);
+}
+
+void scene01_initScene(Scene *sc, int entrance) {
+ g_vars->scene01_picSc01Osk = sc->getPictureObjectById(PIC_SC1_OSK, 0);
+ g_vars->scene01_picSc01Osk->_flags &= 0xFFFB;
+
+ g_vars->scene01_picSc01Osk2 = sc->getPictureObjectById(PIC_SC1_OSK2, 0);
+ g_vars->scene01_picSc01Osk2->_flags &= 0xFFFB;
+
+ if (g_fp->getObjectState(sO_EggCracker) == g_fp->getObjectEnumState(sO_EggCracker, sO_DidNotCrackEgg)) {
+ PictureObject *pic = sc->getPictureObjectById(PIC_SC1_KUCHKA, 0);
+ if (pic)
+ pic->_flags &= 0xFFFB;
+ }
+
+ if (entrance != TrubaLeft) {
+ StaticANIObject *bootAnim = sc->getStaticANIObject1ById(ANI_BOOT_1, -1);
+ if (bootAnim)
+ bootAnim->_flags &= ~0x04;
+ }
+
+ g_fp->lift_setButton(sO_Level2, ST_LBN_2N);
+}
+
+int sceneHandler01(ExCommand *cmd) {
+ int res = 0;
+
+ if (cmd->_messageKind != 17)
+ return 0;
+
+ if (cmd->_messageNum > MSG_SC1_SHOWOSK) {
+ if (cmd->_messageNum == MSG_SC1_UTRUBACLICK)
+ handleObjectInteraction(g_fp->_aniMan, g_fp->_currentScene->getPictureObjectById(PIC_SC1_LADDER, 0), 0);
+
+ return 0;
+ }
+
+ if (cmd->_messageNum == MSG_SC1_SHOWOSK) {
+ g_vars->scene01_picSc01Osk->_flags |= 4;
+
+ g_vars->scene01_picSc01Osk->_priority = 20;
+ g_vars->scene01_picSc01Osk2->_priority = 21;
+
+ return 0;
+ }
+
+ if (cmd->_messageNum != 0x21) {
+ if (cmd->_messageNum == MSG_SC1_SHOWOSK2) {
+ g_vars->scene01_picSc01Osk2->_flags |= 4;
+ g_vars->scene01_picSc01Osk2->_priority = 20;
+ g_vars->scene01_picSc01Osk->_priority = 21;
+
+ return 0;
+ }
+
+ return 0;
+ }
+
+ if (g_fp->_aniMan2) {
+ if (g_fp->_aniMan2->_ox < g_fp->_sceneRect.left + 200) {
+ g_fp->_currentScene->_x = g_fp->_aniMan2->_ox - g_fp->_sceneRect.left - 300;
+ }
+
+ if (g_fp->_aniMan2->_ox > g_fp->_sceneRect.right - 200)
+ g_fp->_currentScene->_x = g_fp->_aniMan2->_ox - g_fp->_sceneRect.right + 300;
+
+ res = 1;
+ }
+ g_fp->_behaviorManager->updateBehaviors();
+
+ g_fp->startSceneTrack();
+
+ return res;
+}
+
+} // End of namespace Fullpipe
diff --git a/engines/fullpipe/scenes/scene02.cpp b/engines/fullpipe/scenes/scene02.cpp
new file mode 100644
index 0000000000..95cf1df7dd
--- /dev/null
+++ b/engines/fullpipe/scenes/scene02.cpp
@@ -0,0 +1,138 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "fullpipe/fullpipe.h"
+
+#include "fullpipe/objectnames.h"
+#include "fullpipe/constants.h"
+
+#include "fullpipe/gameloader.h"
+#include "fullpipe/motion.h"
+#include "fullpipe/scenes.h"
+#include "fullpipe/statics.h"
+
+#include "fullpipe/interaction.h"
+#include "fullpipe/behavior.h"
+#include "fullpipe/floaters.h"
+
+
+namespace Fullpipe {
+
+void scene02_initScene(Scene *sc) {
+ g_vars->scene02_guvTheDrawer = sc->getStaticANIObject1ById(ANI_DADAYASHIK, -1);
+
+ if (g_fp->getObjectState(sO_GuvTheDrawer) == g_fp->getObjectEnumState(sO_GuvTheDrawer, sO_IsSleeping)) {
+ Scene *s = g_fp->_currentScene;
+
+ g_fp->_currentScene = sc;
+ g_vars->scene02_guvTheDrawer->changeStatics2(ST_DYAS_LIES);
+ g_fp->_currentScene = s;
+ }
+
+ g_vars->scene02_boxDelay = 0;
+
+ StaticANIObject *box = sc->getStaticANIObject1ById(ANI_SC2_BOX, -1);
+
+ if (box && box->_flags & 4) {
+ g_vars->scene02_boxOpen = false;
+ } else {
+ g_vars->scene02_boxOpen = true;
+ g_vars->scene02_boxDelay = 100 * g_fp->_rnd->getRandomNumber(32767) + 150;
+ }
+
+ g_fp->_floaters->init(g_fp->_gameLoader->_gameVar->getSubVarByName("SC_2"));
+}
+
+void sceneHandler02_ladderClick() {
+ handleObjectInteraction(g_fp->_aniMan2, g_fp->_currentScene->getPictureObjectById(PIC_SC2_DTRUBA, 0), 0);
+}
+
+void sceneHandler02_showLadder() {
+ g_fp->_currentScene->getPictureObjectById(PIC_SC2_LADDER, 0)->_flags |= 4;
+}
+
+void sceneHandler02_hideLadder() {
+ g_fp->_currentScene->getPictureObjectById(PIC_SC2_LADDER, 0)->_flags &= 0xfffb;
+ g_fp->_aniMan2->_priority = 25;
+}
+
+int sceneHandler02(ExCommand *ex) {
+ int res = 0;
+
+ if (ex->_messageKind != 17)
+ return 0;
+
+ switch(ex->_messageNum) {
+ case MSG_SC2_LADDERCLICK:
+ sceneHandler02_ladderClick();
+ return 0;
+
+ case MSG_SC2_SHOWLADDER:
+ sceneHandler02_showLadder();
+ return 0;
+
+ case MSG_SC2_PUTMANUP:
+ g_fp->_aniMan2->_priority = 0;
+ return 0;
+
+ case MSG_SC2_HIDELADDER:
+ sceneHandler02_hideLadder();
+ return 0;
+
+ case 33:
+ if (g_fp->_aniMan2) {
+ if (g_fp->_aniMan2->_ox < g_fp->_sceneRect.left + 200)
+ g_fp->_currentScene->_x = g_fp->_aniMan2->_ox - g_fp->_sceneRect.left - 300;
+
+ if (g_fp->_aniMan2->_ox > g_fp->_sceneRect.right - 200)
+ g_fp->_currentScene->_x = g_fp->_aniMan2->_ox - g_fp->_sceneRect.right + 300;
+
+ res = 1;
+ }
+
+ if (g_vars->scene02_boxOpen) {
+ if (g_vars->scene02_boxDelay >= 1) {
+ --g_vars->scene02_boxDelay;
+ } else if (g_fp->_floaters->_array2.size() >= 1) {
+ if (g_fp->_floaters->_array2[0]->val5 == -50) {
+ g_fp->_floaters->stopAll();
+ g_vars->scene02_boxOpen = false;
+ g_vars->scene02_boxDelay = 100 * g_fp->_rnd->getRandomNumber(32767) + 150;
+ } else {
+ g_fp->_floaters->_array2[0]->val3 = -50;
+ }
+ } else {
+ g_fp->_floaters->genFlies(g_fp->_currentScene, g_fp->_rnd->getRandomNumber(700) + 100, -50, 0, 0);
+ g_vars->scene02_boxDelay = 500 * g_fp->_rnd->getRandomNumber(32767) + 1000;
+ }
+ }
+
+ g_fp->_floaters->update();
+ g_fp->_behaviorManager->updateBehaviors();
+
+ g_fp->startSceneTrack();
+ }
+
+ return res;
+}
+
+} // End of namespace Fullpipe
diff --git a/engines/fullpipe/scenes/scene03.cpp b/engines/fullpipe/scenes/scene03.cpp
new file mode 100644
index 0000000000..9ba84a540a
--- /dev/null
+++ b/engines/fullpipe/scenes/scene03.cpp
@@ -0,0 +1,295 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public 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 "fullpipe/fullpipe.h"
+
+#include "fullpipe/objectnames.h"
+#include "fullpipe/constants.h"
+
+#include "fullpipe/gameloader.h"
+#include "fullpipe/motion.h"
+#include "fullpipe/scenes.h"
+#include "fullpipe/statics.h"
+
+#include "fullpipe/interaction.h"
+#include "fullpipe/behavior.h"
+
+namespace Fullpipe {
+
+void FullpipeEngine::setSwallowedEggsState() {
+ GameVar *v = _gameLoader->_gameVar->getSubVarByName("OBJSTATES")->getSubVarByName(sO_GulpedEggs);
+
+ g_vars->swallowedEgg1 = v->getSubVarByName(sO_Egg1);
+ g_vars->swallowedEgg2 = v->getSubVarByName(sO_Egg2);
+ g_vars->swallowedEgg3 = v->getSubVarByName(sO_Egg3);
+
+ g_vars->swallowedEgg1->_value.intValue = 0;
+ g_vars->swallowedEgg2->_value.intValue = 0;
+ g_vars->swallowedEgg3->_value.intValue = 0;
+}
+
+void scene03_initScene(Scene *sc) {
+ g_vars->scene03_eggeater = sc->getStaticANIObject1ById(ANI_EGGEATER, -1);
+ g_vars->scene03_domino = sc->getStaticANIObject1ById(ANI_DOMINO_3, -1);
+
+ GameVar *v = g_fp->_gameLoader->_gameVar->getSubVarByName("OBJSTATES")->getSubVarByName(sO_GulpedEggs);
+
+ g_vars->swallowedEgg1 = v->getSubVarByName(sO_Egg1);
+ g_vars->swallowedEgg2 = v->getSubVarByName(sO_Egg2);
+ g_vars->swallowedEgg3 = v->getSubVarByName(sO_Egg3);
+
+ g_fp->lift_setButton(sO_Level2, ST_LBN_2N);
+
+ g_fp->lift_init(sc, QU_SC3_ENTERLIFT, QU_SC3_EXITLIFT);
+}
+
+void scene03_setEaterState() {
+ if (g_fp->getObjectState(sO_EggGulperGaveCoin) == g_fp->getObjectEnumState(sO_EggGulperGaveCoin, sO_Yes)) {
+ g_fp->_behaviorManager->setBehaviorEnabled(g_vars->scene03_eggeater, ST_EGTR_SLIM, QU_EGTR_SLIMSHOW, 0);
+ g_fp->_behaviorManager->setBehaviorEnabled(g_vars->scene03_eggeater, ST_EGTR_MID1, QU_EGTR_MD1_SHOW, 0);
+ g_fp->_behaviorManager->setBehaviorEnabled(g_vars->scene03_eggeater, ST_EGTR_MID2, QU_EGTR_MD2_SHOW, 0);
+ }
+}
+
+int scene03_updateCursor() {
+ g_fp->updateCursorCommon();
+
+ if (g_fp->_cursorId == PIC_CSR_DEFAULT && g_fp->_objectIdAtCursor == PIC_SC3_DOMIN && g_vars->scene03_domino) {
+ if (g_vars->scene03_domino->_flags & 4)
+ g_fp->_cursorId = PIC_CSR_ITN;
+ }
+
+ return g_fp->_cursorId;
+}
+
+void sceneHandler03_eaterFat() {
+ g_vars->scene03_eggeater->_flags &= 0xFF7F;
+
+ g_vars->scene03_eggeater->startAnim(MV_EGTR_FATASK, 0, -1);
+}
+
+void sceneHandler03_swallowEgg(int item) {
+ if (!g_vars->swallowedEgg1->_value.intValue) {
+ g_vars->swallowedEgg1->_value.intValue = item;
+ } else if (!g_vars->swallowedEgg2->_value.intValue) {
+ g_vars->swallowedEgg2->_value.intValue = item;
+ } else if (!g_vars->swallowedEgg3->_value.intValue) {
+ g_vars->swallowedEgg3->_value.intValue = item;
+
+ g_fp->setObjectState(sO_EggGulperGaveCoin, g_fp->getObjectEnumState(sO_EggGulperGaveCoin, sO_Yes));
+
+ scene03_setEaterState();
+ }
+}
+
+void sceneHandler03_giveItem(ExCommand *ex) {
+ if (ex->_parentId == ANI_INV_EGGAPL || ex->_parentId == ANI_INV_EGGDOM ||
+ ex->_parentId == ANI_INV_EGGCOIN || ex->_parentId == ANI_INV_EGGBOOT ||
+ ex->_parentId == ANI_INV_EGGGLS)
+ sceneHandler03_swallowEgg(ex->_parentId);
+}
+
+int sceneHandler03_swallowedEgg1State() {
+ return g_vars->swallowedEgg1->_value.intValue;
+}
+
+void sceneHandler03_giveCoin(ExCommand *ex) {
+ MessageQueue *mq = g_fp->_globalMessageQueueList->getMessageQueueById(ex->_parId);
+
+ if (mq && mq->getCount() > 0) {
+ ExCommand *ex0 = mq->getExCommandByIndex(0);
+ ExCommand *ex1 = mq->getExCommandByIndex(1);
+
+ if (sceneHandler03_swallowedEgg1State()) {
+ ex0->_messageKind = 1;
+ ex1->_messageKind = 1;
+
+ getGameLoaderInventory()->removeItem(ANI_INV_COIN, 1);
+ } else {
+ ex0->_messageKind = 0;
+ ex0->_excFlags |= 1;
+
+ ex1->_messageKind = 0;
+ ex1->_excFlags |= 1;
+
+ g_vars->scene03_eggeater->_flags &= 0xFF7Fu;
+ }
+ }
+}
+
+void sceneHandler03_goLadder() {
+ handleObjectInteraction(g_fp->_aniMan, g_fp->_currentScene->getPictureObjectById(PIC_SC3_LADDER, 0), 0);
+}
+
+void sceneHandler03_pushEggStack() {
+ g_vars->swallowedEgg1->_value.intValue = g_vars->swallowedEgg2->_value.intValue;
+ g_vars->swallowedEgg2->_value.intValue = g_vars->swallowedEgg3->_value.intValue;
+ g_vars->swallowedEgg3->_value.intValue = 0;
+
+ if (g_vars->swallowedEgg2->_value.intValue == ANI_INV_EGGBOOT
+ && g_vars->swallowedEgg1->_value.intValue == ANI_INV_EGGAPL) {
+ g_vars->swallowedEgg1->_value.intValue = ANI_INV_EGGBOOT;
+ g_vars->swallowedEgg2->_value.intValue = ANI_INV_EGGAPL;
+ }
+}
+
+void sceneHandler03_releaseEgg() {
+ g_vars->scene03_eggeater->_flags &= 0xFF7F;
+
+ g_vars->scene03_eggeater->show1(-1, -1, -1, 0);
+}
+
+void sceneHandler03_takeEgg(ExCommand *ex) {
+ MessageQueue *mq = g_fp->_globalMessageQueueList->getMessageQueueById(ex->_parId);
+
+ if (mq && mq->getCount() > 0) {
+ ExCommand *ex0 = mq->getExCommandByIndex(0);
+ ExCommand *ex1 = mq->getExCommandByIndex(1);
+
+ int egg1 = sceneHandler03_swallowedEgg1State();
+
+ if (egg1 && ex0) {
+ ex0->_parentId = egg1;
+ sceneHandler03_pushEggStack();
+ }
+
+ if ( g_vars->swallowedEgg1->_value.intValue == ANI_INV_EGGAPL
+ && !g_vars->swallowedEgg2->_value.intValue
+ && !g_vars->swallowedEgg3->_value.intValue
+ && ex1) {
+
+ if (ex1->_objtype == kObjTypeObjstateCommand) {
+ ObjstateCommand *com = (ObjstateCommand *)ex1;
+
+ com->_value = g_fp->getObjectEnumState(sO_EggGulper, sO_WantsNothing);
+ }
+ }
+ }
+}
+
+int sceneHandler03(ExCommand *ex) {
+ if (ex->_messageKind != 17) {
+ if (ex->_messageKind == 57)
+ sceneHandler03_giveItem(ex);
+ return 0;
+ }
+
+ switch (ex->_messageNum) {
+ case MSG_LIFT_EXITLIFT:
+ g_fp->lift_exitSeq(ex);
+ break;
+
+ case MSG_LIFT_CLOSEDOOR:
+ g_fp->lift_closedoorSeq();
+ break;
+
+ case MSG_SC3_ONTAKECOIN:
+ sceneHandler03_eaterFat();
+ break;
+
+ case MSG_LIFT_STARTEXITQUEUE:
+ g_fp->lift_startExitQueue();
+ break;
+
+ case MSG_SC3_RELEASEEGG:
+ sceneHandler03_releaseEgg();
+ break;
+
+ case MSG_LIFT_CLICKBUTTON:
+ g_fp->lift_clickButton();
+ break;
+
+ case MSG_SC3_HIDEDOMINO:
+ g_vars->scene03_domino->_flags &= 0xFFFB;
+ break;
+
+ case MSG_SC3_TAKEEGG:
+ sceneHandler03_takeEgg(ex);
+ break;
+
+ case MSG_LIFT_GO:
+ g_fp->lift_goAnimation();
+ break;
+
+ case MSG_SC3_UTRUBACLICK:
+ sceneHandler03_goLadder();
+ break;
+
+ case MSG_SC3_TESTFAT:
+ sceneHandler03_giveCoin(ex);
+ break;
+
+ case 64:
+ g_fp->lift_sub05(ex);
+ break;
+
+ case 29:
+ {
+ StaticANIObject *ani = g_fp->_currentScene->getStaticANIObjectAtPos(ex->_sceneClickX, ex->_sceneClickY);
+ if (ani && ani->_id == ANI_LIFTBUTTON) {
+ g_fp->lift_sub1(ani);
+ ex->_messageKind = 0;
+
+ return 0;
+ }
+
+ if (g_fp->_currentScene->getPictureObjectIdAtPos(ex->_sceneClickX, ex->_sceneClickY) == PIC_SC3_DOMIN) {
+ if (g_vars->scene03_domino)
+ if (g_vars->scene03_domino->_flags & 4)
+ if (g_fp->_aniMan->isIdle())
+ if (!(g_fp->_aniMan->_flags & 0x100) && g_fp->_msgObjectId2 != g_vars->scene03_domino->_id) {
+ handleObjectInteraction(g_fp->_aniMan, g_vars->scene03_domino, ex->_keyCode);
+ ex->_messageKind = 0;
+
+ return 0;
+ }
+ }
+
+ break;
+ }
+
+ case 33:
+ {
+ int res = 0;
+
+ if (g_fp->_aniMan2) {
+ if (g_fp->_aniMan2->_ox < g_fp->_sceneRect.left + 200)
+ g_fp->_currentScene->_x = g_fp->_aniMan2->_ox - g_fp->_sceneRect.left - 300;
+
+ if (g_fp->_aniMan2->_ox > g_fp->_sceneRect.right - 200)
+ g_fp->_currentScene->_x = g_fp->_aniMan2->_ox - g_fp->_sceneRect.right + 300;
+
+ res = 1;
+ }
+
+ g_fp->_behaviorManager->updateBehaviors();
+
+ g_fp->startSceneTrack();
+
+ return res;
+ }
+ }
+
+ return 0;
+}
+
+} // End of namespace Fullpipe
diff --git a/engines/fullpipe/scenes/scene04.cpp b/engines/fullpipe/scenes/scene04.cpp
new file mode 100644
index 0000000000..332935072c
--- /dev/null
+++ b/engines/fullpipe/scenes/scene04.cpp
@@ -0,0 +1,1558 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public 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 "fullpipe/fullpipe.h"
+
+#include "fullpipe/objectnames.h"
+#include "fullpipe/constants.h"
+#include "fullpipe/utils.h"
+#include "fullpipe/gfx.h"
+#include "fullpipe/messages.h"
+#include "fullpipe/motion.h"
+#include "fullpipe/scenes.h"
+#include "fullpipe/statics.h"
+#include "fullpipe/scene.h"
+#include "fullpipe/interaction.h"
+#include "fullpipe/gameloader.h"
+#include "fullpipe/behavior.h"
+
+namespace Fullpipe {
+
+static const int scene04_speakerPhases[] = {
+ 0, 1, 2, 3, -1, -1,
+ 0, 2, 3, -1, -1, -1,
+ 0, 2, -1, -1, -1, -1
+};
+
+void scene04_speakerCallback(int *phase) {
+ if (g_vars->scene04_soundPlaying) {
+ if (g_vars->scene04_speakerPhase >= 0) {
+ *phase = scene04_speakerPhases[g_vars->scene04_speakerPhase + 6 * g_vars->scene04_speakerVariant];
+
+ g_vars->scene04_speakerPhase++;
+
+ if (scene04_speakerPhases[g_vars->scene04_speakerPhase + 6 * g_vars->scene04_speakerVariant] < 0) {
+ g_vars->scene04_speakerPhase = 0;
+ g_vars->scene04_speakerVariant = g_fp->_rnd->getRandomNumber(2);
+ }
+ } else {
+ ++g_vars->scene04_speakerPhase;
+ }
+ }
+}
+
+void scene04_initScene(Scene *sc) {
+ g_vars->scene04_dudeOnLadder = false;
+ g_vars->scene04_bottle = sc->getPictureObjectById(PIC_SC4_BOTTLE, 0);
+ g_vars->scene04_hand = sc->getStaticANIObject1ById(ANI_HAND, -1);
+ g_vars->scene04_plank = sc->getStaticANIObject1ById(ANI_PLANK, -1);
+ g_vars->scene04_clock = sc->getStaticANIObject1ById(ANI_CLOCK, -1);
+ g_vars->scene04_spring = sc->getStaticANIObject1ById(ANI_SPRING, -1);
+ g_vars->scene04_mamasha = sc->getStaticANIObject1ById(ANI_MAMASHA_4, -1);
+ g_vars->scene04_boot = sc->getStaticANIObject1ById(ANI_SC4_BOOT, -1);
+ g_vars->scene04_ladder = 0;
+
+ StaticANIObject *koz = sc->getStaticANIObject1ById(ANI_KOZAWKA, -1);
+
+ if (koz) {
+ Movement *kozmov = koz->getMovementById(MV_KZW_JUMP);
+ if (kozmov) {
+ uint kozsize = kozmov->_currMovement ? kozmov->_currMovement->_dynamicPhases.size() : kozmov->_dynamicPhases.size();
+
+ for (uint i = 0; i < kozsize; i++) {
+ kozmov->setDynamicPhaseIndex(i);
+
+ if (kozmov->_framePosOffsets) {
+ g_vars->scene04_jumpingKozyawki[i] = *kozmov->_framePosOffsets[kozmov->_currDynamicPhaseIndex];
+ } else {
+ kozmov->_somePoint.x = 0;
+ kozmov->_somePoint.y = 0;
+ g_vars->scene04_jumpingKozyawki[i] = kozmov->_somePoint;
+ }
+ }
+ }
+
+ kozmov = koz->getMovementById(MV_KZW_JUMPROTATE);
+ if (kozmov) {
+ uint kozsize = kozmov->_currMovement ? kozmov->_currMovement->_dynamicPhases.size() : kozmov->_dynamicPhases.size();
+
+ for (uint i = 0; i < kozsize; i++) {
+ kozmov->setDynamicPhaseIndex(i);
+
+ if (kozmov->_framePosOffsets) {
+ g_vars->scene04_jumpRotateKozyawki[i] = *kozmov->_framePosOffsets[kozmov->_currDynamicPhaseIndex];
+ } else {
+ kozmov->_somePoint.x = 0;
+ kozmov->_somePoint.y = 0;
+ g_vars->scene04_jumpRotateKozyawki[i] = kozmov->_somePoint;
+ }
+ }
+ }
+ }
+
+ Interaction *plank = getGameLoaderInteractionController()->getInteractionByObjectIds(ANI_PLANK, 0, 0);
+ if (plank)
+ plank->_flags |= 8;
+
+ if (g_fp->getObjectState(sO_Jar_4) == g_fp->getObjectEnumState(sO_Jar_4, sO_UpsideDown)) {
+ g_vars->scene04_bottleObjList.clear();
+ g_vars->scene04_kozyawkiObjList.clear();
+
+ sc->getPictureObjectById(PIC_SC4_BOTTLE, 0)->_flags &= 0xfffb;
+ sc->getPictureObjectById(PIC_SC4_MASK, 0)->_flags &= 0xfffb;
+ sc->getStaticANIObject1ById(ANI_SPRING, 0)->_flags &= 0xfffb;
+
+ g_vars->scene04_clockCanGo = false;
+ g_vars->scene04_objectIsTaken = false;
+ } else {
+ StaticANIObject *spring = sc->getStaticANIObject1ById(ANI_SPRING, -1);
+
+ if (spring)
+ spring->_callback2 = 0;
+
+ g_vars->scene04_bottleObjList.clear();
+ g_vars->scene04_bottleObjList.push_back(sc->getPictureObjectById(PIC_SC4_BOTTLE, 0));
+ g_vars->scene04_bottleObjList.push_back(sc->getPictureObjectById(PIC_SC4_MASK, 0));
+
+ g_vars->scene04_kozyawkiObjList.clear();
+
+ if (koz) {
+ koz->loadMovementsPixelData();
+
+ koz->_statics = koz->getStaticsById(ST_KZW_EMPTY);
+ koz->setOXY(0, 0);
+ koz->hide();
+
+ g_vars->scene04_kozyawkiObjList.push_back(koz);
+
+ for (int i = 0; i < 6; i++) {
+ StaticANIObject *koz1 = new StaticANIObject(koz);
+
+ sc->addStaticANIObject(koz1, 1);
+ koz1->_statics = koz->getStaticsById(ST_KZW_EMPTY);
+ koz1->setOXY(0, 0);
+ koz1->hide();
+ g_vars->scene04_kozyawkiObjList.push_back(koz1);
+ }
+ }
+ sc->getPictureObjectById(PIC_SC4_BOTTLE2, 0)->_flags &= 0xfffb;
+
+ g_vars->scene04_clockCanGo = true;
+ g_vars->scene04_objectIsTaken = true;
+ }
+
+ g_vars->scene04_bottleIsTaken = false;
+ g_vars->scene04_soundPlaying = false;
+ g_vars->scene04_kozyawkaOnLadder = false;
+ g_vars->scene04_walkingKozyawka = 0;
+ g_vars->scene04_bottleWeight = 2;
+ g_vars->scene04_dynamicPhaseIndex = 0;
+
+ g_vars->scene04_kozyawkiAni.clear();
+
+ g_fp->setObjectState(sO_LowerPipe, g_fp->getObjectEnumState(sO_LowerPipe, sO_IsClosed));
+
+ g_vars->scene04_var07 = false;
+ g_vars->scene04_ladderClickable = false;
+ g_vars->scene04_coinPut = false;
+ g_vars->scene04_handIsDown = false;
+ g_vars->scene04_dudeInBottle = false;
+ g_vars->scene04_kozHeadRaised = false;
+ g_vars->scene04_bottleIsDropped = false;
+ g_vars->scene04_bigBallIn = true;
+ g_vars->scene04_bigBallCounter = 0;
+ g_vars->scene04_bigBallFromLeft = true;
+
+ if (g_fp->getObjectState(sO_BigMumsy) != g_fp->getObjectEnumState(sO_BigMumsy, sO_IsGone))
+ g_vars->scene04_mamasha->hide();
+
+ g_vars->scene04_speaker = sc->getStaticANIObject1ById(ANI_SPEAKER_4, -1);
+ g_vars->scene04_speaker->_callback2 = scene04_speakerCallback;
+ g_vars->scene04_speaker->startAnim(MV_SPK4_PLAY, 0, -1);
+
+ g_vars->scene04_speakerVariant = 0;
+ g_vars->scene04_speakerPhase = 0;
+
+ g_fp->initArcadeKeys("SC_4");
+}
+
+bool sceneHandler04_friesAreWalking() {
+ if (g_vars->scene04_dudeOnLadder && g_fp->_aniMan->isIdle() && !(g_fp->_aniMan->_flags & 0x100)) {
+ int col = g_vars->scene04_ladder->collisionDetection(g_fp->_aniMan);
+ if (col >= 3 && col <= 6 ) {
+ Movement *koz;
+
+ if (!g_vars->scene04_walkingKozyawka
+ || (koz = g_vars->scene04_walkingKozyawka->_movement) == 0
+ || koz->_id != MV_KZW_WALKPLANK
+ || koz->_currDynamicPhaseIndex < 10
+ || koz->_currDynamicPhaseIndex > 41)
+ return true;
+ }
+ }
+
+ return false;
+}
+
+int scene04_updateCursor() {
+ g_fp->updateCursorCommon();
+
+ if (g_fp->_objectIdAtCursor == PIC_SC4_LRTRUBA) {
+ if (!g_vars->scene04_objectIsTaken) {
+ g_fp->_cursorId = PIC_CSR_DEFAULT;
+
+ return g_fp->_cursorId;
+ }
+ } else if (g_fp->_objectIdAtCursor == ANI_PLANK || g_fp->_objectIdAtCursor == PIC_SC4_PLANK) {
+ if (g_fp->_objectIdAtCursor == ANI_PLANK && g_fp->_cursorId != PIC_CSR_ITN)
+ return g_fp->_cursorId;
+
+ if (g_fp->_objectIdAtCursor == ANI_PLANK || (g_fp->_objectIdAtCursor == PIC_SC4_PLANK && g_fp->_cursorId == PIC_CSR_DEFAULT)) {
+ if (sceneHandler04_friesAreWalking()) {
+ g_fp->_cursorId = PIC_CSR_ARCADE1;
+ return g_fp->_cursorId;
+ }
+ if (g_vars->scene04_soundPlaying) {
+ g_fp->_cursorId = PIC_CSR_DEFAULT;
+ return g_fp->_cursorId;
+ }
+ }
+ }
+
+ if (g_fp->_objectIdAtCursor == PIC_CSR_ITN && g_fp->_objectIdAtCursor == PIC_SC4_DOWNTRUBA)
+ g_fp->_cursorId = PIC_CSR_GOD;
+
+ return g_fp->_cursorId;
+}
+
+void sceneHandler04_checkBigBallClick() {
+ StaticANIObject *ball = g_fp->_currentScene->getStaticANIObject1ById(ANI_BIGBALL, -1);
+
+ if (ball)
+ for (uint i = 0; i < ball->_movements.size(); i++)
+ ((Movement *)ball->_movements[i])->_counterMax = 73;
+
+ g_vars->scene04_bigBallIn = true;
+}
+
+void sceneHandler04_clickBottle() {
+ if (!g_vars->scene04_bottleIsTaken)
+ g_vars->scene04_springOffset += 5;
+}
+
+void sceneHandler04_clickButton() {
+ StaticANIObject *but = g_fp->_currentScene->getStaticANIObject1ById(ANI_BUTTON, -1);
+
+ if (but) {
+ if (!g_vars->scene04_clock->_movement ||
+ (g_vars->scene04_clock->_movement->_id == MV_CLK_GO && g_vars->scene04_clock->_movement->_currDynamicPhaseIndex > 3 &&
+ g_vars->scene04_clock->_movement->_currDynamicPhaseIndex < 105)) {
+ if (!g_vars->scene04_hand->_movement && !g_vars->scene04_bottleIsTaken) {
+ but->startAnim(MV_BTN_CLICK, 0, -1);
+ g_vars->scene04_hand->startAnim(MV_HND_POINT, 0, -1);
+ }
+ }
+ }
+}
+
+void sceneHandler04_downLadder(int x, int y) {
+ g_vars->scene04_ladder->method34(g_fp->_aniMan, x + g_vars->scene04_ladder->_ladder_field_20, y + g_vars->scene04_ladder->_ladder_field_24, 0, 0);
+}
+
+void sceneHandler04_walkClimbLadder(ExCommand *ex) {
+ MessageQueue *mq = new MessageQueue(g_fp->_globalMessageQueueList->compact());
+
+ ExCommand *ex1 = new ExCommand(ANI_MAN, 1, MV_MAN_TOLADDER, 0, 0, 0, 1, 0, 0, 0);
+
+ ex1->_keyCode = g_fp->_aniMan->_okeyCode;
+ ex1->_excFlags |= 2;
+
+ mq->addExCommandToEnd(ex1);
+
+ ExCommand *ex2 = new ExCommand(ANI_MAN, 1, MV_MAN_STOPLADDER, 0, 0, 0, 1, 0, 0, 0);
+
+ ex2->_keyCode = g_fp->_aniMan->_okeyCode;
+ ex2->_excFlags |= 2;
+
+ mq->addExCommandToEnd(ex2);
+
+ ExCommand *ex3;
+
+ if (ex) {
+ ex3 = ex->createClone();
+ } else {
+ ex3 = new ExCommand(0, 17, MSG_SC4_CLICKLADDER, 0, 0, 0, 1, 0, 0, 0);
+ ex3->_excFlags |= 3;
+ }
+
+ mq->addExCommandToEnd(ex3);
+
+ mq->setFlags(mq->getFlags() | 1);
+
+ mq->chain(0);
+
+ g_vars->scene04_dudeOnLadder = 1;
+
+ g_vars->scene04_ladder = new MctlLadder;
+ g_vars->scene04_ladder->_ladderX = 1089;
+ g_vars->scene04_ladder->_ladderY = 406;
+ g_vars->scene04_ladder->_ladder_field_14 = 12;
+ g_vars->scene04_ladder->_width = 0;
+ g_vars->scene04_ladder->_height = -40;
+ g_vars->scene04_ladder->_ladder_field_20 = 0;
+ g_vars->scene04_ladder->_ladder_field_24 = -60;
+
+ g_vars->scene04_ladder->addObject(g_fp->_aniMan);
+
+ if (g_vars->scene04_soundPlaying) {
+ g_vars->scene04_ladder->_movements.front()->movVars->varUpStart = MV_MAN_STARTLADDER2;
+ g_vars->scene04_ladder->_movements.front()->movVars->varUpGo = MV_MAN_GOLADDER2;
+ g_vars->scene04_ladder->_movements.front()->movVars->varUpStop = MV_MAN_STOPLADDER2;
+ g_vars->scene04_ladder->_movements.front()->staticIds[2] = ST_MAN_GOLADDER2;
+ } else {
+ g_vars->scene04_ladder->_movements.front()->movVars->varUpStart = MV_MAN_STARTLADDER;
+ g_vars->scene04_ladder->_movements.front()->movVars->varUpGo = MV_MAN_GOLADDER;
+ g_vars->scene04_ladder->_movements.front()->movVars->varUpStop = MV_MAN_STOPLADDER;
+ g_vars->scene04_ladder->_movements.front()->staticIds[2] = ST_MAN_GOLADDER;
+ }
+
+ g_fp->_aniMan->_priority = 12;
+
+ getSc2MctlCompoundBySceneId(g_fp->_currentScene->_sceneId)->clearEnabled();
+ getGameLoaderInteractionController()->disableFlag24();
+}
+
+void sceneHandler04_clickLadder() {
+ g_vars->scene04_dudePosX = g_fp->_aniMan->_ox;
+ g_vars->scene04_dudePosY = g_fp->_aniMan->_oy;
+
+ if (g_vars->scene04_dudeOnLadder) {
+ if (!g_fp->_aniMan->isIdle() || (g_fp->_aniMan->_flags & 0x100)) {
+ g_vars->scene04_ladderClickable = true;
+ } else {
+ int h3 = 3 * g_vars->scene04_ladder->_height;
+ int half = abs(g_vars->scene04_ladder->_height) / 2;
+ int start = g_vars->scene04_ladder->_ladderY - g_vars->scene04_ladder->_ladder_field_24;
+ int min = 2 * h3 + start + half + 1;
+ int max = h3 + start - half - 1;
+
+ if (g_vars->scene04_sceneClickY > max)
+ g_vars->scene04_sceneClickY = max;
+
+ if (g_vars->scene04_sceneClickY < min)
+ g_vars->scene04_sceneClickY = min;
+
+ sceneHandler04_downLadder(g_vars->scene04_sceneClickX, g_vars->scene04_sceneClickY);
+
+ g_vars->scene04_ladderClickable = false;
+ }
+ } else {
+ if (g_fp->_aniMan->isIdle() && !(g_fp->_aniMan->_flags & 0x100)) {
+ if (abs(1095 - g_vars->scene04_dudePosX) > 1 || abs(434 - g_vars->scene04_dudePosY) > 1) {
+ MessageQueue *mq = getSc2MctlCompoundBySceneId(g_fp->_currentScene->_sceneId)->method34(g_fp->_aniMan, 1095, 434, 1, ST_MAN_UP);
+ if (mq) {
+ ExCommand *ex = new ExCommand(0, 17, MSG_SC4_CLICKLADDER, 0, 0, 0, 1, 0, 0, 0);
+
+ ex->_excFlags = 3;
+ mq->addExCommandToEnd(ex);
+
+ postExCommand(g_fp->_aniMan->_id, 2, 1095, 434, 0, -1);
+ }
+ } else {
+ sceneHandler04_walkClimbLadder(0);
+ }
+ }
+ }
+}
+
+void sceneHandler04_jumpOnLadder() {
+ if (g_fp->_aniMan->_movement && g_fp->_aniMan->_movement->_id != MV_MAN_LOOKLADDER)
+ return;
+
+ if (g_fp->_aniMan->_statics->_staticsId != ST_MAN_STANDLADDER && g_fp->_aniMan->_statics->_staticsId != ST_MAN_LADDERDOWN)
+ return;
+
+ g_fp->_aniMan->changeStatics2(ST_MAN_LADDERDOWN);
+
+ g_fp->_aniMan->_flags |= 1;
+
+ MGM mgm;
+ MGMInfo mgminfo;
+
+ mgm.addItem(ANI_MAN);
+
+ mgminfo.ani = g_fp->_aniMan;
+ mgminfo.staticsId2 = ST_MAN_ONPLANK;
+ mgminfo.x1 = 938;
+ mgminfo.y1 = 442;
+ mgminfo.field_1C = 10;
+ mgminfo.field_10 = 1;
+ mgminfo.flags = 78;
+ mgminfo.movementId = MV_MAN_JUMPONPLANK;
+
+ MessageQueue *mq = mgm.genMovement(&mgminfo);
+
+ if (mq) {
+ mq->_flags |= 1;
+
+ if (!mq->chain(g_fp->_aniMan))
+ delete mq;
+
+ g_fp->_aniMan->_priority = 10;
+ }
+
+ g_vars->scene04_ladderOffset = g_vars->scene04_ladder->collisionDetection(g_fp->_aniMan);
+}
+
+void sceneHandler04_clickPlank() {
+ if (sceneHandler04_friesAreWalking())
+ sceneHandler04_jumpOnLadder();
+ else if (g_vars->scene04_dudeOnLadder)
+ g_fp->playSound(SND_4_033, 0);
+ else if (!g_vars->scene04_soundPlaying)
+ chainQueue(QU_PNK_CLICK, 0);
+}
+
+void sceneHandler04_dropBottle() {
+ g_vars->scene04_bottleIsDropped = true;
+ g_vars->scene04_bottleY = 10;
+ g_vars->scene04_bottleWeight = 0;
+
+ while (g_vars->scene04_kozyawkiAni.size()) {
+ StaticANIObject *koz = g_vars->scene04_kozyawkiAni.front();
+ g_vars->scene04_kozyawkiAni.pop_front();
+
+ for (Common::List<GameObject *>::iterator it = g_vars->scene04_bottleObjList.begin(); it != g_vars->scene04_bottleObjList.end(); ++it)
+ if (*it == koz) {
+ g_vars->scene04_bottleObjList.erase(it);
+ break;
+ }
+
+ koz->queueMessageQueue(0);
+ koz->hide();
+
+ g_vars->scene04_kozyawkiObjList.push_back(koz);
+ }
+
+ g_vars->scene04_hand->changeStatics2(ST_HND_EMPTY);
+
+ g_vars->scene04_hand->setOXY(429, 21);
+ g_vars->scene04_hand->_priority = 15;
+}
+
+void sceneHandler04_gotoLadder(ExCommand *ex) {
+ MGM mgm;
+ MGMInfo mgminfo;
+
+ mgm.addItem(ANI_MAN);
+
+ mgminfo.ani = g_fp->_aniMan;
+ mgminfo.staticsId2 = ST_MAN_UP;
+ mgminfo.x1 = 1095;
+ mgminfo.y1 = 434;
+ mgminfo.field_1C = 12;
+ mgminfo.field_10 = 1;
+ mgminfo.flags = 78;
+ mgminfo.movementId = MV_MAN_PLANKTOLADDER;
+
+ MessageQueue *mq = mgm.genMovement(&mgminfo);
+
+ if (mq) {
+ mq->deleteExCommandByIndex(mq->getCount() - 1, 1);
+
+ ExCommand *ex1 = new ExCommand(ANI_MAN, 1, MV_MAN_TOLADDER, 0, 0, 0, 1, 0, 0, 0);
+ ex1->_excFlags = 2;
+ ex1->_field_24 = 1;
+ ex1->_keyCode = -1;
+ mq->addExCommandToEnd(ex1);
+
+ ExCommand *ex2 = new ExCommand(ANI_MAN, 1, MV_MAN_STOPLADDER, 0, 0, 0, 1, 0, 0, 0);
+ ex2->_excFlags = 2;
+ ex2->_field_24 = 1;
+ ex2->_keyCode = -1;
+ mq->addExCommandToEnd(ex2);
+
+ ExCommand *ex3 = new ExCommand(g_fp->_aniMan->_id, 34, 256, 0, 0, 0, 1, 0, 0, 0);
+ ex3->_field_14 = 256;
+ ex3->_messageNum = 0;
+ ex3->_excFlags |= 3;
+ mq->addExCommandToEnd(ex3);
+
+ if (ex) {
+ ExCommand *ex4 = ex->createClone();
+
+ mq->addExCommandToEnd(ex4);
+ }
+
+ mq->setFlags(mq->getFlags() | 1);
+
+ if (mq->chain(g_fp->_aniMan)) {
+ g_fp->_aniMan->_priority = 12;
+ g_fp->_aniMan->_flags |= 1;
+ } else {
+ delete mq;
+ }
+ }
+
+ g_vars->scene04_kozyawkaOnLadder = false;
+}
+
+void sceneHandler04_lowerPlank() {
+ g_vars->scene04_plank->startAnim(MV_PNK_WEIGHTRIGHT, 0, -1);
+}
+
+void sceneHandler04_manFromBottle() {
+ for (Common::List<GameObject *>::iterator it = g_vars->scene04_bottleObjList.begin(); it != g_vars->scene04_bottleObjList.end(); ++it)
+ if (*it == g_fp->_aniMan) {
+ g_vars->scene04_bottleObjList.erase(it);
+ g_vars->scene04_bottleWeight -= 9;
+ break;
+ }
+
+ if (g_vars->scene04_ladder)
+ delete g_vars->scene04_ladder;
+
+ g_vars->scene04_ladder = 0;
+
+ getSc2MctlCompoundBySceneId(g_fp->_currentScene->_sceneId)->setEnabled();
+ getGameLoaderInteractionController()->enableFlag24();
+}
+
+void sceneHandler04_manToBottle() {
+ g_vars->scene04_bottleObjList.push_back(g_fp->_aniMan);
+ g_vars->scene04_springOffset = 5;
+ g_vars->scene04_bottleWeight += 9;
+ g_fp->_aniMan2 = g_fp->_aniMan;
+ g_vars->scene04_dudeInBottle = 1;
+}
+
+void sceneHandler04_raisePlank() {
+ g_vars->scene04_plank->startAnim(MV_PNK_WEIGHTLEFT, 0, -1);
+}
+
+MessageQueue *sceneHandler04_kozFly3(StaticANIObject *ani, double phase) {
+ MGM mgm;
+ MGMInfo mgminfo;
+
+ mgm.addItem(ANI_KOZAWKA);
+
+ mgminfo.ani = ani;
+ mgminfo.staticsId2 = ST_KZW_SIT;
+ mgminfo.x1 = (int)(723.0 - phase * 185.0);
+ mgminfo.y1 = 486;
+ mgminfo.field_1C = 10;
+ mgminfo.field_10 = 1;
+ mgminfo.flags = 78;
+ mgminfo.movementId = MV_KZW_JUMP;
+
+ MessageQueue *mq = mgm.genMovement(&mgminfo);
+
+ if (mq) {
+ ExCommand *ex = new ExCommand(ANI_KOZAWKA, 1, MV_KZW_STANDUP, 0, 0, 0, 1, 0, 0, 0);
+ ex->_excFlags |= 2;
+ ex->_keyCode = ani->_okeyCode;
+ mq->addExCommandToEnd(ex);
+
+ ex = new ExCommand(ANI_KOZAWKA, 1, MV_KZW_TURN, 0, 0, 0, 1, 0, 0, 0);
+ ex->_excFlags |= 2;
+ ex->_keyCode = ani->_okeyCode;
+ mq->addExCommandToEnd(ex);
+
+ for (int i = 0; i < 5; i++) {
+ ex = new ExCommand(ANI_KOZAWKA, 1, rMV_KZW_GOR, 0, 0, 0, 1, 0, 0, 0);
+ ex->_excFlags |= 2;
+ ex->_keyCode = ani->_okeyCode;
+ mq->addExCommandToEnd(ex);
+ }
+
+ ex = new ExCommand(ANI_KOZAWKA, 6, 0, 0, 0, 0, 1, 0, 0, 0);
+ ex->_excFlags |= 3;
+ ex->_keyCode = ani->_okeyCode;
+ mq->addExCommandToEnd(ex);
+
+ ex = new ExCommand(ANI_KOZAWKA, 17, MSG_KOZAWRESTART, 0, 0, 0, 1, 0, 0, 0);
+ ex->_excFlags |= 3;
+ ex->_keyCode = ani->_okeyCode;
+ mq->addExCommandToEnd(ex);
+ }
+
+ return mq;
+}
+
+MessageQueue *sceneHandler04_kozFly5(StaticANIObject *ani, double phase) {
+ MGM mgm;
+ MGMInfo mgminfo;
+
+ mgm.addItem(ANI_KOZAWKA);
+
+ mgminfo.ani = ani;
+ mgminfo.staticsId2 = ST_KZW_JUMPOUT;
+ mgminfo.x1 = 525;
+ mgminfo.y1 = (int)(344.0 - (double)(320 - g_vars->scene04_bottle->_oy) * phase);
+ mgminfo.field_1C = 10;
+ mgminfo.field_10 = 1;
+ mgminfo.flags = 78;
+ mgminfo.movementId = MV_KZW_JUMPHIT;
+
+ MessageQueue *mq1 = mgm.genMovement(&mgminfo);
+
+ memset(&mgminfo, 0, sizeof(mgminfo));
+ mgminfo.ani = ani;
+ mgminfo.staticsId1 = ST_KZW_JUMPOUT;
+ mgminfo.staticsId2 = ST_KZW_SIT;
+ mgminfo.x2 = 525;
+ mgminfo.y2 = (int)(344.0 - (double)(320 - g_vars->scene04_bottle->_oy) * phase);
+ mgminfo.y1 = 486;
+ mgminfo.field_1C = 10;
+ mgminfo.field_10 = 1;
+ mgminfo.flags = 117;
+ mgminfo.movementId = MV_KZW_JUMPOUT;
+
+ MessageQueue *mq2 = mgm.genMovement(&mgminfo);
+
+ if (mq1 && mq2) {
+ mq1->addExCommandToEnd(mq2->getExCommandByIndex(0)->createClone());
+
+ delete mq2;
+
+ ExCommand *ex = new ExCommand(ANI_KOZAWKA, 1, MV_KZW_STANDUP, 0, 0, 0, 1, 0, 0, 0);
+ ex->_excFlags |= 2;
+ ex->_keyCode = ani->_okeyCode;
+ mq1->addExCommandToEnd(ex);
+
+ ex = new ExCommand(ANI_KOZAWKA, 1, MV_KZW_TURN, 0, 0, 0, 1, 0, 0, 0);
+ ex->_excFlags |= 2;
+ ex->_keyCode = ani->_okeyCode;
+ mq1->addExCommandToEnd(ex);
+
+ for (int i = 0; i < 5; i++) {
+ ex = new ExCommand(ANI_KOZAWKA, 1, rMV_KZW_GOR, 0, 0, 0, 1, 0, 0, 0);
+ ex->_excFlags |= 2;
+ ex->_keyCode = ani->_okeyCode;
+ mq1->addExCommandToEnd(ex);
+ }
+
+ ex = new ExCommand(ANI_KOZAWKA, 6, 0, 0, 0, 0, 1, 0, 0, 0);
+ ex->_excFlags |= 3;
+ ex->_keyCode = ani->_okeyCode;
+ mq1->addExCommandToEnd(ex);
+
+ ex = new ExCommand(ANI_KOZAWKA, 17, MSG_KOZAWRESTART, 0, 0, 0, 1, 0, 0, 0);
+ ex->_excFlags |= 3;
+ ex->_keyCode = ani->_okeyCode;
+ mq1->addExCommandToEnd(ex);
+ }
+
+ return mq1;
+}
+
+MessageQueue *sceneHandler04_kozFly6(StaticANIObject *ani) {
+ MGM mgm;
+ MGMInfo mgminfo;
+
+ mgm.addItem(ANI_KOZAWKA);
+
+ mgminfo.ani = ani;
+ mgminfo.staticsId2 = ST_KZW_SIT;
+ mgminfo.x1 = 397 - 4 * g_fp->_rnd->getRandomNumber(1);
+ mgminfo.field_1C = ani->_priority;
+ mgminfo.y1 = g_vars->scene04_bottle->_oy - 4 * g_fp->_rnd->getRandomNumber(1) + 109;
+ mgminfo.field_10 = 1;
+ mgminfo.flags = 78;
+ mgminfo.movementId = MV_KZW_JUMPROTATE;
+
+ MessageQueue *mq = mgm.genMovement(&mgminfo);
+
+ if (mq) {
+ mq->deleteExCommandByIndex(mq->getCount() - 1, 1);
+
+ ExCommand *ex = new ExCommand(ANI_KOZAWKA, 1, MV_KZW_STANDUP, 0, 0, 0, 1, 0, 0, 0);
+ ex->_excFlags |= 2;
+ ex->_keyCode = ani->_okeyCode;
+ mq->addExCommandToEnd(ex);
+
+ ex = new ExCommand(ANI_KOZAWKA, 1, MV_KZW_GOR, 0, 0, 0, 1, 0, 0, 0);
+ ex->_excFlags |= 2;
+ ex->_keyCode = ani->_okeyCode;
+ mq->addExCommandToEnd(ex);
+
+ ex = new ExCommand(ANI_KOZAWKA, 1, MV_KZW_RAISEHEAD, 0, 0, 0, 1, 0, 0, 0);
+ ex->_excFlags |= 2;
+ ex->_keyCode = ani->_okeyCode;
+ mq->addExCommandToEnd(ex);
+
+ g_vars->scene04_kozHeadRaised = true;
+ }
+
+ return mq;
+}
+
+void sceneHandler04_kozMove(Movement *mov, int from, int to, Common::Point *points, double phase) {
+ for (int i = from; i < to; i++) {
+ mov->setDynamicPhaseIndex(i);
+
+ Common::Point *p;
+ if (mov->_framePosOffsets) {
+ p = mov->_framePosOffsets[mov->_currDynamicPhaseIndex];
+ } else {
+ p = &mov->_somePoint;
+ p->x = 0;
+ p->y = 0;
+ }
+
+ p->y = (int)((double)points[i].y * phase);
+ }
+}
+
+MessageQueue *sceneHandler04_kozFly7(StaticANIObject *ani, double phase) {
+ MGM mgm;
+ MGMInfo mgminfo;
+
+ mgm.addItem(ANI_KOZAWKA);
+
+ mgminfo.ani = ani;
+ mgminfo.staticsId2 = 560;
+ mgminfo.x1 = (int)(250.0 - phase * 100.0);
+ mgminfo.y1 = 455;
+ mgminfo.field_1C = 10;
+ mgminfo.field_10 = 1;
+ mgminfo.flags = 78;
+ mgminfo.movementId = MV_KZW_JUMPROTATE;
+
+ MessageQueue *mq = mgm.genMovement(&mgminfo);
+
+ if (mq) {
+ sceneHandler04_kozMove(ani->getMovementById(MV_KZW_JUMPROTATE), 1, 9, g_vars->scene04_jumpRotateKozyawki, phase * 0.5 + 1.5);
+
+ ani->_priority = 10;
+
+ ExCommand *ex = new ExCommand(ANI_KOZAWKA, 1, MV_KZW_STANDUP, 0, 0, 0, 1, 0, 0, 0);
+ ex->_excFlags |= 2;
+ ex->_keyCode = ani->_okeyCode;
+ mq->addExCommandToEnd(ex);
+
+ ex = new ExCommand(ANI_KOZAWKA, 1, MV_KZW_TURN, 0, 0, 0, 1, 0, 0, 0);
+ ex->_excFlags |= 2;
+ ex->_keyCode = ani->_okeyCode;
+ mq->addExCommandToEnd(ex);
+
+ for (int i = 0; i < 2; i++) {
+ ex = new ExCommand(ANI_KOZAWKA, 1, rMV_KZW_GOR, 0, 0, 0, 1, 0, 0, 0);
+ ex->_excFlags |= 2;
+ ex->_keyCode = ani->_okeyCode;
+ mq->addExCommandToEnd(ex);
+ }
+
+ ex = new ExCommand(ANI_KOZAWKA, 6, 0, 0, 0, 0, 1, 0, 0, 0);
+ ex->_excFlags |= 3;
+ ex->_keyCode = ani->_okeyCode;
+ mq->addExCommandToEnd(ex);
+
+ ex = new ExCommand(ANI_KOZAWKA, 17, MSG_KOZAWRESTART, 0, 0, 0, 1, 0, 0, 0);
+ ex->_excFlags |= 3;
+ ex->_keyCode = ani->_okeyCode;
+ mq->addExCommandToEnd(ex);
+ }
+
+ return mq;
+}
+
+static const int kozTrajectory3[] = {
+ 3, 2, 0,
+ 3, 2, 0,
+ 3, 2, 0
+};
+
+static const int kozTrajectory4[] = {
+ 5, 3, 1,
+ 5, 4, 1,
+ 5, 3, 1
+};
+
+static const int kozTrajectory5[] = {
+ 6, 5, 4,
+ 6, 5, 4,
+ 6, 5, 4
+};
+
+static const int kozTrajectory6[] = {
+ 7, 6, 5,
+ 7, 6, 5,
+ 7, 6, 5
+};
+
+void sceneHandler04_shootKozyawka() {
+ g_vars->scene04_plank->changeStatics2(ST_PNK_WEIGHTRIGHT);
+
+ if (!g_vars->scene04_walkingKozyawka)
+ return;
+
+ if (g_vars->scene04_walkingKozyawka->_movement) {
+ if (g_vars->scene04_walkingKozyawka->_movement->_id == MV_KZW_WALKPLANK) {
+ int dphase = g_vars->scene04_walkingKozyawka->_movement->_currDynamicPhaseIndex;
+
+ if (dphase < 41) {
+ int col = 3 * dphase / 15;
+ if (col > 2)
+ col = 2;
+
+ int row = g_vars->scene04_kozyawkiAni.size();
+ if (row > 2)
+ row = 2;
+
+ int idx = 3 * row + col;
+ int phase;
+
+ if (g_vars->scene04_ladderOffset == 3) {
+ phase = kozTrajectory3[idx];
+ } else if (g_vars->scene04_ladderOffset == 4) {
+ phase = kozTrajectory4[idx];
+ } else {
+ if (g_vars->scene04_ladderOffset == 5)
+ phase = kozTrajectory5[idx];
+ else
+ phase = kozTrajectory6[idx];
+ }
+
+ g_vars->scene04_walkingKozyawka->queueMessageQueue(0);
+ g_vars->scene04_walkingKozyawka->_movement = 0;
+ g_vars->scene04_walkingKozyawka->_statics = g_vars->scene04_walkingKozyawka->getStaticsById(ST_KZW_RIGHT);
+
+ MessageQueue *mq;
+
+ if (phase > 2) {
+ if (phase > 5) {
+ if (phase == 6)
+ mq = sceneHandler04_kozFly6(g_vars->scene04_walkingKozyawka);
+ else
+ mq = sceneHandler04_kozFly7(g_vars->scene04_walkingKozyawka, (double)(phase - 6) * 0.3333333333333333);
+ } else {
+ mq = sceneHandler04_kozFly5(g_vars->scene04_walkingKozyawka, (double)(phase - 2) * 0.3333333333333333);
+ }
+ } else {
+ mq = sceneHandler04_kozFly3(g_vars->scene04_walkingKozyawka, (double)phase * 0.5);
+ }
+
+ if (mq) {
+ g_vars->scene04_lastKozyawka = g_vars->scene04_walkingKozyawka;
+
+ if (!mq->chain(g_vars->scene04_walkingKozyawka) )
+ delete mq;
+ }
+ }
+ }
+ }
+
+ if (g_vars->scene04_ladderOffset > 3)
+ g_fp->_aniMan->changeStatics1(ST_MAN_LOOKPLANK);
+
+ g_vars->scene04_kozyawkaOnLadder = true;
+}
+
+void sceneHandler04_showCoin() {
+ StaticANIObject *ani = g_fp->_currentScene->getStaticANIObject1ById(ANI_SC4_COIN, -1);
+
+ if (ani) {
+ ani->show1(MV_BDG_OPEN, MV_MAN_GOU, MV_SC4_COIN_default, 0);
+
+ ani->_priority = 40;
+ }
+}
+
+void sceneHandler04_stopSound() {
+ g_vars->scene04_soundPlaying = false;
+
+ warning("STUB: sceneHandler04_stopSound()");
+}
+
+void sceneHandler04_animOutOfBottle(ExCommand *ex) {
+ g_fp->_aniMan->changeStatics2(ST_MAN_SIT);
+
+ MessageQueue *mq = new MessageQueue(g_fp->_currentScene->getMessageQueueById(QU_SC4_MANFROMBOTTLE), 0, 0);
+
+ if (ex) {
+ ExCommand *newex = ex->createClone();
+
+ mq->addExCommandToEnd(newex);
+ }
+
+ mq->_flags |= 1;
+ mq->chain(0);
+
+ g_vars->scene04_dudeInBottle = false;
+ g_fp->_behaviorManager->setFlagByStaticAniObject(g_fp->_aniMan, 1);
+}
+
+void sceneHandler04_walkKozyawka() {
+ if (g_vars->scene04_kozyawkiObjList.size()) {
+ g_vars->scene04_walkingKozyawka = g_vars->scene04_kozyawkiObjList.front();
+ g_vars->scene04_kozyawkiObjList.pop_front();
+
+ MessageQueue *mq = new MessageQueue(g_fp->_currentScene->getMessageQueueById(QU_KOZAW_WALK), 0, 1);
+ mq->replaceKeyCode(-1, g_vars->scene04_walkingKozyawka->_okeyCode);
+ mq->chain(0);
+ }
+}
+
+void sceneHandler04_bottleUpdateObjects(int off) {
+ for (Common::List<GameObject *>::iterator it = g_vars->scene04_bottleObjList.begin(); it != g_vars->scene04_bottleObjList.end(); ++it) {
+ GameObject *obj = *it;
+
+ obj->setOXY(obj->_ox, off + obj->_oy);
+ }
+}
+
+void sceneHandler04_springWobble() {
+ int oldDynIndex = g_vars->scene04_dynamicPhaseIndex;
+ int newdelta = g_vars->scene04_springOffset + g_vars->scene04_dynamicPhaseIndex;
+
+ g_vars->scene04_dynamicPhaseIndex += g_vars->scene04_springOffset;
+
+ if (newdelta < 0) {
+ newdelta = 0;
+ g_vars->scene04_dynamicPhaseIndex = 0;
+ g_vars->scene04_springOffset = 0;
+ }
+
+ if (newdelta > 14) {
+ newdelta = 14;
+ g_vars->scene04_dynamicPhaseIndex = 14;
+ g_vars->scene04_springOffset = 0;
+ }
+
+ if (g_vars->scene04_bottleWeight > newdelta)
+ g_vars->scene04_springOffset++;
+
+ 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) {
+ g_vars->scene04_springDelay++;
+
+ if (g_vars->scene04_springOffset && g_vars->scene04_springDelay > 1) {
+ g_vars->scene04_springDelay = 0;
+ g_vars->scene04_springOffset = g_vars->scene04_springOffset - g_vars->scene04_springOffset / abs(g_vars->scene04_springOffset);
+ }
+ }
+
+ Common::Point point;
+
+ if (g_vars->scene04_dynamicPhaseIndex) {
+ if (!g_vars->scene04_spring->_movement)
+ g_vars->scene04_spring->startAnim(MV_SPR_LOWER, 0, -1);
+
+ g_vars->scene04_spring->_movement->setDynamicPhaseIndex(g_vars->scene04_dynamicPhaseIndex);
+ } else {
+ g_vars->scene04_spring->changeStatics2(ST_SPR_UP);
+ }
+
+ if (g_vars->scene04_dynamicPhaseIndex != oldDynIndex)
+ sceneHandler04_bottleUpdateObjects(oldDynIndex - g_vars->scene04_dynamicPhaseIndex);
+}
+
+void sceneHandler04_leaveScene() {
+ g_fp->_aniMan2 = 0;
+
+ MessageQueue *mq = new MessageQueue(g_fp->_currentScene->getMessageQueueById(QU_SC4_MANTOBOTTLE), 0, 0);
+ ExCommand *ex = 0;
+
+ for (uint i = 0; i < mq->getCount(); i++) {
+ if (mq->getExCommandByIndex(i)->_messageKind == 27) {
+ ex = mq->getExCommandByIndex(i);
+ break;
+ }
+ }
+
+ if (!ex) {
+ error("sceneHandler04_leaveScene(): Cannot find exit");
+ }
+
+ ex->_y = g_vars->scene04_bottle->_oy - 304;
+
+ mq->chain(0);
+
+ g_vars->scene04_var07 = false;
+ g_vars->scene04_dudeOnLadder = 0;
+
+ g_fp->_behaviorManager->setFlagByStaticAniObject(g_fp->_aniMan, 0);
+
+ g_fp->updateMapPiece(PIC_MAP_P03, 1);
+}
+
+void sceneHandler04_liftBottle() {
+ int newy = g_vars->scene04_bottleY + g_vars->scene04_spring->_oy;
+
+ g_vars->scene04_bottleY += 5;
+
+ sceneHandler04_bottleUpdateObjects(newy - g_vars->scene04_spring->_oy);
+
+ g_vars->scene04_spring->setOXY(g_vars->scene04_spring->_ox, newy);
+
+ if (g_vars->scene04_bottle->_oy >= 226) {
+ sceneHandler04_bottleUpdateObjects(226 - g_vars->scene04_bottle->_oy);
+
+ g_vars->scene04_spring->setOXY(g_vars->scene04_spring->_ox, 437);
+ g_vars->scene04_bottleIsDropped = false;
+ g_vars->scene04_handIsDown = false;
+ g_vars->scene04_objectIsTaken = true;
+ g_vars->scene04_bottleWeight = 2;
+ g_vars->scene04_springOffset = 10;
+ g_vars->scene04_bottleIsTaken = false;
+
+ g_fp->setObjectState(sO_LowerPipe, g_fp->getObjectEnumState(sO_LowerPipe, sO_IsClosed));
+ }
+}
+
+void sceneHandler04_startSounds(const char *snd1, const char *snd2, const char *snd3) {
+ warning("STUB: sceneHandler04_startSounds()");
+
+ // playFile(snd1);
+ // playFile(snd2);
+ // playFile(snd3);
+}
+
+void sceneHandler04_goClock() {
+ sceneHandler04_walkKozyawka();
+ chainQueue(QU_SC4_GOCLOCK, 0);
+ g_vars->scene04_soundPlaying = true;
+ g_vars->scene04_coinPut = false;
+
+ g_fp->stopAllSoundStreams();
+
+ sceneHandler04_startSounds("sc4_start.ogg", "sc4_loop.ogg", "sc4_stop2.ogg");
+
+ g_vars->scene04_bigBallCounter = 0;
+}
+
+void sceneHandler04_bigBallOut() {
+ StaticANIObject *ball = g_fp->_currentScene->getStaticANIObject1ById(ANI_BIGBALL, -1);
+
+ if (ball && ball->_flags & 4)
+ for (uint i = 0; i < ball->_movements.size(); i++)
+ ((Movement *)ball->_movements[i])->_counterMax = 0;
+
+ g_vars->scene04_bigBallIn = false;
+}
+
+void sceneHandler04_leaveLadder(ExCommand *ex) {
+ if (!g_fp->_aniMan->isIdle())
+ return;
+
+ if (!(g_fp->_aniMan->_flags & 0x100)) {
+ if (getSc2MctlCompoundBySceneId(g_fp->_currentScene->_sceneId)->_objtype == kObjTypeMctlCompound) {
+ MctlCompound *mc = (MctlCompound *)getSc2MctlCompoundBySceneId(g_fp->_currentScene->_sceneId);
+
+ if (mc->_motionControllers[0]->_movGraphReactObj->pointInRegion(g_fp->_sceneRect.left + ex->_x, g_fp->_sceneRect.top + ex->_y)) {
+ if (g_vars->scene04_ladder->collisionDetection(g_fp->_aniMan)) {
+ MessageQueue *mq = g_vars->scene04_ladder->controllerWalkTo(g_fp->_aniMan, 0);
+
+ if (mq) {
+ mq->addExCommandToEnd(ex->createClone());
+
+ if (mq->chain(g_fp->_aniMan) )
+ ex->_messageKind = 0;
+ else
+ delete mq;
+
+ if (g_vars->scene04_bigBallIn) {
+ sceneHandler04_bigBallOut();
+ return;
+ }
+ }
+ } else {
+ MessageQueue *mq = new MessageQueue(g_fp->_globalMessageQueueList->compact());
+ ExCommand *ex1;
+
+ if (g_fp->_aniMan->_statics->_staticsId == ST_MAN_LADDERDOWN) {
+ ex1 = new ExCommand(ANI_MAN, 1, MV_MAN_LOOKLADDERRV, 0, 0, 0, 1, 0, 0, 0);
+ ex1->_keyCode = g_fp->_aniMan->_okeyCode;
+ ex1->_excFlags |= 2;
+ mq->addExCommandToEnd(ex1);
+ }
+
+ ex1 = new ExCommand(ANI_MAN, 1, MV_MAN_STARTLADDERD, 0, 0, 0, 1, 0, 0, 0);
+ ex1->_keyCode = g_fp->_aniMan->_okeyCode;
+ ex1->_excFlags |= 2;
+ mq->addExCommandToEnd(ex1);
+
+ ex1 = new ExCommand(ANI_MAN, 1, MV_MAN_FROMLADDER, 0, 0, 0, 1, 0, 0, 0);
+ ex1->_keyCode = g_fp->_aniMan->_okeyCode;
+ ex1->_excFlags |= 2;
+ mq->addExCommandToEnd(ex1);
+
+ ex1 = ex->createClone();
+ mq->addExCommandToEnd(ex1);
+
+ mq->setFlags(mq->getFlags() | 1);
+
+ if (mq->chain(g_fp->_aniMan)) {
+ if (g_vars->scene04_ladder)
+ delete g_vars->scene04_ladder;
+
+ g_vars->scene04_ladder = 0;
+ g_vars->scene04_dudeOnLadder = 0;
+
+ ex->_messageKind = 0;
+
+ mc->setEnabled();
+ getGameLoaderInteractionController()->enableFlag24();
+ } else {
+ delete mq;
+ }
+
+ if (g_vars->scene04_bigBallIn) {
+ sceneHandler04_bigBallOut();
+ return;
+ }
+ }
+ }
+ }
+ }
+}
+
+void sceneHandler04_handTake() {
+ g_vars->scene04_clock->changeStatics2(ST_CLK_CLOSED);
+
+ if (g_vars->scene04_kozyawkiAni.size()) {
+ if (g_vars->scene04_kozyawkiAni.size() == 1) {
+ chainQueue(QU_HND_TAKE1, 0);
+ g_vars->scene04_objectIsTaken = false;
+ } else {
+ chainQueue((g_vars->scene04_kozyawkiAni.size() != 2) ? QU_HND_TAKEBOTTLE : QU_HND_TAKE2, 0);
+ g_vars->scene04_objectIsTaken = false;
+ }
+ } else {
+ chainQueue(QU_HND_TAKE0, 0);
+ g_vars->scene04_objectIsTaken = false;
+ }
+}
+
+void sceneHandler04_putKozyawkaBack(StaticANIObject *ani) {
+ g_vars->scene04_bottleObjList.push_back(ani);
+ g_vars->scene04_kozyawkiAni.push_back(ani);
+
+ g_vars->scene04_bottleWeight += 2;
+ g_vars->scene04_walkingKozyawka = 0;
+ g_vars->scene04_lastKozyawka = 0;
+
+ if (g_vars->scene04_kozyawkiAni.size() > 1 )
+ g_vars->scene04_objectIsTaken = false;
+
+ if (g_vars->scene04_kozyawkiAni.size() <= 2 || g_vars->scene04_hand->_movement) {
+ sceneHandler04_walkKozyawka();
+ } else {
+ sceneHandler04_handTake();
+ sceneHandler04_stopSound();
+ }
+}
+
+void sceneHandler04_bigBallWalkIn() {
+ StaticANIObject *ball = g_fp->_currentScene->getStaticANIObject1ById(ANI_BIGBALL, -1);
+
+ if (g_vars->scene04_dudeOnLadder
+ && (!ball || !(ball->_flags & 4))
+ && g_vars->scene04_ladder->collisionDetection(g_fp->_aniMan) > 3) {
+
+ if (!g_fp->_rnd->getRandomNumber(49)) {
+ if (g_vars->scene04_bigBallFromLeft)
+ chainQueue(QU_BALL_WALKR, 0);
+ else
+ chainQueue(QU_BALL_WALKL, 0);
+
+ g_vars->scene04_bigBallFromLeft = !g_vars->scene04_bigBallFromLeft;
+
+ sceneHandler04_checkBigBallClick();
+
+ g_vars->scene04_bigBallCounter = 0;
+ }
+ }
+}
+
+void sceneHandler04_takeBottle() {
+ g_vars->scene04_bottleIsTaken = true;
+ g_vars->scene04_hand->_priority = 5;
+
+ g_fp->setObjectState(sO_LowerPipe, g_fp->getObjectEnumState(sO_LowerPipe, sO_IsOpened));
+}
+
+void sceneHandler04_takeKozyawka() {
+ if (g_vars->scene04_kozyawkiAni.size() > 0) {
+ if (g_vars->scene04_kozyawkiAni.size() == 1)
+ g_vars->scene04_objectIsTaken = true;
+
+ StaticANIObject *koz = g_vars->scene04_kozyawkiAni.front();
+ g_vars->scene04_kozyawkiAni.pop_front();
+
+ if (koz) {
+ koz->queueMessageQueue(0);
+ koz->hide();
+
+ g_vars->scene04_kozyawkiObjList.push_back(koz);
+
+ for (Common::List<GameObject *>::iterator it = g_vars->scene04_bottleObjList.begin(); it != g_vars->scene04_bottleObjList.end(); ++it)
+ if (*it == koz) {
+ g_vars->scene04_bottleObjList.erase(it);
+ break;
+ }
+
+ g_vars->scene04_bottleWeight -= 2;
+ }
+ }
+}
+
+void sceneHandler04_testPlank(ExCommand *ex) {
+ MessageQueue *mq = g_fp->_globalMessageQueueList->getMessageQueueById(ex->_parId);
+
+ if (!mq)
+ return;
+
+ if (g_vars->scene04_plank->_movement || !g_vars->scene04_plank->_statics || g_vars->scene04_plank->_statics->_staticsId != ST_PNK_WEIGHTLEFT) {
+ mq->getExCommandByIndex(0)->_messageNum = MV_KZW_TOHOLERV;
+ } else {
+ mq->getExCommandByIndex(0)->_messageNum = MV_KZW_WALKPLANK;
+ }
+}
+
+void sceneHandler04_updateBottle() {
+ Common::Point point;
+
+ int yoff;
+
+ if (g_vars->scene04_hand->_movement)
+ yoff = g_vars->scene04_hand->_movement->_oy;
+ else
+ yoff = g_vars->scene04_hand->_oy;
+
+ int newy = g_vars->scene04_hand->getSomeXY(point)->y + yoff + 140;
+
+ sceneHandler04_bottleUpdateObjects(newy - g_vars->scene04_spring->_oy);
+
+ g_vars->scene04_spring->setOXY(g_vars->scene04_spring->_ox, newy);
+}
+
+void sceneHandler04_winArcade() {
+ if (g_fp->getObjectState(sO_LowerPipe) == g_fp->getObjectEnumState(sO_LowerPipe, sO_IsClosed)
+ && g_vars->scene04_soundPlaying) {
+ g_vars->scene04_clock->changeStatics2(ST_CLK_CLOSED);
+ g_vars->scene04_hand->changeStatics2(ST_HND_EMPTY);
+
+ chainQueue(QU_HND_TAKEBOTTLE, 1);
+
+ if (g_vars->scene04_walkingKozyawka) {
+ g_vars->scene04_kozyawkiObjList.push_back(g_vars->scene04_walkingKozyawka);
+
+ g_vars->scene04_walkingKozyawka->changeStatics2(ST_KZW_EMPTY);
+ g_vars->scene04_walkingKozyawka->hide();
+ g_vars->scene04_walkingKozyawka = 0;
+ }
+
+ g_vars->scene04_objectIsTaken = false;
+ g_vars->scene04_soundPlaying = false;
+
+ getSc2MctlCompoundBySceneId(g_fp->_currentScene->_sceneId)->setEnabled();
+
+ getGameLoaderInteractionController()->enableFlag24();
+
+ g_fp->stopSoundStream2();
+ }
+}
+
+int sceneHandler04(ExCommand *ex) {
+ if (ex->_messageKind != 17)
+ return 0;
+
+ switch (ex->_messageNum) {
+ case MSG_UPDATEBOTTLE:
+ sceneHandler04_updateBottle();
+ break;
+
+ case MSG_CLICKBOTTLE:
+ sceneHandler04_clickBottle();
+ break;
+
+ case MSG_SHOOTKOZAW:
+ sceneHandler04_shootKozyawka();
+ break;
+
+ case MSG_SHAKEBOTTLE:
+ if (!g_vars->scene04_bottleIsTaken)
+ ++g_vars->scene04_springOffset;
+ break;
+
+ case MSG_STARTHAND:
+ g_vars->scene04_handIsDown = true;
+ g_vars->scene04_coinPut = false;
+
+ if (g_vars->scene04_dudeInBottle)
+ sceneHandler04_animOutOfBottle(0);
+
+ sceneHandler04_handTake();
+ sceneHandler04_stopSound();
+ break;
+
+ case MSG_TAKEKOZAW:
+ sceneHandler04_takeKozyawka();
+ break;
+
+ case MSG_CLICKBUTTON:
+ sceneHandler04_clickButton();
+ break;
+
+ case MSG_CLICKPLANK:
+ sceneHandler04_clickPlank();
+ break;
+
+ case MSG_RAISEPLANK:
+ sceneHandler04_raisePlank();
+ break;
+
+ case MSG_KOZAWRESTART:
+ if (g_vars->scene04_walkingKozyawka) {
+ g_vars->scene04_kozyawkiObjList.push_back(g_vars->scene04_walkingKozyawka);
+ g_vars->scene04_walkingKozyawka->hide();
+ g_vars->scene04_walkingKozyawka = 0;
+ }
+
+ if (g_vars->scene04_soundPlaying)
+ sceneHandler04_walkKozyawka();
+
+ break;
+
+ case MSG_LOWERPLANK:
+ sceneHandler04_lowerPlank();
+ break;
+
+ case MSG_TESTPLANK:
+ sceneHandler04_testPlank(ex);
+ break;
+
+ case 33:
+ {
+ g_vars->scene04_dudePosX = g_fp->_aniMan->_ox;
+ g_vars->scene04_dudePosY = g_fp->_aniMan->_oy;
+
+ int res = 0;
+
+ if (g_fp->_aniMan2) {
+ if (g_fp->_aniMan->_ox < g_fp->_sceneRect.left + 200) {
+ g_fp->_currentScene->_x = g_fp->_aniMan->_ox - g_fp->_sceneRect.left - 300;
+ g_fp->_aniMan->_ox = g_vars->scene04_dudePosX;
+ }
+ if (g_fp->_aniMan->_ox > g_fp->_sceneRect.right - 200) {
+ g_fp->_currentScene->_x = g_fp->_aniMan->_ox - g_fp->_sceneRect.right + 300;
+ }
+
+ res = 1;
+
+ if (g_vars->scene04_soundPlaying) {
+ if (g_fp->_aniMan->_movement) {
+ if (g_fp->_aniMan->_movement->_id == MV_MAN_TOLADDER) {
+ g_fp->_aniMan2 = 0;
+
+ if (g_fp->_sceneRect.left > 380)
+ g_fp->_currentScene->_x = 380 - g_fp->_sceneRect.left;
+ }
+ }
+ }
+ } else {
+ if (g_fp->_aniMan->_movement && g_fp->_aniMan->_movement->_id == MV_MAN_GOD)
+ g_fp->_aniMan2 = g_fp->_aniMan;
+ }
+
+ sceneHandler04_springWobble();
+
+ if (g_vars->scene04_var07 && !g_vars->scene04_handIsDown)
+ sceneHandler04_leaveScene();
+
+ if (g_vars->scene04_bottleIsDropped)
+ sceneHandler04_liftBottle();
+
+ if (g_vars->scene04_ladderClickable)
+ sceneHandler04_clickLadder();
+
+ if (g_vars->scene04_dudeInBottle && g_vars->scene04_hand->_movement)
+ sceneHandler04_animOutOfBottle(0);
+
+ if (g_vars->scene04_coinPut && g_vars->scene04_clockCanGo && !g_vars->scene04_handIsDown && !g_vars->scene04_soundPlaying)
+ sceneHandler04_goClock();
+
+ if (g_vars->scene04_dudeOnLadder) {
+ if (!g_vars->scene04_soundPlaying) {
+ g_fp->startSceneTrack();
+
+ g_fp->_behaviorManager->updateBehaviors();
+ return res;
+ }
+
+ g_vars->scene04_bigBallCounter++;
+
+ if (g_vars->scene04_bigBallCounter > 600)
+ sceneHandler04_bigBallWalkIn();
+ }
+
+ if (g_vars->scene04_soundPlaying) {
+ g_fp->_behaviorManager->updateBehaviors();
+
+ return res;
+ }
+
+ g_fp->startSceneTrack();
+
+ g_fp->_behaviorManager->updateBehaviors();
+
+ return res;
+ }
+
+ case 29:
+ {
+ int picid = g_fp->_currentScene->getPictureObjectIdAtPos(ex->_sceneClickX, ex->_sceneClickY);
+
+ if (g_vars->scene04_dudeInBottle) {
+ sceneHandler04_animOutOfBottle(ex);
+
+ break;
+ }
+
+ if (picid == PIC_SC4_LADDER) {
+ if (!g_vars->scene04_kozyawkaOnLadder) {
+ g_vars->scene04_sceneClickX = ex->_sceneClickX;
+ g_vars->scene04_sceneClickY = ex->_sceneClickY;
+
+ sceneHandler04_clickLadder();
+
+ ex->_messageKind = 0;
+
+ break;
+ }
+
+ sceneHandler04_gotoLadder(0);
+
+ break;
+ }
+
+ StaticANIObject *ani = g_fp->_currentScene->getStaticANIObjectAtPos(ex->_sceneClickX, ex->_sceneClickY);
+
+ if ((ani && ani->_id == ANI_PLANK) || picid == PIC_SC4_PLANK) {
+ sceneHandler04_clickPlank();
+
+ ex->_messageKind = 0;
+ } else if (g_vars->scene04_dudeOnLadder) {
+ sceneHandler04_leaveLadder(ex);
+ } else if (!ani || !canInteractAny(g_fp->_aniMan, ani, ex->_keyCode)) {
+ PictureObject *pic = g_fp->_currentScene->getPictureObjectById(picid, 0);
+
+ if (!pic || !canInteractAny(g_fp->_aniMan, pic,ex->_keyCode)) {
+ if ((g_fp->_sceneRect.right - ex->_sceneClickX < 47 && g_fp->_sceneRect.right < g_fp->_sceneWidth - 1)
+ || (ex->_sceneClickX - g_fp->_sceneRect.left < 47 && g_fp->_sceneRect.left > 0))
+ g_fp->processArcade(ex);
+ }
+ }
+ }
+
+ break;
+
+ case MSG_SC4_HIDEBOOT:
+ g_vars->scene04_boot->_flags &= 0xfffb;
+ break;
+
+ case MSG_CMN_WINARCADE:
+ sceneHandler04_winArcade();
+ break;
+
+ case MSG_SC4_HANDOVER:
+ g_vars->scene04_handIsDown = false;
+ g_vars->scene04_objectIsTaken = true;
+ break;
+
+ case MSG_SC4_DROPBOTTLE:
+ sceneHandler04_dropBottle();
+ break;
+
+ case MSG_SC4_COINOUT:
+ g_vars->scene04_clock->changeStatics2(ST_CLK_CLOSED);
+ g_vars->scene04_coinPut = false;
+ sceneHandler04_stopSound();
+
+ if (g_vars->scene04_kozyawkiAni.size() && !g_vars->scene04_bottleIsTaken) {
+ g_vars->scene04_handIsDown = true;
+
+ if (g_vars->scene04_dudeInBottle)
+ sceneHandler04_animOutOfBottle(0);
+
+ sceneHandler04_handTake();
+ }
+
+ break;
+
+ case MSG_SC4_KOZAWFALL:
+ {
+ ExCommand *exnew;
+
+ if (g_vars->scene04_kozHeadRaised) {
+ sceneHandler04_putKozyawkaBack(g_vars->scene04_lastKozyawka);
+
+ g_vars->scene04_kozHeadRaised = 0;
+
+ exnew = new ExCommand(0, 35, SND_4_010, 0, 0, 0, 1, 0, 0, 0);
+ } else {
+ exnew = new ExCommand(0, 35, SND_4_012, 0, 0, 0, 1, 0, 0, 0);
+ }
+
+ exnew->_field_14 = 5;
+ exnew->_excFlags |= 2;
+ exnew->postMessage();
+ break;
+ }
+
+ case MSG_SC4_MANFROMBOTTLE:
+ sceneHandler04_manFromBottle();
+ break;
+
+ case MSG_SC4_CLICKLADDER:
+ sceneHandler04_clickLadder();
+ break;
+
+ case MSG_SC4_MANTOBOTTLE:
+ sceneHandler04_manToBottle();
+ break;
+
+ case MSG_SHOWCOIN:
+ sceneHandler04_showCoin();
+ break;
+
+ case MSG_TAKEBOTTLE:
+ sceneHandler04_takeBottle();
+ break;
+
+ case MSG_GOTOLADDER:
+ sceneHandler04_gotoLadder(0);
+ break;
+
+ case MSG_SC4_COINPUT:
+ g_vars->scene04_coinPut = true;
+ break;
+ }
+
+ return 0;
+}
+
+} // End of namespace Fullpipe
diff --git a/engines/fullpipe/scenes/scene05.cpp b/engines/fullpipe/scenes/scene05.cpp
new file mode 100644
index 0000000000..c6e21daf1e
--- /dev/null
+++ b/engines/fullpipe/scenes/scene05.cpp
@@ -0,0 +1,386 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public 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 "fullpipe/fullpipe.h"
+
+#include "fullpipe/objects.h"
+#include "fullpipe/objectnames.h"
+#include "fullpipe/constants.h"
+#include "fullpipe/statics.h"
+#include "fullpipe/scene.h"
+#include "fullpipe/motion.h"
+#include "fullpipe/scenes.h"
+#include "fullpipe/messages.h"
+#include "fullpipe/floaters.h"
+#include "fullpipe/behavior.h"
+
+namespace Fullpipe {
+
+void scene05_initScene(Scene *sc) {
+ g_vars->scene05_handle = sc->getStaticANIObject1ById(ANI_HANDLE, -1);
+ g_vars->scene05_wacko = sc->getStaticANIObject1ById(ANI_OTMOROZ, -1);
+ g_vars->scene05_bigHatch = sc->getStaticANIObject1ById(ANI_BIGLUK, -1);
+
+
+ g_vars->scene05_wackoTicker = 0;
+ g_vars->scene05_handleFlipper = 1;
+ g_vars->scene05_floatersTicker = 1000;
+
+ Scene *oldscene = g_fp->_currentScene;
+
+ g_fp->_currentScene = sc;
+
+ if (g_fp->getObjectState(sO_WeirdWacko) == g_fp->getObjectEnumState(sO_WeirdWacko, sO_InGlasses)) {
+ g_vars->scene05_wacko->changeStatics2(ST_OTM_GLS_LEFT);
+ g_vars->scene05_bigHatch->changeStatics2(ST_BLK_CLOSED);
+
+ g_vars->scene05_handle->changeStatics2(ST_HDL_UP);
+ g_vars->scene05_handle->_flags |= 4;
+ } else if (g_fp->getObjectState(sO_WeirdWacko) == g_fp->getObjectEnumState(sO_WeirdWacko, sO_WithDrawer)) {
+ g_vars->scene05_wacko->changeStatics2(ST_OTM_BOX_LEFT);
+ g_vars->scene05_bigHatch->changeStatics2(ST_BLK_CLOSED);
+ g_vars->scene05_handle->changeStatics2(ST_HDL_UP);
+ g_vars->scene05_handle->_flags |= 4;
+ } else {
+ g_vars->scene05_wacko->changeStatics2(ST_OTM_VNT_LEFT);
+
+ if (g_fp->getObjectState(sO_WeirdWacko) != g_fp->getObjectEnumState(sO_WeirdWacko, sO_WithPlunger)) {
+ g_vars->scene05_handle->changeStatics2(ST_HDL_BROKEN);
+ g_vars->scene05_bigHatch->changeStatics2(ST_BLK_CLOSED);
+ }
+ }
+
+ g_fp->_currentScene = oldscene;
+}
+
+void sceneHandler05_makeManFlight() {
+ int qid;
+
+ if (!g_vars->scene05_bigHatch->_statics || g_vars->scene05_bigHatch->_statics->_staticsId != ST_BLK_OPEN)
+ qid = QU_SC5_MANBUMP;
+ else
+ qid = QU_SC5_MANFLY;
+
+ MessageQueue *mq = new MessageQueue(g_fp->_currentScene->getMessageQueueById(qid), 0, 0);
+
+ mq->setFlags(mq->getFlags() | 1);
+
+ mq->chain(0);
+}
+
+void sceneHandler05_makeWackoFeedback() {
+ int staticsId1;
+ int staticsId2;
+
+ if (g_fp->getObjectState(sO_WeirdWacko) == g_fp->getObjectEnumState(sO_WeirdWacko, sO_InGlasses)) {
+ staticsId1 = ST_OTM_GLS_LEFT;
+ staticsId2 = (g_vars->scene05_handle->_statics->_staticsId == ST_HDL_DOWN) ? MV_OTM_HANDLEUP : MV_OTM_HANDLEDOWN;
+ } else if (g_fp->getObjectState(sO_WeirdWacko) != g_fp->getObjectEnumState(sO_WeirdWacko, sO_WithDrawer)) {
+ return;
+ } else {
+ staticsId1 = ST_OTM_BOX_LEFT;
+ staticsId2 = (g_vars->scene05_handle->_statics->_staticsId == ST_HDL_DOWN) ? MV_OTM_BOXHANDLEUP : MV_OTM_BOXHANDLEDOWN;
+ }
+
+ if (g_vars->scene05_wacko->_movement)
+ g_vars->scene05_wacko->changeStatics2(g_vars->scene05_wacko->_movement->_staticsObj2->_staticsId);
+
+ if (staticsId1 == g_vars->scene05_wacko->_statics->_staticsId) {
+ g_vars->scene05_wacko->startAnim(staticsId2, 0, -1);
+ } else {
+ MessageQueue *mq = g_vars->scene05_wacko->changeStatics1(staticsId1);
+
+ if (mq) {
+ mq->setFlags(mq->getFlags() | 1);
+
+ ExCommand *ex = new ExCommand(0, 17, MSG_SC5_MAKEOTMFEEDBACK, 0, 0, 0, 1, 0, 0, 0);
+
+ ex->_excFlags |= 2;
+
+ mq->addExCommandToEnd(ex);
+ mq->_isFinished = 0;
+ }
+ }
+}
+
+void sceneHandler05_resetTicks() {
+ if (g_fp->_aniMan->_movement && (g_fp->_aniMan->_movement->_id == MV_MANHDL_HANDLEUP
+ || g_fp->_aniMan->_movement->_id == MV_MANHDL_HANDLEDOWN))
+ g_vars->scene05_wackoTicker = g_fp->_updateTicks;
+ else
+ g_vars->scene05_wackoTicker = 0;
+}
+
+void sceneHandler05_genFlies() {
+ if (g_vars->scene05_floatersTicker <= 1000)
+ return;
+
+ if (g_fp->_rnd->getRandomNumber(1)) {
+ int numFlies = g_fp->_rnd->getRandomNumber(3) + 1;
+
+ for (int i = 0; i < numFlies; i++) {
+ int x = g_fp->_rnd->getRandomNumber(55) + 538;
+ int y = g_fp->_rnd->getRandomNumber(60) + i * 30 + 520;
+
+ g_fp->_floaters->genFlies(g_fp->_currentScene, x, y, 5, 1);
+ g_fp->_floaters->_array2.back()->val2 = 585;
+ g_fp->_floaters->_array2.back()->val3 = -70;
+ g_fp->_floaters->_array2.back()->val11 = 8.0;
+ }
+ }
+
+ g_vars->scene05_floatersTicker = 0;
+}
+
+void sceneHandler05_showHandle() {
+ g_fp->_currentScene->getStaticANIObject1ById(ANI_HANDLE, -1)->show1(-1, -1, -1, 0);
+}
+
+void sceneHandler05_handleDown() {
+ StaticANIObject *hatch = g_fp->_currentScene->getStaticANIObject1ById(ANI_BIGLUK, -1);
+
+ hatch->changeStatics2(ST_BLK_CLOSED);
+ hatch->startAnim(MV_BLK_OPEN, 0, -1);
+
+ sceneHandler05_resetTicks();
+ sceneHandler05_genFlies();
+}
+
+void sceneHandler05_hideHandle() {
+ g_fp->_currentScene->getStaticANIObject1ById(ANI_HANDLE, -1)->hide();
+}
+
+void sceneHandler05_handleUp() {
+ StaticANIObject *hatch = g_fp->_currentScene->getStaticANIObject1ById(ANI_BIGLUK, -1);
+
+ hatch->changeStatics2(ST_BLK_OPEN);
+ hatch->startAnim(MV_BLK_CLOSE, 0, -1);
+
+ sceneHandler05_resetTicks();
+}
+
+void sceneHandler05_testHatch(ExCommand *inex) {
+ ExCommand *ex;
+
+ if (g_fp->_currentScene->getStaticANIObject1ById(ANI_BIGLUK, -1)->_statics->_staticsId == ST_BLK_CLOSED) {
+ ex = new ExCommand(SC_5, 17, 61, 0, 0, 0, 1, 0, 0, 0);
+ ex->_keyCode = TrubaLeft;
+ ex->_excFlags |= 2;
+ ex->postMessage();
+
+ return;
+ }
+
+ StaticANIObject *wacko = g_fp->_currentScene->getStaticANIObject1ById(ANI_OTMOROZ, -1);
+
+ if (wacko->_movement)
+ wacko->changeStatics2(wacko->_movement->_staticsObj2->_staticsId);
+
+ if (g_fp->getObjectState(sO_WeirdWacko) == g_fp->getObjectEnumState(sO_WeirdWacko, sO_InGlasses)) {
+ MessageQueue *mq = g_fp->_globalMessageQueueList->getMessageQueueById(inex->_parId);
+
+ if (mq)
+ mq->deleteExCommandByIndex(mq->getCount() - 1, 1);
+
+ if (wacko->_statics->_staticsId != ST_OTM_GLS_LEFT) {
+ mq = wacko->changeStatics1(ST_OTM_GLS_LEFT);
+
+ if (!mq) {
+ wacko->changeStatics2(ST_OTM_GLS_LEFT);
+ mq = new MessageQueue(g_fp->_globalMessageQueueList->compact());
+ }
+
+ mq->setFlags(mq->getFlags() | 1);
+
+ ex = new ExCommand(ANI_OTMOROZ, 1, MV_OTM_HANDLEUP, 0, 0, 0, 1, 0, 0, 0);
+ ex->_excFlags |= 2u;
+ mq->addExCommandToEnd(ex);
+
+ ex = new ExCommand(SC_5, 17, 61, 0, 0, 0, 1, 0, 0, 0);
+ ex->_keyCode = TrubaLeft;
+ ex->_excFlags |= 2;
+ mq->addExCommandToEnd(ex);
+
+ mq->_isFinished = 0;
+ return;
+ }
+
+ mq = new MessageQueue(g_fp->_globalMessageQueueList->compact());
+ mq->setFlags(mq->getFlags() | 1);
+
+ ex = new ExCommand(ANI_OTMOROZ, 1, MV_OTM_HANDLEUP, 0, 0, 0, 1, 0, 0, 0);
+ ex->_excFlags |= 2;
+ mq->addExCommandToEnd(ex);
+
+ ex = new ExCommand(SC_5, 17, 61, 0, 0, 0, 1, 0, 0, 0);
+ ex->_keyCode = TrubaLeft;
+ ex->_excFlags |= 2;
+ mq->addExCommandToEnd(ex);
+
+ if (!mq->chain(wacko))
+ delete mq;
+ } else if (g_fp->getObjectState(sO_WeirdWacko) == g_fp->getObjectEnumState(sO_WeirdWacko, sO_WithDrawer)) {
+ MessageQueue *mq = g_fp->_globalMessageQueueList->getMessageQueueById(inex->_parId);
+
+ if (mq)
+ mq->deleteExCommandByIndex(mq->getCount() - 1, 1);
+
+ if (wacko->_statics->_staticsId != ST_OTM_BOX_LEFT) {
+ mq = wacko->changeStatics1(ST_OTM_BOX_LEFT);
+ if (!mq) {
+ wacko->changeStatics2(ST_OTM_BOX_LEFT);
+ mq = new MessageQueue(g_fp->_globalMessageQueueList->compact());
+ }
+
+ mq->setFlags(mq->getFlags() | 1);
+
+ ex = new ExCommand(ANI_OTMOROZ, 1, MV_OTM_BOXHANDLEUP, 0, 0, 0, 1, 0, 0, 0);
+ ex->_excFlags |= 2;
+ mq->addExCommandToEnd(ex);
+
+ ex = new ExCommand(SC_5, 17, 61, 0, 0, 0, 1, 0, 0, 0);
+ ex->_keyCode = TrubaLeft;
+ ex->_excFlags |= 2;
+ mq->addExCommandToEnd(ex);
+
+ mq->_isFinished = 0;
+
+ return;
+ }
+
+ mq = new MessageQueue(g_fp->_globalMessageQueueList->compact());
+ mq->setFlags(mq->getFlags() | 1);
+
+ ex = new ExCommand(ANI_OTMOROZ, 1, MV_OTM_BOXHANDLEUP, 0, 0, 0, 1, 0, 0, 0);
+ ex->_excFlags |= 2;
+ mq->addExCommandToEnd(ex);
+
+ ex = new ExCommand(SC_5, 17, 61, 0, 0, 0, 1, 0, 0, 0);
+ ex->_keyCode = TrubaLeft;
+ ex->_excFlags |= 2;
+ mq->addExCommandToEnd(ex);
+
+ if (!mq->chain(wacko))
+ delete mq;
+
+ return;
+ } else {
+ ex = new ExCommand(SC_5, 17, 61, 0, 0, 0, 1, 0, 0, 0);
+ ex->_keyCode = TrubaLeft;
+ ex->_excFlags |= 2;
+ ex->postMessage();
+
+ return;
+ }
+}
+
+
+int sceneHandler05(ExCommand *ex) {
+ if (ex->_messageKind != 17)
+ return 0;
+
+ switch (ex->_messageNum) {
+ case MSG_SC5_BGRSOUNDOFF:
+ g_fp->stopAllSoundInstances(SND_5_026);
+ break;
+
+ case MSG_SC5_BGRSOUNDON:
+ g_fp->playSound(SND_5_026, 1);
+ break;
+
+ case MSG_SC5_MAKEMANFLIGHT:
+ sceneHandler05_makeManFlight();
+ break;
+
+ case MSG_SC5_MAKEOTMFEEDBACK:
+ if (!g_fp->_aniMan->_movement || (g_fp->_aniMan->_movement->_id != MV_MANHDL_HANDLEUP
+ && g_fp->_aniMan->_movement->_id != MV_MANHDL_HANDLEDOWN)) {
+ sceneHandler05_makeWackoFeedback();
+ g_vars->scene05_wackoTicker = 0;
+ }
+ break;
+
+ case MSG_SC5_SHOWHANDLE:
+ sceneHandler05_showHandle();
+ break;
+
+ case MSG_SC5_HANDLEDOWN:
+ g_vars->scene05_handle->changeStatics2(ST_HDL_DOWN);
+ sceneHandler05_handleDown();
+ break;
+
+ case MSG_SC5_HIDEHANDLE:
+ sceneHandler05_hideHandle();
+ break;
+
+ case MSG_SC5_HANDLEUP:
+ g_vars->scene05_handle->changeStatics2(ST_HDL_UP);
+ sceneHandler05_handleUp();
+ break;
+
+ case MSG_SC5_TESTLUK:
+ sceneHandler05_testHatch(ex);
+ break;
+
+ case 33:
+ {
+ int res = 0;
+ if (g_fp->_aniMan2) {
+ if (g_fp->_aniMan2->_ox < g_fp->_sceneRect.left + 200)
+ g_fp->_currentScene->_x = g_fp->_aniMan2->_ox - g_fp->_sceneRect.left - 300;
+
+ if (g_fp->_aniMan2->_ox > g_fp->_sceneRect.right - 200)
+ g_fp->_currentScene->_x = g_fp->_aniMan2->_ox - g_fp->_sceneRect.right + 300;
+
+ res = 1;
+ }
+
+ if (g_vars->scene05_wackoTicker) {
+ if ((g_fp->_updateTicks - g_vars->scene05_wackoTicker) > 62) {
+ if (!g_fp->_aniMan->_movement || (g_fp->_aniMan->_movement->_id != MV_MANHDL_HANDLEUP
+ && g_fp->_aniMan->_movement->_id != MV_MANHDL_HANDLEDOWN)) {
+ if (g_vars->scene05_handleFlipper % 2)
+ sceneHandler05_makeWackoFeedback();
+
+ g_vars->scene05_wackoTicker = 0;
+
+ ++g_vars->scene05_handleFlipper;
+ }
+ }
+ }
+
+ ++g_vars->scene05_floatersTicker;
+
+ g_fp->_floaters->update();
+
+ g_fp->_behaviorManager->updateBehaviors();
+
+ g_fp->startSceneTrack();
+
+ return res;
+ }
+ }
+
+ return 0;
+}
+
+} // End of namespace Fullpipe
diff --git a/engines/fullpipe/scenes/scene06.cpp b/engines/fullpipe/scenes/scene06.cpp
new file mode 100644
index 0000000000..7d637d8306
--- /dev/null
+++ b/engines/fullpipe/scenes/scene06.cpp
@@ -0,0 +1,770 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public 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 "fullpipe/fullpipe.h"
+
+#include "fullpipe/objects.h"
+#include "fullpipe/objectnames.h"
+#include "fullpipe/constants.h"
+#include "fullpipe/gfx.h"
+#include "fullpipe/motion.h"
+#include "fullpipe/scenes.h"
+#include "fullpipe/statics.h"
+#include "fullpipe/scene.h"
+#include "fullpipe/messages.h"
+#include "fullpipe/gameloader.h"
+#include "fullpipe/behavior.h"
+#include "fullpipe/interaction.h"
+
+namespace Fullpipe {
+
+void scene06_initMumsy() {
+ g_vars->scene06_mumsyJumpFw = g_fp->_behaviorManager->getBehaviorEntryInfoByMessageQueueDataId(g_vars->scene06_mumsy, ST_MOM_STANDS, QU_MOM_JUMPFW);
+ g_vars->scene06_mumsyJumpBk = g_fp->_behaviorManager->getBehaviorEntryInfoByMessageQueueDataId(g_vars->scene06_mumsy, ST_MOM_STANDS, QU_MOM_JUMPBK);
+ g_vars->scene06_mumsyJumpFwPercent = g_vars->scene06_mumsyJumpFw->_percent;
+ g_vars->scene06_mumsyJumpBkPercent = g_vars->scene06_mumsyJumpBk->_percent;
+}
+
+int scene06_updateCursor() {
+ g_fp->updateCursorCommon();
+
+ if (g_vars->scene06_arcadeEnabled) {
+ if (g_vars->scene06_aimingBall) {
+ g_fp->_cursorId = PIC_CSR_ARCADE2_D;
+
+ return PIC_CSR_ARCADE2_D;
+ }
+ if (g_fp->_aniMan == (StaticANIObject *)g_fp->_objectAtCursor) {
+ if (g_fp->_aniMan->_statics->_staticsId == ST_MAN6_BALL && g_fp->_cursorId == PIC_CSR_DEFAULT) {
+ g_fp->_cursorId = PIC_CSR_ITN;
+
+ return PIC_CSR_ITN;
+ }
+ } else if (g_fp->_objectAtCursor && (StaticANIObject *)g_fp->_objectAtCursor == g_vars->scene06_currentBall
+ && g_fp->_cursorId == PIC_CSR_DEFAULT) {
+ g_fp->_cursorId = PIC_CSR_ITN;
+ }
+ }
+
+ return g_fp->_cursorId;
+}
+
+void sceneHandler06_setExits(Scene *sc) {
+ MotionController *mc = getSc2MctlCompoundBySceneId(sc->_sceneId);
+
+ mc->enableLinks(sO_CloseThing, (g_fp->getObjectState(sO_BigMumsy) != g_fp->getObjectEnumState(sO_BigMumsy, sO_IsGone)));
+ mc->enableLinks(sO_CloseThing2, g_vars->scene06_arcadeEnabled);
+}
+
+void sceneHandler06_winArcade() {
+ g_fp->setObjectState(sO_BigMumsy, g_fp->getObjectEnumState(sO_BigMumsy, sO_IsGone));
+
+ if (g_fp->getObjectState(sO_ClockAxis) == g_fp->getObjectEnumState(sO_ClockAxis, sO_IsNotAvailable))
+ g_fp->setObjectState(sO_ClockAxis, g_fp->getObjectEnumState(sO_ClockAxis, sO_WithoutHandle));
+
+ if (g_vars->scene06_arcadeEnabled) {
+ g_fp->_aniMan->_callback2 = 0;
+
+ g_fp->_aniMan->changeStatics2(ST_MAN_RIGHT | 0x4000);
+
+ if (g_vars->scene06_someBall) {
+ g_vars->scene06_someBall->_flags &= 0xFFFB;
+
+ g_vars->scene06_balls.push_back(g_vars->scene06_someBall);
+
+ g_vars->scene06_someBall = 0;
+ }
+
+ if (g_vars->scene06_flyingBall) {
+ g_vars->scene06_flyingBall->_flags &= 0xFFFB;
+
+ g_vars->scene06_balls.push_back(g_vars->scene06_flyingBall);
+
+ g_vars->scene06_flyingBall = 0;
+ }
+
+ if (g_vars->scene06_ballInHands) {
+ g_vars->scene06_ballInHands->_flags &= 0xFFFB;
+
+ g_vars->scene06_balls.push_back(g_vars->scene06_ballInHands);
+
+ g_vars->scene06_ballInHands = 0;
+ }
+
+ g_vars->scene06_arcadeEnabled = false;
+ g_vars->scene06_aimingBall = false;
+ }
+
+ g_vars->scene06_mumsy->_flags &= 0xFFFB;
+
+ sceneHandler06_setExits(g_fp->_currentScene);
+
+ getCurrSceneSc2MotionController()->setEnabled();
+ getGameLoaderInteractionController()->enableFlag24();
+}
+
+void sceneHandler06_enableDrops() {
+ chainQueue(QU_SC6_DROPS, 0);
+
+ g_vars->scene06_mumsy->changeStatics2(ST_MOM_SITS);
+ g_fp->setObjectState(sO_BigMumsy, g_fp->getObjectEnumState(sO_BigMumsy, sO_IsPlaying));
+
+ chainQueue(QU_MOM_STANDUP, 1);
+
+ g_vars->scene06_arcadeEnabled = true;
+ g_vars->scene06_numBallsGiven = 0;
+ g_vars->scene06_mumsyPos = 0;
+ g_vars->scene06_mumsyNumBalls = 0;
+ g_vars->scene06_mumsyGotBall = false;
+
+ sceneHandler06_setExits(g_fp->_currentScene);
+}
+
+void sceneHandler06_mumsyBallTake() {
+ int momAni = 0;
+
+ switch (g_vars->scene06_mumsyNumBalls) {
+ case 1:
+ momAni = MV_MOM_TAKE1;
+ break;
+ case 2:
+ momAni = MV_MOM_TAKE2;
+ break;
+ case 3:
+ momAni = MV_MOM_TAKE3;
+ break;
+ case 4:
+ momAni = MV_MOM_TAKE4;
+ break;
+ case 5:
+ momAni = MV_MOM_TAKE5;
+ break;
+ }
+
+ MessageQueue *mq = new MessageQueue(g_fp->_globalMessageQueueList->compact());
+
+ ExCommand *ex = new ExCommand(ANI_MAMASHA, 2, 50, 0, 0, 0, 1, 0, 0, 0);
+
+ ex->_excFlags = 2u;
+ mq->addExCommandToEnd(ex);
+
+ if (g_vars->scene06_mumsyNumBalls >= 5) {
+ g_fp->setObjectState(sO_BigMumsy, g_fp->getObjectEnumState(sO_BigMumsy, sO_IsGone));
+
+ if (g_fp->getObjectState(sO_ClockAxis) == g_fp->getObjectEnumState(sO_ClockAxis, sO_IsNotAvailable))
+ g_fp->setObjectState(sO_ClockAxis, g_fp->getObjectEnumState(sO_ClockAxis, sO_WithoutHandle));
+
+ ex = new ExCommand(ANI_MAMASHA, 1, momAni, 0, 0, 0, 1, 0, 0, 0);
+ ex->_excFlags |= 2;
+ mq->addExCommandToEnd(ex);
+
+ if (g_vars->scene06_mumsyPos + 3 >= 0) {
+ ex = new ExCommand(ANI_MAMASHA, 1, MV_MOM_STARTBK, 0, 0, 0, 1, 0, 0, 0);
+ ex->_excFlags |= 2u;
+ mq->addExCommandToEnd(ex);
+
+ for (int i = 0; i < g_vars->scene06_mumsyPos + 3; i++) {
+ ex = new ExCommand(ANI_MAMASHA, 1, MV_MOM_CYCLEBK, 0, 0, 0, 1, 0, 0, 0);
+ ex->_excFlags |= 2;
+ mq->addExCommandToEnd(ex);
+ }
+
+ ex = new ExCommand(ANI_MAMASHA, 1, MV_MOM_STOPBK, 0, 0, 0, 1, 0, 0, 0);
+ ex->_excFlags |= 2;
+ mq->addExCommandToEnd(ex);
+ }
+
+ ex = new ExCommand(0, 18, QU_MOM_TOLIFT, 0, 0, 0, 1, 0, 0, 0);
+ ex->_excFlags |= 3;
+ mq->addExCommandToEnd(ex);
+ } else {
+ if (momAni) {
+ ex = new ExCommand(ANI_MAMASHA, 1, momAni, 0, 0, 0, 1, 0, 0, 0);
+ ex->_excFlags |= 2;
+ mq->addExCommandToEnd(ex);
+ }
+
+ if (g_vars->scene06_mumsyPos < 0) {
+ for (int i = 0; i > g_vars->scene06_mumsyPos; i--) {
+ ex = new ExCommand(ANI_MAMASHA, 1, MV_MOM_JUMPFW, 0, 0, 0, 1, 0, 0, 0);
+ ex->_excFlags |= 2;
+ mq->addExCommandToEnd(ex);
+ }
+ } else if (g_vars->scene06_mumsyPos > 0) {
+ for (int i = 0; i < g_vars->scene06_mumsyPos; i++) {
+ ex = new ExCommand(ANI_MAMASHA, 1, MV_MOM_JUMPBK, 0, 0, 0, 1, 0, 0, 0);
+ ex->_excFlags |= 2;
+ mq->addExCommandToEnd(ex);
+ }
+ }
+
+ ex = new ExCommand(0, 18, QU_MOM_SITDOWN, 0, 0, 0, 1, 0, 0, 0);
+ ex->_excFlags |= 3u;
+ mq->addExCommandToEnd(ex);
+ }
+
+ mq->setFlags(mq->getFlags() | 1);
+ mq->chain(0);
+
+ g_vars->scene06_mumsyNumBalls = 0;
+ g_vars->scene06_arcadeEnabled = false;
+
+ g_fp->_aniMan2 = 0;
+}
+
+void sceneHandler06_spinHandle() {
+ int tummy = g_fp->getObjectState(sO_TummyTrampie);
+
+ if (tummy == g_fp->getObjectEnumState(sO_TummyTrampie, sO_IsEating))
+ g_fp->setObjectState(sO_TummyTrampie, g_fp->getObjectEnumState(sO_TummyTrampie, sO_IsSleeping));
+ else if (tummy == g_fp->getObjectEnumState(sO_TummyTrampie, sO_IsSleeping))
+ g_fp->setObjectState(sO_TummyTrampie, g_fp->getObjectEnumState(sO_TummyTrampie, sO_IsDrinking));
+ else if (tummy == g_fp->getObjectEnumState(sO_TummyTrampie, sO_IsDrinking))
+ g_fp->setObjectState(sO_TummyTrampie, g_fp->getObjectEnumState(sO_TummyTrampie, sO_IsScratchingBelly));
+ else if (tummy == g_fp->getObjectEnumState(sO_TummyTrampie, sO_IsScratchingBelly))
+ g_fp->setObjectState(sO_TummyTrampie, g_fp->getObjectEnumState(sO_TummyTrampie, sO_IsEating));
+}
+
+void sceneHandler06_uPipeClick() {
+ if (getGameLoaderInteractionController()->_flag24)
+ handleObjectInteraction(g_fp->_aniMan2, g_fp->_currentScene->getPictureObjectById(PIC_SC6_LADDER, 0), 0);
+}
+
+void sceneHandler06_buttonPush() {
+ g_vars->scene06_invHandle = g_fp->_currentScene->getStaticANIObject1ById(ANI_INV_HANDLE, -1);
+
+ if (g_vars->scene06_invHandle)
+ if (g_vars->scene06_invHandle->_flags & 4)
+ if (g_vars->scene06_invHandle->_statics)
+ if (g_vars->scene06_invHandle->_statics->_staticsId == ST_HDL_PLUGGED)
+ chainQueue(QU_SC6_FALLHANDLE, 1);
+}
+
+void sceneHandler06_showNextBall() {
+ if (g_vars->scene06_balls.size()) {
+ g_vars->scene06_currentBall = new StaticANIObject(g_vars->scene06_balls.front());
+ g_vars->scene06_balls.remove_at(0);
+
+ MessageQueue *mq = new MessageQueue(g_fp->_currentScene->getMessageQueueById(QU_SC6_SHOWNEXTBALL), 0, 1);
+
+ mq->replaceKeyCode(-1, g_vars->scene06_currentBall->_okeyCode);
+ mq->chain(0);
+
+ ++g_vars->scene06_numBallsGiven;
+ }
+}
+
+void sceneHandler06_installHandle() {
+ chainQueue(QU_SC6_SHOWHANDLE, 0);
+}
+
+int sceneHandler06_updateScreenCallback() {
+ int res;
+
+ res = g_fp->drawArcadeOverlay(g_vars->scene06_arcadeEnabled);
+
+ if (!res)
+ g_fp->_updateScreenCallback = 0;
+
+ return res;
+}
+
+void sceneHandler06_startAiming() {
+ if (g_vars->scene06_currentBall) {
+ g_vars->scene06_currentBall->hide();
+
+ g_fp->_aniMan->startAnim(MV_MAN6_TAKEBALL, 0, -1);
+
+ g_vars->scene06_ballInHands = g_vars->scene06_currentBall;
+ g_vars->scene06_currentBall = 0;
+
+ if (getCurrSceneSc2MotionController()->_isEnabled)
+ g_fp->_updateScreenCallback = sceneHandler06_updateScreenCallback;
+
+ getCurrSceneSc2MotionController()->clearEnabled();
+ getGameLoaderInteractionController()->disableFlag24();
+
+ g_vars->scene06_ballDrop->queueMessageQueue(0);
+ }
+}
+
+void sceneHandler06_takeBall() {
+ if (g_vars->scene06_currentBall && !g_vars->scene06_currentBall->_movement && g_vars->scene06_currentBall->_statics->_staticsId == ST_NBL_NORM) {
+ if (abs(1158 - g_fp->_aniMan->_ox) > 1
+ || abs(452 - g_fp->_aniMan->_oy) > 1
+ || g_fp->_aniMan->_movement
+ || g_fp->_aniMan->_statics->_staticsId != (0x4000 | ST_MAN_RIGHT)) {
+ MessageQueue *mq = getCurrSceneSc2MotionController()->method34(g_fp->_aniMan, 1158, 452, 1, (0x4000 | ST_MAN_RIGHT));
+
+ if (mq) {
+ ExCommand *ex = new ExCommand(0, 17, MSG_SC6_TAKEBALL, 0, 0, 0, 1, 0, 0, 0);
+ ex->_excFlags |= 3;
+ mq->addExCommandToEnd(ex);
+
+ postExCommand(g_fp->_aniMan->_id, 2, 1158, 452, 0, -1);
+ }
+ } else {
+ sceneHandler06_startAiming();
+ }
+ }
+}
+
+void sceneHandler06_aiming() {
+ if (g_vars->scene06_ballInHands) {
+ g_vars->scene06_ballDeltaX = 4 * g_fp->_aniMan->_movement->_currDynamicPhaseIndex + 16;
+ g_vars->scene06_ballDeltaY = 5 * (g_fp->_aniMan->_movement->_currDynamicPhaseIndex + 4);
+
+ if (g_fp->_aniMan->_movement->_currDynamicPhaseIndex < 4) {
+ g_fp->_aniMan->_movement->setDynamicPhaseIndex(11);
+
+ g_vars->scene06_aimingBall = false;
+
+ return;
+ }
+
+ g_fp->_aniMan->_movement->setDynamicPhaseIndex(9);
+ }
+
+ g_vars->scene06_aimingBall = false;
+}
+
+void sceneHandler06_ballStartFly() {
+ if (g_vars->scene06_ballInHands) {
+ g_vars->scene06_flyingBall = g_vars->scene06_ballInHands;
+ g_vars->scene06_ballInHands = 0;
+ g_vars->scene06_flyingBall->show1(g_fp->_aniMan->_ox - 60, g_fp->_aniMan->_oy - 60, -1, 0);
+
+ g_vars->scene06_flyingBall->_priority = 27;
+ }
+}
+
+void sceneHandler06_throwCallback(int *arg) {
+ if (g_vars->scene06_aimingBall) {
+ int dist = (g_fp->_mouseVirtY - g_vars->scene06_sceneClickY)
+ * (g_fp->_mouseVirtY - g_vars->scene06_sceneClickY)
+ + (g_fp->_mouseVirtX - g_vars->scene06_sceneClickX)
+ * (g_fp->_mouseVirtX - g_vars->scene06_sceneClickX);
+
+ *arg = (int)(sqrt((double)dist) * 0.1);
+
+ if (*arg > 8)
+ *arg = 8;
+ } else {
+ *arg = *arg + 1;
+ if (*arg == 12)
+ sceneHandler06_ballStartFly();
+ }
+}
+
+void sceneHandler06_throwBall() {
+ g_fp->_aniMan->_callback2 = sceneHandler06_throwCallback;
+ g_fp->_aniMan->startAnim(MV_MAN6_THROWBALL, 0, -1);
+
+ g_vars->scene06_aimingBall = true;
+}
+
+void sceneHandler06_eggieWalk() {
+ if (15 - g_vars->scene06_numBallsGiven >= 4 && !g_fp->_rnd->getRandomNumber(9)) {
+ StaticANIObject *ani = g_fp->_currentScene->getStaticANIObject1ById(ANI_EGGIE, -1);
+
+ if (!ani || !(ani->_flags & 4)) {
+ if (g_vars->scene06_eggieDirection)
+ chainQueue(QU_EGG6_GOR, 0);
+ else
+ chainQueue(QU_EGG6_GOL, 0);
+
+ g_vars->scene06_eggieTimeout = 0;
+ g_vars->scene06_eggieDirection = !g_vars->scene06_eggieDirection;
+ }
+ }
+}
+
+void sceneHandler06_dropBall() {
+ if (g_vars->scene06_numBallsGiven >= 15 || g_vars->scene06_mumsyNumBalls >= 5)
+ g_vars->scene06_ballDrop->hide();
+ else
+ chainQueue(QU_SC6_DROPS3, 0);
+}
+
+void sceneHandler06_fallBall() {
+ g_vars->scene06_ballY = 475;
+
+ g_vars->scene06_flyingBall->setOXY(g_vars->scene06_ballX, g_vars->scene06_ballY);
+
+ MessageQueue *mq = new MessageQueue(g_fp->_currentScene->getMessageQueueById(QU_SC6_FALLBALL), 0, 1);
+
+ mq->replaceKeyCode(-1, g_vars->scene06_flyingBall->_okeyCode);
+ mq->chain(0);
+
+ g_vars->scene06_balls.push_back(g_vars->scene06_flyingBall);
+
+ g_vars->scene06_flyingBall = 0;
+
+ sceneHandler06_dropBall();
+ sceneHandler06_eggieWalk();
+}
+
+void sceneHandler06_catchBall() {
+ if (g_vars->scene06_flyingBall) {
+ g_vars->scene06_flyingBall->hide();
+
+ g_vars->scene06_balls.push_back(g_vars->scene06_flyingBall);
+
+ g_vars->scene06_flyingBall = 0;
+
+ g_vars->scene06_mumsyNumBalls++;
+
+ if (g_vars->scene06_mumsy->_movement) {
+ Common::Point point;
+
+ if (g_vars->scene06_mumsy->_movement->_id == MV_MOM_JUMPFW) {
+ if (g_vars->scene06_mumsy->_movement->_currDynamicPhaseIndex <= 5) {
+ g_vars->scene06_mumsy->_movement->calcSomeXY(point, 0);
+
+ point.x = -point.x;
+ point.y = -point.y;
+ } else {
+ g_vars->scene06_mumsy->_movement->calcSomeXY(point, 1);
+
+ g_vars->scene06_mumsyPos++;
+ }
+ } else if (g_vars->scene06_mumsy->_movement->_id == MV_MOM_JUMPBK) {
+ if (g_vars->scene06_mumsy->_movement->_currDynamicPhaseIndex <= 4) {
+ g_vars->scene06_mumsy->_movement->calcSomeXY(point, 0);
+
+ point.x = -point.x;
+ point.y = -point.y;
+ } else {
+ g_vars->scene06_mumsy->_movement->calcSomeXY(point, 1);
+
+ g_vars->scene06_mumsyPos--;
+ }
+ }
+
+ g_vars->scene06_mumsy->changeStatics2(ST_MOM_STANDS);
+ g_vars->scene06_mumsy->setOXY(point.x + g_vars->scene06_mumsy->_ox,
+ point.y + g_vars->scene06_mumsy->_oy);
+ } else {
+ g_vars->scene06_mumsy->changeStatics2(ST_MOM_STANDS);
+ }
+
+ chainQueue(QU_MOM_PUTBALL, 1);
+ g_vars->scene06_mumsyGotBall = true;
+
+ sceneHandler06_dropBall();
+ }
+}
+
+void sceneHandler06_checkBallTarget(int par) {
+ int pixel;
+
+ if (g_vars->scene06_ballY <= 475) {
+ if (g_vars->scene06_mumsy->getPixelAtPos(g_vars->scene06_ballX, g_vars->scene06_ballY, &pixel)) {
+ if (pixel) {
+ chainObjQueue(g_vars->scene06_mumsy, QU_MOM_JUMPBK, 0);
+
+ sceneHandler06_catchBall();
+ }
+ }
+ } else {
+ sceneHandler06_fallBall();
+ }
+}
+
+void scene06_initScene(Scene *sc) {
+ g_vars->scene06_mumsy = sc->getStaticANIObject1ById(ANI_MAMASHA, -1);
+ g_vars->scene06_someBall = 0;
+ g_vars->scene06_invHandle = sc->getStaticANIObject1ById(ANI_INV_HANDLE, -1);
+ g_vars->scene06_liftButton = sc->getStaticANIObject1ById(ANI_BUTTON_6, -1);
+ g_vars->scene06_ballDrop = sc->getStaticANIObject1ById(ANI_BALLDROP, -1);
+ g_vars->scene06_arcadeEnabled = false;
+ g_vars->scene06_aimingBall = false;
+ g_vars->scene06_currentBall = 0;
+ g_vars->scene06_ballInHands = 0;
+ g_vars->scene06_flyingBall = 0;
+ g_vars->scene06_balls.clear();
+ g_vars->scene06_numBallsGiven = 0;
+ g_vars->scene06_mumsyNumBalls = 0;
+ g_vars->scene06_eggieTimeout = 0;
+ g_vars->scene06_eggieDirection = true;
+
+ StaticANIObject *ball = sc->getStaticANIObject1ById(ANI_NEWBALL, -1);
+
+ ball->hide();
+ ball->_statics = ball->getStaticsById(ST_NBL_NORM);
+ g_vars->scene06_balls.push_back(ball);
+
+ for (int i = 0; i < 3; i++) {
+ StaticANIObject *ball2 = new StaticANIObject(ball);
+
+ ball2->hide();
+ ball2->_statics = ball2->getStaticsById(ST_NBL_NORM);
+
+ sc->addStaticANIObject(ball2, 1);
+
+ g_vars->scene06_balls.push_back(ball2);
+ }
+
+ if (g_fp->getObjectState(sO_BigMumsy) == g_fp->getObjectEnumState(sO_BigMumsy, sO_IsPlaying))
+ g_fp->setObjectState(sO_BigMumsy, g_fp->getObjectEnumState(sO_BigMumsy, sO_IsSleeping));
+
+ if (g_fp->getObjectState(sO_BigMumsy) != g_fp->getObjectEnumState(sO_BigMumsy, sO_IsSleeping))
+ g_vars->scene06_mumsy->hide();
+
+ g_fp->lift_setButton(sO_Level3, ST_LBN_3N);
+ g_fp->lift_init(sc, QU_SC6_ENTERLIFT, QU_SC6_EXITLIFT);
+ g_fp->initArcadeKeys("SC_6");
+
+ sceneHandler06_setExits(sc);
+
+ g_fp->setArcadeOverlay(PIC_CSR_ARCADE2);
+}
+
+int sceneHandler06(ExCommand *ex) {
+ if (ex->_messageKind != 17)
+ return 0;
+
+ switch(ex->_messageNum) {
+ case MSG_LIFT_CLOSEDOOR:
+ g_fp->lift_closedoorSeq();
+ break;
+
+ case MSG_LIFT_EXITLIFT:
+ g_fp->lift_exitSeq(ex);
+ break;
+
+ case MSG_CMN_WINARCADE:
+ sceneHandler06_winArcade();
+ break;
+
+ case MSG_LIFT_STARTEXITQUEUE:
+ g_fp->lift_startExitQueue();
+ break;
+
+ case MSG_SC6_RESTORESCROLL:
+ g_fp->_aniMan2 = g_fp->_aniMan;
+ getCurrSceneSc2MotionController()->setEnabled();
+ getGameLoaderInteractionController()->enableFlag24();
+ sceneHandler06_setExits(g_fp->_currentScene);
+ break;
+
+ case MSG_SC6_STARTDROPS:
+ if (g_fp->getObjectState(sO_BigMumsy) == g_fp->getObjectEnumState(sO_BigMumsy, sO_IsSleeping))
+ sceneHandler06_enableDrops();
+ break;
+
+ case MSG_SC6_TESTNUMBALLS:
+ g_vars->scene06_mumsyGotBall = false;
+
+ if (g_vars->scene06_mumsyNumBalls < 5 || !g_vars->scene06_arcadeEnabled)
+ return 0;
+
+ sceneHandler06_mumsyBallTake();
+ break;
+
+ case MSG_SC6_JUMPFW:
+ ++g_vars->scene06_mumsyPos;
+ break;
+
+ case MSG_SC6_JUMPBK:
+ --g_vars->scene06_mumsyPos;
+ break;
+
+ case MSG_LIFT_CLICKBUTTON:
+ g_fp->lift_clickButton();
+ break;
+
+ case MSG_SPINHANDLE:
+ sceneHandler06_spinHandle();
+ break;
+
+ case MSG_LIFT_GO:
+ g_fp->lift_goAnimation();
+ break;
+
+ case MSG_SC6_UTRUBACLICK:
+ sceneHandler06_uPipeClick();
+ break;
+
+ case MSG_SC6_BTNPUSH:
+ sceneHandler06_buttonPush();
+ break;
+
+ case MSG_SC6_SHOWNEXTBALL:
+ sceneHandler06_showNextBall();
+ break;
+
+ case MSG_SC6_INSTHANDLE:
+ sceneHandler06_installHandle();
+ break;
+
+ case MSG_SC6_ENABLEDROPS:
+ sceneHandler06_enableDrops();
+ break;
+
+ case 64:
+ g_fp->lift_sub05(ex);
+ break;
+
+ case MSG_SC6_TAKEBALL:
+ sceneHandler06_takeBall();
+ break;
+
+ case 30:
+ if (g_vars->scene06_aimingBall) {
+ sceneHandler06_aiming();
+ break;
+ }
+
+ if (!g_vars->scene06_arcadeEnabled) {
+ // Do nothing
+ break;
+ }
+ break;
+
+ case 29:
+ {
+ StaticANIObject *st = g_fp->_currentScene->getStaticANIObjectAtPos(ex->_sceneClickX, ex->_sceneClickY);
+
+ if (st) {
+ if (!g_vars->scene06_arcadeEnabled && st->_id == ANI_LIFTBUTTON) {
+ g_fp->lift_sub1(st);
+ ex->_messageKind = 0;
+ return 0;
+ }
+
+ if (g_vars->scene06_currentBall == st) {
+ if (g_vars->scene06_numBallsGiven == 1)
+ sceneHandler06_takeBall();
+
+ ex->_messageKind = 0;
+ } else if (g_vars->scene06_ballInHands && g_fp->_aniMan == st && !g_fp->_aniMan->_movement && g_fp->_aniMan->_statics->_staticsId == ST_MAN6_BALL) {
+ g_vars->scene06_sceneClickX = ex->_sceneClickX;
+ g_vars->scene06_sceneClickY = ex->_sceneClickY;
+
+ sceneHandler06_throwBall();
+ }
+ }
+
+ if (!st || !canInteractAny(g_fp->_aniMan, st, ex->_keyCode)) {
+ int picId = g_fp->_currentScene->getPictureObjectIdAtPos(ex->_sceneClickX, ex->_sceneClickY);
+ PictureObject *pic = g_fp->_currentScene->getPictureObjectById(picId, 0);
+
+ if (!pic || !canInteractAny(g_fp->_aniMan, pic, ex->_keyCode)) {
+ if ((g_fp->_sceneRect.right - ex->_sceneClickX < 47
+ && g_fp->_sceneRect.right < g_fp->_sceneWidth - 1)
+ || (ex->_sceneClickX - g_fp->_sceneRect.left < 47 && g_fp->_sceneRect.left > 0)) {
+ g_fp->processArcade(ex);
+ return 0;
+ }
+ }
+ }
+ }
+
+ break;
+
+ case 33:
+ {
+ int res = 0;
+
+ if (g_fp->_aniMan2) {
+ int ox = g_fp->_aniMan2->_ox;
+ int oy = g_fp->_aniMan2->_oy;
+
+ g_vars->scene06_manX = ox;
+ g_vars->scene06_manY = oy;
+
+ if (g_vars->scene06_arcadeEnabled && oy <= 470 && ox >= 1088) {
+ if (ox < g_fp->_sceneRect.left + 600) {
+ g_fp->_currentScene->_x = ox - g_fp->_sceneRect.left - 700;
+ ox = g_vars->scene06_manX;
+ }
+
+ if (ox > g_fp->_sceneRect.right - 50)
+ g_fp->_currentScene->_x = ox - g_fp->_sceneRect.right + 70;
+ } else {
+ if (ox < g_fp->_sceneRect.left + 200) {
+ g_fp->_currentScene->_x = ox - g_fp->_sceneRect.left - 300;
+ ox = g_vars->scene06_manX;
+ }
+
+ if (ox > g_fp->_sceneRect.right - 200)
+ g_fp->_currentScene->_x = ox - g_fp->_sceneRect.right + 300;
+ }
+
+ res = 1;
+ }
+ if (g_vars->scene06_arcadeEnabled) {
+ if (g_vars->scene06_mumsyPos > -3)
+ g_vars->scene06_mumsyJumpBk->_percent = g_vars->scene06_mumsyJumpBkPercent;
+ else
+ g_vars->scene06_mumsyJumpBk->_percent = 0;
+
+ if (g_vars->scene06_mumsyPos < 4)
+ g_vars->scene06_mumsyJumpFw->_percent = g_vars->scene06_mumsyJumpFwPercent;
+ else
+ g_vars->scene06_mumsyJumpFw->_percent = 0;
+
+ if (g_vars->scene06_aimingBall) {
+ g_vars->scene06_eggieTimeout++;
+
+ if (g_vars->scene06_eggieTimeout >= 600)
+ sceneHandler06_eggieWalk();
+ }
+ } else {
+ g_vars->scene06_mumsyJumpFw->_percent = 0;
+ g_vars->scene06_mumsyJumpBk->_percent = 0;
+ }
+
+ if (g_vars->scene06_flyingBall) {
+ g_vars->scene06_ballX = g_vars->scene06_flyingBall->_ox - g_vars->scene06_ballDeltaX;
+ g_vars->scene06_ballY = g_vars->scene06_flyingBall->_oy - g_vars->scene06_ballDeltaY;
+
+ g_vars->scene06_flyingBall->setOXY(g_vars->scene06_ballX, g_vars->scene06_ballY);
+
+ if (g_vars->scene06_ballDeltaX >= 2)
+ g_vars->scene06_ballDeltaX -= 2;
+
+ g_vars->scene06_ballDeltaY -= 5;
+
+ sceneHandler06_checkBallTarget(g_vars->scene06_ballDeltaX);
+ }
+ if (g_vars->scene06_arcadeEnabled
+ && !g_vars->scene06_currentBall
+ && !g_vars->scene06_ballInHands
+ && !g_vars->scene06_flyingBall
+ && g_vars->scene06_numBallsGiven >= 15
+ && !g_vars->scene06_ballDrop->_movement
+ && !g_vars->scene06_mumsy->_movement
+ && !g_vars->scene06_mumsyGotBall)
+ sceneHandler06_mumsyBallTake();
+ g_fp->_behaviorManager->updateBehaviors();
+ g_fp->startSceneTrack();
+
+ return res;
+ }
+ }
+
+ return 0;
+}
+
+} // End of namespace Fullpipe
diff --git a/engines/fullpipe/scenes/scene07.cpp b/engines/fullpipe/scenes/scene07.cpp
new file mode 100644
index 0000000000..207189d151
--- /dev/null
+++ b/engines/fullpipe/scenes/scene07.cpp
@@ -0,0 +1,175 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public 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 "fullpipe/fullpipe.h"
+
+#include "fullpipe/objects.h"
+#include "fullpipe/objectnames.h"
+#include "fullpipe/constants.h"
+#include "fullpipe/motion.h"
+#include "fullpipe/scenes.h"
+#include "fullpipe/scene.h"
+#include "fullpipe/statics.h"
+#include "fullpipe/messages.h"
+#include "fullpipe/behavior.h"
+
+namespace Fullpipe {
+
+void scene07_initScene(Scene *sc) {
+ g_vars->scene07_lukeAnim = 0;
+ g_vars->scene07_lukePercent = 0;
+ g_vars->scene07_plusMinus = sc->getStaticANIObject1ById(ANI_PLUSMINUS, -1);
+
+ if (g_fp->getObjectState(sO_Guard_1) == g_fp->getObjectEnumState(sO_Guard_1, sO_Off))
+ g_vars->scene07_plusMinus->_statics = g_vars->scene07_plusMinus->getStaticsById(ST_PMS_MINUS);
+ else
+ g_vars->scene07_plusMinus->_statics = g_vars->scene07_plusMinus->getStaticsById(ST_PMS_PLUS);
+
+ if (g_fp->getObjectState(sO_HareTheNooksiter) == g_fp->getObjectEnumState(sO_HareTheNooksiter, sO_WithoutHandle)) {
+ Scene *oldsc = g_fp->_currentScene;
+
+ g_fp->_currentScene = sc;
+
+ sc->getStaticANIObject1ById(ANI_CORNERSITTER, -1)->changeStatics2(ST_CST_HANDLELESS);
+
+ g_fp->_currentScene = oldsc;
+ }
+}
+
+void sceneHandler07_openLuke() {
+ StaticANIObject *luke = g_fp->_currentScene->getStaticANIObject1ById(ANI_LUKE, -1);
+
+ luke->changeStatics2(ST_LUK_OPEN);
+ luke->show1(-1, -1, -1, 0);
+
+ if (g_vars->scene07_lukeAnim) {
+ g_vars->scene07_lukeAnim->_percent = g_vars->scene07_lukePercent;
+ } else {
+ StaticANIObject *ani = g_fp->_currentScene->getStaticANIObject1ById(ANI_CORNERSITTER, -1);
+
+ g_vars->scene07_lukeAnim = g_fp->_behaviorManager->getBehaviorEntryInfoByMessageQueueDataId(ani, ST_CST_HANDLELESS, QU_CST_CLOSELUKE);
+
+ g_vars->scene07_lukeAnim->_percent = g_vars->scene07_lukePercent;
+ }
+}
+
+void sceneHandler07_closeLuke() {
+ g_fp->_currentScene->getStaticANIObject1ById(ANI_LUKE, -1)->changeStatics2(ST_LUK_CLOSED);
+
+ if (!g_vars->scene07_lukeAnim) {
+ StaticANIObject *ani = g_fp->_currentScene->getStaticANIObject1ById(ANI_CORNERSITTER, -1);
+
+ g_vars->scene07_lukeAnim = g_fp->_behaviorManager->getBehaviorEntryInfoByMessageQueueDataId(ani, ST_CST_HANDLELESS, QU_CST_CLOSELUKE);
+ }
+
+ g_vars->scene07_lukePercent = g_vars->scene07_lukeAnim->_percent;
+ g_vars->scene07_lukeAnim->_percent = 0;
+
+ StaticANIObject *ani = g_fp->_currentScene->getStaticANIObject1ById(ANI_HOOLIGAN, -1);
+
+ ani->changeStatics2(ST_HGN_LUKE);
+ ani->show1(-1, -1, -1, 0);
+}
+
+void sceneHandler07_hideLuke() {
+ g_fp->_currentScene->getStaticANIObject1ById(ANI_LUKE, -1)->hide();
+
+ Movement *mov = g_fp->_currentScene->getStaticANIObject1ById(ANI_CORNERSITTER, -1)->_movement;
+
+ if (mov) {
+ if (mov->_id == MV_CST_CLOSELUKE) {
+ StaticANIObject *ani = g_fp->_currentScene->getStaticANIObject1ById(ANI_HOOLIGAN, -1);
+
+ ani->changeStatics2(ST_HGN_LOOK);
+ ani->_flags &= 0xFFFB;
+ }
+ }
+}
+
+void sceneHandler07_showBox() {
+ StaticANIObject *box = g_fp->_currentScene->getStaticANIObject1ById(ANI_SC7_BOX, -1);
+
+ box->show1(492, 474, MV_SC7_BOX_default, 0);
+ box->_priority = 25;
+}
+
+void sceneHandler07_hideBox() {
+ g_fp->_currentScene->getStaticANIObject1ById(ANI_SC7_BOX, -1)->hide();
+}
+
+int sceneHandler07(ExCommand *ex) {
+ if (ex->_messageKind != 17)
+ return 0;
+
+ switch(ex->_messageNum) {
+ case MSG_SC7_OPENLUKE:
+ sceneHandler07_openLuke();
+ break;
+
+ case MSG_SC7_PULL:
+ if (g_vars->scene07_plusMinus->_statics->_staticsId == ST_PMS_MINUS)
+ g_vars->scene07_plusMinus->_statics = g_vars->scene07_plusMinus->getStaticsById(ST_PMS_PLUS);
+ else
+ g_vars->scene07_plusMinus->_statics = g_vars->scene07_plusMinus->getStaticsById(ST_PMS_MINUS);
+
+ break;
+
+ case MSG_SC7_CLOSELUKE:
+ sceneHandler07_closeLuke();
+ break;
+
+ case MSG_SC7_HIDELUKE:
+ sceneHandler07_hideLuke();
+ break;
+
+ case MSG_SC7_SHOWBOX:
+ sceneHandler07_showBox();
+ break;
+
+ case MSG_SC7_HIDEBOX:
+ sceneHandler07_hideBox();
+ break;
+
+ case 33:
+ {
+ int res = 0;
+
+ if (g_fp->_aniMan2) {
+ if (g_fp->_aniMan2->_ox < g_fp->_sceneRect.left + 200)
+ g_fp->_currentScene->_x = g_fp->_aniMan2->_ox - g_fp->_sceneRect.left - 300;
+
+ if (g_fp->_aniMan2->_ox > g_fp->_sceneRect.right - 200)
+ g_fp->_currentScene->_x = g_fp->_aniMan2->_ox - g_fp->_sceneRect.right + 300;
+
+ res = 1;
+ }
+
+ g_fp->_behaviorManager->updateBehaviors();
+
+ return res;
+ }
+ }
+
+ return 0;
+}
+
+} // End of namespace Fullpipe
diff --git a/engines/fullpipe/scenes/scene08.cpp b/engines/fullpipe/scenes/scene08.cpp
new file mode 100644
index 0000000000..716ca1f593
--- /dev/null
+++ b/engines/fullpipe/scenes/scene08.cpp
@@ -0,0 +1,546 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public 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 "fullpipe/fullpipe.h"
+
+#include "fullpipe/objects.h"
+#include "fullpipe/objectnames.h"
+#include "fullpipe/constants.h"
+#include "fullpipe/motion.h"
+#include "fullpipe/scenes.h"
+#include "fullpipe/scene.h"
+#include "fullpipe/statics.h"
+#include "fullpipe/floaters.h"
+#include "fullpipe/gameloader.h"
+#include "fullpipe/behavior.h"
+#include "fullpipe/interaction.h"
+
+namespace Fullpipe {
+
+void scene08_initScene(Scene *sc) {
+ g_vars->scene08_inArcade = false;
+ g_vars->scene08_inAir = false;
+ g_vars->scene08_flyingUp = false;
+ g_vars->scene08_onBelly = false;
+ g_vars->scene08_batuta = sc->getStaticANIObject1ById(ANI_BATUTA, -1);
+ g_vars->scene08_vmyats = sc->getStaticANIObject1ById(ANI_VMYATS, -1);
+ g_vars->scene08_clock = sc->getStaticANIObject1ById(ANI_CLOCK_8, -1);
+ g_vars->scene08_stairsOffset = -37;
+ g_vars->scene08_snoringCountdown = -1;
+
+ Scene *oldsc = g_fp->_currentScene;
+ g_fp->_currentScene = sc;
+
+ int batuta = g_fp->getObjectState(sO_TummyTrampie);
+ MovGraphLink *lock = getSc2MctlCompoundBySceneId(sc->_sceneId)->getLinkByName(sO_CloseThing);
+
+ if (lock)
+ lock->_flags &= 0xDFFFFFFF;
+
+ if (batuta == g_fp->getObjectEnumState(sO_TummyTrampie, sO_IsEating)) {
+ g_vars->scene08_batuta->changeStatics2(ST_BTT_SPOON);
+ } else if (batuta == g_fp->getObjectEnumState(sO_TummyTrampie, sO_IsDrinking)) {
+ g_vars->scene08_batuta->changeStatics2(ST_BTT_NOSPOON);
+
+ g_vars->scene08_clock->startAnim(MV_CLK8_GO, 0, -1);
+ g_vars->scene08_clock->_movement->setDynamicPhaseIndex(3);
+ } else if (batuta== g_fp->getObjectEnumState(sO_TummyTrampie, sO_IsScratchingBelly)) {
+ g_vars->scene08_batuta->changeStatics2(ST_BTT_CHESHET);
+
+ g_vars->scene08_clock->startAnim(MV_CLK8_GO, 0, -1);
+ g_vars->scene08_clock->_movement->setDynamicPhaseIndex(8);
+ } else if (batuta == g_fp->getObjectEnumState(sO_TummyTrampie, sO_IsSleeping)) {
+ g_vars->scene08_batuta->changeStatics2(ST_BTT_SLEEPS);
+
+ g_vars->scene08_clock->startAnim(MV_CLK8_GO, 0, -1);
+ g_vars->scene08_clock->_movement->setDynamicPhaseIndex(2);
+
+ if (lock)
+ lock->_flags |= 0x20000000;
+
+ g_vars->scene08_snoringCountdown = 71;
+ }
+
+ g_vars->scene08_clock->_callback2 = 0;
+
+ if (g_fp->getObjectState(sO_StairsUp_8) == g_fp->getObjectEnumState(sO_StairsUp_8, sO_Broken)) {
+ g_vars->scene08_stairsVisible = false;
+
+ sc->getPictureObjectById(PIC_SC8_LADDER, 0)->_flags &= 0xFFFB;
+
+ g_vars->scene08_stairsOffset = -39;
+ } else {
+ g_vars->scene08_stairsVisible = true;
+ }
+
+ sc->getPictureObjectById(PIC_SC8_ARCADENOW, 0)->_flags &= 0xFFFB;
+
+ g_fp->_currentScene = oldsc;
+
+ g_fp->_floaters->init(g_fp->getGameLoaderGameVar()->getSubVarByName("SC_8"));
+ g_fp->_floaters->genFlies(sc, 100, 100, 0, 0);
+
+ g_fp->setArcadeOverlay(PIC_CSR_ARCADE3);
+}
+
+void scene08_setupMusic() {
+ if (g_fp->getObjectState(sO_TummyTrampie) == g_fp->getObjectEnumState(sO_TummyTrampie, sO_IsSleeping))
+ g_fp->playTrack(g_fp->getGameLoaderGameVar()->getSubVarByName("SC_8"), "MUSIC_ARCADE", 1);
+}
+
+int scene08_updateCursor() {
+ g_fp->updateCursorCommon();
+
+ if (g_vars->scene08_inArcade) {
+ if (g_vars->scene08_onBelly) {
+ if (g_fp->_objectIdAtCursor == PIC_SC8_LADDERD && g_fp->_cursorId == PIC_CSR_ITN)
+ g_fp->_cursorId = PIC_CSR_GOU;
+ } else {
+ g_fp->_cursorId = -1;
+ }
+ } else {
+ if (g_fp->_objectIdAtCursor == PIC_SC8_LADDERD && g_fp->_cursorId == PIC_CSR_ITN) {
+ if (g_fp->_aniMan2->_oy >= 520) {
+ if (g_fp->_aniMan2->_oy <= 750)
+ g_fp->_cursorId = PIC_CSR_GOU;
+ } else {
+ g_fp->_cursorId = PIC_CSR_GOD;
+ }
+ }
+ }
+
+ return g_fp->_cursorId;
+}
+
+void sceneHandler08_enterUp() {
+ g_fp->_currentScene->getPictureObjectById(PIC_SC8_LADDER, 0)->_flags &= 0xFFFB;
+
+ g_fp->_aniMan->changeStatics2(ST_MAN8_HANDSUP);
+ g_fp->_aniMan->setOXY(386, 236);
+ g_fp->_aniMan->_priority = 10;
+ g_fp->_aniMan->_flags = 4;
+
+ chainObjQueue(g_fp->_aniMan, QU_SC8_FINISH, 1);
+
+ g_vars->scene08_inAir = false;
+}
+
+void sceneHandler08_winArcade() {
+ if (g_vars->scene08_inArcade) {
+ g_vars->scene08_inArcade = false;
+ g_fp->_sceneRect.top = 0;
+ g_fp->_sceneRect.bottom = 600;
+
+ sceneHandler08_enterUp();
+ }
+}
+
+void sceneHandler08_hideLadder() {
+ g_fp->_currentScene->getPictureObjectById(PIC_SC8_LADDER_D, 0)->_flags &= 0xFFFB;
+}
+
+void sceneHandler08_arcadeNow() {
+ MovGraphLink *lnk = getCurrSceneSc2MotionController()->getLinkByName(sO_Stairway);
+
+ g_fp->setObjectState(sO_TummyTrampie, g_fp->getObjectEnumState(sO_TummyTrampie, sO_IsSleeping));
+
+ g_vars->scene08_batuta->changeStatics2(ST_BTT_SLEEPS);
+
+ if (lnk)
+ lnk->_flags |= 0x20000000;
+}
+
+void sceneHandler08_resumeFlight() {
+ g_vars->scene08_manOffsetY = 3;
+ g_vars->scene08_stairsOffset = -39;
+ g_vars->scene08_inAir = true;
+ g_vars->scene08_stairsVisible = false;
+}
+
+int sceneHandler08_calcOffset(int off, int flag) {
+ if (off > 0) {
+ if (flag)
+ return off * 31 / 10; // off * 3.1
+ else
+ return 5 * off;
+ } else {
+ return 5 * off;
+ }
+}
+
+void sceneHandler08_pushCallback(int *par) {
+ Common::Point point;
+
+ int y = g_fp->_aniMan->_oy + g_fp->_aniMan->getSomeXY(point)->y;
+
+ if (g_fp->_aniMan->_statics && g_fp->_aniMan->_statics->_staticsId == ST_MAN8_FLYDOWN)
+ y -= 25;
+
+ *par = (y - 703) / 10;
+ if (*par > 11) {
+ *par = 11;
+ g_vars->scene08_manOffsetY = 0;
+ }
+ if (*par >= 0)
+ g_vars->scene08_manOffsetY -= sceneHandler08_calcOffset(*par, g_vars->scene08_manOffsetY < 0);
+ else
+ *par = 0;
+}
+
+int sceneHandler08_updateScreenCallback() {
+ int res;
+
+ res = g_fp->drawArcadeOverlay(g_vars->scene08_inArcade);
+
+ if (!res)
+ g_fp->_updateScreenCallback = 0;
+
+ return res;
+}
+
+void sceneHandler08_startArcade() {
+ g_vars->scene08_inArcade = true;
+ g_vars->scene08_inAir = true;
+ g_vars->scene08_flyingUp = false;
+ g_vars->scene08_onBelly = false;
+
+ getGameLoaderInteractionController()->disableFlag24();
+ getCurrSceneSc2MotionController()->clearEnabled();
+
+ g_vars->scene08_batuta->stopAnim_maybe();
+
+ g_vars->scene08_vmyats->_statics = g_vars->scene08_vmyats->getStaticsById(ST_VMT_MIN);
+ g_vars->scene08_vmyats->setOXY(382, 703);
+ g_vars->scene08_vmyats->_priority = 29;
+ g_vars->scene08_vmyats->_callback2 = sceneHandler08_pushCallback;
+
+ g_fp->_aniMan = g_fp->_currentScene->getStaticANIObject1ById(ANI_MAN, -1);
+
+ g_vars->scene08_manOffsetY = 15;
+
+ g_fp->_currentScene->_y = 0;
+
+ g_fp->_updateScreenCallback = sceneHandler08_updateScreenCallback;
+}
+
+void sceneHandler08_airMoves() {
+ if (g_fp->_aniMan->isIdle() && !(g_fp->_aniMan->_flags & 0x100)) {
+ int x = g_fp->_aniMan->_ox;
+ int y = g_fp->_aniMan->_oy;
+ Common::Point point;
+
+ if (703 - g_fp->_aniMan->getSomeXY(point)->y - y < 150) {
+ if (g_fp->_aniMan->_statics) {
+ if (g_fp->_aniMan->_statics->_staticsId == ST_MAN8_FLYDOWN) {
+ y -= 25;
+
+ g_fp->_aniMan->setOXY(x, y);
+ }
+ }
+
+ g_fp->_aniMan->changeStatics2(ST_MAN8_STAND);
+ g_fp->_aniMan->setOXY(380, y);
+ g_fp->_aniMan->startAnim(MV_MAN8_JUMP, 0, -1);
+
+ } else if (g_fp->_aniMan->_statics) {
+ if (g_fp->_aniMan->_statics->_staticsId == ST_MAN8_FLYUP) {
+ g_fp->_aniMan->startAnim(MV_MAN8_DRYGUP, 0, -1);
+
+ } else if (g_fp->_aniMan->_statics->_staticsId == ST_MAN8_FLYDOWN) {
+ g_fp->_aniMan->startAnim(MV_MAN8_DRYGDOWN, 0, -1);
+ }
+ }
+ }
+}
+
+void sceneHandler08_finishArcade() {
+ g_vars->scene08_inArcade = false;
+
+ getGameLoaderInteractionController()->enableFlag24();
+ getCurrSceneSc2MotionController()->setEnabled();
+}
+
+void sceneHandler08_jumpOff(ExCommand *cmd) {
+ MessageQueue *mq = new MessageQueue(g_fp->_globalMessageQueueList->compact());
+
+ mq->addExCommandToEnd(cmd->createClone());
+ mq->setFlags(mq->getFlags() | 1);
+
+ g_fp->_globalMessageQueueList->addMessageQueue(mq);
+
+ g_fp->_aniMan->startAnim(MV_MAN8_JUMPOFF, mq->_id, -1);
+
+ sceneHandler08_finishArcade();
+}
+
+void sceneHandler08_standUp() {
+ chainQueue(QU_SC8_STANDUP, 1);
+ g_vars->scene08_onBelly = false;
+}
+
+void sceneHandler08_jumpLogic(ExCommand *cmd) {
+ if (g_fp->_currentScene->getPictureObjectIdAtPos(cmd->_sceneClickX, cmd->_sceneClickY) == PIC_SC8_LADDERD) {
+ sceneHandler08_jumpOff(cmd);
+
+ cmd->_messageKind = 0;
+ } else {
+ sceneHandler08_standUp();
+ }
+}
+
+void sceneHandler08_badLuck() {
+ g_fp->_currentScene->getPictureObjectById(PIC_SC8_LADDER, 0)->_flags &= 0xFFFB;
+
+ g_fp->_aniMan->changeStatics2(ST_MAN8_HANDSUP);
+ g_fp->_aniMan->setOXY(376, 280);
+ g_fp->_aniMan->_priority = 10;
+
+ MessageQueue *mq = new MessageQueue(g_fp->_globalMessageQueueList->compact());
+
+ ExCommand *ex = new ExCommand(g_fp->_aniMan->_id, 1, MV_MAN8_BADLUCK, 0, 0, 0, 1, 0, 0, 0);
+ ex->_excFlags |= 2;
+ ex->_keyCode = g_fp->_aniMan->_okeyCode;
+ mq->addExCommandToEnd(ex);
+
+ mq->setFlags(mq->getFlags() | 1);
+ mq->chain(0);
+
+ g_fp->setObjectState(sO_StairsUp_8, g_fp->getObjectEnumState(sO_StairsUp_8, sO_NotBroken));
+
+ g_vars->scene08_inAir = false;
+}
+
+void sceneHandler08_sitDown() {
+ g_fp->_aniMan->setOXY(380, g_fp->_aniMan->_oy);
+
+ g_fp->_aniMan->changeStatics2(ST_MAN8_FLYDOWN);
+ g_fp->_aniMan->startAnim(MV_MAN8_SITDOWN, 0, -1);
+
+ g_vars->scene08_vmyats->changeStatics2(ST_VMT_MIN);
+ g_vars->scene08_vmyats->hide();
+
+ g_vars->scene08_inAir = false;
+ g_vars->scene08_onBelly = true;
+}
+
+void sceneHandler08_calcFlight() {
+ Common::Point point;
+ int y = g_vars->scene08_manOffsetY + g_fp->_aniMan->_oy;
+
+ g_fp->_aniMan->setOXY(g_fp->_aniMan->_ox, y);
+
+ g_vars->scene08_manOffsetY += 2;
+
+ if (g_vars->scene08_manOffsetY < g_vars->scene08_stairsOffset)
+ g_vars->scene08_manOffsetY = g_vars->scene08_stairsOffset;
+
+ y = y + g_fp->_aniMan->getSomeXY(point)->y;
+
+ if (g_fp->_aniMan->_statics && g_fp->_aniMan->_statics->_staticsId == ST_MAN8_FLYDOWN)
+ y -= 25;
+
+ if (y <= g_vars->scene08_vmyats->_oy) {
+ g_vars->scene08_vmyats->hide();
+ } else {
+ g_vars->scene08_vmyats->show1(-1, -1, -1, 0);
+
+ if (!g_vars->scene08_vmyats->_movement)
+ g_vars->scene08_vmyats->startAnim(MV_VMT_DEF, 0, -1);
+ }
+
+ if (g_fp->_aniMan->_oy <= 280 && g_vars->scene08_stairsVisible
+ && g_fp->_aniMan->_statics && g_fp->_aniMan->_statics->_staticsId == ST_MAN8_HANDSUP) {
+ sceneHandler08_badLuck();
+ } else if (g_fp->_aniMan->_oy > 236 || g_vars->scene08_stairsVisible
+ || !g_fp->_aniMan->_statics || g_fp->_aniMan->_statics->_staticsId != ST_MAN8_HANDSUP) {
+ if (g_fp->_aniMan->_movement || g_fp->_aniMan->_oy < 660
+ || (g_vars->scene08_vmyats->_movement && g_vars->scene08_vmyats->_movement->_currDynamicPhaseIndex > 0)
+ || abs(g_vars->scene08_manOffsetY) > 2) {
+ if (g_vars->scene08_manOffsetY >= 0 && !g_fp->_aniMan->_movement) {
+ if (g_fp->_aniMan->_statics->_staticsId == ST_MAN8_HANDSUP)
+ g_fp->_aniMan->startAnim(MV_MAN8_HANDSDOWN, 0, -1);
+ else
+ g_fp->_aniMan->changeStatics2(ST_MAN8_FLYDOWN);
+ }
+
+ if (g_fp->_aniMan->_oy < 500 && !g_fp->_aniMan->_movement && g_fp->_aniMan->_statics->_staticsId == ST_MAN8_FLYUP && g_vars->scene08_manOffsetY < 0)
+ g_fp->_aniMan->startAnim(MV_MAN8_HANDSUP, 0, -1);
+ } else {
+ sceneHandler08_sitDown();
+ }
+ } else {
+ sceneHandler08_enterUp();
+ }
+}
+
+void sceneHandler08_checkEndArcade() {
+ if (g_vars->scene08_flyingUp) {
+ int x = g_fp->_aniMan->_ox;
+ int y = g_vars->scene08_manOffsetY + g_fp->_aniMan->_oy;
+
+ if (!((g_vars->scene08_manOffsetY + g_fp->_aniMan->_oy) % 3))
+ g_vars->scene08_manOffsetY--;
+
+ g_fp->_aniMan->setOXY(x, y);
+
+ if (y < 80) {
+ sceneHandler08_finishArcade();
+
+ ExCommand *ex = new ExCommand(SC_8, 17, 0, 0, 0, 0, 1, 0, 0, 0);
+ ex->_messageNum = 61;
+ ex->_excFlags |= 2;
+ ex->_keyCode = TrubaUp;
+
+ ex->postMessage();
+ }
+ }
+}
+
+int sceneHandler08(ExCommand *cmd) {
+ if (cmd->_messageKind != 17)
+ return 0;
+
+ switch (cmd->_messageNum) {
+ case MSG_CMN_WINARCADE:
+ sceneHandler08_winArcade();
+ break;
+
+ case MSG_SC8_ENTERUP:
+ sceneHandler08_enterUp();
+ break;
+
+ case MSG_SC8_HIDELADDER_D:
+ sceneHandler08_hideLadder();
+ break;
+
+ case MSG_SC8_STANDUP:
+ g_vars->scene08_manOffsetY = -10;
+ g_vars->scene08_vmyats->changeStatics2(ST_VMT_MIN);
+ g_vars->scene08_vmyats->setOXY(382, 703);
+ g_vars->scene08_vmyats->_priority = 29;
+ g_vars->scene08_vmyats->_callback2 = sceneHandler08_pushCallback;
+ g_vars->scene08_inAir = true;
+ break;
+
+ case MSG_SC8_ARCADENOW:
+ sceneHandler08_arcadeNow();
+ break;
+
+ case MSG_SC8_RESUMEFLIGHT:
+ sceneHandler08_resumeFlight();
+ break;
+
+ case MSG_SC8_GETHIMUP:
+ g_vars->scene08_manOffsetY = 0;
+ g_vars->scene08_flyingUp = true;
+ break;
+
+ case MSG_STARTARCADE:
+ sceneHandler08_startArcade();
+ break;
+
+ case 29:
+ if (g_vars->scene08_inArcade) {
+ if (g_vars->scene08_inAir) {
+ sceneHandler08_airMoves();
+ break;
+ }
+ if (g_vars->scene08_onBelly) {
+ sceneHandler08_jumpLogic(cmd);
+ break;
+ }
+ }
+ break;
+
+ case 33:
+ {
+ int res = 0;
+
+ if (g_fp->_aniMan2) {
+ if (g_vars->scene08_inArcade) {
+ int scHeight = g_fp->_sceneRect.bottom - g_fp->_sceneRect.top;
+
+ if (g_fp->_aniMan2->_oy < g_fp->_sceneRect.top + 200) {
+ g_fp->_sceneRect.top = g_fp->_aniMan2->_oy - 200;
+
+ if (g_fp->_sceneRect.top < 0)
+ g_fp->_sceneRect.top = 0;
+
+ g_fp->_sceneRect.bottom = scHeight + g_fp->_sceneRect.top;
+ }
+
+ if (g_fp->_aniMan2->_oy > g_fp->_sceneRect.bottom - 350) {
+ g_fp->_sceneRect.bottom = g_fp->_aniMan2->_oy + 350;
+ g_fp->_sceneRect.top = g_fp->_aniMan2->_oy + 350 - scHeight;
+ }
+ } else {
+ if (g_fp->_aniMan2->_ox < g_fp->_sceneRect.left + 200)
+ g_fp->_currentScene->_x = g_fp->_aniMan2->_ox - g_fp->_sceneRect.left - 300;
+
+ if (g_fp->_aniMan2->_ox > g_fp->_sceneRect.right - 200)
+ g_fp->_currentScene->_x = g_fp->_aniMan2->_ox - g_fp->_sceneRect.right + 300;
+
+ res = 1;
+ }
+ }
+
+ g_fp->_floaters->update();
+
+ if (g_vars->scene08_inArcade) {
+ if (g_vars->scene08_inAir)
+ sceneHandler08_calcFlight();
+ } else {
+ Movement *mov = g_fp->_aniMan->_movement;
+
+ if (mov) {
+ if (mov->_id == MV_MAN_TOLADDERD && mov->_currDynamicPhaseIndex == 8)
+ g_fp->_aniMan->_priority = 2;
+
+ if (mov && mov->_id == MV_MAN_FROMLADDERUP && mov->_currDynamicPhaseIndex == 13)
+ g_fp->_aniMan->_priority = 20;
+ }
+
+ g_fp->_behaviorManager->updateBehaviors();
+ g_fp->startSceneTrack();
+ }
+
+ if (g_vars->scene08_flyingUp)
+ sceneHandler08_checkEndArcade();
+
+ if (g_vars->scene08_snoringCountdown > 0) {
+ g_vars->scene08_snoringCountdown--;
+
+ if (!g_vars->scene08_snoringCountdown) {
+ g_fp->playSound(SND_8_014, 0);
+
+ g_vars->scene08_snoringCountdown = 71;
+ }
+ }
+
+ return res;
+ }
+ }
+
+ return 0;
+}
+
+} // End of namespace Fullpipe
diff --git a/engines/fullpipe/scenes/scene10.cpp b/engines/fullpipe/scenes/scene10.cpp
new file mode 100644
index 0000000000..9c00902bba
--- /dev/null
+++ b/engines/fullpipe/scenes/scene10.cpp
@@ -0,0 +1,220 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "fullpipe/fullpipe.h"
+
+#include "fullpipe/objectnames.h"
+#include "fullpipe/constants.h"
+
+#include "fullpipe/gameloader.h"
+#include "fullpipe/motion.h"
+#include "fullpipe/scenes.h"
+#include "fullpipe/statics.h"
+
+#include "fullpipe/behavior.h"
+#include "fullpipe/interaction.h"
+
+namespace Fullpipe {
+
+void scene10_initScene(Scene *sc) {
+ g_vars->scene10_gum = sc->getStaticANIObject1ById(ANI_GUM, -1);
+ g_vars->scene10_packet = sc->getStaticANIObject1ById(ANI_PACHKA, -1);
+ g_vars->scene10_packet2 = sc->getStaticANIObject1ById(ANI_PACHKA2, -1);
+ g_vars->scene10_inflater = sc->getStaticANIObject1ById(ANI_NADUVATEL, -1);
+ g_vars->scene10_ladder = sc->getPictureObjectById(PIC_SC10_LADDER, 0);
+
+ g_fp->lift_setButton(sO_Level1, ST_LBN_1N);
+ g_fp->lift_init(sc, QU_SC10_ENTERLIFT, QU_SC10_EXITLIFT);
+
+ if (g_fp->getObjectState(sO_Inflater) == g_fp->getObjectEnumState(sO_Inflater, sO_WithGum)) {
+ g_vars->scene10_hasGum = 1;
+ } else {
+ g_vars->scene10_hasGum = 0;
+ g_vars->scene10_gum->hide();
+ }
+}
+
+bool sceneHandler10_inflaterIsBlind() {
+ return g_vars->scene10_inflater->_movement
+ && g_vars->scene10_inflater->_movement->_id == MV_NDV_BLOW2
+ && g_vars->scene10_inflater->_movement->_currDynamicPhaseIndex < 42;
+}
+
+int scene10_updateCursor() {
+ g_fp->updateCursorCommon();
+
+ if (g_fp->_objectIdAtCursor == ANI_PACHKA || g_fp->_objectIdAtCursor == ANI_GUM) {
+ if (g_fp->_cursorId == PIC_CSR_ITN) {
+ if (g_vars->scene10_hasGum)
+ g_fp->_cursorId = (sceneHandler10_inflaterIsBlind() != 0) ? PIC_CSR_ITN_RED : PIC_CSR_ITN_GREEN;
+ else
+ g_fp->_cursorId = PIC_CSR_DEFAULT;
+ }
+ }
+
+ return g_fp->_cursorId;
+}
+
+void sceneHandler10_clickGum() {
+ if (g_vars->scene10_hasGum) {
+ if (sceneHandler10_inflaterIsBlind()) {
+ if (g_vars->scene10_hasGum) {
+ int x = g_vars->scene10_gum->_ox - 139;
+ int y = g_vars->scene10_gum->_oy - 48;
+
+ if (abs(x - g_fp->_aniMan->_ox) > 1 || abs(y - g_fp->_aniMan->_oy) > 1) {
+ MessageQueue *mq = getCurrSceneSc2MotionController()->method34(g_fp->_aniMan, x, y, 1, ST_MAN_RIGHT);
+ if (mq) {
+ ExCommand *ex = new ExCommand(0, 17, MSG_SC10_CLICKGUM, 0, 0, 0, 1, 0, 0, 0);
+ ex->_excFlags = 2;
+ mq->addExCommandToEnd(ex);
+
+ postExCommand(g_fp->_aniMan->_id, 2, x, y, 0, -1);
+ }
+ } else {
+ g_vars->scene10_hasGum = 0;
+
+ chainQueue(QU_SC10_TAKEGUM, 1);
+ }
+ }
+ } else {
+ g_vars->scene10_inflater->changeStatics2(ST_NDV_SIT);
+
+ if (g_fp->getObjectState(sO_Inflater) == g_fp->getObjectEnumState(sO_Inflater, sO_WithGum))
+ g_vars->scene10_inflater->startAnim(MV_NDV_DENIES, 0, -1);
+ else
+ g_vars->scene10_inflater->startAnim(MV_NDV_DENY_NOGUM, 0, -1);
+ }
+ }
+}
+
+void sceneHandler10_hideGum() {
+ g_vars->scene10_gum->hide();
+ g_vars->scene10_packet->hide();
+ g_vars->scene10_packet2->hide();
+}
+
+void sceneHandler10_showGum() {
+ if (g_vars->scene10_hasGum)
+ g_vars->scene10_gum->show1(-1, -1, -1, 0);
+
+ g_vars->scene10_packet->show1(-1, -1, -1, 0);
+ g_vars->scene10_packet2->show1(-1, -1, -1, 0);
+}
+
+
+int sceneHandler10(ExCommand *ex) {
+ if (ex->_messageKind != 17)
+ return 0;
+
+ switch(ex->_messageNum) {
+ case MSG_LIFT_CLOSEDOOR:
+ g_fp->lift_closedoorSeq();
+ break;
+
+ case MSG_LIFT_EXITLIFT:
+ g_fp->lift_exitSeq(ex);
+ break;
+
+ case MSG_LIFT_STARTEXITQUEUE:
+ g_fp->lift_startExitQueue();
+ break;
+
+ case MSG_LIFT_CLICKBUTTON:
+ g_fp->lift_clickButton();
+ break;
+
+ case MSG_SC10_LADDERTOBACK:
+ g_vars->scene10_ladder->_priority = 49;
+ break;
+
+ case MSG_SC10_LADDERTOFORE:
+ g_vars->scene10_ladder->_priority = 0;
+ break;
+
+ case MSG_LIFT_GO:
+ g_fp->lift_goAnimation();
+ break;
+
+ case MSG_SC10_CLICKGUM:
+ sceneHandler10_clickGum();
+
+ ex->_messageKind = 0;
+ break;
+
+ case MSG_SC10_HIDEGUM:
+ sceneHandler10_hideGum();
+ break;
+
+ case MSG_SC10_SHOWGUM:
+ sceneHandler10_showGum();
+ break;
+
+ case 64:
+ g_fp->lift_sub05(ex);
+ break;
+
+ case 29:
+ {
+ if (g_fp->_currentScene->getPictureObjectIdAtPos(ex->_sceneClickX, ex->_sceneClickY) == PIC_SC10_LADDER) {
+ handleObjectInteraction(g_fp->_aniMan, g_fp->_currentScene->getPictureObjectById(PIC_SC10_DTRUBA, 0), ex->_keyCode);
+ ex->_messageKind = 0;
+
+ return 0;
+ }
+
+ StaticANIObject *ani = g_fp->_currentScene->getStaticANIObjectAtPos(ex->_sceneClickX, ex->_sceneClickY);
+
+ if (ani && ani->_id == ANI_LIFTBUTTON) {
+ g_fp->lift_sub1(ani);
+ ex->_messageKind = 0;
+
+ return 0;
+ }
+ }
+ break;
+
+ case 33:
+ {
+ int res = 0;
+
+ if (g_fp->_aniMan2) {
+ if (g_fp->_aniMan2->_ox < g_fp->_sceneRect.left + 200)
+ g_fp->_currentScene->_x = g_fp->_aniMan2->_ox - g_fp->_sceneRect.left - 300;
+
+ if (g_fp->_aniMan2->_ox > g_fp->_sceneRect.right - 200)
+ g_fp->_currentScene->_x = g_fp->_aniMan2->_ox - g_fp->_sceneRect.right + 300;
+
+ res = 1;
+ }
+
+ g_fp->_behaviorManager->updateBehaviors();
+ g_fp->startSceneTrack();
+
+ return res;
+ }
+ }
+
+ return 0;
+}
+
+} // End of namespace Fullpipe
diff --git a/engines/fullpipe/scenes/scene11.cpp b/engines/fullpipe/scenes/scene11.cpp
new file mode 100644
index 0000000000..e7ed947a00
--- /dev/null
+++ b/engines/fullpipe/scenes/scene11.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 "fullpipe/fullpipe.h"
+
+#include "fullpipe/objectnames.h"
+#include "fullpipe/constants.h"
+
+#include "fullpipe/gameloader.h"
+#include "fullpipe/motion.h"
+#include "fullpipe/scenes.h"
+#include "fullpipe/statics.h"
+
+#include "fullpipe/interaction.h"
+#include "fullpipe/behavior.h"
+
+
+namespace Fullpipe {
+
+void scene11_dudeSwingCallback(int *arg) {
+ int oldarg = *arg;
+
+ *arg = 45 - (int)(g_vars->scene11_swingAngle * -29.66666666666666);
+
+ if (*arg < 1)
+ *arg = 1;
+
+ if (*arg > 90)
+ *arg = 90;
+
+ g_vars->scene11_swingAngleDiff = (g_vars->scene11_swingAngle - g_vars->scene11_swingOldAngle) * -490.0000000000001;
+ g_vars->scene11_swingSpeed = g_vars->scene11_swingAngleDiff * 0.0042 + g_vars->scene11_swingSpeed - g_vars->scene11_swingInertia * (g_vars->scene11_swingAngleDiff * 0.0042 + g_vars->scene11_swingSpeed);
+ g_vars->scene11_swingAngle = g_vars->scene11_swingSpeed * 0.0042 + g_vars->scene11_swingAngle;
+
+ if (g_vars->scene11_swingAngle < -1.5) {
+ g_vars->scene11_swingAngle = -1.5; //1.0004882812500000;
+ g_vars->scene11_swingSpeed = 0.0;
+ g_vars->scene11_swingAngleDiff = 0.0;
+ }
+
+ if (g_vars->scene11_swingAngle > 1.5) {
+ g_vars->scene11_swingAngle = 1.5; //1.9990234375;
+ g_vars->scene11_swingSpeed = 0.0;
+ g_vars->scene11_swingAngleDiff = 0.0;
+ }
+
+ if (g_vars->scene11_swingMaxAngle == *arg && 0.0 != g_vars->scene11_swingSpeed && fabs(g_vars->scene11_swingSpeed) < 2.5) {
+ g_vars->scene11_swingSpeed = 0.0;
+ g_vars->scene11_swingAngleDiff = 0.0;
+ g_vars->scene11_swingAngle = g_vars->scene11_swingOldAngle;
+ }
+
+ g_vars->scene11_swingCounter++;
+
+ if (g_vars->scene11_arcadeIsOn) {
+ if (g_vars->scene11_hintCounter <= 720) {
+ g_vars->scene11_hintCounter++;
+
+ if (g_vars->scene11_hintCounter == 720)
+ g_vars->scene11_hint->_flags |= 4;
+ }
+ }
+
+ if ((oldarg >= 45) != (*arg >= 45) && g_vars->scene11_arcadeIsOn) {
+ if (oldarg >= *arg)
+ g_fp->playSound(SND_11_031, 0);
+ else
+ g_fp->playSound(SND_11_020, 0);
+ }
+}
+
+void scene11_setupMusic() {
+ if (g_fp->getObjectState(sO_DudeHasJumped) == g_fp->getObjectEnumState(sO_DudeHasJumped, sO_Yes))
+ g_fp->playTrack(g_fp->getGameLoaderGameVar()->getSubVarByName("SC_11"), "MUSIC2", 1);
+}
+
+void scene11_initScene(Scene *sc) {
+ g_vars->scene11_swingie = sc->getStaticANIObject1ById(ANI_SWINGER, -1);
+ g_vars->scene11_boots = sc->getStaticANIObject1ById(ANI_BOOTS_11, -1);
+ g_vars->scene11_mgm.clear();
+ g_vars->scene11_dudeOnSwing = sc->getStaticANIObject1ById(ANI_MAN11, -1);
+ g_vars->scene11_dudeOnSwing->_callback2 = scene11_dudeSwingCallback;
+ g_vars->scene11_dudeOnSwing = sc->getStaticANIObject1ById(ANI_KACHELI, -1);
+ g_vars->scene11_dudeOnSwing->_callback2 = scene11_dudeSwingCallback;
+ g_vars->scene11_hint = sc->getPictureObjectById(PIC_SC11_HINT, 0);
+ g_vars->scene11_hint->_flags &= 0xFFFB;
+
+ g_vars->scene11_arcadeIsOn = false;
+ g_vars->scene11_scrollIsEnabled = false;
+ g_vars->scene11_scrollIsMaximized = false;
+ g_vars->scene11_hintCounter = 0;
+ g_vars->scene11_swingieScreenEdge = 0;
+ g_vars->scene11_crySound = 0;
+ g_vars->scene11_swingAngle = 0.0;
+ g_vars->scene11_swingOldAngle = 0.0;
+ g_vars->scene11_swingSpeed = 0.0;
+ g_vars->scene11_swingAngleDiff = 0.0;
+ g_vars->scene11_swingInertia = 1.28; //1.9849218750000000;
+ g_vars->scene11_swingCounter = 0;
+ g_vars->scene11_swingCounterPrevTurn = 0;
+ g_vars->scene11_swingDirection = 0;
+ g_vars->scene11_swingDirectionPrevTurn = 0;
+
+ Scene *oldsc = g_fp->_currentScene;
+
+ g_fp->_currentScene = sc;
+
+ int swingie = g_fp->getObjectState(sO_Swingie);
+
+ if (swingie == g_fp->getObjectEnumState(sO_Swingie, sO_IsSwinging)
+ || swingie == g_fp->getObjectEnumState(sO_Swingie, sO_IsSwingingWithBoot)) {
+ g_vars->scene11_swingIsSwinging = true;
+ g_vars->scene11_swingieStands = false;
+
+ getCurrSceneSc2MotionController()->enableLinks(sO_CloseThing1, 1);
+ getCurrSceneSc2MotionController()->enableLinks(sO_CloseThing2, 1);
+ getCurrSceneSc2MotionController()->enableLinks(sO_CloseThing3, 0);
+
+ ((MctlCompound *)getCurrSceneSc2MotionController())->replaceNodeX(805, 905);
+
+ getSc2MctlCompoundBySceneId(sc->_sceneId)->replaceNodeX(303, 353);
+ } else if (swingie == g_fp->getObjectEnumState(sO_Swingie, sO_IsStandingInBoots)
+ || swingie == g_fp->getObjectEnumState(sO_Swingie, sO_IsStandingInCorner)) {
+ g_vars->scene11_swingIsSwinging = false;
+ g_vars->scene11_swingieStands = true;
+
+ g_vars->scene11_swingie->changeStatics2(ST_SWR_STAND3);
+
+ getCurrSceneSc2MotionController()->enableLinks(sO_CloseThing1, 0);
+ getCurrSceneSc2MotionController()->enableLinks(sO_CloseThing2, 1);
+ getCurrSceneSc2MotionController()->enableLinks(sO_CloseThing3, 0);
+
+ ((MctlCompound *)getCurrSceneSc2MotionController())->replaceNodeX(905, 805);
+ } else {
+ g_vars->scene11_swingIsSwinging = false;
+ g_vars->scene11_swingieStands = false;
+
+ if (swingie == g_fp->getObjectEnumState(sO_Swingie, sO_IsSitting)) {
+ g_vars->scene11_swingie->_movement = 0;
+ g_vars->scene11_swingie->_statics = g_vars->scene11_swingie->getStaticsById(ST_SWR_SIT);
+ g_vars->scene11_swingie->setOXY(144, 389);
+
+ getCurrSceneSc2MotionController()->enableLinks(sO_CloseThing1, 0);
+ getCurrSceneSc2MotionController()->enableLinks(sO_CloseThing2, 0);
+ getCurrSceneSc2MotionController()->enableLinks(sO_CloseThing3, 1);
+ } else {
+ g_vars->scene11_swingie->_movement = 0;
+ g_vars->scene11_swingie->_statics = g_vars->scene11_swingie->getStaticsById(ST_SWR_SITBALD);
+ g_vars->scene11_swingie->setOXY(144, 415);
+
+ getCurrSceneSc2MotionController()->enableLinks(sO_CloseThing1, 0);
+ getCurrSceneSc2MotionController()->enableLinks(sO_CloseThing2, 0);
+ getCurrSceneSc2MotionController()->enableLinks(sO_CloseThing3, 1);
+ }
+ }
+
+ if (!g_vars->scene11_swingIsSwinging) {
+ g_vars->scene11_dudeOnSwing->changeStatics2(ST_KCH_STATIC);
+ g_vars->scene11_dudeOnSwing->setOXY(691, 371);
+ g_vars->scene11_dudeOnSwing->_priority = 20;
+
+ g_vars->scene11_dudeOnSwing->_flags |= 4;
+ }
+
+ g_fp->_currentScene = oldsc;
+
+ g_fp->initArcadeKeys("SC_11");
+ g_fp->setArcadeOverlay(PIC_CSR_ARCADE5);
+}
+
+void sceneHandler11_restartMan() {
+ chainObjQueue(0, QU_SC11_RESTARTMAN, 1);
+
+ getGameLoaderInteractionController()->enableFlag24();
+ getCurrSceneSc2MotionController()->setEnabled();
+
+ g_vars->scene11_scrollIsEnabled = false;
+}
+
+void sceneHandler11_hitMan() {
+ if (g_fp->_aniMan->_ox > 345 && g_fp->_aniMan->_ox < 355) {
+ g_fp->_aniMan->changeStatics2(ST_MAN_RIGHT);
+
+ MessageQueue *mq = new MessageQueue(g_fp->_currentScene->getMessageQueueById(QU_SC11_MANFALL), 0, 0);
+
+ mq->setFlags(mq->getFlags() | 1);
+ if (!mq->chain(g_fp->_aniMan))
+ delete mq;
+
+ getCurrSceneSc2MotionController()->replaceNodeX(353, 303);
+ }
+}
+
+int scene11_updateCursor() {
+ g_fp->updateCursorCommon();
+
+ if (g_vars->scene11_arcadeIsOn) {
+ if (g_fp->_cursorId != PIC_CSR_DEFAULT_INV && g_fp->_cursorId != PIC_CSR_ITN_INV)
+ g_fp->_cursorId = -1;
+ } else if (g_vars->scene11_swingie == g_fp->_objectAtCursor && g_fp->_inventory->getSelectedItemId() == ANI_INV_BOOT)
+ g_fp->_cursorId = PIC_CSR_ITN_INV;
+
+ return g_fp->_cursorId;
+}
+
+int sceneHandler11_updateScreenCallback() {
+ int res = g_fp->drawArcadeOverlay(g_vars->scene11_arcadeIsOn);
+
+ if (!res)
+ g_fp->_updateScreenCallback = 0;
+
+ return res;
+}
+
+void sceneHandler11_manToSwing() {
+ g_vars->scene11_arcadeIsOn = true;
+
+ getCurrSceneSc2MotionController()->clearEnabled();
+ getGameLoaderInteractionController()->disableFlag24();
+
+ g_fp->_aniMan2->hide();
+
+ g_vars->scene11_swingCounter = 0;
+ g_vars->scene11_swingInertia = 1.28; //1.9849218;
+
+ g_vars->scene11_dudeOnSwing->_flags &= 0xFFFB;
+ g_vars->scene11_dudeOnSwing = g_fp->_currentScene->getStaticANIObject1ById(ANI_MAN11, -1);
+ g_vars->scene11_dudeOnSwing->_statics = g_vars->scene11_dudeOnSwing->getStaticsById(ST_MAN11_EMPTY);
+ g_vars->scene11_dudeOnSwing->_movement = 0;
+ g_vars->scene11_dudeOnSwing->show1(690, 215, MV_MAN11_SWING_0, 0);
+ g_vars->scene11_dudeOnSwing->_priority = 20;
+ g_vars->scene11_dudeOnSwing->startAnim(MV_MAN11_SWING_0, 0, -1);
+ g_vars->scene11_dudeOnSwing->_movement->setDynamicPhaseIndex(45);
+
+ g_vars->scene11_mgm.addItem(g_fp->_aniMan->_id);
+
+ g_fp->_currentScene->_x = 1400 - g_fp->_sceneRect.right;
+
+ g_vars->scene11_scrollIsEnabled = true;
+ g_fp->_updateScreenCallback = sceneHandler11_updateScreenCallback;
+}
+
+void sceneHandler11_putABoot() {
+ if (g_vars->scene11_boots->_flags & 4) {
+ if (g_vars->scene11_boots->_statics->_staticsId == ST_BTS11_ONE)
+ chainObjQueue(0, QU_SC11_PUTBOOT2, 1);
+ } else {
+ chainObjQueue(0, QU_SC11_PUTBOOT1, 1);
+ }
+}
+
+void sceneHandler11_putBoot() {
+ if (abs(353 - g_fp->_aniMan->_ox) > 1 || abs(498 - g_fp->_aniMan->_oy) > 1
+ || g_fp->_aniMan->_movement || g_fp->_aniMan->_statics->_staticsId != ST_MAN_RIGHT) {
+ MessageQueue *mq = getCurrSceneSc2MotionController()->method34(g_fp->_aniMan, 353, 498, 1, ST_MAN_RIGHT);
+
+ if (mq) {
+ ExCommand *ex = new ExCommand(0, 17, MSG_SC11_PUTBOOT, 0, 0, 0, 1, 0, 0, 0);
+ ex->_excFlags |= 3;
+
+ mq->addExCommandToEnd(ex);
+
+ postExCommand(g_fp->_aniMan->_id, 2, 353, 498, 0, -1);
+ }
+ } else {
+ sceneHandler11_putABoot();
+ }
+}
+
+void sceneHandler11_showSwing() {
+ g_vars->scene11_dudeOnSwing = g_fp->_currentScene->getStaticANIObject1ById(ANI_KACHELI, -1);
+ g_vars->scene11_dudeOnSwing->_statics = g_vars->scene11_dudeOnSwing->getStaticsById(ST_KCH_0);
+ g_vars->scene11_dudeOnSwing->_movement = 0;
+ g_vars->scene11_dudeOnSwing->show1(691, 371, MV_KCH_START, 0);
+ g_vars->scene11_dudeOnSwing->_priority = 20;
+}
+
+void sceneHandler11_jumpFromSwing() {
+ g_vars->scene11_arcadeIsOn = false;
+ g_vars->scene11_hint->_flags &= 0xFFFB;
+ g_vars->scene11_scrollIsEnabled = false;
+
+ getCurrSceneSc2MotionController()->setEnabled();
+ getGameLoaderInteractionController()->enableFlag24();
+
+ g_vars->scene11_swingOldAngle = 0.0;
+ g_vars->scene11_swingAngleDiff = 0.0;
+ g_vars->scene11_swingSpeed = 0.0;
+ g_vars->scene11_swingAngle = 0.0;
+
+ g_vars->scene11_dudeOnSwing = g_fp->_currentScene->getStaticANIObject1ById(ANI_MAN11, -1);
+ g_vars->scene11_dudeOnSwing->_flags &= 0xFFFB;
+ g_vars->scene11_dudeOnSwing = g_fp->_currentScene->getStaticANIObject1ById(ANI_KACHELI, -1);
+ g_vars->scene11_dudeOnSwing->changeStatics2(ST_KCH_STATIC);
+ g_vars->scene11_dudeOnSwing->setOXY(691, 371);
+ g_vars->scene11_dudeOnSwing->_priority = 20;
+ g_vars->scene11_dudeOnSwing->_flags |= 4;
+
+ MessageQueue *mq = new MessageQueue(g_fp->_globalMessageQueueList->compact());
+ ExCommand *ex = new ExCommand(g_fp->_aniMan->_id, 34, 256, 0, 0, 0, 1, 0, 0, 0);
+ ex->_field_14 = 256;
+ ex->_messageNum = 0;
+ ex->_excFlags |= 3;
+ mq->addExCommandToEnd(ex);
+ mq->setFlags(mq->getFlags() | 1);
+
+ g_fp->_globalMessageQueueList->addMessageQueue(mq);
+
+ g_fp->_aniMan->_flags |= 0x104;
+ g_fp->_aniMan->changeStatics2(ST_MAN11_SWING);
+ g_fp->_aniMan->setOXY(685, 373);
+ g_fp->_aniMan->startAnim(MV_MAN11_JUMPFROMSWING, mq->_id, -1);
+
+ g_fp->_aniMan2 = g_fp->_aniMan;
+}
+
+void sceneHandler11_swing0() {
+ g_vars->scene11_dudeOnSwing->_statics = g_vars->scene11_dudeOnSwing->getStaticsById(ST_MAN11_EMPTY);
+ g_vars->scene11_dudeOnSwing->_movement = 0;
+ g_vars->scene11_dudeOnSwing->show1(690, 215, MV_MAN11_SWING_0, 0);
+ g_vars->scene11_dudeOnSwing->startAnim(MV_MAN11_SWING_0, 0, -1);
+ g_vars->scene11_dudeOnSwing->_movement->setDynamicPhaseIndex(g_vars->scene11_dudeOnSwing->_movement->_currDynamicPhaseIndex);
+
+ g_vars->scene11_swingDirection = 0;
+ g_vars->scene11_swingMaxAngle = 45;
+ g_vars->scene11_swingOldAngle = 0.0;
+}
+
+void sceneHandler11_swing1() {
+ g_vars->scene11_dudeOnSwing->_statics = g_vars->scene11_dudeOnSwing->getStaticsById(ST_MAN11_EMPTY);
+ g_vars->scene11_dudeOnSwing->_movement = 0;
+ g_vars->scene11_dudeOnSwing->show1(690, 215, MV_MAN11_SWING_1, 0);
+ g_vars->scene11_dudeOnSwing->startAnim(MV_MAN11_SWING_1, 0, -1);
+ g_vars->scene11_dudeOnSwing->_movement->setDynamicPhaseIndex(g_vars->scene11_dudeOnSwing->_movement->_currDynamicPhaseIndex);
+
+ g_vars->scene11_swingDirection = 1;
+ g_vars->scene11_swingMaxAngle = 42;
+ g_vars->scene11_swingOldAngle = -(fabs(g_vars->scene11_swingAngle) * 0.075 + 0.12);
+}
+
+void sceneHandler11_swing2() {
+ g_vars->scene11_dudeOnSwing->_statics = g_vars->scene11_dudeOnSwing->getStaticsById(ST_MAN11_EMPTY);
+ g_vars->scene11_dudeOnSwing->_movement = 0;
+ g_vars->scene11_dudeOnSwing->show1(690, 215, MV_MAN11_SWING_2, 0);
+ g_vars->scene11_dudeOnSwing->startAnim(MV_MAN11_SWING_2, 0, -1);
+ g_vars->scene11_dudeOnSwing->_movement->setDynamicPhaseIndex(g_vars->scene11_dudeOnSwing->_movement->_currDynamicPhaseIndex);
+
+ g_vars->scene11_swingDirection = 2;
+ g_vars->scene11_swingMaxAngle = 48;
+ g_vars->scene11_swingOldAngle = fabs(g_vars->scene11_swingAngle) * 0.075 + 0.12;
+}
+
+void sceneHandler11_emptySwing() {
+ if (g_vars->scene11_swingDirection)
+ sceneHandler11_swing0();
+
+ g_vars->scene11_dudeOnSwing->stopAnim_maybe();
+ g_vars->scene11_dudeOnSwing->hide();
+ g_vars->scene11_dudeOnSwing = g_fp->_currentScene->getStaticANIObject1ById(ANI_KACHELI, -1);
+ g_vars->scene11_dudeOnSwing->show1(-1, -1, -1, 0);
+ g_vars->scene11_dudeOnSwing->changeStatics2(ST_KCH_EMPTY);
+ g_vars->scene11_dudeOnSwing->startAnim(MV_KCH_MOVE2, 0, -1);
+ g_vars->scene11_dudeOnSwing->_movement->setDynamicPhaseIndex(g_vars->scene11_dudeOnSwing->_movement->_currDynamicPhaseIndex);
+
+ g_vars->scene11_swingInertia = 0.03; //1.9881250;
+}
+
+void sceneHandler11_jumpHitAndWin() {
+ MGMInfo mgminfo;
+
+ sceneHandler11_emptySwing();
+
+ g_fp->_aniMan->show1(690 - (int)(sin(g_vars->scene11_swingAngle) * -267.0), 215 - (int)(cos(g_vars->scene11_swingAngle) * -267.0),
+ MV_MAN11_JUMPHIT, 0);
+ g_fp->_aniMan->_priority = 10;
+
+ mgminfo.field_1C = 10;
+ mgminfo.ani = g_fp->_aniMan;
+ mgminfo.staticsId2 = ST_MAN_1PIX;
+ mgminfo.x1 = 1400;
+ mgminfo.y1 = 0;
+ mgminfo.field_10 = 1;
+ mgminfo.flags = 66;
+ mgminfo.movementId = MV_MAN11_JUMPHIT;
+
+ MessageQueue *mq = g_vars->scene11_mgm.genMovement(&mgminfo);
+
+ if (mq) {
+ g_vars->scene11_crySound = SND_11_024;
+ ExCommand *ex = new ExCommand(ANI_MAN, 2, 36, 0, 0, 0, 1, 0, 0, 0);
+ ex->_keyCode = -1;
+ ex->_excFlags = 2;
+
+ mq->addExCommandToEnd(ex);
+
+ ex = new ExCommand(SC_11, 17, 61, 0, 0, 0, 1, 0, 0, 0);
+ ex->_keyCode = TrubaRight;
+ ex->_excFlags = 3;
+
+ mq->addExCommandToEnd(ex);
+
+ if (!mq->chain(g_fp->_aniMan))
+ delete mq;
+
+
+ if (g_fp->getObjectState(sO_Swingie) == g_fp->getObjectEnumState(sO_Swingie, sO_IsStandingInCorner))
+ g_fp->setObjectState(sO_Swingie, g_fp->getObjectEnumState(sO_Swingie, sO_IsSitting));
+
+ g_fp->setObjectState(sO_DudeHasJumped, g_fp->getObjectEnumState(sO_DudeHasJumped, sO_Yes));
+ }
+}
+
+void sceneHandler11_jumpOver(double angle) {
+ MGMInfo mgminfo;
+
+ sceneHandler11_emptySwing();
+
+ g_fp->_aniMan->show1(690 - (int)(sin(g_vars->scene11_swingAngle) * -267.0), 215 - (int)(cos(g_vars->scene11_swingAngle) * -267.0),
+ MV_MAN11_JUMPOVER, 0);
+ g_fp->_aniMan->_priority = 0;
+
+ mgminfo.staticsId2 = ST_MAN_1PIX;
+ mgminfo.ani = g_fp->_aniMan;
+ mgminfo.x1 = 1163;
+ mgminfo.y1 = 837 - (int)(angle * 153.0);
+ mgminfo.field_1C = 0;
+ mgminfo.field_10 = 1;
+ mgminfo.flags = 78;
+ mgminfo.movementId = MV_MAN11_JUMPOVER;
+
+ MessageQueue *mq = g_vars->scene11_mgm.genMovement(&mgminfo);
+
+ if (mq) {
+ g_vars->scene11_crySound = SND_11_022;
+
+ ExCommand *ex = new ExCommand(0, 17, MSG_SC11_RESTARTMAN, 0, 0, 0, 1, 0, 0, 0);
+ ex->_excFlags = 2;
+
+ mq->addExCommandToEnd(ex);
+
+ if (!mq->chain(g_fp->_aniMan))
+ delete mq;
+ }
+}
+
+void sceneHandler11_jumpHit(double angle) {
+ MGMInfo mgminfo;
+
+ sceneHandler11_emptySwing();
+
+ if (angle >= 0.0) {
+ if (angle > 1.0)
+ angle = 1.0;
+ } else {
+ angle = 0.0;
+ }
+
+ g_fp->_aniMan->show1(690 - (int)(sin(g_vars->scene11_swingAngle) * -267.0), 215 - (int)(cos(g_vars->scene11_swingAngle) * -267.0),
+ MV_MAN11_JUMPOVER, 0);
+ g_fp->_aniMan->_priority = 0;
+
+ mgminfo.staticsId2 = ST_MAN_1PIX;
+ mgminfo.ani = g_fp->_aniMan;
+ mgminfo.x1 = 1017 - (int)(angle * -214.0);
+ mgminfo.y1 = 700;
+ mgminfo.field_1C = 0;
+ mgminfo.field_10 = 1;
+ mgminfo.flags = 78;
+ mgminfo.movementId = MV_MAN11_JUMPHIT;
+
+ MessageQueue *mq = g_vars->scene11_mgm.genMovement(&mgminfo);
+
+ if (mq) {
+ g_vars->scene11_crySound = SND_11_022;
+
+ ExCommand *ex = new ExCommand(0, 17, MSG_SC11_RESTARTMAN, 0, 0, 0, 1, 0, 0, 0);
+ ex->_excFlags = 2;
+
+ mq->addExCommandToEnd(ex);
+
+ if (!mq->chain(g_fp->_aniMan))
+ delete mq;
+
+ }
+}
+
+void sceneHandler11_swingLogic() {
+ if (g_vars->scene11_dudeOnSwing->_movement) {
+ int ph = g_vars->scene11_dudeOnSwing->_movement->_currDynamicPhaseIndex;
+ if (ph > 53 && ph < 90) {
+ if (ph < 70 && g_vars->scene11_swingSpeed >= 22.0) {
+ sceneHandler11_jumpOver((double)ph * 0.01428571428571429); // = 1 / 70
+ } else if (ph <= 80 && g_vars->scene11_swingSpeed >= 22.0) {
+ sceneHandler11_jumpHitAndWin();
+ } else {
+ sceneHandler11_jumpHit((double)ph * g_vars->scene11_swingSpeed * 0.0006493506493506494); // = 1/1540
+ }
+
+ g_vars->scene11_arcadeIsOn = false;
+ g_vars->scene11_hint->_flags &= 0xFFFB;
+ return;
+ }
+
+ if (ph > 38 && ph < 53 && fabs(g_vars->scene11_swingSpeed) <= 5.0)
+ sceneHandler11_jumpFromSwing();
+ }
+}
+
+void sceneHandler11_setSwingDirection() {
+ if (g_vars->scene11_swingDirection == 2)
+ g_vars->scene11_swingDirectionPrevTurn = 1;
+ else if (g_vars->scene11_swingDirection == 1)
+ g_vars->scene11_swingDirectionPrevTurn = 2;
+ else
+ g_vars->scene11_swingDirectionPrevTurn = (g_vars->scene11_dudeOnSwing->_movement->_currDynamicPhaseIndex <= 45) + 1;
+}
+
+void sceneHandler11_swingieSit() {
+ if (g_fp->getObjectState(sO_Swingie) == g_fp->getObjectEnumState(sO_Swingie, sO_IsStandingInBoots)) {
+ g_vars->scene11_swingIsSwinging = false;
+ g_vars->scene11_swingieStands = false;
+
+ g_vars->scene11_swingie->changeStatics2(ST_SWR_SIT);
+ g_vars->scene11_swingie->setOXY(144, 389);
+
+ g_fp->setObjectState(sO_Swingie, g_fp->getObjectEnumState(sO_Swingie, sO_IsSitting));
+
+ getCurrSceneSc2MotionController()->enableLinks(sO_CloseThing1, 0);
+ getCurrSceneSc2MotionController()->enableLinks(sO_CloseThing2, 0);
+ getCurrSceneSc2MotionController()->enableLinks(sO_CloseThing3, 1);
+ }
+}
+
+void sceneHandler11_swingieJumpDown() {
+ MessageQueue *mq = new MessageQueue(g_fp->_currentScene->getMessageQueueById(QU_SWR_JUMPDOWN), 0, 0);
+
+ mq->setFlags(mq->getFlags() | 1);
+
+ if (!mq->chain(g_vars->scene11_swingie))
+ delete mq;
+
+ g_vars->scene11_swingIsSwinging = false;
+ g_vars->scene11_swingieStands = true;
+ g_vars->scene11_swingieScreenEdge = g_fp->_sceneRect.left;
+
+ getCurrSceneSc2MotionController()->enableLinks(sO_CloseThing1, 0);
+ getCurrSceneSc2MotionController()->enableLinks(sO_CloseThing2, 1);
+ getCurrSceneSc2MotionController()->enableLinks(sO_CloseThing3, 0);
+
+ getCurrSceneSc2MotionController()->replaceNodeX(905, 805);
+}
+
+void sceneHandler11_winArcade() {
+ if (g_vars->scene11_arcadeIsOn) {
+ g_vars->scene11_arcadeIsOn = false;
+
+ sceneHandler11_emptySwing();
+
+ g_fp->_gameLoader->preloadScene(SC_11, TrubaRight);
+ }
+}
+
+int sceneHandler11(ExCommand *cmd) {
+ if (cmd->_messageKind != 17)
+ return 0;
+
+ switch (cmd->_messageNum) {
+ case MSG_CMN_WINARCADE:
+ sceneHandler11_winArcade();
+ break;
+
+ case MSG_SC11_SITSWINGER:
+ if (g_fp->getObjectState(sO_Swingie) == g_fp->getObjectEnumState(sO_Swingie, sO_IsStandingInBoots)
+ || g_fp->getObjectState(sO_Swingie) == g_fp->getObjectEnumState(sO_Swingie, sO_IsStandingInCorner)) {
+ g_fp->setObjectState(sO_Swingie, g_fp->getObjectEnumState(sO_Swingie, sO_IsSitting));
+ }
+ break;
+
+ case MSG_SC11_MANCRY:
+ g_fp->playSound(g_vars->scene11_crySound, 0);
+
+ g_vars->scene11_crySound = 0;
+ break;
+
+ case MSG_SC11_RESTARTMAN:
+ sceneHandler11_restartMan();
+ break;
+
+ case MSG_SC11_HITMAN:
+ sceneHandler11_hitMan();
+ break;
+
+ case MSG_SC11_MANTOSWING:
+ sceneHandler11_manToSwing();
+ break;
+
+ case MSG_SC11_PUTBOOT:
+ sceneHandler11_putBoot();
+ break;
+
+ case MSG_SC11_SHOWSWING:
+ sceneHandler11_showSwing();
+ break;
+
+ case 107:
+ if (g_vars->scene11_arcadeIsOn)
+ sceneHandler11_swingLogic();
+ break;
+
+ case 33:
+ {
+ int res = 0;
+ int x, y;
+
+ if (!g_fp->_aniMan2)
+ goto LABEL_27;
+
+ x = g_fp->_aniMan2->_ox;
+ y = g_fp->_aniMan2->_oy;
+
+ g_vars->scene11_dudeX = x;
+ g_vars->scene11_dudeY = y;
+
+ if (g_vars->scene11_scrollIsEnabled) {
+ if (x > g_fp->_sceneRect.right - 200)
+ g_fp->_currentScene->_x = x - g_fp->_sceneRect.right + 300;
+ goto LABEL_26;
+ }
+
+ if (g_vars->scene11_scrollIsMaximized) {
+ g_fp->_currentScene->_x = g_fp->_sceneWidth - x;
+
+ if (g_vars->scene11_dudeX < 910)
+ g_vars->scene11_scrollIsMaximized = false;
+
+ LABEL_26:
+ res = 1;
+ LABEL_27:
+ if (g_vars->scene11_swingieStands) {
+ if (g_fp->_sceneRect.left >= 534 && g_vars->scene11_swingieScreenEdge < 534)
+ sceneHandler11_swingieSit();
+
+ g_vars->scene11_swingieScreenEdge = g_fp->_sceneRect.left;
+ }
+
+ if (!g_vars->scene11_arcadeIsOn)
+ goto LABEL_50;
+
+ if (g_vars->scene11_swingCounterPrevTurn <= 0 || g_vars->scene11_swingCounter - g_vars->scene11_swingCounterPrevTurn <= 72) {
+ } else {
+ sceneHandler11_swing0();
+ g_vars->scene11_swingDirectionPrevTurn = 0;
+ g_vars->scene11_swingCounterPrevTurn = 0;
+ }
+
+ if (!g_vars->scene11_arcadeIsOn)
+ goto LABEL_50;
+
+ if (g_vars->scene11_swingDirection == g_vars->scene11_swingDirectionPrevTurn || g_vars->scene11_swingCounterPrevTurn <= 0 || g_vars->scene11_swingCounter - g_vars->scene11_swingCounterPrevTurn <= 2) {
+ LABEL_49:
+ if (g_vars->scene11_arcadeIsOn) {
+ g_fp->_behaviorManager->updateBehaviors();
+ g_fp->startSceneTrack();
+ return res;
+ }
+ LABEL_50:
+ if (g_vars->scene11_swingIsSwinging
+ || (0.0 == g_vars->scene11_swingSpeed
+ && g_vars->scene11_dudeOnSwing->_movement != 0
+ && g_vars->scene11_dudeOnSwing->_movement->_currDynamicPhaseIndex == 45
+ && (g_vars->scene11_dudeOnSwing->changeStatics2(ST_KCH_STATIC), !g_vars->scene11_arcadeIsOn)
+ && g_vars->scene11_swingIsSwinging)) {
+ if (!g_vars->scene11_swingie->_movement) {
+ if ((g_vars->scene11_boots->_flags & 4) && g_vars->scene11_boots->_statics->_staticsId == ST_BTS11_2) {
+ sceneHandler11_swingieJumpDown();
+
+ g_fp->_behaviorManager->updateBehaviors();
+ g_fp->startSceneTrack();
+ return res;
+ }
+ g_vars->scene11_swingie->startAnim(MV_SWR_SWING, 0, -1);
+ }
+ }
+ g_fp->_behaviorManager->updateBehaviors();
+ g_fp->startSceneTrack();
+ return res;
+ }
+
+ if (g_vars->scene11_swingDirectionPrevTurn == 1) {
+ if (!g_vars->scene11_swingDirection)
+ sceneHandler11_swing1();
+ else
+ sceneHandler11_swing0();
+ } else if (g_vars->scene11_swingDirectionPrevTurn == 2) {
+ if (!g_vars->scene11_swingDirection)
+ sceneHandler11_swing2();
+ else
+ sceneHandler11_swing0();
+ }
+
+ g_vars->scene11_swingCounterPrevTurn = g_vars->scene11_swingCounter;
+ goto LABEL_49;
+ }
+ if (x >= g_fp->_sceneRect.left + 200) {
+ if (x <= g_fp->_sceneRect.right - 200) {
+ LABEL_18:
+ if (y < g_fp->_sceneRect.top + 200) {
+ g_fp->_currentScene->_y = y - g_fp->_sceneRect.top - 300;
+ y = g_vars->scene11_dudeY;
+ x = g_vars->scene11_dudeX;
+ }
+ if (y > g_fp->_sceneRect.bottom - 300) {
+ g_fp->_currentScene->_y = y - g_fp->_sceneRect.bottom + 300;
+ x = g_vars->scene11_dudeX;
+ }
+ if (x >= 940)
+ g_vars->scene11_scrollIsMaximized = true;
+ goto LABEL_26;
+ }
+ g_fp->_currentScene->_x = x - g_fp->_sceneRect.right + 300;
+ } else {
+ g_fp->_currentScene->_x = x - g_fp->_sceneRect.left - 300;
+ }
+ y = g_vars->scene11_dudeY;
+ x = g_vars->scene11_dudeX;
+ goto LABEL_18;
+ }
+
+ break;
+
+ case 29:
+ if (g_vars->scene11_swingIsSwinging) {
+ if (g_fp->_currentScene->getStaticANIObjectAtPos(g_fp->_sceneRect.left + cmd->_x, g_fp->_sceneRect.top + cmd->_y) == g_vars->scene11_swingie
+ && cmd->_keyCode == ANI_INV_BOOT)
+ sceneHandler11_putBoot();
+ } else {
+ if (g_vars->scene11_arcadeIsOn) {
+ sceneHandler11_setSwingDirection();
+
+ g_vars->scene11_swingCounterPrevTurn = g_vars->scene11_swingCounter;
+ }
+ }
+
+ if (!g_vars->scene11_arcadeIsOn) {
+ StaticANIObject *ani = g_fp->_currentScene->getStaticANIObjectAtPos(cmd->_sceneClickX, cmd->_sceneClickY);
+
+ if (!ani || !canInteractAny(g_fp->_aniMan, ani, cmd->_keyCode)) {
+ int picId = g_fp->_currentScene->getPictureObjectIdAtPos(cmd->_sceneClickX, cmd->_sceneClickY);
+ PictureObject *pic = g_fp->_currentScene->getPictureObjectById(picId, 0);
+
+ if (!pic || !canInteractAny(g_fp->_aniMan, pic, cmd->_keyCode)) {
+ if ((g_fp->_sceneRect.right - cmd->_sceneClickX < 47 && g_fp->_sceneRect.right < g_fp->_sceneWidth - 1)
+ || (cmd->_sceneClickX - g_fp->_sceneRect.left < 47 && g_fp->_sceneRect.left > 0)) {
+ g_fp->processArcade(cmd);
+
+ return 0;
+ }
+ }
+ }
+ return 0;
+ }
+ }
+
+ return 0;
+}
+
+} // End of namespace Fullpipe
diff --git a/engines/fullpipe/scenes/scene12.cpp b/engines/fullpipe/scenes/scene12.cpp
new file mode 100644
index 0000000000..0295efcaf5
--- /dev/null
+++ b/engines/fullpipe/scenes/scene12.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 "fullpipe/fullpipe.h"
+
+#include "fullpipe/objects.h"
+#include "fullpipe/objectnames.h"
+#include "fullpipe/constants.h"
+#include "fullpipe/motion.h"
+#include "fullpipe/scenes.h"
+#include "fullpipe/scene.h"
+#include "fullpipe/floaters.h"
+#include "fullpipe/messages.h"
+#include "fullpipe/statics.h"
+#include "fullpipe/behavior.h"
+
+namespace Fullpipe {
+
+void scene12_initScene(Scene *sc) {
+ GameVar *var = g_fp->getGameLoaderGameVar()->getSubVarByName("SC_12");
+ g_fp->_floaters->init(var);
+
+ g_vars->scene12_fly = g_fp->getObjectState(sO_Fly_12);
+
+ if (g_vars->scene12_fly)
+ g_vars->scene12_flyCountdown = g_fp->_rnd->getRandomNumber(600) + 600;
+
+ g_fp->setObjectState(sO_Fly_12, g_fp->_rnd->getRandomNumber(1));
+}
+
+void sceneHandler12_updateFloaters() {
+ g_fp->_floaters->genFlies(g_fp->_currentScene, 397, -50, 100, 6);
+
+ g_fp->_floaters->_array2[0]->countdown = g_fp->_rnd->getRandomNumber(6) + 4;
+ g_fp->_floaters->_array2[0]->val6 = 397;
+ g_fp->_floaters->_array2[0]->val7 = -50;
+}
+
+int sceneHandler12(ExCommand *cmd) {
+ int res = 0;
+
+ if (cmd->_messageKind == 17 && cmd->_messageNum == 33) {
+ if (g_fp->_aniMan2) {
+ if (g_fp->_aniMan2->_ox < g_fp->_sceneRect.left + 200)
+ g_fp->_currentScene->_x = g_fp->_aniMan2->_ox - g_fp->_sceneRect.left - 300;
+
+ if (g_fp->_aniMan2->_ox > g_fp->_sceneRect.right - 200)
+ g_fp->_currentScene->_x = g_fp->_aniMan2->_ox - g_fp->_sceneRect.right + 300;
+
+ res = 1;
+ }
+
+ g_vars->scene12_flyCountdown--;
+
+ if (!g_vars->scene12_flyCountdown)
+ sceneHandler12_updateFloaters();
+
+ g_fp->_floaters->update();
+
+ g_fp->_behaviorManager->updateBehaviors();
+ }
+
+ return res;
+}
+
+} // End of namespace Fullpipe
diff --git a/engines/fullpipe/scenes/scene13.cpp b/engines/fullpipe/scenes/scene13.cpp
new file mode 100644
index 0000000000..0a0c2f3906
--- /dev/null
+++ b/engines/fullpipe/scenes/scene13.cpp
@@ -0,0 +1,380 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public 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 "fullpipe/fullpipe.h"
+
+#include "fullpipe/objectnames.h"
+#include "fullpipe/constants.h"
+
+#include "fullpipe/gameloader.h"
+#include "fullpipe/motion.h"
+#include "fullpipe/scenes.h"
+#include "fullpipe/statics.h"
+
+#include "fullpipe/interaction.h"
+#include "fullpipe/behavior.h"
+
+
+namespace Fullpipe {
+
+void scene13_initScene(Scene *sc) {
+ g_vars->scene13_whirlgig = sc->getStaticANIObject1ById(ANI_WHIRLGIG_13, -1);
+ g_vars->scene13_guard = sc->getStaticANIObject1ById(ANI_STOROZH, -1);
+ g_vars->scene13_handleR = sc->getStaticANIObject1ById(ANI_HANDLE_R, -1);
+ g_vars->scene13_handleL = sc->getStaticANIObject1ById(ANI_HANDLE_L, -1);
+ g_vars->scene13_bridge = sc->getStaticANIObject1ById(ANI_BRIDGE, -1);
+ g_vars->scene13_guardDirection = true;
+
+ MovGraphLink *lnk = getSc2MctlCompoundBySceneId(sc->_sceneId)->getLinkByName(sO_Bridge);
+ Scene *oldsc = g_fp->_currentScene;
+
+ g_fp->_currentScene = sc;
+
+ if (g_fp->getObjectState(sO_Bridge) == g_fp->getObjectEnumState(sO_Bridge, sO_Convoluted)) {
+ g_vars->scene13_bridge->changeStatics2(ST_BDG_CLOSED);
+
+ lnk->_flags |= 0x20000000u;
+
+ g_fp->playSound(SND_13_018, 1);
+
+ g_vars->scene13_whirlgig->_callback2 = 0;
+ } else {
+ g_vars->scene13_bridge->changeStatics2(ST_BDG_OPEN2);
+
+ lnk->_flags &= 0xDFFFFFFF;
+
+ g_vars->scene13_whirlgig->stopAnim_maybe();
+ g_vars->scene13_whirlgig->_callback2 = 0;
+ g_vars->scene13_whirlgig->startAnim(MV_WHR13_SPIN, 0, -1);
+
+ if (g_vars->scene13_whirlgig->_movement)
+ g_vars->scene13_whirlgig->_movement->setDynamicPhaseIndex(30);
+
+ g_fp->playSound(SND_13_037, 1);
+ }
+
+ g_vars->scene13_bridge->_flags &= 0xFFFD;
+
+ g_fp->_currentScene = oldsc;
+
+ g_fp->initArcadeKeys("SC_13");
+}
+
+void sceneHandler13_openBridge() {
+ Movement *mov = g_vars->scene13_bridge->_movement;
+
+ if (mov && mov->_id == MV_BDG_CLOSE) {
+ int sz;
+
+ if (mov->_currMovement)
+ sz = mov->_currMovement->_dynamicPhases.size();
+ else
+ sz = mov->_dynamicPhases.size();
+
+ g_vars->scene13_bridge->changeStatics2(ST_BDG_CLOSED);
+ g_vars->scene13_bridge->startAnim(MV_BDG_OPEN, 0, -1);
+
+ mov->setDynamicPhaseIndex(sz - mov->_currDynamicPhaseIndex);
+ } else {
+ g_vars->scene13_bridge->changeStatics2(ST_BDG_CLOSED);
+ g_vars->scene13_bridge->startAnim(MV_BDG_OPEN, 0, -1);
+ }
+}
+
+void sceneHandler13_testClose() {
+ int id = g_vars->scene13_handleL->_statics->_staticsId;
+
+ if (id == ST_HDLL_UP)
+ chainQueue(QU_SC13_CLOSEFAIL, 1);
+ else if (id == ST_HDLL_FIRECAN || id == ST_HDLL_HAMMER)
+ chainQueue(QU_SC13_CLOSESUCCESS, 1);
+}
+
+void sceneHandler13_testOpen() {
+ switch (g_vars->scene13_handleR->_statics->_staticsId) {
+ case ST_HDLR_DOWN:
+ chainQueue(QU_SC13_OPENFAIL, 1);
+ break;
+
+ case ST_HDLR_DOWN_GUM:
+ chainQueue(QU_SC13_OPENSUCCESS, 1);
+ break;
+
+ case ST_HDLR_GUM:
+ g_vars->scene13_handleR->changeStatics2(ST_HDLR_DOWN_GUM);
+
+ chainQueue(QU_SC13_OPENSUCCESS, 1);
+ break;
+ }
+}
+
+void sceneHandler13_closeBridge() {
+ Movement *mov = g_vars->scene13_bridge->_movement;
+
+ if (mov && mov->_id == MV_BDG_OPEN) {
+ int sz;
+
+ if (mov->_currMovement)
+ sz = mov->_currMovement->_dynamicPhases.size();
+ else
+ sz = mov->_dynamicPhases.size();
+
+ g_vars->scene13_bridge->changeStatics2(ST_BDG_OPEN2);
+ g_vars->scene13_bridge->startAnim(MV_BDG_CLOSE, 0, -1);
+
+ mov->setDynamicPhaseIndex(sz - mov->_currDynamicPhaseIndex);
+ } else {
+ g_vars->scene13_bridge->changeStatics2(ST_BDG_OPEN2);
+ g_vars->scene13_bridge->startAnim(MV_BDG_CLOSE, 0, -1);
+ }
+}
+
+void sceneHandler13_closeFast() {
+ g_vars->scene13_bridge->changeStatics2(ST_BDG_OPEN2);
+ g_vars->scene13_bridge->startAnim(MV_BDG_CLOSE, 0, -1);
+ g_vars->scene13_bridge->_movement->setDynamicPhaseIndex(21);
+}
+
+void sceneHandler13_stopWhirlgig() {
+ g_vars->scene13_whirlgig->_callback2 = 0;
+
+ g_fp->stopAllSoundInstances(SND_13_018);
+ g_fp->playSound(SND_13_033, 0);
+ g_fp->playSound(SND_13_037, 1);
+}
+
+void sceneHandler13_startWhirlgig() {
+ g_vars->scene13_whirlgig->_callback2 = 0;
+
+ g_fp->playSound(SND_13_018, 1);
+ g_fp->playSound(SND_13_034, 0);
+
+ g_fp->stopAllSoundInstances(SND_13_037);
+}
+
+void sceneHandler13_openFast() {
+ g_vars->scene13_bridge->changeStatics2(ST_BDG_CLOSED);
+ g_vars->scene13_bridge->startAnim(MV_BDG_OPEN, 0, -1);
+ g_vars->scene13_bridge->_movement->setDynamicPhaseIndex(15);
+}
+
+void sceneHandler13_uneatGum() {
+ BehaviorEntryInfo *beh = g_fp->_behaviorManager->getBehaviorEntryInfoByMessageQueueDataId(g_vars->scene13_guard, ST_STR_RIGHT, QU_STR_CHEW);
+
+ if (beh) {
+ beh->_percent = 0;
+ beh->_delay = 36;
+ }
+
+ beh = g_fp->_behaviorManager->getBehaviorEntryInfoByMessageQueueDataId(g_vars->scene13_guard, ST_STR_RIGHT, QU_STR_PLUU);
+ if (beh) {
+ beh->_percent = 0;
+ beh->_delay = 36;
+ }
+}
+
+void sceneHandler13_eatGum() {
+ BehaviorEntryInfo *beh = g_fp->_behaviorManager->getBehaviorEntryInfoByMessageQueueDataId(g_vars->scene13_guard, ST_STR_RIGHT, QU_STR_CHEW);
+
+ if (beh) {
+ beh->_percent = 10922;
+ beh->_delay = 0;
+ }
+}
+
+void sceneHandler13_updateBridge() {
+ MovGraphLink *lnk = getCurrSceneSc2MotionController()->getLinkByName(sO_Bridge);
+
+ if (lnk) {
+ if (g_fp->getObjectState(sO_Bridge) == g_fp->getObjectEnumState(sO_Bridge, sO_Convoluted))
+ lnk->_flags |= 0x20000000;
+ else
+ lnk->_flags &= 0xDFFFFFFF;
+ }
+}
+
+void sceneHandler13_showGum() {
+ chainQueue(QU_SC13_SHOWGUM, 0);
+}
+
+void sceneHandler13_setBehFlag(BehaviorEntryInfo *beh, bool flag) {
+ if (!flag) {
+ beh->_percent = 327;
+ beh->_flags |= 1;
+ beh->_delay = 36;
+ } else {
+ beh->_percent = 0x7FFF;
+ beh->_flags &= 0xFFFFFFFE;
+ beh->_delay = 0;
+ }
+}
+
+void sceneHandler13_walkForward(bool flag) {
+ BehaviorEntryInfo *beh = g_fp->_behaviorManager->getBehaviorEntryInfoByMessageQueueDataId(g_vars->scene13_guard, ST_STR_RIGHT, QU_STR_RTOL);
+
+ sceneHandler13_setBehFlag(beh, flag);
+
+ beh = g_fp->_behaviorManager->getBehaviorEntryInfoByMessageQueueDataId(g_vars->scene13_guard, ST_STR_LEFT, QU_STR_TURNR);
+
+ sceneHandler13_setBehFlag(beh, flag);
+
+ beh->_flags &= 0xFE;
+}
+
+void sceneHandler13_walkBackward(bool flag) {
+ BehaviorEntryInfo *beh = g_fp->_behaviorManager->getBehaviorEntryInfoByMessageQueueDataId(g_vars->scene13_guard, ST_STR_RIGHT|0x4000, QU_STR_LTOR);
+
+ sceneHandler13_setBehFlag(beh, flag);
+
+ beh = g_fp->_behaviorManager->getBehaviorEntryInfoByMessageQueueDataId(g_vars->scene13_guard, ST_STR_LEFT|0x4000, QU_STR_TURNR_L);
+
+ sceneHandler13_setBehFlag(beh, flag);
+
+ beh->_flags &= 0xFE;
+}
+
+int sceneHandler13(ExCommand *cmd) {
+ if (cmd->_messageKind != 17)
+ return 0;
+
+ switch(cmd->_messageNum) {
+ case MSG_SC13_OPENBRIDGE:
+ sceneHandler13_openBridge();
+ break;
+
+ case MSG_SC13_TESTCLOSE:
+ sceneHandler13_testClose();
+ break;
+
+ case MSG_SC13_TESTOPEN:
+ sceneHandler13_testOpen();
+ break;
+
+ case MSG_SC13_CLOSEBRIDGE:
+ sceneHandler13_closeBridge();
+ break;
+
+ case MSG_SC13_CLOSEFAST:
+ sceneHandler13_closeFast();
+ break;
+
+ case MSG_SC13_STOPWHIRLGIG:
+ sceneHandler13_stopWhirlgig();
+ break;
+
+ case MSG_SC13_STARTWHIRLGIG:
+ sceneHandler13_startWhirlgig();
+ break;
+
+ case MSG_SC13_OPENFAST:
+ sceneHandler13_openFast();
+ break;
+
+ case MSG_SC13_UNEATGUM:
+ sceneHandler13_uneatGum();
+ break;
+
+ case MSG_SC13_EATGUM:
+ sceneHandler13_eatGum();
+ break;
+
+ case MSG_SC13_CHEW:
+ g_vars->scene13_guard->_flags &= 0xFF7Fu;
+ break;
+
+ case MSG_SC13_UPDATEBRIDGE:
+ sceneHandler13_updateBridge();
+ break;
+
+ case MSG_SC13_SHOWGUM:
+ sceneHandler13_showGum();
+ break;
+
+ case 29:
+ {
+ StaticANIObject *ani = g_fp->_currentScene->getStaticANIObjectAtPos(cmd->_sceneClickX, cmd->_sceneClickY);
+
+ if (!ani || !canInteractAny(g_fp->_aniMan, ani, cmd->_keyCode)) {
+ int picId = g_fp->_currentScene->getPictureObjectIdAtPos(cmd->_sceneClickX, cmd->_sceneClickY);
+ PictureObject *pic = g_fp->_currentScene->getPictureObjectById(picId, 0);
+
+ if (!pic || !canInteractAny(g_fp->_aniMan, pic, cmd->_keyCode)) {
+ if ((g_fp->_sceneRect.right - cmd->_sceneClickX < 47
+ && g_fp->_sceneRect.right < g_fp->_sceneWidth - 1)
+ || (cmd->_sceneClickX - g_fp->_sceneRect.left < 47 && g_fp->_sceneRect.left > 0)) {
+ g_fp->processArcade(cmd);
+ }
+ }
+ }
+ break;
+ }
+
+ case 33:
+ {
+ int res = 0;
+ int x;
+
+ if (g_fp->_aniMan2) {
+ x = g_fp->_aniMan2->_ox;
+ g_vars->scene13_dudeX = x;
+
+ if (x < g_fp->_sceneRect.left + 200)
+ g_fp->_currentScene->_x = x - g_fp->_sceneRect.left - 300;
+
+ if (x > g_fp->_sceneRect.right - 200)
+ g_fp->_currentScene->_x = x - g_fp->_sceneRect.right + 300;
+
+ res = 1;
+ } else {
+ x = g_vars->scene13_dudeX;
+ }
+
+ if (g_vars->scene13_guardDirection) {
+ if (x < 1022) {
+ sceneHandler13_walkForward(1);
+ sceneHandler13_walkBackward(0);
+
+ g_vars->scene13_guardDirection = false;
+
+ g_fp->_behaviorManager->updateBehaviors();
+ g_fp->startSceneTrack();
+
+ return res;
+ }
+ } else if (x > 1022) {
+ sceneHandler13_walkForward(0);
+ sceneHandler13_walkBackward(1);
+
+ g_vars->scene13_guardDirection = true;
+ }
+
+ g_fp->_behaviorManager->updateBehaviors();
+ g_fp->startSceneTrack();
+
+ return res;
+ }
+ }
+
+ return 0;
+}
+
+} // End of namespace Fullpipe
diff --git a/engines/fullpipe/scenes/scene14.cpp b/engines/fullpipe/scenes/scene14.cpp
new file mode 100644
index 0000000000..ab0487974a
--- /dev/null
+++ b/engines/fullpipe/scenes/scene14.cpp
@@ -0,0 +1,849 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public 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 "fullpipe/fullpipe.h"
+
+#include "fullpipe/objectnames.h"
+#include "fullpipe/constants.h"
+
+#include "fullpipe/gameloader.h"
+#include "fullpipe/motion.h"
+#include "fullpipe/scenes.h"
+#include "fullpipe/statics.h"
+
+#include "fullpipe/interaction.h"
+#include "fullpipe/behavior.h"
+#include "fullpipe/input.h"
+
+namespace Fullpipe {
+
+void scene14_initScene(Scene *sc) {
+ g_vars->scene14_grandma = sc->getStaticANIObject1ById(ANI_GRANDMA, -1);
+ g_vars->scene14_sceneDeltaX = 200;
+ g_vars->scene14_sceneDeltaY = 200;
+ g_vars->scene14_arcadeIsOn = false;
+ g_vars->scene14_dudeIsKicking = false;
+ g_vars->scene14_ballIsFlying = false;
+ g_vars->scene14_dudeCanKick = false;
+ g_vars->scene14_sceneDiffX = 300;
+ g_vars->scene14_sceneDiffY = 300;
+ g_vars->scene14_pink = 0;
+ g_vars->scene14_flyingBall = 0;
+ g_vars->scene14_balls.clear();
+
+ if (g_fp->getObjectState(sO_Grandma) == g_fp->getObjectEnumState(sO_Grandma, sO_In_14)) {
+ g_vars->scene14_grandmaIsHere = true;
+
+ StaticANIObject *ball = sc->getStaticANIObject1ById(ANI_BALL14, -1);
+
+ ball->_flags &= 0xFFFB;
+ g_vars->scene14_balls.push_back(ball);
+
+ for (uint i = 0; i < 3; i++) {
+ ball = new StaticANIObject(ball); // create a copy
+
+ ball->_flags &= 0xFFFB;
+ g_vars->scene14_balls.push_back(ball);
+
+ sc->addStaticANIObject(ball, 1);
+ }
+ } else {
+ g_vars->scene14_grandmaIsHere = false;
+ g_vars->scene14_grandma->hide();
+ }
+
+ g_fp->lift_setButton(sO_Level4, ST_LBN_4N);
+ g_fp->lift_init(sc, QU_SC14_ENTERLIFT, QU_SC14_EXITLIFT);
+
+ g_fp->initArcadeKeys("SC_14");
+ g_fp->setArcadeOverlay(PIC_CSR_ARCADE6);
+}
+
+void scene14_setupMusic() {
+ if (!g_vars->scene14_grandmaIsHere)
+ g_fp->playTrack(g_fp->getGameLoaderGameVar()->getSubVarByName("SC_14"), "MUSIC2", 0);
+}
+
+int scene14_updateCursor() {
+ g_fp->updateCursorCommon();
+
+ if (g_vars->scene14_arcadeIsOn) {
+ if (g_vars->scene14_dudeIsKicking) {
+ g_fp->_cursorId = PIC_CSR_ARCADE2_D;
+ } else {
+ if (g_fp->_aniMan != g_fp->_objectAtCursor || g_fp->_aniMan->_movement || g_fp->_cursorId != PIC_CSR_DEFAULT) {
+ if (g_fp->_cursorId != PIC_CSR_DEFAULT_INV && g_fp->_cursorId != PIC_CSR_ITN_INV) {
+ g_fp->_cursorId = PIC_CSR_DEFAULT;
+ }
+ } else {
+ g_fp->_cursorId = PIC_CSR_ITN;
+ }
+ }
+ }
+
+ return g_fp->_cursorId;
+}
+
+int sceneHandler14_updateScreenCallback() {
+ int res;
+
+ res = g_fp->drawArcadeOverlay(g_vars->scene14_arcadeIsOn);
+ if (!res)
+ g_fp->_updateScreenCallback = 0;
+
+ return res;
+}
+
+void sceneHandler14_showBallGrandmaHit2() {
+ if (g_vars->scene14_flyingBall) {
+ g_vars->scene14_flyingBall->show1(g_vars->scene14_grandmaX + 223, g_vars->scene14_grandmaY + 35, MV_BAL14_SPIN, 0);
+ g_vars->scene14_flyingBall->_priority = 27;
+
+ g_vars->scene14_pink = g_vars->scene14_flyingBall;
+
+ g_vars->scene14_flyingBall = 0;
+ }
+}
+
+void sceneHandler14_showBallGrandmaDive() {
+ if (g_vars->scene14_flyingBall) {
+ g_vars->scene14_flyingBall->show1(g_vars->scene14_grandmaX + 506, g_vars->scene14_grandmaY - 29, -1, 0);
+
+ g_vars->scene14_balls.push_back(g_vars->scene14_flyingBall);
+ g_vars->scene14_flyingBall = 0;
+ }
+
+ g_fp->_aniMan2 = g_fp->_aniMan;
+}
+
+void sceneHandler14_showBallGrandmaHit() {
+ if (g_vars->scene14_flyingBall) {
+ g_vars->scene14_flyingBall->show1(g_vars->scene14_grandmaX + 190, g_vars->scene14_grandmaY + 56, MV_BAL14_TOGMA, 0);
+ g_vars->scene14_flyingBall->_priority = 27;
+
+ MessageQueue *mq = new MessageQueue(g_fp->_globalMessageQueueList->compact());
+ ExCommand *ex = new ExCommand(ANI_BALL14, 1, MV_BAL14_TOGMA, 0, 0, 0, 1, 0, 0, 0);
+
+ ex->_keyCode = g_vars->scene14_flyingBall->_okeyCode;
+ ex->_excFlags |= 2;
+ ex->_field_24 = 1;
+ mq->addExCommandToEnd(ex);
+
+ ex = new ExCommand(ANI_BALL14, 6, 0, 0, 0, 0, 1, 0, 0, 0);
+ ex->_keyCode = g_vars->scene14_flyingBall->_okeyCode;
+ ex->_excFlags |= 3;
+ mq->addExCommandToEnd(ex);
+ mq->chain(0);
+
+ g_vars->scene14_balls.push_back(g_vars->scene14_flyingBall);
+ g_vars->scene14_flyingBall = 0;
+ }
+}
+
+void sceneHandler14_exitScene() {
+ g_vars->scene14_arcadeIsOn = false;
+
+ if (g_fp->_aniMan->_movement)
+ g_fp->_aniMan->_movement->gotoLastFrame();
+
+ g_fp->_aniMan->stopAnim_maybe();
+
+ handleObjectInteraction(g_fp->_aniMan, g_fp->_currentScene->getPictureObjectById(PIC_SC14_RTRUBA, 0), 0);
+
+ g_vars->scene14_grandma->changeStatics2(ST_GMA_SIT);
+
+ chainQueue(QU_SC14_ENDARCADE, 0);
+
+ getGameLoaderInteractionController()->disableFlag24();
+ getCurrSceneSc2MotionController()->clearEnabled();
+}
+
+void sceneHandler14_showBallMan() {
+ if (g_vars->scene14_flyingBall) {
+ g_vars->scene14_flyingBall->show1(g_vars->scene14_dudeX - 166, g_vars->scene14_dudeY + 40, MV_BAL14_TOGMA, 0);
+ g_vars->scene14_flyingBall->_priority = 27;
+
+ MessageQueue *mq = new MessageQueue(g_fp->_globalMessageQueueList->compact());
+ ExCommand *ex = new ExCommand(ANI_BALL14, 1, MV_BAL14_TOGMA, 0, 0, 0, 1, 0, 0, 0);
+
+ ex->_keyCode = g_vars->scene14_flyingBall->_okeyCode;
+ ex->_excFlags |= 2;
+ ex->_field_24 = 1;
+ mq->addExCommandToEnd(ex);
+
+ ex = new ExCommand(ANI_BALL14, 6, 0, 0, 0, 0, 1, 0, 0, 0);
+ ex->_keyCode = g_vars->scene14_flyingBall->_okeyCode;
+ ex->_excFlags |= 3;
+ mq->addExCommandToEnd(ex);
+ mq->chain(0);
+
+ g_vars->scene14_flyingBall->startAnim(MV_BAL14_TOGMA, 0, -1);
+
+ g_vars->scene14_balls.push_back(g_vars->scene14_flyingBall);
+ g_vars->scene14_flyingBall = 0;
+
+ if (g_vars->scene14_dudeX >= 1300)
+ sceneHandler14_exitScene();
+ }
+}
+
+void sceneHandler14_manKickBall() {
+ int val = (g_vars->scene14_grandmaX + 65 - (g_vars->scene14_dudeX - 85)) / -32;
+ int den = val;
+
+ g_vars->scene14_ballX = g_vars->scene14_dudeX - 85;
+ g_vars->scene14_ballY = g_vars->scene14_dudeY - 76;
+ g_vars->scene14_ballDeltaX = -32;
+
+ if (!val)
+ den = 1;
+
+ g_vars->scene14_ballDeltaY = (g_vars->scene14_grandmaY - 102 - val * val / 2 - (g_vars->scene14_dudeY - 76)) / den;
+
+ g_vars->scene14_flyingBall->show1(g_vars->scene14_dudeX - 85, g_vars->scene14_dudeY - 76, -1, 0);
+ g_vars->scene14_flyingBall->startAnim(MV_BAL14_SPIN, 0, -1);
+ g_vars->scene14_flyingBall->_priority = 5;
+
+ g_vars->scene14_ballIsFlying = true;
+}
+
+void sceneHandler14_showBallFly() {
+ if (g_vars->scene14_balls.size()) {
+ g_vars->scene14_flyingBall = g_vars->scene14_balls.front();
+ g_vars->scene14_balls.pop_front();
+ }
+
+ int x, y;
+
+ if (g_vars->scene14_grandma->_movement) {
+ x = g_vars->scene14_grandma->_movement->_ox;
+ g_vars->scene14_ballX = x;
+ y = g_vars->scene14_grandma->_movement->_oy;
+ } else {
+ x = g_vars->scene14_grandmaX;
+ y = g_vars->scene14_grandmaY;
+ }
+
+ x = x + 38;
+ y = y - 77;
+
+ g_vars->scene14_ballDeltaX = 32;
+
+ int dist = (g_vars->scene14_dudeX - 16 - x) / 32;
+ int den = dist;
+
+ if (!dist)
+ den = 1;
+
+ g_vars->scene14_ballX = x + 32;
+ g_vars->scene14_ballDeltaY = (g_vars->scene14_dudeY - 40 - dist * dist / 2 - y) / den;
+ g_vars->scene14_ballY = g_vars->scene14_ballDeltaY + y;
+
+ g_vars->scene14_flyingBall->show1(x + 32, g_vars->scene14_ballDeltaY + y, MV_BAL14_SPIN, 0);
+ g_vars->scene14_flyingBall->_priority = 5;
+ g_vars->scene14_flyingBall->startAnim(MV_BAL14_SPIN, 0, -1);
+
+ g_vars->scene14_ballIsFlying = true;
+}
+
+void sceneHandler14_grandmaJump() {
+ BehaviorEntryInfo *beh1 = g_fp->_behaviorManager->getBehaviorEntryInfoByMessageQueueDataId(g_vars->scene14_grandma, ST_GMA_SIT, QU_GMA_JUMPFW);
+ BehaviorEntryInfo *beh2 = g_fp->_behaviorManager->getBehaviorEntryInfoByMessageQueueDataId(g_vars->scene14_grandma, ST_GMA_SIT, QU_GMA_JUMPBK);
+
+ if (beh1) {
+ if (beh2) {
+ int p = beh1->_percent;
+ beh1->_percent = beh2->_percent;
+ beh2->_percent = p;
+ }
+ }
+}
+
+void sceneHandler14_endArcade() {
+ g_vars->scene14_arcadeIsOn = false;
+
+ setInputDisabled(0);
+
+ getGameLoaderInteractionController()->enableFlag24();
+ getCurrSceneSc2MotionController()->setEnabled();
+
+ BehaviorEntryInfo *beh = g_fp->_behaviorManager->getBehaviorEntryInfoByMessageQueueDataId(g_vars->scene14_grandma, ST_GMA_SIT, QU_GMA_BLINK);
+ if (beh)
+ beh->_percent = 327;
+
+ beh = g_fp->_behaviorManager->getBehaviorEntryInfoByMessageQueueDataId(g_vars->scene14_grandma, ST_GMA_SIT, QU_GMA_THROW);
+ if (beh)
+ beh->_percent = 0;
+
+ g_vars->scene14_sceneDeltaX = 200;
+ g_vars->scene14_sceneDeltaY = 200;
+
+ g_fp->_aniMan2 = g_fp->_aniMan;
+
+ g_vars->scene14_sceneDiffX = 300;
+ g_vars->scene14_sceneDiffY = 300;
+}
+
+void sceneHandler14_winArcade() {
+ if (g_vars->scene14_arcadeIsOn) {
+ if (g_vars->scene14_dudeIsKicking) {
+ g_fp->_aniMan->changeStatics2(ST_MAN_RIGHT|0x4000);
+
+ g_vars->scene14_dudeIsKicking = false;
+ }
+
+ if (g_vars->scene14_flyingBall) {
+ g_vars->scene14_balls.push_back(g_vars->scene14_flyingBall);
+
+ g_vars->scene14_flyingBall->_flags &= 0xFFFB;
+ g_vars->scene14_flyingBall = 0;
+ }
+
+ g_vars->scene14_ballIsFlying = false;
+
+ sceneHandler14_endArcade();
+
+ g_vars->scene14_grandmaIsHere = false;
+
+ if (g_fp->getObjectState(sO_Grandma) == g_fp->getObjectEnumState(sO_Grandma, sO_In_14)) {
+ g_fp->setObjectState(sO_Grandma, g_fp->getObjectEnumState(sO_Grandma, sO_In_15));
+ g_vars->scene14_grandma->changeStatics2(ST_GMA_SIT);
+ g_vars->scene14_grandma->_flags &= 0xFFFB;
+ }
+
+ if (g_fp->_currentScene->_messageQueueId) {
+ MessageQueue *mq = g_fp->_globalMessageQueueList->getMessageQueueById(g_fp->_currentScene->_messageQueueId);
+ if (mq)
+ delete mq;
+
+ g_fp->_currentScene->_messageQueueId = 0;
+ }
+ }
+}
+
+void sceneHandler14_showBallLast() {
+ if (g_vars->scene14_pink) {
+ g_vars->scene14_pink->show1(693, 491, MV_BAL14_SPIN, 0);
+ g_vars->scene14_pink->_priority = 27;
+ }
+}
+
+void sceneHandler14_hideBallLast() {
+ if (g_vars->scene14_pink) {
+ g_vars->scene14_pink->hide();
+ g_vars->scene14_balls.push_back(g_vars->scene14_pink);
+ g_vars->scene14_pink = 0;
+ }
+}
+
+void sceneHandler14_startArcade() {
+ g_vars->scene14_arcadeIsOn = true;
+ g_vars->scene14_dudeCanKick = true;
+
+ if (g_fp->_aniMan->_movement) {
+ g_fp->_aniMan->changeStatics2(ST_MAN_RIGHT | 0x4000);
+ g_fp->_aniMan->setOXY(1237, 451);
+ g_fp->_aniMan->_priority = 25;
+ }
+
+ getCurrSceneSc2MotionController()->clearEnabled();
+ getGameLoaderInteractionController()->disableFlag24();
+
+ g_fp->_aniMan2 = 0;
+ g_vars->scene14_sceneDeltaX = 50;
+ g_vars->scene14_sceneDiffX = 100;
+ g_vars->scene14_hitsLeft = 4;
+ g_vars->scene14_pink = 0;
+
+ chainQueue(QU_SC14_STARTARCADE, 0);
+
+ g_fp->_updateScreenCallback = sceneHandler14_updateScreenCallback;
+}
+
+void sceneHandler14_clearCallback() {
+ g_fp->_aniMan->_callback2 = 0;
+ g_vars->scene14_dudeIsKicking = false;
+}
+
+void sceneHandler14_kickAnimation() {
+ if (g_fp->_aniMan->_movement) {
+ sceneHandler14_clearCallback();
+
+ if (g_vars->scene14_flyingBall && g_vars->scene14_dudeX - g_vars->scene14_flyingBall->_ox < 180) {
+ g_fp->_aniMan->changeStatics2(g_fp->_aniMan->_movement->_staticsObj2->_staticsId);
+ g_fp->_aniMan->startAnim(MV_MAN14_KICK, 0, -1);
+
+ g_vars->scene14_ballIsFlying = false;
+
+ g_vars->scene14_flyingBall->stopAnim_maybe();
+ g_vars->scene14_flyingBall->hide();
+ } else {
+ g_fp->_aniMan->changeStatics2(g_fp->_aniMan->_movement->_staticsObj2->_staticsId);
+ g_fp->_aniMan->startAnim(MV_MAN14_KICKAIR, 0, -1);
+ }
+ }
+}
+
+void sceneHandler14_declineCallback(int *arg) {
+ Common::Point point;
+
+ if (g_vars->scene14_dudeIsKicking) {
+ *arg = (int)(sqrt((double)(g_fp->_mouseVirtY - g_vars->scene14_mouseCursorPos.y)
+ * (g_fp->_mouseVirtY - g_vars->scene14_mouseCursorPos.y)
+ + (g_fp->_mouseVirtX - g_vars->scene14_mouseCursorPos.x)
+ * (g_fp->_mouseVirtX - g_vars->scene14_mouseCursorPos.x)) * 0.1);
+
+ if (*arg > 11)
+ *arg = 11;
+ } else {
+ ++*arg;
+ }
+}
+
+void sceneHandler14_dudeDecline() {
+ g_vars->scene14_mouseCursorPos.x = g_fp->_mouseVirtX;
+ g_vars->scene14_mouseCursorPos.y = g_fp->_mouseVirtY;
+
+ g_fp->_aniMan->_callback2 = sceneHandler14_declineCallback;
+ g_fp->_aniMan->changeStatics2(ST_MAN_RIGHT|0x4000);
+ g_fp->_aniMan->startAnim(MV_MAN14_DECLINE, 0, -1);
+
+ g_vars->scene14_dudeIsKicking = true;
+}
+
+bool sceneHandler14_arcadeProcessClick(ExCommand *cmd) {
+ if (!getCurrSceneSc2MotionController()->_isEnabled)
+ return 0;
+
+ if (!g_vars->scene14_grandmaIsHere) {
+ if (!cmd->_keyCode) {
+ if (g_vars->scene14_pink) {
+ if (g_vars->scene14_pink->_flags & 4) {
+ if (cmd->_sceneClickX < g_vars->scene14_pink->_ox + 40) {
+ handleObjectInteraction(g_fp->_aniMan, g_vars->scene14_pink, 0);
+ cmd->_messageKind = 0;
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+ if (getCurrSceneSc2MotionController()->_objtype != kObjTypeMctlCompound)
+ return false;
+
+ if (!getCurrSceneSc2MotionController()->_motionControllers[0]->_movGraphReactObj->pointInRegion(cmd->_sceneClickX, cmd->_sceneClickY))
+ return false;
+
+ if (cmd->_sceneClickX > 1237)
+ return false;
+
+ MessageQueue *mq = getCurrSceneSc2MotionController()->method34(g_fp->_aniMan, 1237, 451, 1, 0);
+
+ if (!mq)
+ return false;
+
+ ExCommand *ex = new ExCommand(0, 17, MSG_SC14_STARTARCADE, 0, 0, 0, 1, 0, 0, 0);
+
+ ex->_excFlags |= 3;
+ mq->addExCommandToEnd(ex);
+ mq->setFlags(mq->getFlags() | 1);
+
+ postExCommand(g_fp->_aniMan->_id, 2, 1237, 451, 0, -1);
+
+ cmd->_messageKind = 0;
+
+ getCurrSceneSc2MotionController()->clearEnabled();
+ getGameLoaderInteractionController()->disableFlag24();
+ return true;
+}
+
+void sceneHandler14_grandmaThrow() {
+ g_vars->scene14_grandma->changeStatics2(ST_GMA_SIT);
+
+ MessageQueue *mq = new MessageQueue;
+ ExCommand *ex = new ExCommand(ANI_GRANDMA, 2, 30, 0, 0, 0, 1, 0, 0, 0);
+
+ ex->_excFlags |= 2;
+ mq->addExCommandToEnd(ex);
+
+ ex = new ExCommand(ANI_GRANDMA, 1, MV_GMA_THROW, 0, 0, 0, 1, 0, 0, 0);
+ ex->_excFlags |= 2;
+ mq->addExCommandToEnd(ex);
+
+ mq->chain(0);
+}
+
+void sceneHandler14_passToGrandma() {
+ g_vars->scene14_flyingBall->stopAnim_maybe();
+ g_vars->scene14_flyingBall->_priority = 27;
+
+ MessageQueue *mq = new MessageQueue(g_fp->_globalMessageQueueList->compact());
+ ExCommand *ex = new ExCommand(ANI_BALL14, 1, MV_BAL14_FALL, 0, 0, 0, 1, 0, 0, 0);
+
+ ex->_keyCode = g_vars->scene14_flyingBall->_okeyCode;
+ ex->_excFlags |= 2;
+ ex->_field_24 = 1;
+ mq->addExCommandToEnd(ex);
+
+ ex = new ExCommand(ANI_BALL14, 6, 0, 0, 0, 0, 1, 0, 0, 0);
+ ex->_keyCode = g_vars->scene14_flyingBall->_okeyCode;
+ ex->_excFlags |= 3;
+ mq->addExCommandToEnd(ex);
+ mq->chain(0);
+
+ g_vars->scene14_balls.push_back(g_vars->scene14_flyingBall);
+ g_vars->scene14_flyingBall = 0;
+
+ sceneHandler14_grandmaThrow();
+}
+
+void sceneHandler14_grandmaJumpThrow() {
+ g_vars->scene14_grandma->changeStatics2(ST_GMA_SIT);
+
+ MessageQueue *mq = new MessageQueue;
+ ExCommand *ex = new ExCommand(ANI_GRANDMA, 2, 30, 0, 0, 0, 1, 0, 0, 0);
+
+ ex->_excFlags |= 2;
+ mq->addExCommandToEnd(ex);
+
+ ex = new ExCommand(ANI_GRANDMA, 1, MV_GMA_JUMPFW, 0, 0, 0, 1, 0, 0, 0);
+ ex->_excFlags |= 2;
+ mq->addExCommandToEnd(ex);
+
+ ex = new ExCommand(ANI_GRANDMA, 1, MV_GMA_THROW, 0, 0, 0, 1, 0, 0, 0);
+ ex->_excFlags |= 2;
+ mq->addExCommandToEnd(ex);
+
+ mq->chain(0);
+
+ g_vars->scene14_dude2X += 71;
+ g_fp->_currentScene->_x = 71;
+
+ g_fp->_aniMan2 = g_fp->_aniMan;
+}
+
+void sceneHandler14_dudeFall() {
+ if (!g_fp->_aniMan->_movement || g_fp->_aniMan->_movement->_id != MV_MAN14_FALL) {
+ sceneHandler14_clearCallback();
+
+ g_fp->_aniMan->changeStatics2(ST_MAN_RIGHT|0x4000);
+ g_fp->_aniMan->startAnim(MV_MAN14_FALL, 0, -1);
+ g_vars->scene14_flyingBall->stopAnim_maybe();
+ g_vars->scene14_flyingBall->hide();
+
+ sceneHandler14_grandmaJumpThrow();
+ }
+ ++g_vars->scene14_hitsLeft;
+}
+
+void sceneHandler14_grandmaStepForward() {
+ g_fp->_aniMan->changeStatics2(ST_MAN_RIGHT|0x4000);
+ g_fp->_aniMan->startAnim(MV_MAN14_STEPFW, 0, -1);
+
+ g_vars->scene14_dude2X -= 71;
+
+ g_fp->_currentScene->_x = -71;
+ g_fp->_aniMan2 = g_vars->scene14_grandma;
+}
+
+void sceneHandler14_arcadeLogic() {
+ g_vars->scene14_flyingBall->stopAnim_maybe();
+ g_vars->scene14_flyingBall->hide();
+
+ if (g_vars->scene14_dudeIsKicking)
+ sceneHandler14_clearCallback();
+
+ if (g_vars->scene14_hitsLeft <= 1) {
+ setInputDisabled(1);
+
+ sceneHandler14_clearCallback();
+
+ g_vars->scene14_dudeCanKick = false;
+ g_fp->_aniMan2 = 0;
+
+ chainQueue(QU_SC14_WINARCADE, 1);
+
+ --g_vars->scene14_hitsLeft;
+ } else {
+ ExCommand *ex;
+
+ g_vars->scene14_grandma->changeStatics2(ST_GMA_SIT);
+
+ if (g_vars->scene14_hitsLeft != 3 || g_vars->scene14_pink) {
+ MessageQueue *mq = new MessageQueue(g_fp->_globalMessageQueueList->compact());
+
+ ex = new ExCommand(ANI_GRANDMA, 1, MV_GMA_BACKOFF, 0, 0, 0, 1, 0, 0, 0);
+ ex->_excFlags |= 2;
+ mq->addExCommandToEnd(ex);
+
+ ex = new ExCommand(ANI_GRANDMA, 1, MV_GMA_THROW, 0, 0, 0, 1, 0, 0, 0);
+ ex->_excFlags |= 2;
+ mq->addExCommandToEnd(ex);
+
+ mq->chain(0);
+ } else {
+ MessageQueue *mq = new MessageQueue(g_fp->_globalMessageQueueList->compact());
+
+ ex = new ExCommand(ANI_GRANDMA, 1, MV_GMA_BACKOFF2, 0, 0, 0, 1, 0, 0, 0);
+ ex->_excFlags |= 2;
+ mq->addExCommandToEnd(ex);
+
+ ex = new ExCommand(ANI_GRANDMA, 1, MV_GMA_THROW, 0, 0, 0, 1, 0, 0, 0);
+ ex->_excFlags |= 2;
+ mq->addExCommandToEnd(ex);
+
+ mq->chain(0);
+ }
+
+ sceneHandler14_grandmaStepForward();
+ --g_vars->scene14_hitsLeft;
+ }
+}
+
+void sceneHandler14_animateBall() {
+ int x = g_vars->scene14_ballDeltaX + g_vars->scene14_ballX;
+ int y = g_vars->scene14_ballDeltaY + g_vars->scene14_ballY;
+
+ g_vars->scene14_ballX += g_vars->scene14_ballDeltaX;
+ g_vars->scene14_ballY += g_vars->scene14_ballDeltaY;
+
+ g_vars->scene14_ballDeltaY++;
+
+ if (g_vars->scene14_ballDeltaY - 1 + g_vars->scene14_ballY > 517) {
+ if (x <= g_vars->scene14_dudeX - 16 ) {
+ if ( g_vars->scene14_ballDeltaX >= 0 || x >= g_vars->scene14_grandmaX + 65 || x <= g_vars->scene14_grandmaX - 135 || y <= g_vars->scene14_grandmaY - 102 ) {
+ if (g_vars->scene14_flyingBall->_movement)
+ g_vars->scene14_flyingBall->_movement->setOXY(x, y);
+ else
+ g_vars->scene14_flyingBall->setOXY(x, y);
+ } else {
+ sceneHandler14_arcadeLogic();
+ g_vars->scene14_ballIsFlying = false;
+ }
+ } else {
+ sceneHandler14_dudeFall();
+ g_vars->scene14_ballIsFlying = false;
+ }
+ } else {
+ sceneHandler14_passToGrandma();
+ g_vars->scene14_ballIsFlying = false;
+ }
+}
+
+int sceneHandler14(ExCommand *cmd) {
+ if (cmd->_messageKind != 17)
+ return 0;
+
+ switch(cmd->_messageNum) {
+ case MSG_SC14_SHOWBALLGMAHIT2:
+ sceneHandler14_showBallGrandmaHit2();
+ break;
+
+ case MSG_SC14_SHOWBALLGMADIVE:
+ sceneHandler14_showBallGrandmaDive();
+ break;
+
+ case MSG_LIFT_CLICKBUTTON:
+ g_fp->lift_clickButton();
+ break;
+
+ case MSG_SC14_SHOWBALLGMAHIT:
+ sceneHandler14_showBallGrandmaHit();
+ break;
+
+ case MSG_SC14_SHOWBALLMAN:
+ sceneHandler14_showBallMan();
+ break;
+
+ case MSG_SC14_MANKICKBALL:
+ sceneHandler14_manKickBall();
+ break;
+
+ case MSG_SC14_SHOWBALLFLY:
+ sceneHandler14_showBallFly();
+ break;
+
+ case MSG_LIFT_GO:
+ g_fp->lift_goAnimation();
+ break;
+
+ case MSG_SC14_GMAJUMP:
+ sceneHandler14_grandmaJump();
+ break;
+
+ case MSG_LIFT_CLOSEDOOR:
+ g_fp->lift_closedoorSeq();
+ break;
+
+ case MSG_LIFT_EXITLIFT:
+ g_fp->lift_exitSeq(cmd);
+ break;
+
+ case MSG_LIFT_STARTEXITQUEUE:
+ g_fp->lift_startExitQueue();
+ break;
+
+ case MSG_SC14_RESTORESCROLL:
+ g_fp->_aniMan2 = g_fp->_aniMan;
+ g_fp->_scrollSpeed = 8;
+ break;
+
+ case MSG_CMN_WINARCADE:
+ sceneHandler14_winArcade();
+ break;
+
+ case MSG_SC14_SCROLLLEFT:
+ g_fp->_aniMan2 = 0;
+ g_fp->_currentScene->_x = -g_fp->_sceneRect.left;
+ g_fp->_scrollSpeed = 24;
+ break;
+
+ case MSG_SC14_SHOWBALLLAST:
+ sceneHandler14_showBallLast();
+ break;
+
+ case MSG_SC14_HIDEBALLLAST:
+ sceneHandler14_hideBallLast();
+ break;
+
+ case MSG_SC14_HIDEPINK:
+ if (!g_vars->scene14_pink)
+ break;
+
+ g_vars->scene14_pink->hide();
+ break;
+
+ case MSG_SC14_GMATOTRUBA:
+ g_fp->_currentScene->_x = -g_fp->_sceneRect.left;
+ break;
+
+ case MSG_SC14_STARTARCADE:
+ sceneHandler14_startArcade();
+ break;
+
+ case MSG_SC14_ENDARCADE:
+ sceneHandler14_endArcade();
+
+ g_vars->scene14_grandmaIsHere = false;
+ break;
+
+ case 64:
+ g_fp->lift_sub05(cmd);
+ break;
+
+ case 33:
+ {
+ Movement *mov = g_fp->_aniMan->_movement;
+
+ if (mov) {
+ g_vars->scene14_dudeX = mov->_ox;
+ g_vars->scene14_dudeY = mov->_oy;
+
+ if (mov->_id == MV_MAN14_KICK)
+ g_vars->scene14_dudeX = mov->_ox + 2 * g_fp->_aniMan->_movement->_currDynamicPhaseIndex;
+ } else {
+ g_vars->scene14_dudeX = g_fp->_aniMan->_ox;
+ g_vars->scene14_dudeY = g_fp->_aniMan->_oy;
+ }
+
+ mov = g_vars->scene14_grandma->_movement;
+ if (mov) {
+ g_vars->scene14_grandmaX = mov->_ox;
+ g_vars->scene14_grandmaY = mov->_oy;
+ } else {
+ g_vars->scene14_grandmaX = g_vars->scene14_grandma->_ox;
+ g_vars->scene14_grandmaY = g_vars->scene14_grandma->_oy;
+ }
+
+ if (g_fp->_aniMan2) {
+ int x = g_fp->_aniMan2->_ox;
+ g_vars->scene14_dude2X = x;
+
+ if (x < g_fp->_sceneRect.left + g_vars->scene14_sceneDeltaX) {
+ g_fp->_currentScene->_x = x - g_vars->scene14_sceneDiffX - g_fp->_sceneRect.left;
+ x = g_vars->scene14_dude2X;
+ }
+
+ if (x > g_fp->_sceneRect.right - g_vars->scene14_sceneDeltaX)
+ g_fp->_currentScene->_x = x + g_vars->scene14_sceneDiffX - g_fp->_sceneRect.right;
+ }
+
+ if (g_vars->scene14_ballIsFlying)
+ sceneHandler14_animateBall();
+
+ g_fp->_behaviorManager->updateBehaviors();
+ g_fp->startSceneTrack();
+ break;
+ }
+
+ case 30:
+ if (g_vars->scene14_dudeIsKicking) {
+ sceneHandler14_kickAnimation();
+ break;
+ }
+
+ if (!g_vars->scene14_arcadeIsOn) {
+ break;
+ }
+ break;
+
+ case 29:
+ if (g_vars->scene14_arcadeIsOn) {
+ int pixel;
+
+ if (g_vars->scene14_dudeCanKick && g_fp->_aniMan->getPixelAtPos(cmd->_sceneClickX, cmd->_sceneClickY, &pixel) && !g_fp->_aniMan->_movement) {
+ sceneHandler14_dudeDecline();
+ break;
+ }
+ } else {
+ StaticANIObject *ani = g_fp->_currentScene->getStaticANIObjectAtPos(cmd->_sceneClickX, cmd->_sceneClickY);
+
+ if (ani && ani->_id == ANI_LIFTBUTTON) {
+ g_fp->lift_sub1(ani);
+ cmd->_messageKind = 0;
+ break;
+ }
+
+ if (!sceneHandler14_arcadeProcessClick(cmd) && (!ani || !canInteractAny(g_fp->_aniMan, ani, cmd->_keyCode))) {
+ int picId = g_fp->_currentScene->getPictureObjectIdAtPos(cmd->_sceneClickX, cmd->_sceneClickY);
+
+ PictureObject *pic = g_fp->_currentScene->getPictureObjectById(picId, 0);
+
+ if (!pic || !canInteractAny(g_fp->_aniMan, pic, cmd->_keyCode)) {
+ if ((g_fp->_sceneRect.right - cmd->_sceneClickX < 47 && g_fp->_sceneRect.right < g_fp->_sceneWidth - 1)
+ || (cmd->_sceneClickX - g_fp->_sceneRect.left < 47 && g_fp->_sceneRect.left > 0)) {
+ g_fp->processArcade(cmd);
+ sceneHandler14_arcadeProcessClick(cmd);
+ break;
+ }
+ }
+ }
+ }
+ break;
+ }
+
+ return 0;
+}
+
+} // End of namespace Fullpipe
diff --git a/engines/fullpipe/scenes/scene15.cpp b/engines/fullpipe/scenes/scene15.cpp
new file mode 100644
index 0000000000..155897619f
--- /dev/null
+++ b/engines/fullpipe/scenes/scene15.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 "fullpipe/fullpipe.h"
+
+#include "fullpipe/objectnames.h"
+#include "fullpipe/constants.h"
+
+#include "fullpipe/gameloader.h"
+#include "fullpipe/motion.h"
+#include "fullpipe/scenes.h"
+#include "fullpipe/statics.h"
+
+#include "fullpipe/interaction.h"
+#include "fullpipe/behavior.h"
+
+
+namespace Fullpipe {
+
+void scene15_initScene(Scene *sc) {
+ g_vars->scene15_chantingCountdown = 0;
+
+ StaticANIObject *grandma = sc->getStaticANIObject1ById(ANI_GRANDMA_ASS, -1);
+
+ Scene *oldsc = g_fp->_currentScene;
+ g_fp->_currentScene = sc;
+
+ int grandmaState = g_fp->getObjectState(sO_Grandma);
+
+ if (grandmaState == g_fp->getObjectEnumState(sO_Grandma, sO_In_15)) {
+ grandma->changeStatics2(ST_GMS_BOOT);
+ grandma->setOXY(97, 399);
+ g_fp->setObjectState(sO_LeftPipe_15, g_fp->getObjectEnumState(sO_LeftPipe_15, sO_IsClosed));
+ } else if (grandmaState == g_fp->getObjectEnumState(sO_Grandma, sO_In_15_1)) {
+ grandma->changeStatics2(ST_GMS_BOOT);
+ grandma->setOXY(86, 399);
+ g_fp->setObjectState(sO_LeftPipe_15, g_fp->getObjectEnumState(sO_LeftPipe_15, sO_IsClosed));
+ } else if (grandmaState == g_fp->getObjectEnumState(sO_Grandma, sO_In_15_2)) {
+ grandma->changeStatics2(ST_GMS_BOOT);
+ grandma->setOXY(71, 399);
+ g_fp->setObjectState(sO_LeftPipe_15, g_fp->getObjectEnumState(sO_LeftPipe_15, sO_IsClosed));
+ } else if (grandmaState == g_fp->getObjectEnumState(sO_Grandma, sO_In_15_3)) {
+ grandma->changeStatics2(ST_GMS_BOOT);
+ grandma->setOXY(49, 399);
+ g_fp->setObjectState(sO_LeftPipe_15, g_fp->getObjectEnumState(sO_LeftPipe_15, sO_IsClosed));
+ } else if (grandmaState == g_fp->getObjectEnumState(sO_Grandma, sO_WithoutBoot)) {
+ grandma->changeStatics2(ST_GMS_BOOT);
+ grandma->setOXY(97, 399);
+ grandma->changeStatics2(ST_GMS_BOOTLESS2);
+ g_fp->setObjectState(sO_LeftPipe_15, g_fp->getObjectEnumState(sO_LeftPipe_15, sO_IsClosed));
+ } else {
+ 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))
+ g_vars->scene15_plusminus->_statics = g_vars->scene15_plusminus->getStaticsById(ST_PMS_MINUS);
+ else
+ g_vars->scene15_plusminus->_statics = g_vars->scene15_plusminus->getStaticsById(ST_PMS_PLUS);
+
+ g_vars->scene15_ladder = sc->getPictureObjectById(PIC_SC15_LADDER, 0);
+ g_vars->scene15_boot = sc->getStaticANIObject1ById(ANI_BOOT_15, -1);
+
+ if (g_fp->getObjectState(sO_Boot_15) != g_fp->getObjectEnumState(sO_Boot_15, sO_IsPresent))
+ g_vars->scene15_boot->_flags &= 0xFFFB;
+
+ g_fp->_currentScene = oldsc;
+
+ g_fp->lift_setButton(sO_Level5, ST_LBN_5N);
+ g_fp->lift_init(sc, QU_SC15_ENTERLIFT, QU_SC15_EXITLIFT);
+}
+
+int scene15_updateCursor() {
+ g_fp->updateCursorCommon();
+
+ if (g_fp->_cursorId == PIC_CSR_ITN && g_fp->_objectIdAtCursor == PIC_SC15_LTRUBA)
+ g_fp->_cursorId = PIC_CSR_GOL;
+
+ return g_fp->_cursorId;
+}
+
+int sceneHandler15(ExCommand *cmd) {
+ if (cmd->_messageKind != 17)
+ return 0;
+
+ switch(cmd->_messageNum) {
+ case MSG_LIFT_CLOSEDOOR:
+ g_fp->lift_closedoorSeq();
+ break;
+
+ case MSG_LIFT_EXITLIFT:
+ g_fp->lift_exitSeq(cmd);
+ break;
+
+ case MSG_LIFT_STARTEXITQUEUE:
+ g_fp->lift_startExitQueue();
+ break;
+
+ case MSG_SC4_HIDEBOOT:
+ g_vars->scene15_boot->_flags &= 0xFFFB;
+ break;
+
+ case MSG_SC15_STOPCHANTING:
+ g_fp->stopAllSoundInstances(SND_15_001);
+
+ g_vars->scene15_chantingCountdown = 120;
+ break;
+
+ case MSG_SC15_ASSDRYG:
+ if (g_fp->_rnd->getRandomNumber(1))
+ g_fp->playSound(SND_15_011, 0);
+ else
+ g_fp->playSound(SND_15_006, 0);
+
+ break;
+
+ case MSG_SC15_LADDERTOBACK:
+ g_vars->scene15_ladder->_priority = 60;
+ break;
+
+ case MSG_LIFT_GO:
+ g_fp->lift_goAnimation();
+ break;
+
+ case MSG_LIFT_CLICKBUTTON:
+ g_fp->lift_clickButton();
+ break;
+
+ case MSG_SC15_PULL:
+ if (g_vars->scene15_plusminus->_statics->_staticsId == ST_PMS_MINUS)
+ g_vars->scene15_plusminus->_statics = g_vars->scene15_plusminus->getStaticsById(ST_PMS_PLUS);
+ else
+ g_vars->scene15_plusminus->_statics = g_vars->scene15_plusminus->getStaticsById(ST_PMS_MINUS);
+
+ break;
+
+ case 64:
+ g_fp->lift_sub05(cmd);
+ break;
+
+ case 29:
+ {
+ if (g_fp->_currentScene->getPictureObjectIdAtPos(cmd->_sceneClickX, cmd->_sceneClickY) == PIC_SC15_LADDER) {
+ handleObjectInteraction(g_fp->_aniMan, g_fp->_currentScene->getPictureObjectById(PIC_SC15_DTRUBA, 0), cmd->_keyCode);
+ cmd->_messageKind = 0;
+
+ return 0;
+ }
+
+ StaticANIObject *ani = g_fp->_currentScene->getStaticANIObjectAtPos(cmd->_sceneClickX, cmd->_sceneClickY);
+
+ if (ani && ani->_id == ANI_LIFTBUTTON) {
+ g_fp->lift_sub1(ani);
+
+ cmd->_messageKind = 0;
+ }
+ break;
+ }
+
+ case 30:
+ // nop
+ break;
+
+ case 33:
+ if (g_fp->_aniMan2) {
+ int x = g_fp->_aniMan2->_ox;
+
+ if (x < g_fp->_sceneRect.left + 200)
+ g_fp->_currentScene->_x = x - 300 - g_fp->_sceneRect.left;
+
+ if (x > g_fp->_sceneRect.right - 200)
+ g_fp->_currentScene->_x = x + 300 - g_fp->_sceneRect.right;
+ }
+
+ if (g_vars->scene15_chantingCountdown > 0) {
+ g_vars->scene15_chantingCountdown--;
+
+ if (!g_vars->scene15_chantingCountdown)
+ g_fp->playSound(SND_15_001, 1);
+ }
+
+ g_fp->_behaviorManager->updateBehaviors();
+ }
+
+ return 0;
+}
+
+} // End of namespace Fullpipe
diff --git a/engines/fullpipe/scenes/scene16.cpp b/engines/fullpipe/scenes/scene16.cpp
new file mode 100644
index 0000000000..b1e261287a
--- /dev/null
+++ b/engines/fullpipe/scenes/scene16.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 "fullpipe/fullpipe.h"
+
+#include "fullpipe/objectnames.h"
+#include "fullpipe/constants.h"
+
+#include "fullpipe/gameloader.h"
+#include "fullpipe/motion.h"
+#include "fullpipe/scenes.h"
+#include "fullpipe/statics.h"
+
+#include "fullpipe/interaction.h"
+#include "fullpipe/behavior.h"
+
+
+namespace Fullpipe {
+
+void scene16_initScene(Scene *sc) {
+ g_vars->scene16_figures.clear();
+ g_vars->scene16_walkingBoy = 0;
+ g_vars->scene16_walkingGirl = 0;
+ g_vars->scene16_walkingCount = 200;
+ g_vars->scene16_wire = sc->getStaticANIObject1ById(ANI_WIRE16, -1);
+ g_vars->scene16_mug = sc->getStaticANIObject1ById(ANI_MUG, -1);
+ g_vars->scene16_jettie = sc->getStaticANIObject1ById(ANI_JETTIE, -1);
+ g_vars->scene16_boot = sc->getStaticANIObject1ById(ANI_BOOT_16, -1);
+ g_vars->scene16_girlIsLaughing = false;
+ g_vars->scene16_sound = SND_16_034;
+
+ if (g_fp->getObjectState(sO_Bridge) == g_fp->getObjectEnumState(sO_Bridge, sO_Convoluted)) {
+ g_vars->scene16_placeIsOccupied = true;
+
+ StaticANIObject *boy[2];
+ boy[0] = sc->getStaticANIObject1ById(ANI_BOY, -1);
+ boy[0]->loadMovementsPixelData();
+
+ 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]);
+
+ idx++;
+
+ if (idx >= 2)
+ idx = 0;
+ }
+
+ g_vars->scene16_figures.push_back(sc->getStaticANIObject1ById(ANI_GIRL, -1));
+
+ for (int i = 0; i < 4; i++) {
+ g_vars->scene16_figures.push_back(boy[idx]);
+
+ idx++;
+
+ if (idx >= 2)
+ idx = 0;
+ }
+ } else {
+ g_fp->setObjectState(sO_Girl, g_fp->getObjectEnumState(sO_Girl, sO_IsSwinging));
+
+ g_vars->scene16_placeIsOccupied = false;
+
+ StaticANIObject *ani = new StaticANIObject(g_fp->accessScene(SC_COMMON)->getStaticANIObject1ById(ANI_BEARDED_CMN, -1));
+ ani->_movement = 0;
+ ani->_statics = (Statics *)ani->_staticsList[0];
+ sc->addStaticANIObject(ani, 1);
+ }
+
+ if (g_fp->getObjectState(sO_Girl) == g_fp->getObjectEnumState(sO_Girl, sO_IsLaughing)) {
+ StaticANIObject *girl = sc->getStaticANIObject1ById(ANI_GIRL, -1);
+
+ girl->show1(554, 432, MV_GRL_LAUGH_POPA, 0);
+ girl->_priority = 20;
+ }
+
+ if (g_fp->getObjectState(sO_Cup) == g_fp->getObjectEnumState(sO_Cup, sO_In_16)) {
+ g_vars->scene16_mug->_statics = g_vars->scene16_mug->getStaticsById(ST_MUG_EMPTY);
+ g_vars->scene16_mug->_movement = 0;
+ g_vars->scene16_mug->setOXY(409, 459);
+ g_vars->scene16_mug->_priority = 5;
+ g_vars->scene16_mug->_flags |= 4;
+ }
+}
+
+int scene16_updateCursor() {
+ g_fp->updateCursorCommon();
+
+ if (g_fp->_objectIdAtCursor == PIC_SC16_TUMBA) {
+ if (g_fp->_cursorId == PIC_CSR_DEFAULT)
+ g_fp->_cursorId = PIC_CSR_ITN;
+ } else {
+ if (g_fp->_objectIdAtCursor == ANI_MUG && g_fp->_cursorId == PIC_CSR_ITN && g_vars->scene16_mug->_statics->_staticsId == ST_MUG_FULL)
+ g_fp->_cursorId = PIC_CSR_ITN_GREEN;
+ }
+
+ return g_fp->_cursorId;
+}
+
+void sceneHandler16_laughSound() {
+ int snd = SND_16_035;
+
+ switch (g_vars->scene16_sound) {
+ case SND_16_034:
+ snd = SND_16_035;
+ break;
+
+ case SND_16_035:
+ snd = SND_16_037;
+ break;
+
+ case SND_16_037:
+ snd = SND_16_034;
+ break;
+ }
+
+ g_vars->scene16_sound = snd;
+
+ g_fp->playSound(snd, 0);
+}
+
+void sceneHandler16_showBearded() {
+ if (g_fp->getObjectState(sO_Bridge) == g_fp->getObjectEnumState(sO_Bridge, sO_Unconvoluted)) {
+ StaticANIObject *brd = g_fp->_currentScene->getStaticANIObject1ById(ANI_BEARDED_CMN, -1);
+
+ if (!brd || !(brd->_flags & 4))
+ chainQueue(QU_BRD16_STARTBEARDED, 0);
+ }
+}
+
+void sceneHandler16_showMugFull() {
+ g_vars->scene16_mug->changeStatics2(ST_MUG_FULL);
+}
+
+void sceneHandler16_fillMug() {
+ if (g_vars->scene16_mug->_flags & 4) {
+ g_vars->scene16_jettie->_priority = 2;
+ g_vars->scene16_jettie->startAnim(MV_JTI_FLOWIN, 0, -1);
+
+ if (g_fp->_aniMan->_movement) {
+ if (g_fp->_aniMan->_movement->_id == MV_MAN16_TAKEMUG) {
+ g_fp->_aniMan->changeStatics2(ST_MAN_RIGHT);
+
+ g_vars->scene16_mug->show1(-1, -1, -1, 0);
+
+ g_fp->setObjectState(sO_Cup, g_fp->getObjectEnumState(sO_Cup, sO_DudeHas));
+ }
+ }
+ return;
+ }
+
+ MessageQueue *mq;
+
+ if (!(g_vars->scene16_boot->_flags & 4)) {
+ g_vars->scene16_jettie->_priority = 15;
+ g_vars->scene16_jettie->startAnim(MV_JTI_FLOWBY, 0, -1);
+
+ if (g_vars->scene16_walkingBoy) {
+ mq = new MessageQueue(g_fp->_currentScene->getMessageQueueById(QU_SC16_BOYOUT), 0, 1);
+
+ mq->replaceKeyCode(-1, g_vars->scene16_walkingBoy->_okeyCode);
+ if (mq->chain(g_vars->scene16_walkingBoy) || !mq)
+ return;
+ } else {
+ if (!g_vars->scene16_walkingGirl)
+ return;
+
+ mq = new MessageQueue(g_fp->_currentScene->getMessageQueueById(QU_SC16_GIRLOUT), 0, 1);
+
+ mq->replaceKeyCode(-1, g_vars->scene16_walkingGirl->_okeyCode);
+ if (mq->chain(g_vars->scene16_walkingGirl))
+ return;
+ }
+ delete mq;
+
+ return;
+ }
+
+ g_vars->scene16_jettie->_priority = 15;
+
+ g_vars->scene16_boot->startAnim(MV_BT16_FILL, 0, -1);
+
+ StaticANIObject *ani;
+
+ if (g_vars->scene16_walkingBoy) {
+ mq = new MessageQueue(g_fp->_currentScene->getMessageQueueById(QU_SC16_BOYOUT), 0, 1);
+
+ mq->replaceKeyCode(-1, g_vars->scene16_walkingBoy->_okeyCode);
+
+ ani = g_vars->scene16_walkingBoy;
+ } else {
+ if (!g_vars->scene16_walkingGirl)
+ return;
+
+ mq = new MessageQueue(g_fp->_currentScene->getMessageQueueById(QU_SC16_GIRLOUT), 0, 1);
+
+ mq->replaceKeyCode(-1, g_vars->scene16_walkingGirl->_okeyCode);
+ ani = g_vars->scene16_walkingGirl;
+ }
+
+ if (!mq->chain(ani))
+ delete mq;
+}
+
+void sceneHandler16_startLaugh() {
+ StaticANIObject *girl = g_fp->_currentScene->getStaticANIObject1ById(ANI_GIRL, -1);
+
+ girl->changeStatics2(ST_GRL_STAND);
+
+ MessageQueue *mq = new MessageQueue(g_fp->_currentScene->getMessageQueueById(QU_SC16_GIRLLAUGH), 0, 1);
+
+ mq->replaceKeyCode(-1, girl->_okeyCode);
+ mq->setFlags(mq->getFlags() | 1);
+ mq->chain(0);
+
+ g_fp->getGameLoaderGameVar()->getSubVarByName("OBJSTATES")->setSubVarAsInt(sO_DudeSwinged, 0);
+
+ g_vars->scene16_girlIsLaughing = true;
+}
+
+void sceneHandler16_drink() {
+ if (g_vars->scene16_mug->_flags & 4) {
+ if (!g_vars->scene16_jettie->_movement) {
+ if (!g_vars->scene16_walkingBoy || !g_vars->scene16_walkingBoy->_movement || g_vars->scene16_walkingBoy->_movement->_id != MV_BOY_DRINK) {
+ if (!g_vars->scene16_walkingGirl || !g_vars->scene16_walkingGirl->_movement || g_vars->scene16_walkingGirl->_movement->_id != MV_GRL_DRINK) {
+ if (g_vars->scene16_mug->_statics->_staticsId == ST_MUG_FULL) {
+ MessageQueue *mq;
+ ExCommand *ex;
+
+ if (g_vars->scene16_walkingBoy) {
+ g_fp->_aniMan->_flags |= 0x180;
+
+ g_vars->scene16_walkingBoy->changeStatics2(ST_BOY_STAND);
+ g_vars->scene16_walkingBoy->queueMessageQueue(0);
+
+ 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;
+ ex->_messageNum = 0;
+
+ mq->insertExCommandAt(2, ex);
+ mq->setFlags(mq->getFlags() | 1);
+ mq->chain(0);
+ } else {
+ g_fp->_aniMan->_flags |= 1;
+
+ mq = new MessageQueue(g_fp->_currentScene->getMessageQueueById(QU_SC16_MANDRINK), 0, 1);
+
+ ex = new ExCommand(ANI_MAN, 34, 256, 0, 0, 0, 1, 0, 0, 0);
+ ex->_excFlags |= 3u;
+ ex->_field_14 = 256;
+ ex->_messageNum = 0;
+
+ mq->addExCommandToEnd(ex);
+ mq->setFlags(mq->getFlags() | 1);
+ mq->chain(0);
+
+ g_fp->_currentScene->getStaticANIObject1ById(ANI_GIRL, -1)->changeStatics2(ST_GRL_STAND);
+ }
+
+ g_fp->_currentScene->getStaticANIObject1ById(ANI_WIRE16, -1)->show1(-1, -1, -1, 0);
+ } else {
+ chainObjQueue(g_fp->_aniMan, QU_SC16_TAKEMUG, 1);
+ }
+ }
+ }
+ }
+ }
+}
+
+void sceneHandler16_mugClick() {
+ if (abs(310 - g_fp->_aniMan->_ox) >= 1 || abs(449 - g_fp->_aniMan->_oy) >= 1
+ || g_fp->_aniMan->_movement || g_fp->_aniMan->_statics->_staticsId != ST_MAN_RIGHT) {
+ MessageQueue *mq = getCurrSceneSc2MotionController()->method34(g_fp->_aniMan, 310, 449, 1, ST_MAN_RIGHT);
+
+ if (mq) {
+ ExCommand *ex = new ExCommand(0, 17, MSG_SC16_MUGCLICK, 0, 0, 0, 1, 0, 0, 0);
+ ex->_excFlags = 2;
+ mq->addExCommandToEnd(ex);
+
+ postExCommand(g_fp->_aniMan->_id, 2, 310, 449, 0, -1);
+ }
+ } else {
+ sceneHandler16_drink();
+ }
+}
+
+void sceneHandler16_showMan() {
+ g_fp->_aniMan->changeStatics2(ST_MAN_RIGHT);
+ g_fp->_aniMan->show1(-1, -1, -1, 0);
+
+ g_vars->scene16_mug->show1(-1, -1, -1, 0);
+}
+
+void sceneHandler16_showMug() {
+ chainQueue(QU_SC16_SHOWMUG, 0);
+}
+
+void sceneHandler16_hideMan() {
+ g_fp->_aniMan->changeStatics2(ST_MAN_RIGHT);
+ g_fp->_aniMan->hide();
+
+ g_vars->scene16_mug->hide();
+}
+
+void sceneHandler16_hideMug() {
+ g_vars->scene16_mug->hide();
+}
+
+void sceneHandler16_hideWire() {
+ g_vars->scene16_wire->hide();
+}
+
+void sceneHandler16_showWire() {
+ g_vars->scene16_wire->show1(-1, -1, -1, 0);
+}
+
+void sceneHandler16_putOnWheel() {
+ StaticANIObject *ani = g_vars->scene16_walkingBoy;
+
+ if (!ani)
+ ani = g_vars->scene16_walkingGirl;
+
+ if (ani)
+ g_vars->scene16_figures.push_back(ani);
+
+ ani = g_vars->scene16_figures.front();
+
+ g_vars->scene16_figures.pop_front();
+
+ if (ani) {
+ MessageQueue *mq;
+
+ if (ani->_id == ANI_BOY) {
+ mq = new MessageQueue(g_fp->_currentScene->getMessageQueueById(QU_SC16_GOBOY), 0, 1);
+
+ mq->replaceKeyCode(-1, ani->_okeyCode);
+ mq->chain(0);
+
+ g_vars->scene16_walkingBoy = ani;
+ g_vars->scene16_walkingGirl = 0;
+ } else if (ani->_id == ANI_GIRL) {
+ if (g_fp->getObjectState(sO_Girl) == g_fp->getObjectEnumState(sO_Girl, sO_IsSwinging)) {
+ mq = new MessageQueue(g_fp->_currentScene->getMessageQueueById(QU_SC16_GOGIRL), 0, 1);
+
+ mq->replaceKeyCode(-1, ani->_okeyCode);
+ mq->chain(0);
+
+ g_vars->scene16_walkingBoy = 0;
+ g_vars->scene16_walkingGirl = ani;
+ }
+ }
+ }
+}
+
+void sceneHandler16_girlROTFL() {
+ StaticANIObject *girl = g_fp->_currentScene->getStaticANIObject1ById(ANI_GIRL, -1);
+
+ girl->changeStatics2(ST_GRL_LAUGH);
+ girl->startAnim(MV_GRL_FALL, 0, -1);
+
+ g_vars->scene16_girlIsLaughing = false;
+}
+
+int sceneHandler16(ExCommand *cmd) {
+ if (cmd->_messageKind != 17)
+ return 0;
+
+ switch(cmd->_messageNum) {
+ case MSG_SC16_LAUGHSOUND:
+ sceneHandler16_laughSound();
+ break;
+
+ case MSG_SC16_SHOWBEARDED:
+ sceneHandler16_showBearded();
+ break;
+
+ case MSG_SC16_SHOWMUGFULL:
+ sceneHandler16_showMugFull();
+ break;
+
+ case MSG_SC16_FILLMUG:
+ sceneHandler16_fillMug();
+ break;
+
+ case MSG_SC16_STARTLAUGH:
+ sceneHandler16_startLaugh();
+ break;
+
+ case MSG_SC16_MUGCLICK:
+ if (!g_fp->_aniMan->isIdle() || g_fp->_aniMan->_flags & 0x100)
+ cmd->_messageKind = 0;
+ else
+ sceneHandler16_mugClick();
+
+ break;
+
+ case MSG_SC16_SHOWMAN:
+ sceneHandler16_showMan();
+ break;
+
+ case MSG_SC16_SHOWMUG:
+ sceneHandler16_showMug();
+ break;
+
+ case MSG_SC16_HIDEMAN:
+ sceneHandler16_hideMan();
+ break;
+
+ case MSG_SC16_HIDEMUG:
+ sceneHandler16_hideMug();
+ break;
+
+ case MSG_SC16_HIDEWIRE:
+ sceneHandler16_hideWire();
+ break;
+
+ case MSG_SC16_SHOWWIRE:
+ sceneHandler16_showWire();
+ break;
+
+ case 33:
+ if (g_fp->_aniMan2) {
+ int x = g_fp->_aniMan2->_ox;
+
+ if (x < g_fp->_sceneRect.left + 200)
+ g_fp->_currentScene->_x = x - 300 - g_fp->_sceneRect.left;
+
+ if (x > g_fp->_sceneRect.right - 200)
+ g_fp->_currentScene->_x = x + 300 - g_fp->_sceneRect.right;
+ }
+
+ if (g_vars->scene16_placeIsOccupied) {
+ g_vars->scene16_walkingCount++;
+
+ if (g_vars->scene16_walkingCount < 280) {
+ sceneHandler16_putOnWheel();
+
+ g_vars->scene16_walkingCount = 0;
+ }
+ }
+
+ if (g_vars->scene16_girlIsLaughing) {
+ if (g_fp->_aniMan->_movement)
+ if (g_fp->_aniMan->_movement->_id == MV_MAN_TURN_RL)
+ sceneHandler16_girlROTFL();
+ }
+
+ g_fp->_behaviorManager->updateBehaviors();
+ g_fp->startSceneTrack();
+
+ }
+
+ return 0;
+}
+
+} // End of namespace Fullpipe
diff --git a/engines/fullpipe/scenes/scene17.cpp b/engines/fullpipe/scenes/scene17.cpp
new file mode 100644
index 0000000000..73bf7ab1c0
--- /dev/null
+++ b/engines/fullpipe/scenes/scene17.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 "fullpipe/fullpipe.h"
+
+#include "fullpipe/objectnames.h"
+#include "fullpipe/constants.h"
+
+#include "fullpipe/gameloader.h"
+#include "fullpipe/motion.h"
+#include "fullpipe/scenes.h"
+#include "fullpipe/statics.h"
+
+#include "fullpipe/interaction.h"
+#include "fullpipe/behavior.h"
+#include "fullpipe/floaters.h"
+
+namespace Fullpipe {
+
+void scene17_initScene(Scene *sc) {
+ g_vars->scene17_flyState = 1;
+ g_vars->scene17_sugarIsShown = false;
+ g_vars->scene17_sceneOldEdgeX = 0;
+ g_vars->scene17_flyCountdown = 0;
+ g_vars->scene17_hand = sc->getStaticANIObject1ById(ANI_HAND17, -1);
+}
+
+void scene17_restoreState() {
+ if (g_fp->getObjectState(sO_UsherHand) == g_fp->getObjectEnumState(sO_UsherHand, sO_WithCoin)) {
+ g_fp->_behaviorManager->setBehaviorEnabled(g_vars->scene17_hand, ST_HND17_EMPTY, QU_HND17_ASK, 0);
+ g_fp->_behaviorManager->setBehaviorEnabled(g_vars->scene17_hand, ST_HND17_EMPTY, QU_HND17_TOCYCLE, 0);
+
+ g_vars->scene17_handPhase = false;
+ } else {
+ g_fp->_behaviorManager->setBehaviorEnabled(g_vars->scene17_hand, ST_HND17_EMPTY, QU_HND17_ASK, 0);
+ g_fp->_behaviorManager->setBehaviorEnabled(g_vars->scene17_hand, ST_HND17_EMPTY, QU_HND17_TOCYCLE, 1);
+
+ g_vars->scene17_handPhase = true;
+ }
+
+ g_fp->_floaters->init(g_fp->getGameLoaderGameVar()->getSubVarByName("SC_17"));
+
+ g_vars->scene17_flyState = g_fp->getObjectState(sO_Fly_17);
+
+ if (g_vars->scene17_flyState <= 0 ) {
+ g_vars->scene17_flyCountdown = g_fp->_rnd->getRandomNumber(600) + 600;
+
+ g_vars->scene17_flyState = g_fp->_rnd->getRandomNumber(4) + 1;
+ }
+
+ g_fp->setObjectState(sO_Fly_17, g_vars->scene17_flyState - 1);
+}
+
+int scene17_updateCursor() {
+ g_fp->updateCursorCommon();
+
+ if (g_fp->_objectIdAtCursor != PIC_SC17_RTRUBA2 && g_fp->_objectIdAtCursor != PIC_SC17_RTRUBA)
+ return g_fp->_cursorId;
+
+ if (!g_vars->scene17_handPhase)
+ return g_fp->_cursorId;
+
+ int item = g_fp->_inventory->getSelectedItemId();
+
+ if ((g_fp->_cursorId != PIC_CSR_DEFAULT_INV || item != ANI_INV_COIN) && item != ANI_INV_BOOT && item != ANI_INV_HAMMER)
+ ; // empty
+ else
+ g_fp->_cursorId = PIC_CSR_ITN_INV;
+
+ return g_fp->_cursorId;
+}
+
+void sceneHandler17_drop() {
+ StaticANIObject *mug = g_fp->_currentScene->getStaticANIObject1ById(ANI_MUG_17, -1);
+ StaticANIObject *jet = g_fp->_currentScene->getStaticANIObject1ById(ANI_JET_17, -1);
+
+ if (mug && mug->_flags & 4) {
+ mug->changeStatics2(ST_MUG17_EMPTY);
+ chainQueue(QU_SC17_FILLMUG_DROP, 0);
+ } else if (jet) {
+ jet->queueMessageQueue(0);
+ chainQueue(QU_JET17_DROP, 0);
+ }
+}
+
+void sceneHandler17_fillBottle() {
+ StaticANIObject *bottle = g_fp->_currentScene->getStaticANIObject1ById(ANI_INV_BOTTLE, -1);
+ StaticANIObject *mug = g_fp->_currentScene->getStaticANIObject1ById(ANI_MUG_17, -1);
+ StaticANIObject *boot = g_fp->_currentScene->getStaticANIObject1ById(ANI_BOOT_17, -1);
+
+ if (bottle && (bottle->_flags & 4))
+ chainQueue(QU_SC17_FILLBOTTLE, 1);
+ else if (mug && (mug->_flags & 4) && mug->_statics->_staticsId == ST_MUG17_EMPTY)
+ chainQueue(QU_SC17_FILLMUG, 1);
+ else if (boot && (boot->_flags & 4))
+ chainQueue(QU_SC17_FILLBOOT, 1);
+ else
+ chainQueue(QU_JET17_FLOW, 1);
+}
+
+void sceneHandler17_testTruba() {
+ if (g_vars->scene17_hand->isIdle()) {
+ if (!g_vars->scene17_hand->_movement || g_vars->scene17_hand->_movement->_id != MV_HND17_FIGA) {
+ g_vars->scene17_hand->changeStatics2(ST_HND17_EMPTY);
+ g_vars->scene17_hand->startAnim(MV_HND17_FIGA, 0, -1);
+ }
+ }
+}
+
+void sceneHandler17_showBottle() {
+ chainQueue(QU_SC17_SHOWBOTTLE, 0);
+}
+
+void sceneHandler17_hideSugar() {
+ StaticANIObject *sugar = g_fp->_currentScene->getStaticANIObject1ById(ANI_INV_SUGAR, -1);
+
+ if (sugar)
+ sugar->hide();
+}
+
+void sceneHandler17_showSugar() {
+ chainQueue(QU_SC17_SHOWSUGAR, 0);
+
+ g_vars->scene17_sugarIsShown = true;
+}
+
+void sceneHandler17_moonshineFill() {
+ StaticANIObject *moonshiner = g_fp->_currentScene->getStaticANIObject1ById(ANI_SAMOGONSHCHIK, -1);
+
+ if (!(moonshiner->_flags & 0x80)) {
+ moonshiner->changeStatics2(ST_SMG_SIT);
+ chainObjQueue(moonshiner, QU_SMG_FILLBOTTLE, 1);
+
+ g_vars->scene17_sugarIsShown = false;
+ }
+}
+
+void sceneHandler17_updateFlies() {
+ g_fp->_floaters->genFlies(g_fp->_currentScene, 239, -50, 20, 4);
+
+ g_fp->_floaters->_array2[0]->countdown = g_fp->_rnd->getRandomNumber(5) + 6;
+ g_fp->_floaters->_array2[0]->val6 = 239;
+ g_fp->_floaters->_array2[0]->val7 = -50;
+}
+
+
+int sceneHandler17(ExCommand *cmd) {
+ if (cmd->_messageKind != 17)
+ return 0;
+
+ switch (cmd->_messageNum) {
+ case MSG_SC17_DROP:
+ sceneHandler17_drop();
+ break;
+
+ case MSG_SC17_UPDATEHAND:
+ if (g_fp->getObjectState(sO_UsherHand) == g_fp->getObjectEnumState(sO_UsherHand, sO_WithCoin)) {
+ g_fp->_behaviorManager->setBehaviorEnabled(g_vars->scene17_hand, ST_HND17_EMPTY, QU_HND17_ASK, 0);
+ g_fp->_behaviorManager->setBehaviorEnabled(g_vars->scene17_hand, ST_HND17_EMPTY, QU_HND17_TOCYCLE, 0);
+
+ g_vars->scene17_handPhase = false;
+ } else {
+ g_fp->_behaviorManager->setBehaviorEnabled(g_vars->scene17_hand, ST_HND17_EMPTY, QU_HND17_ASK, 0);
+ g_fp->_behaviorManager->setBehaviorEnabled(g_vars->scene17_hand, ST_HND17_EMPTY, QU_HND17_TOCYCLE, 1);
+
+ g_vars->scene17_handPhase = true;
+ }
+ break;
+
+ case MSG_SC17_FILLBOTTLE:
+ sceneHandler17_fillBottle();
+ break;
+
+ case MSG_SC17_TESTTRUBA:
+ sceneHandler17_testTruba();
+ break;
+
+ case MSG_SC17_SHOWBOTTLE:
+ sceneHandler17_showBottle();
+ break;
+
+ case MSG_SC17_HIDESUGAR:
+ sceneHandler17_hideSugar();
+ break;
+
+ case MSG_SC17_SHOWSUGAR:
+ sceneHandler17_showSugar();
+ break;
+
+ case 29:
+ {
+ int pic = g_fp->_currentScene->getPictureObjectIdAtPos(cmd->_sceneClickX, cmd->_sceneClickY);
+
+ if (pic == PIC_SC17_RTRUBA2 || pic == PIC_SC17_RTRUBA) {
+ if (cmd->_keyCode == ANI_INV_COIN || cmd->_keyCode == ANI_INV_BOOT || cmd->_keyCode == ANI_INV_HAMMER) {
+ if (g_vars->scene17_handPhase) {
+ if (g_fp->_aniMan->isIdle()) {
+ if (!(g_fp->_aniMan->_flags & 0x100)) {
+ handleObjectInteraction(g_fp->_aniMan, g_vars->scene17_hand, cmd->_keyCode);
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+ break;
+
+ case 33:
+ {
+ int x = g_vars->scene17_sceneEdgeX;
+ g_vars->scene17_sceneOldEdgeX = g_vars->scene17_sceneEdgeX;
+
+ if (g_fp->_aniMan2) {
+ x = g_fp->_aniMan2->_ox;
+
+ g_vars->scene17_sceneEdgeX = x;
+
+ if (x < g_fp->_sceneRect.left + 200) {
+ g_fp->_currentScene->_x = x - 300 - g_fp->_sceneRect.left;
+
+ x = g_vars->scene17_sceneEdgeX;
+ }
+
+ if (x > g_fp->_sceneRect.right - 200) {
+ g_fp->_currentScene->_x = x + 300 - g_fp->_sceneRect.right;
+ x = g_vars->scene17_sceneEdgeX;
+ }
+ }
+
+ if (g_vars->scene17_sugarIsShown) {
+ sceneHandler17_moonshineFill();
+ x = g_vars->scene17_sceneEdgeX;
+ }
+
+ if (g_vars->scene17_handPhase) {
+ if (g_vars->scene17_sceneOldEdgeX < 410 && x >= 410) {
+ g_fp->_behaviorManager->setBehaviorEnabled(g_vars->scene17_hand, ST_HND17_EMPTY, QU_HND17_TOCYCLE, 0);
+ g_fp->_behaviorManager->setBehaviorEnabled(g_vars->scene17_hand, ST_HND17_ATTRACT, QU_HND17_ATTRACT, 0);
+ g_fp->_behaviorManager->setBehaviorEnabled(g_vars->scene17_hand, ST_HND17_EMPTY, QU_HND17_ASK, 1);
+ } else if (g_vars->scene17_sceneOldEdgeX > 410 && x <= 410) {
+ g_fp->_behaviorManager->setBehaviorEnabled(g_vars->scene17_hand, ST_HND17_EMPTY, QU_HND17_TOCYCLE, 1);
+ g_fp->_behaviorManager->setBehaviorEnabled(g_vars->scene17_hand, ST_HND17_ATTRACT, QU_HND17_ATTRACT, 1);
+ g_fp->_behaviorManager->setBehaviorEnabled(g_vars->scene17_hand, ST_HND17_EMPTY, QU_HND17_ASK, 0);
+ }
+ }
+
+ --g_vars->scene17_flyCountdown;
+
+ if (!g_vars->scene17_flyCountdown)
+ sceneHandler17_updateFlies();
+
+ g_fp->_floaters->update();
+
+ g_fp->_behaviorManager->updateBehaviors();
+
+ g_fp->startSceneTrack();
+
+ break;
+ }
+ }
+
+ return 0;
+}
+
+} // End of namespace Fullpipe
diff --git a/engines/fullpipe/scenes/scene18and19.cpp b/engines/fullpipe/scenes/scene18and19.cpp
new file mode 100644
index 0000000000..a965cfb98e
--- /dev/null
+++ b/engines/fullpipe/scenes/scene18and19.cpp
@@ -0,0 +1,49 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "fullpipe/fullpipe.h"
+
+#include "fullpipe/objectnames.h"
+#include "fullpipe/constants.h"
+
+#include "fullpipe/gameloader.h"
+#include "fullpipe/motion.h"
+#include "fullpipe/scenes.h"
+#include "fullpipe/statics.h"
+
+#include "fullpipe/interaction.h"
+#include "fullpipe/behavior.h"
+
+
+namespace Fullpipe {
+
+void scene18_preload() {
+ warning("WARNING: scene18_preload()");
+}
+
+void scene19_preload(Scene *sc, int key) {
+ warning("WARNING: scene19_preload()");
+}
+
+
+
+} // End of namespace Fullpipe
diff --git a/engines/fullpipe/scenes/scene20.cpp b/engines/fullpipe/scenes/scene20.cpp
new file mode 100644
index 0000000000..5fed24aabd
--- /dev/null
+++ b/engines/fullpipe/scenes/scene20.cpp
@@ -0,0 +1,155 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public 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 "fullpipe/fullpipe.h"
+
+#include "fullpipe/objectnames.h"
+#include "fullpipe/constants.h"
+
+#include "fullpipe/gameloader.h"
+#include "fullpipe/motion.h"
+#include "fullpipe/scenes.h"
+#include "fullpipe/statics.h"
+
+#include "fullpipe/interaction.h"
+#include "fullpipe/behavior.h"
+#include "fullpipe/floaters.h"
+
+namespace Fullpipe {
+
+void scene20_setExits(Scene *sc) {
+ int thingpar;
+
+ if (g_fp->getObjectState(sO_Grandma) == g_fp->getObjectEnumState(sO_Grandma, sO_OnStool)
+ || g_fp->getObjectState(sO_Grandma) == g_fp->getObjectEnumState(sO_Grandma, sO_OnTheFloor))
+ thingpar = 1;
+ else if (g_fp->getObjectState(sO_Grandma) == g_fp->getObjectEnumState(sO_Grandma, sO_NearPipe)
+ || g_fp->getObjectState(sO_Grandma) == g_fp->getObjectEnumState(sO_Grandma, sO_NearPipeWithStool)) {
+ getSc2MctlCompoundBySceneId(sc->_sceneId)->enableLinks(sO_CloseThing, 1);
+ getSc2MctlCompoundBySceneId(sc->_sceneId)->enableLinks(sO_CloseThing2, 1);
+ getSc2MctlCompoundBySceneId(sc->_sceneId)->enableLinks(sO_CloseThing3, 0);
+
+ return;
+ } else {
+ thingpar = 0;
+ }
+
+ getSc2MctlCompoundBySceneId(sc->_sceneId)->enableLinks(sO_CloseThing, thingpar);
+ getSc2MctlCompoundBySceneId(sc->_sceneId)->enableLinks(sO_CloseThing2, 0);
+ getSc2MctlCompoundBySceneId(sc->_sceneId)->enableLinks(sO_CloseThing3, 1);
+}
+
+void scene20_initScene(Scene *sc) {
+ Scene *oldsc = g_fp->_currentScene;
+
+ g_vars->scene20_grandma = sc->getStaticANIObject1ById(ANI_GRANDMA_20, -1);
+
+ g_fp->_currentScene = sc;
+
+ if (g_fp->getObjectState(sO_Grandma) == g_fp->getObjectEnumState(sO_Grandma, sO_OnTheFloor))
+ g_fp->setObjectState(sO_Grandma, g_fp->getObjectEnumState(sO_Grandma, sO_NearPipe));
+
+ if (g_fp->getObjectState(sO_Grandma) == g_fp->getObjectEnumState(sO_Grandma, sO_OnStool)) {
+ g_vars->scene20_grandma->changeStatics2(ST_GMA20_STOOL);
+ } else if (g_fp->getObjectState(sO_Grandma) == g_fp->getObjectEnumState(sO_Grandma, sO_OnTheFloor)) {
+ g_vars->scene20_grandma->changeStatics2(ST_GMA20_FLOOR);
+ } else if (g_fp->getObjectState(sO_Grandma) == g_fp->getObjectEnumState(sO_Grandma, sO_NearPipe)
+ || g_fp->getObjectState(sO_Grandma) == g_fp->getObjectEnumState(sO_Grandma, sO_NearPipeWithStool)) {
+ g_vars->scene20_grandma->changeStatics2(ST_GMA20_STAND);
+ } else {
+ g_vars->scene20_grandma->hide();
+ }
+
+ scene20_setExits(sc);
+
+ g_fp->_floaters->init(g_fp->getGameLoaderGameVar()->getSubVarByName("SC_20"));
+
+ for (int i = 0; i < 3; i++) {
+ g_fp->_floaters->genFlies(sc, g_fp->_rnd->getRandomNumber(101) + 70, g_fp->_rnd->getRandomNumber(51) + 175, 100, 0);
+ g_fp->_floaters->_array2[g_fp->_floaters->_array2.size() - 1]->val13 = g_fp->_rnd->getRandomNumber(9);
+ }
+
+ g_fp->_currentScene = oldsc;
+
+ g_vars->scene20_fliesCountdown = g_fp->_rnd->getRandomNumber(200) + 400;
+}
+
+void sceneHandler20_updateFlies() {
+ int sz = g_fp->_floaters->_array2.size();
+
+ if (sz < 3) {
+ g_fp->_floaters->genFlies(g_fp->_currentScene, 253, 650, 200, 0);
+ g_fp->_floaters->_array2[sz - 1]->val2 = 250;
+ g_fp->_floaters->_array2[sz - 1]->val3 = 200;
+ } else {
+ int idx = g_fp->_rnd->getRandomNumber(sz);
+
+ g_fp->_floaters->_array2[idx]->countdown = 0;
+ g_fp->_floaters->_array2[idx]->fflags |= 4u;
+ g_fp->_floaters->_array2[idx]->val2 = 250;
+ g_fp->_floaters->_array2[idx]->val3 = 200;
+ g_fp->_floaters->_array2[idx]->val6 = 253;
+ g_fp->_floaters->_array2[idx]->val7 = 650;
+ g_fp->_floaters->_array2[idx]->ani->_priority = 200;
+ }
+
+ g_vars->scene20_fliesCountdown = g_fp->_rnd->getRandomNumber(200) + 400;
+}
+
+int sceneHandler20(ExCommand *cmd) {
+ if (cmd->_messageKind != 17)
+ return 0;
+
+ switch (cmd->_messageNum) {
+ case MSG_SC20_UPDATELOCKABLE:
+ scene20_setExits(g_fp->_currentScene);
+ break;
+
+ case 33:
+ if (g_fp->_aniMan2) {
+ int x = g_fp->_aniMan2->_ox;
+
+ if (x < g_fp->_sceneRect.left + 200)
+ g_fp->_currentScene->_x = x - 300 - g_fp->_sceneRect.left;
+
+ if (x > g_fp->_sceneRect.right - 200)
+ g_fp->_currentScene->_x = x + 300 - g_fp->_sceneRect.right;
+ }
+
+ --g_vars->scene20_fliesCountdown;
+
+ if (g_vars->scene20_fliesCountdown <= 0)
+ sceneHandler20_updateFlies();
+
+ g_fp->_floaters->update();
+
+ g_fp->_behaviorManager->updateBehaviors();
+
+ g_fp->startSceneTrack();
+
+ break;
+ }
+
+ return 0;
+}
+
+} // End of namespace Fullpipe
diff --git a/engines/fullpipe/scenes/scene21.cpp b/engines/fullpipe/scenes/scene21.cpp
new file mode 100644
index 0000000000..5a6509964d
--- /dev/null
+++ b/engines/fullpipe/scenes/scene21.cpp
@@ -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.
+ *
+ */
+
+#include "fullpipe/fullpipe.h"
+
+#include "fullpipe/objectnames.h"
+#include "fullpipe/constants.h"
+
+#include "fullpipe/gameloader.h"
+#include "fullpipe/motion.h"
+#include "fullpipe/scenes.h"
+#include "fullpipe/statics.h"
+
+#include "fullpipe/interaction.h"
+#include "fullpipe/behavior.h"
+
+
+namespace Fullpipe {
+
+void scene21_initScene(Scene *sc) {
+ Scene *oldsc = g_fp->_currentScene;
+
+ g_vars->scene21_giraffeBottom = sc->getStaticANIObject1ById(ANI_GIRAFFE_BOTTOM, -1);
+ g_fp->_currentScene = sc;
+
+ if (g_fp->getObjectState(sO_LowerPipe_21) == g_fp->getObjectEnumState(sO_LowerPipe_21, sO_IsOpened)) {
+ g_vars->scene21_giraffeBottom->changeStatics2(ST_GRFB_HANG);
+ g_vars->scene21_pipeIsOpen = true;
+ g_vars->scene21_wigglePos = 0.0;
+ g_vars->scene21_giraffeBottomX = g_vars->scene21_giraffeBottom->_ox;
+ g_vars->scene21_giraffeBottomY = g_vars->scene21_giraffeBottom->_oy;
+ g_vars->scene21_wiggleTrigger = false;
+ } else {
+ g_vars->scene21_pipeIsOpen = false;
+ }
+ g_fp->_currentScene = oldsc;
+ g_fp->initArcadeKeys("SC_21");
+}
+
+int scene21_updateCursor() {
+ g_fp->updateCursorCommon();
+
+ if (g_fp->_cursorId == PIC_CSR_ITN && g_fp->_objectIdAtCursor == PIC_SC21_DTRUBA)
+
+ g_fp->_cursorId = PIC_CSR_GOD;
+
+ return g_fp->_cursorId;
+}
+
+void sceneHandler21_doWiggle() {
+ g_vars->scene21_giraffeBottom->setOXY((int)(cos(g_vars->scene21_wigglePos) * 4.0) + g_vars->scene21_giraffeBottom->_ox,
+ g_vars->scene21_giraffeBottom->_oy);
+
+ g_vars->scene21_wigglePos += 0.19635;
+
+ if (g_vars->scene21_wigglePos > 6.2831853) {
+ g_vars->scene21_wigglePos = 0;
+
+ if (!g_vars->scene21_giraffeBottom->_movement)
+ g_vars->scene21_giraffeBottom->setOXY(g_vars->scene21_giraffeBottomX, g_vars->scene21_giraffeBottomY);
+ }
+}
+
+int sceneHandler21(ExCommand *cmd) {
+ if (cmd->_messageKind != 17)
+ return 0;
+
+ switch (cmd->_messageNum) {
+ case MSG_SC21_UPDATEASS:
+ if (g_fp->getObjectState(sO_LowerPipe_21) == g_fp->getObjectEnumState(sO_LowerPipe_21, sO_IsOpened)) {
+ g_vars->scene21_giraffeBottom->changeStatics2(ST_GRFB_HANG);
+ g_vars->scene21_giraffeBottom->setOXY(g_vars->scene21_giraffeBottomX, g_vars->scene21_giraffeBottomY);
+ g_vars->scene21_giraffeBottom->changeStatics2(ST_GRFB_SIT);
+
+ g_vars->scene21_pipeIsOpen = false;
+
+ g_fp->setObjectState(sO_LowerPipe_21, g_fp->getObjectEnumState(sO_LowerPipe_21, sO_IsClosed));
+ }
+
+ break;
+
+ case 29:
+ {
+ StaticANIObject *ani = g_fp->_currentScene->getStaticANIObjectAtPos(cmd->_sceneClickX, cmd->_sceneClickY);
+ if (!ani || !canInteractAny(g_fp->_aniMan, ani, cmd->_keyCode)) {
+ int picId = g_fp->_currentScene->getPictureObjectIdAtPos(cmd->_sceneClickX, cmd->_sceneClickY);
+
+ PictureObject *pic = g_fp->_currentScene->getPictureObjectById(picId, 0);
+
+ if (!pic || !canInteractAny(g_fp->_aniMan, pic, cmd->_keyCode) ) {
+ if ((g_fp->_sceneRect.right - cmd->_sceneClickX < 47 && g_fp->_sceneRect.right < g_fp->_sceneWidth - 1)
+ || (cmd->_sceneClickX - g_fp->_sceneRect.left < 47 && g_fp->_sceneRect.left > 0))
+ g_fp->processArcade(cmd);
+ }
+ }
+
+ break;
+ }
+
+ case 33:
+ if (g_fp->_aniMan2) {
+ int x = g_fp->_aniMan2->_ox;
+
+ if (x <= g_fp->_sceneWidth - 460) {
+ if (x < g_fp->_sceneRect.left + 200)
+ g_fp->_currentScene->_x = x - 300 - g_fp->_sceneRect.left;
+ } else {
+ g_fp->_currentScene->_x = g_fp->_sceneWidth - x;
+ }
+
+ if (x > g_fp->_sceneRect.right - 200)
+ g_fp->_currentScene->_x = x + 300 - g_fp->_sceneRect.right;
+ }
+
+ if (g_vars->scene21_pipeIsOpen && !g_vars->scene21_wiggleTrigger)
+ sceneHandler21_doWiggle();
+
+ g_vars->scene21_wiggleTrigger = !g_vars->scene21_wiggleTrigger;
+
+ g_fp->_behaviorManager->updateBehaviors();
+ g_fp->startSceneTrack();
+
+ break;
+ }
+
+ return 0;
+}
+
+} // End of namespace Fullpipe
diff --git a/engines/fullpipe/scenes/scene22.cpp b/engines/fullpipe/scenes/scene22.cpp
new file mode 100644
index 0000000000..13c9ab36e9
--- /dev/null
+++ b/engines/fullpipe/scenes/scene22.cpp
@@ -0,0 +1,395 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "fullpipe/fullpipe.h"
+
+#include "fullpipe/objectnames.h"
+#include "fullpipe/constants.h"
+
+#include "fullpipe/gameloader.h"
+#include "fullpipe/motion.h"
+#include "fullpipe/scenes.h"
+#include "fullpipe/statics.h"
+
+#include "fullpipe/interaction.h"
+#include "fullpipe/behavior.h"
+
+
+namespace Fullpipe {
+
+void scene22_initScene(Scene *sc) {
+ g_vars->scene22_bag = sc->getStaticANIObject1ById(ANI_MESHOK, -1);
+
+ Scene *oldsc = g_fp->_currentScene;
+ g_fp->_currentScene = sc;
+
+ g_vars->scene22_giraffeMiddle = sc->getStaticANIObject1ById(ANI_GIRAFFE_MIDDLE, -1);
+ g_vars->scene22_dudeIsOnStool = false;
+ g_vars->scene22_interactionIsDisabled = false;
+ g_vars->scene22_craneIsOut = true;
+
+ if (g_fp->getObjectState(sO_Bag_22) == g_fp->getObjectEnumState(sO_Bag_22, sO_NotFallen))
+ g_vars->scene22_numBagFalls = 0;
+ else if (g_fp->getObjectState(sO_Bag_22) == g_fp->getObjectEnumState(sO_Bag_22, sO_FallenOnce))
+ g_vars->scene22_numBagFalls = 1;
+ else if ( g_fp->getObjectState(sO_Bag_22) == g_fp->getObjectEnumState(sO_Bag_22, sO_FallenTwice))
+ g_vars->scene22_numBagFalls = 2;
+ else {
+ g_vars->scene22_numBagFalls = 3;
+ g_vars->scene22_craneIsOut = false;
+ }
+
+
+ if ( g_fp->getObjectState(sO_LowerPipe_21) == g_fp->getObjectEnumState(sO_LowerPipe_21, sO_IsOpened))
+ g_vars->scene22_giraffeMiddle->changeStatics2(ST_GRFM_AFTER);
+ else
+ g_vars->scene22_giraffeMiddle->changeStatics2(ST_GRFM_NORM);
+
+ g_fp->_currentScene = oldsc;
+
+ g_fp->initArcadeKeys("SC_22");
+}
+
+int scene22_updateCursor() {
+ g_fp->updateCursorCommon();
+
+ if (g_fp->_objectIdAtCursor != ANI_HANDLE_L)
+ return g_fp->_cursorId;
+
+ int sel = g_fp->_inventory->getSelectedItemId();
+
+ if (!sel) {
+ g_fp->_cursorId = PIC_CSR_ITN;
+ return g_fp->_cursorId;
+ }
+
+ if (g_vars->scene22_dudeIsOnStool || (sel != ANI_INV_STOOL && sel != ANI_INV_BOX))
+ ; //empty
+ else
+ g_fp->_cursorId = PIC_CSR_ITN_INV;
+
+ return g_fp->_cursorId;
+}
+
+void scene22_setBagState() {
+ if (g_vars->scene22_craneIsOut) {
+ g_fp->_behaviorManager->setBehaviorEnabled(g_vars->scene22_bag, ST_MSH_SIT, QU_MSH_CRANEOUT, 1);
+ g_fp->_behaviorManager->setBehaviorEnabled(g_vars->scene22_bag, ST_MSH_SIT, QU_MSH_MOVE, 0);
+ } else {
+ g_fp->_behaviorManager->setBehaviorEnabled(g_vars->scene22_bag, ST_MSH_SIT, QU_MSH_CRANEOUT, 0);
+ g_fp->_behaviorManager->setBehaviorEnabled(g_vars->scene22_bag, ST_MSH_SIT, QU_MSH_MOVE, 1);
+ }
+}
+
+void sceneHandler22_showStool() {
+ chainQueue(QU_SC22_SHOWSTOOL, 0);
+}
+
+void sceneHandler22_hideStool() {
+ g_fp->_currentScene->getStaticANIObject1ById(ANI_TABURETTE, -1)->hide();
+}
+
+void sceneHandler22_handleDown() {
+ if (g_vars->scene22_bag->_statics->_staticsId == ST_MSH_SIT) {
+ chainQueue(QU_MSH_CRANEOUT, 1);
+ g_vars->scene22_interactionIsDisabled = false;
+ } else {
+ ++g_vars->scene22_numBagFalls;
+
+ int qid;
+
+ if (g_vars->scene22_numBagFalls == 3) {
+ chainQueue(QU_SC22_FALLSACK_GMA, 1);
+ qid = QU_SC22_FALLBROOM;
+ } else {
+ qid = QU_SC22_FALLSACK;
+ }
+
+ chainQueue(qid, 1);
+
+ int state;
+
+ if (g_vars->scene22_numBagFalls) {
+ if (g_vars->scene22_numBagFalls == 1) {
+ state = g_fp->getObjectEnumState(sO_Bag_22, sO_FallenOnce);
+ } else if (g_vars->scene22_numBagFalls == 2) {
+ state = g_fp->getObjectEnumState(sO_Bag_22, sO_FallenTwice);
+ } else {
+ state = g_fp->getObjectEnumState(sO_Bag_22, sO_BrushHasFallen);
+ }
+ } else {
+ state = g_fp->getObjectEnumState(sO_Bag_22, sO_NotFallen);
+ }
+
+ g_fp->setObjectState(sO_Bag_22, state);
+ }
+
+ g_vars->scene22_craneIsOut = true;
+
+ g_fp->_behaviorManager->setBehaviorEnabled(g_vars->scene22_bag, ST_MSH_SIT, QU_MSH_CRANEOUT, 1);
+ g_fp->_behaviorManager->setBehaviorEnabled(g_vars->scene22_bag, ST_MSH_SIT, QU_MSH_MOVE, 0);
+}
+
+void sceneHandler22_fromStool(ExCommand *cmd) {
+ if (g_fp->_aniMan->isIdle() && !(g_fp->_aniMan->_flags & 0x100)) {
+ MessageQueue *mq = new MessageQueue(g_fp->_currentScene->getMessageQueueById(QU_SC22_FROMSTOOL), 0, 0);
+
+ mq->addExCommandToEnd(cmd->createClone());
+ mq->setFlags(mq->getFlags() | 1);
+ mq->chain(0);
+ }
+}
+
+void sceneHandler22_stoolLogic(ExCommand *cmd) {
+ StaticANIObject *ani;
+ MessageQueue *mq;
+ int xpos;
+ int manId;
+
+ if (g_fp->_aniMan->isIdle() && !(g_fp->_aniMan->_flags & 0x100)) {
+ if (cmd->_keyCode == ANI_INV_STOOL) {
+ if (abs(841 - g_fp->_aniMan->_ox) <= 1) {
+ if (abs(449 - g_fp->_aniMan->_oy) <= 1) {
+ chainQueue(QU_SC22_PUTSTOOL, 1);
+ g_vars->scene22_interactionIsDisabled = true;
+
+ return;
+ }
+ }
+ goto LABEL_13;
+ }
+
+ if (cmd->_keyCode == ANI_INV_BOX) {
+ ani = g_fp->_currentScene->getStaticANIObject1ById(ANI_TABURETTE, -1);
+ if (!ani || !(ani->_flags & 4)) {
+ if (abs(841 - g_fp->_aniMan->_ox) <= 1) {
+ if (abs(449 - g_fp->_aniMan->_oy) <= 1) {
+ chainObjQueue(g_fp->_aniMan, QU_SC22_TRYBOX, 1);
+ return;
+ }
+ }
+ LABEL_13:
+ xpos = 841;
+ manId = ST_MAN_RIGHT;
+ LABEL_31:
+ mq = getCurrSceneSc2MotionController()->method34(g_fp->_aniMan, xpos, 449, 1, manId);
+
+ if (!mq)
+ return;
+
+ mq->addExCommandToEnd(cmd->createClone());
+
+ postExCommand(g_fp->_aniMan->_id, 2, 841, 449, 0, -1);
+ return;
+ }
+ } else {
+ if (cmd->_keyCode)
+ return;
+
+ if (g_vars->scene22_dudeIsOnStool) {
+ if (g_fp->_aniMan->_movement)
+ return;
+
+ chainQueue(QU_SC22_HANDLEDOWN, 1);
+
+ g_vars->scene22_interactionIsDisabled = true;
+ return;
+ }
+
+ ani = g_fp->_currentScene->getStaticANIObject1ById(ANI_TABURETTE, -1);
+ if (ani && (ani->_flags & 4)) {
+ int x = g_fp->_aniMan->_ox;
+ int y = g_fp->_aniMan->_ox;
+
+ if (sqrt((double)((841 - x) * (841 - x) + (449 - y) * (449 - y)))
+ < sqrt((double)((1075 - x) * (1075 - x) + (449 - y) * (449 - y)))) {
+ if (abs(841 - x) <= 1) {
+ if (abs(449 - y) <= 1) {
+ chainQueue(QU_SC22_TOSTOOL, 1);
+
+ g_vars->scene22_interactionIsDisabled = true;
+ return;
+ }
+ }
+ goto LABEL_13;
+ }
+
+ if (abs(1075 - x) > 1 || abs(449 - y) > 1) {
+ xpos = 1075;
+ manId = ST_MAN_RIGHT | 0x4000;
+ goto LABEL_31;
+ }
+
+ MGM mgm;
+ MGMInfo mgminfo;
+
+ mgm.addItem(ANI_MAN);
+ mgminfo.ani = g_fp->_aniMan;
+ mgminfo.staticsId2 = ST_MAN_RIGHT;
+ mgminfo.x1 = 934;
+ mgminfo.y1 = 391;
+ mgminfo.field_1C = 10;
+ mgminfo.staticsId1 = 0x4145;
+ mgminfo.x2 = 981;
+ mgminfo.y2 = 390;
+ mgminfo.field_10 = 1;
+ mgminfo.flags = 127;
+ mgminfo.movementId = rMV_MAN_TURN_SRL;
+
+ mq = mgm.genMovement(&mgminfo);
+
+ ExCommand *ex = mq->getExCommandByIndex(0);
+
+ mq->deleteExCommandByIndex(0, 0);
+
+ delete mq;
+
+ mq = new MessageQueue(g_fp->_currentScene->getMessageQueueById(QU_SC22_TOSTOOL_R), 0, 0);
+
+ mq->insertExCommandAt(2, ex);
+ mq->setFlags(mq->getFlags() | 1);
+ mq->chain(0);
+
+ g_vars->scene22_interactionIsDisabled = true;
+ } else {
+ if (abs(1010 - g_fp->_aniMan->_ox) <= 1) {
+ if (abs(443 - g_fp->_aniMan->_oy) <= 1) {
+ chainQueue(QU_SC22_TRYHANDLE, 1);
+ return;
+ }
+ }
+
+ mq = getCurrSceneSc2MotionController()->method34(g_fp->_aniMan, 1010, 443, 1, ST_MAN_UP);
+
+ if (mq) {
+ mq->addExCommandToEnd(cmd->createClone());
+
+ postExCommand(g_fp->_aniMan->_id, 2, 1010, 443, 0, -1);
+ return;
+ }
+ }
+ }
+ }
+}
+
+int sceneHandler22(ExCommand *cmd) {
+ if (cmd->_messageKind != 17)
+ return 0;
+
+ switch (cmd->_messageNum) {
+ case MSG_SC22_CRANEOUT_GMA:
+ chainQueue(QU_MSH_CRANEOUT_GMA, 1);
+ break;
+
+ case MSG_SC22_CHECKGMABOOT:
+ if (g_fp->getObjectState(sO_Grandma) == g_fp->getObjectEnumState(sO_Grandma, sO_In_15))
+ g_fp->setObjectState(sO_Boot_15, g_fp->getObjectEnumState(sO_Boot_15, sO_IsPresent));
+
+ break;
+
+ case MSG_SC22_SHOWSTOOL:
+ sceneHandler22_showStool();
+ break;
+
+ case MSG_SC22_HIDESTOOL:
+ sceneHandler22_hideStool();
+ break;
+
+ case MSG_SC22_FROMSTOOL:
+ g_vars->scene22_dudeIsOnStool = false;
+ g_vars->scene22_interactionIsDisabled = false;
+
+ getCurrSceneSc2MotionController()->setEnabled();
+ g_fp->_behaviorManager->setFlagByStaticAniObject(g_fp->_aniMan, 1);
+ break;
+
+ case MSG_SC22_ONSTOOL:
+ g_vars->scene22_dudeIsOnStool = true;
+ getCurrSceneSc2MotionController()->clearEnabled();
+ g_fp->_behaviorManager->setFlagByStaticAniObject(g_fp->_aniMan, 0);
+ break;
+
+ case MSG_SC22_HANDLEDOWN:
+ sceneHandler22_handleDown();
+ break;
+
+ case 29:
+ if (!g_vars->scene22_interactionIsDisabled) {
+ StaticANIObject *ani = g_fp->_currentScene->getStaticANIObjectAtPos(cmd->_sceneClickX, cmd->_sceneClickY);
+
+ if (ani && ani->_id == ANI_HANDLE_L) {
+ sceneHandler22_stoolLogic(cmd);
+ return 0;
+ }
+
+ if (!g_vars->scene22_dudeIsOnStool) {
+ if (!ani || !canInteractAny(g_fp->_aniMan, ani, cmd->_keyCode)) {
+ int picId = g_fp->_currentScene->getPictureObjectIdAtPos(cmd->_sceneClickX, cmd->_sceneClickY);
+ PictureObject *pic = g_fp->_currentScene->getPictureObjectById(picId, 0);
+
+ if (!pic || !canInteractAny(g_fp->_aniMan, pic, cmd->_keyCode)) {
+ if ((g_fp->_sceneRect.right - cmd->_sceneClickX < 47 && g_fp->_sceneRect.right < g_fp->_sceneWidth - 1)
+ || (cmd->_sceneClickX - g_fp->_sceneRect.left < 47 && g_fp->_sceneRect.left > 0)) {
+ g_fp->processArcade(cmd);
+ return 0;
+ }
+ }
+ }
+ return 0;
+ }
+
+ if (g_fp->_aniMan->_statics->_staticsId == ST_MAN_RIGHT && !g_fp->_aniMan->_movement) {
+ sceneHandler22_fromStool(cmd);
+
+ return 0;
+ }
+ }
+
+ cmd->_messageKind = 0;
+ break;
+
+ case 33:
+ if (g_fp->_aniMan2) {
+ int x = g_fp->_aniMan2->_ox;
+
+ if (x <= g_fp->_sceneWidth - 460) {
+ if (x < g_fp->_sceneRect.left + 200)
+ g_fp->_currentScene->_x = x - 300 - g_fp->_sceneRect.left;
+ } else {
+ g_fp->_currentScene->_x = g_fp->_sceneWidth - x;
+ }
+
+ if (x > g_fp->_sceneRect.right - 200)
+ g_fp->_currentScene->_x = x + 300 - g_fp->_sceneRect.right;
+
+ g_fp->_behaviorManager->updateBehaviors();
+
+ g_fp->startSceneTrack();
+ }
+
+ break;
+ }
+
+ return 0;
+}
+
+} // End of namespace Fullpipe
diff --git a/engines/fullpipe/scenes/scene23.cpp b/engines/fullpipe/scenes/scene23.cpp
new file mode 100644
index 0000000000..1f2587eba4
--- /dev/null
+++ b/engines/fullpipe/scenes/scene23.cpp
@@ -0,0 +1,555 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public 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 "fullpipe/fullpipe.h"
+
+#include "fullpipe/objectnames.h"
+#include "fullpipe/constants.h"
+
+#include "fullpipe/gameloader.h"
+#include "fullpipe/motion.h"
+#include "fullpipe/scenes.h"
+#include "fullpipe/statics.h"
+
+#include "fullpipe/interaction.h"
+#include "fullpipe/behavior.h"
+#include "fullpipe/floaters.h"
+
+namespace Fullpipe {
+
+bool sceneHandler23_testCalendar() {
+ int cal0, cal1, cal2, cal3;
+
+ if (g_vars->scene23_calend0->_movement)
+ cal0 = g_vars->scene23_calend0->_movement->_staticsObj2->_staticsId;
+ else
+ cal0 = g_vars->scene23_calend0->_statics->_staticsId;
+
+ if (g_vars->scene23_calend1->_movement)
+ cal1 = g_vars->scene23_calend1->_movement->_staticsObj2->_staticsId;
+ else
+ cal1 = g_vars->scene23_calend1->_statics->_staticsId;
+
+ if (g_vars->scene23_calend2->_movement)
+ cal2 = g_vars->scene23_calend2->_movement->_staticsObj2->_staticsId;
+ else
+ cal2 = g_vars->scene23_calend2->_statics->_staticsId;
+
+ if (g_vars->scene23_calend3->_movement)
+ cal3 = g_vars->scene23_calend3->_movement->_staticsObj2->_staticsId;
+ else
+ cal3 = g_vars->scene23_calend3->_statics->_staticsId;
+
+ return (cal0 == ST_CND_1 && cal1 == ST_CND_4 && cal2 == ST_CND_0 && cal3 == ST_CND_2 && (g_vars->scene23_giraffee->_flags & 4));
+}
+
+void scene23_initScene(Scene *sc) {
+ g_vars->scene23_calend0 = sc->getStaticANIObject1ById(ANI_CALENDWHEEL, 0);
+ g_vars->scene23_calend1 = sc->getStaticANIObject1ById(ANI_CALENDWHEEL, 1);
+ g_vars->scene23_calend2 = sc->getStaticANIObject1ById(ANI_CALENDWHEEL, 2);
+ g_vars->scene23_calend3 = sc->getStaticANIObject1ById(ANI_CALENDWHEEL, 3);
+ g_vars->scene23_topReached = false;
+ g_vars->scene23_isOnStool = false;
+ g_vars->scene23_someVar = 0;
+ g_vars->scene23_giraffeTop = sc->getStaticANIObject1ById(ANI_GIRAFFE_TOP, -1);
+ g_vars->scene23_giraffee = sc->getStaticANIObject1ById(ANI_GIRAFFEE, -1);
+
+ g_fp->_floaters->init(g_fp->getGameLoaderGameVar()->getSubVarByName("SC_23"));
+
+ Scene *oldsc = g_fp->_currentScene;
+ g_fp->_currentScene = sc;
+
+ if (g_fp->getObjectState(sO_UpperHatch_23) == g_fp->getObjectEnumState(sO_UpperHatch_23, sO_Opened)) {
+ sc->getPictureObjectById(PIC_SC23_BOXOPEN, 0)->_flags |= 4;
+ sc->getPictureObjectById(PIC_SC23_BOXCLOSED, 0)->_flags &= 0xFFFB;
+ sc->getPictureObjectById(PIC_SC23_BTN1, 0)->_flags |= 4;
+ sc->getPictureObjectById(PIC_SC23_BTN2, 0)->_flags |= 4;
+ sc->getPictureObjectById(PIC_SC23_BTN3, 0)->_flags |= 4;
+ sc->getPictureObjectById(PIC_SC23_BTN4, 0)->_flags |= 4;
+
+ if (g_vars->scene23_giraffee->_statics->_staticsId == ST_GRFG_EMPTY || !(g_vars->scene23_giraffee->_flags & 4)) {
+ g_vars->scene23_giraffee->changeStatics2(ST_GRFG_BALD);
+ g_vars->scene23_giraffee->_flags |= 4;
+ }
+ g_vars->scene23_calend0->show1(-1, -1, -1, 0);
+ g_vars->scene23_calend1->show1(-1, -1, -1, 0);
+ g_vars->scene23_calend2->show1(-1, -1, -1, 0);
+ g_vars->scene23_calend3->show1(-1, -1, -1, 0);
+
+ sc->getStaticANIObject1ById(ANI_LUK23_U, -1)->changeStatics2(ST_LUK23U_OPEN);
+ } else {
+ sc->getPictureObjectById(PIC_SC23_BOXOPEN, 0)->_flags &= 0xFFFB;
+ sc->getPictureObjectById(PIC_SC23_BOXCLOSED, 0)->_flags |= 4;
+ sc->getPictureObjectById(PIC_SC23_BTN1, 0)->_flags &= 0xFFFB;
+ sc->getPictureObjectById(PIC_SC23_BTN2, 0)->_flags &= 0xFFFB;
+ sc->getPictureObjectById(PIC_SC23_BTN3, 0)->_flags &= 0xFFFB;
+ sc->getPictureObjectById(PIC_SC23_BTN4, 0)->_flags &= 0xFFFB;
+
+ g_vars->scene23_giraffee->hide();
+ g_vars->scene23_calend0->hide();
+ g_vars->scene23_calend1->hide();
+ g_vars->scene23_calend2->hide();
+ g_vars->scene23_calend3->hide();
+
+ sc->getStaticANIObject1ById(ANI_LUK23_U, -1)->changeStatics2(ST_LUK23U_CLOSED);
+
+ g_fp->_floaters->genFlies(sc, 600, 90, 0, 0);
+ }
+
+ if (g_fp->getObjectState(sO_LowerHatch_23) == g_fp->getObjectEnumState(sO_LowerHatch_23, sO_Opened)) {
+ g_vars->scene23_giraffeTop->show1(-1, -1, -1, 0);
+ g_vars->scene23_giraffeTop->changeStatics2(ST_GRFU_UP);
+
+ if (g_fp->getObjectState(sO_LowerPipe_21) == g_fp->getObjectEnumState(sO_LowerPipe_21, sO_IsOpened)) {
+ g_vars->scene23_giraffeTop->changeStatics2(ST_GRFU_KISS);
+ g_vars->scene23_giraffee->hide();
+ } else {
+ if (g_fp->getObjectState(sO_UpperHatch_23) == g_fp->getObjectEnumState(sO_UpperHatch_23, sO_Opened)
+ && (g_vars->scene23_giraffee->_flags & 4))
+ g_vars->scene23_giraffeTop->setOXY(614, 362);
+ else
+ g_vars->scene23_giraffeTop->setOXY(618, 350);
+
+ if (sceneHandler23_testCalendar())
+ g_vars->scene23_calend1->_statics = g_vars->scene23_calend1->getStaticsById(ST_CND_5);
+ }
+
+ sc->getStaticANIObject1ById(ANI_LUK23_D, -1)->changeStatics2(ST_LUK23_OPEN);
+
+ if (g_fp->getObjectState(sO_Lever_23) == g_fp->getObjectEnumState(sO_Lever_23, sO_Taken))
+ sc->getStaticANIObject1ById(ANI_INV_LEVERHANDLE, -1)->hide();
+
+ sc->getStaticANIObject1ById(ANI_HANDLE23, -1)->hide();
+ } else {
+ g_vars->scene23_giraffeTop->hide();
+
+ sc->getStaticANIObject1ById(ANI_LUK23_D, -1)->changeStatics2(ST_LUK23_WHANDLE2);
+
+ sc->getStaticANIObject1ById(ANI_INV_LEVERHANDLE, -1)->hide();
+ }
+
+ g_fp->_currentScene = oldsc;
+}
+
+void scene23_setGiraffeState() {
+ if (g_fp->getObjectState(sO_UpperHatch_23) == g_fp->getObjectEnumState(sO_UpperHatch_23, sO_Opened)) {
+ g_fp->_behaviorManager->setBehaviorEnabled(g_vars->scene23_giraffeTop, ST_GRFU_UP, QU_GRFU_TURN_UL, 0);
+ g_fp->_behaviorManager->setBehaviorEnabled(g_vars->scene23_giraffeTop, ST_GRFU_UP, QU_GRFU_TURN_UD, 0);
+ }
+}
+
+int scene23_updateCursor() {
+ g_fp->updateCursorCommon();
+
+ if (g_fp->_objectIdAtCursor == PIC_SC23_LADDERU) {
+ if (g_vars->scene23_topReached)
+ return g_fp->_cursorId;
+
+ g_fp->_cursorId = getGameLoaderInventory()->getSelectedItemId() ? PIC_CSR_GOU : PIC_CSR_ITN; // FIXME check
+ }
+
+ if (g_fp->_objectIdAtCursor == PIC_SC23_BTN1 || g_fp->_objectIdAtCursor == PIC_SC23_BTN2
+ || g_fp->_objectIdAtCursor == PIC_SC23_BTN3 || g_fp->_objectIdAtCursor == PIC_SC23_BTN4
+ || g_fp->_objectIdAtCursor == ANI_CALENDWHEEL)
+ g_fp->_cursorId = PIC_CSR_LIFT;
+
+ return g_fp->_cursorId;
+}
+
+void sceneHandler23_showStool() {
+ chainQueue(QU_SC23_SHOWSTOOL, 0);
+}
+
+void sceneHandler23_hideStool() {
+ g_fp->_currentScene->getStaticANIObject1ById(ANI_TABURETTE, -1)->hide();
+}
+
+void sceneHandler23_startKiss() {
+ g_vars->scene23_giraffeTop->changeStatics2(ST_GRFU_UP);
+ g_vars->scene23_giraffeTop->startMQIfIdle(QU_SC23_STARTKISS, 0);
+}
+
+void sceneHandler23_spinWheel1() {
+ int mv = 0;
+
+ switch (g_vars->scene23_calend0->_statics->_staticsId) {
+ case ST_CND_0:
+ mv = MV_CND_0_1;
+ break;
+
+ case ST_CND_1:
+ mv = MV_CND_1_2;
+ break;
+
+ case ST_CND_2:
+ mv = MV_CND_2_3;
+ break;
+
+ case ST_CND_3:
+ g_vars->scene23_calend0->changeStatics2(ST_CND_9);
+ mv = MV_CND_9_0;
+ break;
+
+ default:
+ break;
+ }
+
+ if (mv)
+ g_vars->scene23_calend0->startAnim(mv, 0, -1);
+
+ if (sceneHandler23_testCalendar())
+ sceneHandler23_startKiss();
+}
+
+void sceneHandler23_spinWheel2and4(StaticANIObject *ani) {
+ int mv = 0;
+
+ switch (ani->_statics->_staticsId) {
+ case ST_CND_0:
+ mv = MV_CND_0_1;
+ break;
+
+ case ST_CND_1:
+ mv = MV_CND_1_2;
+ break;
+
+ case ST_CND_2:
+ mv = MV_CND_2_3;
+ break;
+
+ case ST_CND_3:
+ mv = MV_CND_3_4;
+ break;
+
+ case ST_CND_4:
+ mv = MV_CND_4_5;
+ break;
+
+ case ST_CND_5:
+ mv = MV_CND_5_6;
+ break;
+
+ case ST_CND_6:
+ mv = MV_CND_6_7;
+ break;
+
+ case ST_CND_7:
+ mv = MV_CND_7_8;
+ break;
+
+ case ST_CND_8:
+ mv = MV_CND_8_9;
+ break;
+
+ case ST_CND_9:
+ mv = MV_CND_9_0;
+ break;
+
+ default:
+ break;
+ }
+
+ if (mv)
+ ani->startAnim(mv, 0, -1);
+
+ if (sceneHandler23_testCalendar())
+ sceneHandler23_startKiss();
+}
+
+void sceneHandler23_spinWheel3() {
+ if (g_vars->scene23_calend2->_statics->_staticsId == ST_CND_0) {
+ g_vars->scene23_calend2->startAnim(MV_CND_0_1, 0, -1);
+ } else if (g_vars->scene23_calend2->_statics->_staticsId == ST_CND_1) {
+ g_vars->scene23_calend2->changeStatics2(ST_CND_9);
+ g_vars->scene23_calend2->startAnim(MV_CND_9_0, 0, -1);
+ }
+
+ if (sceneHandler23_testCalendar())
+ sceneHandler23_startKiss();
+}
+
+void sceneHandler23_pushButton(ExCommand *cmd) {
+ if (g_fp->_aniMan->isIdle() || !(g_fp->_aniMan->_flags & 0x100)) {
+ if (!g_vars->scene23_topReached) {
+ if (g_fp->_aniMan->_ox != 405 || g_fp->_aniMan->_oy != 220) {
+ if (g_fp->_aniMan->_ox != 276 || g_fp->_aniMan->_oy != 438
+ || g_fp->_aniMan->_movement || g_fp->_aniMan->_statics->_staticsId != ST_MAN_RIGHT) {
+ if (g_fp->_msgX == 276 && g_fp->_msgY == 438 )
+ return;
+
+ MessageQueue *mq = getCurrSceneSc2MotionController()->method34(g_fp->_aniMan, 276, 438, 1, ST_MAN_RIGHT);
+
+ if (mq) {
+ 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->setFlags(mq->getFlags() | 1);
+ mq->chain(0);
+ }
+
+ if (!g_vars->scene23_topReached)
+ return;
+ } else {
+ g_vars->scene23_topReached = true;
+ }
+ }
+
+ if (!g_fp->_aniMan->_movement && g_fp->_aniMan->_statics->_staticsId == ST_MAN_STANDLADDER) {
+ int mv = 0;
+
+ switch (cmd->_messageNum) {
+ case MSG_SC23_CLICKBTN1:
+ mv = MV_MAN23_PUSH1;
+ break;
+
+ case MSG_SC23_CLICKBTN2:
+ mv = MV_MAN23_PUSH2;
+ break;
+
+ case MSG_SC23_CLICKBTN3:
+ mv = MV_MAN23_PUSH3;
+ break;
+
+ case MSG_SC23_CLICKBTN4:
+ mv = MV_MAN23_PUSH4;
+ break;
+
+ default:
+ return;
+ }
+
+ if (mv)
+ g_fp->_aniMan->startAnim(mv, 0, -1);
+
+ }
+ }
+}
+
+void sceneHandler23_sendClick(StaticANIObject *ani) {
+ int msg = 0;
+ switch (ani->_okeyCode) {
+ case 0:
+ msg = MSG_SC23_CLICKBTN1;
+ break;
+ case 1:
+ msg = MSG_SC23_CLICKBTN2;
+ break;
+ case 2:
+ msg = MSG_SC23_CLICKBTN3;
+ break;
+ case 3:
+ msg = MSG_SC23_CLICKBTN4;
+ break;
+ default:
+ break;
+ }
+
+ ExCommand *ex = new ExCommand(0, 17, msg, 0, 0, 0, 1, 0, 0, 0);
+ ex->_excFlags |= 3;
+
+ ex->postMessage();
+}
+
+void sceneHandler23_checkReachingTop() {
+ if (g_fp->_aniMan->_movement || g_fp->_aniMan->_statics->_staticsId != ST_MAN_STANDLADDER
+ || g_fp->_aniMan->_ox != 405 || g_fp->_aniMan->_oy != 220)
+ g_vars->scene23_topReached = false;
+ else
+ g_vars->scene23_topReached = true;
+}
+
+void sceneHandler23_exitCalendar() {
+ if (!g_fp->_aniMan->_movement && g_fp->_aniMan->_statics->_staticsId == ST_MAN_STANDLADDER
+ && !g_fp->_aniMan->getMessageQueue() && !(g_fp->_aniMan->_flags & 0x100)) {
+ chainQueue(QU_SC23_FROMCALENDAREXIT, 1);
+ g_vars->scene23_someVar = 2;
+ }
+}
+
+void sceneHandler23_fromCalendar(ExCommand *cmd) {
+ if (!g_fp->_aniMan->_movement && g_fp->_aniMan->_statics->_staticsId == ST_MAN_STANDLADDER
+ && !g_fp->_aniMan->getMessageQueue() && !(g_fp->_aniMan->_flags & 0x100)) {
+ MessageQueue *mq = new MessageQueue(g_fp->_currentScene->getMessageQueueById(QU_SC23_FROMCALENDAR), 0, 0);
+
+ mq->addExCommandToEnd(cmd->createClone());
+ mq->setFlags(mq->getFlags() | 1);
+ mq->chain(0);
+
+ g_vars->scene23_topReached = false;
+ g_vars->scene23_someVar = 0;
+ }
+}
+
+void sceneHandler23_fromStool(ExCommand *cmd) {
+ if (!g_fp->_aniMan->getMessageQueue() && !(g_fp->_aniMan->_flags & 0x100)) {
+ MessageQueue *mq = new MessageQueue(g_fp->_currentScene->getMessageQueueById(QU_SC23_FROMSTOOL), 0, 0);
+
+ mq->addExCommandToEnd(cmd->createClone());
+ mq->setFlags(mq->getFlags() | 1);
+ mq->chain(0);
+
+ cmd->_messageKind = 0;
+ }
+}
+
+int sceneHandler23(ExCommand *cmd) {
+ if (cmd->_messageKind != 17)
+ return 0;
+
+ switch (cmd->_messageNum) {
+ case MSG_SC23_FROMSTOOL:
+ g_vars->scene23_isOnStool = false;
+
+ getCurrSceneSc2MotionController()->setEnabled();
+ getGameLoaderInteractionController()->enableFlag24();
+
+ g_fp->_behaviorManager->setFlagByStaticAniObject(g_fp->_aniMan, 1);
+ break;
+
+ case MSG_SC23_HIDEGIRAFFEE:
+ g_vars->scene23_giraffee->queueMessageQueue(0);
+ g_vars->scene23_giraffee->_flags &= 0xFFFB;
+ break;
+
+ case MSG_SC23_ONSTOOL:
+ g_vars->scene23_isOnStool = true;
+
+ getCurrSceneSc2MotionController()->clearEnabled();
+ getGameLoaderInteractionController()->disableFlag24();
+
+ g_fp->_behaviorManager->setFlagByStaticAniObject(g_fp->_aniMan, 0);
+ break;
+
+ case MSG_SC22_SHOWSTOOL:
+ sceneHandler23_showStool();
+ break;
+
+ case MSG_SC22_HIDESTOOL:
+ sceneHandler23_hideStool();
+ break;
+
+ case MSG_SC23_SPINWHEEL1:
+ sceneHandler23_spinWheel1();
+ break;
+
+ case MSG_SC23_SPINWHEEL2:
+ sceneHandler23_spinWheel2and4(g_vars->scene23_calend1);
+ break;
+
+ case MSG_SC23_SPINWHEEL3:
+ sceneHandler23_spinWheel3();
+ break;
+
+ case MSG_SC23_SPINWHEEL4:
+ sceneHandler23_spinWheel2and4(g_vars->scene23_calend3);
+ break;
+
+ case MSG_SC23_CLICKBTN1:
+ case MSG_SC23_CLICKBTN2:
+ case MSG_SC23_CLICKBTN3:
+ case MSG_SC23_CLICKBTN4:
+ sceneHandler23_pushButton(cmd);
+ break;
+
+ case 33:
+ if (g_fp->_aniMan2) {
+ int x = g_fp->_aniMan2->_ox;
+
+ if (x < g_fp->_sceneRect.left + 200)
+ g_fp->_currentScene->_x = x - 300 - g_fp->_sceneRect.left;
+
+ if (x > g_fp->_sceneRect.right - 200)
+ g_fp->_currentScene->_x = x + 300 - g_fp->_sceneRect.right;
+ }
+
+ g_fp->_floaters->update();
+ g_fp->_behaviorManager->updateBehaviors();
+
+ g_fp->startSceneTrack();
+
+ break;
+
+ case 29:
+ {
+ StaticANIObject *ani = g_fp->_currentScene->getStaticANIObjectAtPos(cmd->_sceneClickX, cmd->_sceneClickY);
+ int picId;
+
+ if (ani && ani->_id == ANI_CALENDWHEEL) {
+ sceneHandler23_sendClick(ani);
+ cmd->_messageKind = 0;
+ }
+
+ sceneHandler23_checkReachingTop();
+
+ if (g_vars->scene23_topReached) {
+ picId = g_fp->_currentScene->getPictureObjectIdAtPos(cmd->_sceneClickX, cmd->_sceneClickY);
+
+ if (picId == PIC_SC23_LADDER) {
+ sceneHandler23_exitCalendar();
+
+ cmd->_messageKind = 0;
+ break;
+ }
+
+ if (cmd->_sceneClickY > 450) {
+ sceneHandler23_fromCalendar(cmd);
+
+ cmd->_messageKind = 0;
+ break;
+ }
+ break;
+ }
+
+ if (!g_vars->scene23_isOnStool) {
+ picId = g_fp->_currentScene->getPictureObjectIdAtPos(cmd->_sceneClickX, cmd->_sceneClickY);
+
+ if (picId == PIC_SC23_LADDERU && !g_vars->scene23_topReached) {
+ sceneHandler23_pushButton(cmd);
+
+ cmd->_messageKind = 0;
+ break;
+ }
+ break;
+ }
+
+ if (ani && ani->_id == ANI_HANDLE23) {
+ handleObjectInteraction(g_fp->_aniMan, ani, cmd->_keyCode);
+ cmd->_messageKind = 0;
+ } else {
+ sceneHandler23_fromStool(cmd);
+
+ cmd->_messageKind = 0;
+ }
+
+ break;
+ }
+ }
+
+ return 0;
+}
+
+} // End of namespace Fullpipe
diff --git a/engines/fullpipe/scenes/scene24.cpp b/engines/fullpipe/scenes/scene24.cpp
new file mode 100644
index 0000000000..508f776573
--- /dev/null
+++ b/engines/fullpipe/scenes/scene24.cpp
@@ -0,0 +1,129 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public 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 "fullpipe/fullpipe.h"
+
+#include "fullpipe/objectnames.h"
+#include "fullpipe/constants.h"
+
+#include "fullpipe/gameloader.h"
+#include "fullpipe/motion.h"
+#include "fullpipe/scenes.h"
+#include "fullpipe/statics.h"
+
+#include "fullpipe/interaction.h"
+#include "fullpipe/behavior.h"
+
+
+namespace Fullpipe {
+
+void scene24_initScene(Scene *sc) {
+ g_vars->scene24_water = sc->getStaticANIObject1ById(ANI_WATER24, -1);
+ g_vars->scene24_jet = sc->getStaticANIObject1ById(ANI_JET24, -1);
+ g_vars->scene24_drop = sc->getStaticANIObject1ById(ANI_DROP_24, -1);
+
+ g_vars->scene24_water->setAlpha(0xa0);
+ g_vars->scene24_jet->setAlpha(0xa0);
+ g_vars->scene24_drop->setAlpha(0xa0);
+
+ Scene *oldsc = g_fp->_currentScene;
+ g_fp->_currentScene = sc;
+
+ if (g_fp->getObjectState(sO_Pool) == g_fp->getObjectEnumState(sO_Pool, sO_Overfull)) {
+ g_vars->scene24_jetIsOn = true;
+ g_vars->scene24_flowIsLow = false;
+ } else {
+ g_vars->scene24_jet->hide();
+
+ g_vars->scene24_jetIsOn = false;
+
+ g_vars->scene24_water->changeStatics2(ST_WTR24_FLOWLOWER);
+
+ g_vars->scene24_flowIsLow = true;
+ }
+
+ if (g_fp->getObjectState(sO_Pool) < g_fp->getObjectEnumState(sO_Pool, sO_Full)) {
+ g_vars->scene24_waterIsOn = false;
+
+ g_vars->scene24_water->hide();
+
+ g_fp->setObjectState(sO_StairsDown_24, g_fp->getObjectEnumState(sO_StairsDown_24, sO_IsOpened));
+ } else {
+ g_vars->scene24_waterIsOn = true;
+
+ g_fp->setObjectState(sO_StairsDown_24, g_fp->getObjectEnumState(sO_StairsDown_24, sO_IsClosed));
+ }
+
+ g_fp->_currentScene = oldsc;
+}
+
+void scene24_setPoolState() {
+ if (g_fp->getObjectState(sO_Pool) == g_fp->getObjectEnumState(sO_Pool, sO_Overfull)) {
+ g_fp->_behaviorManager->setFlagByStaticAniObject(g_vars->scene24_drop, 0);
+
+ g_fp->playSound(SND_24_007, 1);
+ } else if (g_fp->getObjectState(sO_Pool) == g_fp->getObjectEnumState(sO_Pool, sO_Full)) {
+ g_fp->_behaviorManager->setBehaviorEnabled(g_vars->scene24_drop, ST_DRP24_EMPTY, QU_DRP24_TOFLOOR, 0);
+ g_fp->_behaviorManager->setBehaviorEnabled(g_vars->scene24_drop, ST_DRP24_EMPTY, QU_DRP24_TOWATER, 1);
+ g_fp->_behaviorManager->setBehaviorEnabled(g_vars->scene24_drop, ST_DRP24_EMPTY, QU_DRP24_TOWATER2, 0);
+
+ g_fp->playSound(SND_24_006, 1);
+ } else if (g_fp->getObjectState(sO_Pool) == g_fp->getObjectEnumState(sO_Pool, sO_HalfFull)) {
+ g_fp->_behaviorManager->setBehaviorEnabled(g_vars->scene24_drop, ST_DRP24_EMPTY, QU_DRP24_TOFLOOR, 0);
+ g_fp->_behaviorManager->setBehaviorEnabled(g_vars->scene24_drop, ST_DRP24_EMPTY, QU_DRP24_TOWATER, 0);
+ g_fp->_behaviorManager->setBehaviorEnabled(g_vars->scene24_drop, ST_DRP24_EMPTY, QU_DRP24_TOWATER2, 1);
+ } else {
+ g_fp->_behaviorManager->setBehaviorEnabled(g_vars->scene24_drop, ST_DRP24_EMPTY, QU_DRP24_TOFLOOR, 1);
+ g_fp->_behaviorManager->setBehaviorEnabled(g_vars->scene24_drop, ST_DRP24_EMPTY, QU_DRP24_TOWATER, 0);
+ g_fp->_behaviorManager->setBehaviorEnabled(g_vars->scene24_drop, ST_DRP24_EMPTY, QU_DRP24_TOWATER2, 0);
+ }
+}
+
+int sceneHandler24(ExCommand *cmd) {
+ if (cmd->_messageKind == 17 && cmd->_messageNum == 33) {
+ if (g_fp->_aniMan2) {
+ int x = g_fp->_aniMan2->_ox;
+
+ if (x < g_fp->_sceneRect.left + 200) {
+ g_fp->_currentScene->_x = x - 300 - g_fp->_sceneRect.left;
+ }
+ if (x > g_fp->_sceneRect.right - 200)
+ g_fp->_currentScene->_x = x + 300 - g_fp->_sceneRect.right;
+ }
+
+ if (g_vars->scene24_waterIsOn && !g_vars->scene24_water->_movement) {
+ if (g_vars->scene24_flowIsLow)
+ g_vars->scene24_water->startAnim(MV_WTR24_FLOWLOWER, 0, -1);
+ else
+ g_vars->scene24_water->startAnim(MV_WTR24_FLOW, 0, -1);
+ }
+
+ if (g_vars->scene24_jetIsOn && !g_vars->scene24_jet->_movement)
+ g_vars->scene24_jet->startAnim(MV_JET24_FLOW, 0, -1);
+
+ g_fp->_behaviorManager->updateBehaviors();
+ }
+
+ return 0;
+}
+
+} // End of namespace Fullpipe
diff --git a/engines/fullpipe/scenes/scene25.cpp b/engines/fullpipe/scenes/scene25.cpp
new file mode 100644
index 0000000000..ba07c3e5b9
--- /dev/null
+++ b/engines/fullpipe/scenes/scene25.cpp
@@ -0,0 +1,723 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public 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 "fullpipe/fullpipe.h"
+
+#include "fullpipe/objectnames.h"
+#include "fullpipe/constants.h"
+
+#include "fullpipe/gameloader.h"
+#include "fullpipe/motion.h"
+#include "fullpipe/scenes.h"
+#include "fullpipe/statics.h"
+
+#include "fullpipe/interaction.h"
+#include "fullpipe/behavior.h"
+
+
+namespace Fullpipe {
+
+void scene25_showBoardOnRightFar() {
+ g_vars->scene25_board->show1(453, 557, MV_BRD25_RIGHT, 0);
+ g_vars->scene25_board->_priority = 28;
+}
+
+void scene25_showBoardOnRightClose() {
+ g_vars->scene25_board->show1(632, 557, rMV_BRD25_RIGHT, 0);
+ g_vars->scene25_board->_priority = 28;
+}
+
+void scene25_initScene(Scene *sc, int entranceId) {
+ g_vars->scene25_water = sc->getStaticANIObject1ById(ANI_WATER25, -1);
+ g_vars->scene25_board = sc->getStaticANIObject1ById(ANI_BOARD25, -1);
+ g_vars->scene25_drop = sc->getStaticANIObject1ById(ANI_DROP_25, -1);
+ g_vars->scene25_water->setAlpha(0xa0);
+ g_vars->scene25_drop->setAlpha(0xa0);
+ g_vars->scene25_dudeIsOnBoard = false;
+
+ if (g_fp->getObjectState(sO_Pool) < g_fp->getObjectEnumState(sO_Pool, sO_HalfFull)) {
+ g_vars->scene25_waterIsPresent = false;
+
+ g_vars->scene25_water->hide();
+ } else {
+ g_vars->scene25_waterIsPresent = true;
+
+ g_fp->playSound(SND_25_006, 1);
+ }
+
+ int boardState = g_fp->getObjectState(sO_Board_25);
+
+ if (entranceId == TrubaRight) {
+ if (boardState == g_fp->getObjectEnumState(sO_Board_25, sO_FarAway)) {
+ scene25_showBoardOnRightFar();
+
+ g_fp->playSound(SND_25_029, 0);
+
+ g_vars->scene25_boardIsSelectable = false;
+ } else {
+ if (boardState == g_fp->getObjectEnumState(sO_Board_25, sO_Nearby)
+ || boardState == g_fp->getObjectEnumState(sO_Board_25, sO_WithDudeOnRight))
+ scene25_showBoardOnRightClose();
+ g_vars->scene25_boardIsSelectable = false;
+ }
+ } else {
+ if (boardState == g_fp->getObjectEnumState(sO_Board_25, sO_WithDudeOnLeft)) {
+ if (!getGameLoaderInventory()->getCountItemsWithId(ANI_INV_BOARD)) {
+ getGameLoaderInventory()->addItem(ANI_INV_BOARD, 1);
+ getGameLoaderInventory()->rebuildItemRects();
+ }
+ } else {
+ g_vars->scene25_boardIsSelectable = true;
+ }
+ }
+
+ g_vars->scene25_beardersAreThere = false;
+ g_vars->scene25_beardersCounter = 0;
+}
+
+int scene25_updateCursor() {
+ g_fp->updateCursorCommon();
+
+ if (g_vars->scene25_waterIsPresent) {
+ int inv = getGameLoaderInventory()->getSelectedItemId();
+
+ if (g_fp->_objectIdAtCursor == ANI_WATER25) {
+ if ((g_vars->scene25_boardIsSelectable && (!inv || inv == ANI_INV_BOARD)) || (g_vars->scene25_dudeIsOnBoard && (inv == ANI_INV_LOPAT || !inv)))
+ g_fp->_cursorId = (g_fp->_cursorId != PIC_CSR_DEFAULT) ? PIC_CSR_ITN : PIC_CSR_ITN_INV; // FIXME check
+ } else if (g_fp->_objectIdAtCursor == ANI_BOARD25 && (!inv || inv == ANI_INV_SWAB || inv == ANI_INV_BROOM || inv == ANI_INV_LOPAT)) {
+ g_fp->_cursorId = (g_fp->_cursorId != PIC_CSR_DEFAULT) ? PIC_CSR_ITN : PIC_CSR_ITN_INV;
+ }
+ }
+
+ return g_fp->_cursorId;
+}
+
+void scene25_setupWater(Scene *a1, int entranceId) {
+ if (g_vars->scene25_waterIsPresent) {
+ g_fp->_behaviorManager->setBehaviorEnabled(g_vars->scene25_drop, ST_DRP25_EMPTY, QU_DRP25_TOFLOOR, 0);
+ g_fp->_behaviorManager->setBehaviorEnabled(g_vars->scene25_drop, ST_DRP25_EMPTY, QU_DRP25_TOWATER, 1);
+
+ if (entranceId != TrubaRight)
+ g_fp->playTrack(g_fp->getGameLoaderGameVar()->getSubVarByName("SC_25"), "MUSIC2", 0);
+ } else {
+ g_fp->_behaviorManager->setBehaviorEnabled(g_vars->scene25_drop, ST_DRP25_EMPTY, QU_DRP25_TOFLOOR, 1);
+ g_fp->_behaviorManager->setBehaviorEnabled(g_vars->scene25_drop, ST_DRP25_EMPTY, QU_DRP25_TOWATER, 0);
+ }
+}
+
+void sceneHandler25_stopBearders() {
+ g_vars->scene25_beardersAreThere = false;
+
+ g_vars->scene25_bearders.clear();
+}
+
+void sceneHandler25_startBearders() {
+ g_vars->scene25_bearders.clear();
+ g_vars->scene25_beardersCounter = 0;
+
+ StaticANIObject *bearded = g_fp->accessScene(SC_COMMON)->getStaticANIObject1ById(ANI_BEARDED_CMN, -1);
+
+ for (int i = 0; i < 3; i++) {
+ StaticANIObject *ani = new StaticANIObject(bearded);
+
+ g_vars->scene25_bearders.push_back(ani);
+
+ ani->_statics = ani->getStaticsById(ST_BRDCMN_EMPTY);
+
+ g_fp->_currentScene->addStaticANIObject(ani, 1);
+ }
+
+ g_vars->scene25_beardersAreThere = true;
+}
+
+void sceneHandler25_enterMan() {
+ if (g_vars->scene25_waterIsPresent) {
+ chainQueue(QU_SC25_ENTERUP_WATER, 1);
+
+ getCurrSceneSc2MotionController()->clearEnabled();
+ } else {
+ chainQueue(QU_SC25_ENTERUP_FLOOR, 1);
+ }
+}
+
+void sceneHandler25_enterTruba() {
+ PicAniInfo info;
+
+ g_fp->_aniMan->getPicAniInfo(&info);
+ g_fp->_aniMan->_messageQueueId = 0;
+ g_fp->_aniMan->changeStatics2(g_fp->_aniMan->_statics->_staticsId);
+
+ int x = g_fp->_aniMan->_ox;
+ int y = g_fp->_aniMan->_oy;
+
+ g_fp->_aniMan->setPicAniInfo(&info);
+
+ int id = g_fp->_aniMan->_statics->_staticsId;
+ int qid = 0;
+
+ if (id == ST_MAN25_ONBOARD && x == 634 && y == 502) {
+ g_fp->_aniMan->changeStatics2(ST_MAN25_ONBOARD);
+
+ qid = QU_SC25_MANTOTRUBA;
+ } else if (id == (ST_MAN25_ONBOARD|0x4000) && x == 632 && y == 502) {
+ g_fp->_aniMan->changeStatics2(ST_MAN25_ONBOARD|0x4000);
+
+ qid = QU_SC25_MANTOTRUBA_R;
+ }
+
+ if (qid) {
+ chainQueue(qid, 1);
+ g_vars->scene25_sneezeFlipper = false;
+ }
+}
+
+void sceneHandler25_saveEntrance(int value) {
+ g_fp->getGameLoaderGameVar()->getSubVarByName("OBJSTATES")->getSubVarByName("SAVEGAME")->setSubVarAsInt("Entrance", value);
+}
+
+void sceneHandler25_toLadder() {
+ PicAniInfo info;
+
+ g_fp->_aniMan->getPicAniInfo(&info);
+ g_fp->_aniMan->_messageQueueId = 0;
+ g_fp->_aniMan->changeStatics2(g_fp->_aniMan->_statics->_staticsId);
+
+ int x = g_fp->_aniMan->_ox;
+ int y = g_fp->_aniMan->_oy;
+
+ g_fp->_aniMan->setPicAniInfo(&info);
+
+ int id = g_fp->_aniMan->_statics->_staticsId;
+ int qid = 0;
+
+ if (id == ST_MAN25_ONBOARD && x == 307 && y == 502) {
+ g_fp->_aniMan->changeStatics2(ST_MAN25_ONBOARD);
+
+ qid = QU_SC25_BACKTOLADDER;
+ } else if (id == (ST_MAN25_ONBOARD|0x4000) && x == 192 && y == 502) {
+ g_fp->_aniMan->changeStatics2(ST_MAN25_ONBOARD|0x4000);
+
+ qid = QU_SC25_BOARDTOLADDER;
+ }
+
+ if (qid) {
+ chainQueue(qid, 1);
+ g_vars->scene25_dudeIsOnBoard = false;
+ g_vars->scene25_boardIsSelectable = true;
+ g_vars->scene25_sneezeFlipper = false;
+
+ sceneHandler25_saveEntrance(TrubaUp);
+ }
+}
+
+void sceneHandler25_animateBearders() {
+ if (g_fp->_rnd->getRandomNumber(32767) < 218) {
+ MessageQueue *mq;
+
+ mq = new MessageQueue(g_fp->_currentScene->getMessageQueueById(QU_SC25_BEARDED), 0, 1);
+
+ mq->replaceKeyCode(-1, g_vars->scene25_bearders[0]->_okeyCode);
+ mq->getExCommandByIndex(0)->_x = g_fp->_rnd->getRandomNumber(650) + 100;
+ mq->chain(0);
+
+ g_vars->scene25_beardersCounter = 0;
+
+ if (g_fp->_rnd->getRandomNumber(32767) < 0x1FFF) {
+ mq = new MessageQueue(g_fp->_currentScene->getMessageQueueById(QU_SC25_BEARDED2), 0, 1);
+
+ mq->replaceKeyCode(-1, g_vars->scene25_bearders[1]->_okeyCode);
+ mq->getExCommandByIndex(0)->_x = g_fp->_rnd->getRandomNumber(650) + 100;
+ mq->chain(0);
+
+ if (g_fp->_rnd->getRandomNumber(32767) < 8191) {
+ mq = new MessageQueue(g_fp->_currentScene->getMessageQueueById(QU_SC25_BEARDED3), 0, 1);
+
+ mq->replaceKeyCode(-1, g_vars->scene25_bearders[2]->_okeyCode);
+ mq->getExCommandByIndex(0)->_x = g_fp->_rnd->getRandomNumber(650) + 100;
+ mq->chain(0);
+ }
+ }
+ }
+}
+
+void sceneHandler25_sneeze() {
+ if (g_fp->_rnd->getRandomNumber(32767) % 10) {
+ if (g_fp->_aniMan->_statics->_staticsId == ST_MAN25_ONBOARD) {
+ g_fp->_aniMan->startAnim(MV_MAN25_ONBOARD, 0, -1);
+ } else if (g_fp->_aniMan->_statics->_staticsId == (ST_MAN25_ONBOARD|0x4000)) {
+ g_fp->_aniMan->startAnim(rMV_MAN25_ONBOARD, 0, -1);
+ }
+ } else if (g_fp->_aniMan->_statics->_staticsId == ST_MAN25_ONBOARD) {
+ g_fp->_aniMan->startAnim(MV_MAN25_CHIH, 0, -1);
+ } else if (g_fp->_aniMan->_statics->_staticsId == (ST_MAN25_ONBOARD|0x4000)) {
+ g_fp->_aniMan->startAnim(rMV_MAN25_CHIH, 0, -1);
+ }
+}
+
+void sceneHandler25_rowShovel() {
+ PicAniInfo info;
+
+ g_fp->_aniMan->getPicAniInfo(&info);
+ g_fp->_aniMan->_messageQueueId = 0;
+ g_fp->_aniMan->changeStatics2(g_fp->_aniMan->_statics->_staticsId);
+
+ int x = g_fp->_aniMan->_ox;
+ int y = g_fp->_aniMan->_oy;
+
+ g_fp->_aniMan->setPicAniInfo(&info);
+
+ int id = g_fp->_aniMan->_statics->_staticsId;
+ int qid = 0;
+
+ if (id == ST_MAN25_ONBOARD && x == 370 && y == 502) {
+ g_fp->_aniMan->changeStatics2(ST_MAN25_ONBOARD);
+
+ qid = QU_SC25_ROWTOTRUBA;
+ } else if (id == (ST_MAN25_ONBOARD|0x4000) && x == 632 && y == 502) {
+ g_fp->_aniMan->changeStatics2(ST_MAN25_ONBOARD|0x4000);
+
+ qid = QU_SC25_ROWTOLADDER;
+
+ g_fp->playSound(SND_25_030, 0);
+ }
+
+ if (qid) {
+ chainQueue(qid, 1);
+
+ g_vars->scene25_sneezeFlipper = false;
+ }
+}
+
+void sceneHandler25_rowHand() {
+ PicAniInfo info;
+
+ g_fp->_aniMan->getPicAniInfo(&info);
+ g_fp->_aniMan->_messageQueueId = 0;
+ g_fp->_aniMan->changeStatics2(g_fp->_aniMan->_statics->_staticsId);
+
+ int x = g_fp->_aniMan->_ox;
+ int y = g_fp->_aniMan->_oy;
+
+ g_fp->_aniMan->setPicAniInfo(&info);
+
+ int id = g_fp->_aniMan->_statics->_staticsId;
+ int qid = 0;
+
+ if (id == ST_MAN25_ONBOARD && x == 370 && y == 502) {
+ g_fp->_aniMan->changeStatics2(ST_MAN25_ONBOARD);
+
+ qid = QU_SC25_TRYROWHAND;
+ } else if (id == (ST_MAN25_ONBOARD|0x4000) && x == 632 && y == 502) {
+ g_fp->_aniMan->changeStatics2(ST_MAN25_ONBOARD|0x4000);
+
+ qid = QU_SC25_TRYROWHAND_R;
+ }
+
+ if (qid) {
+ chainObjQueue(g_fp->_aniMan, qid, 1);
+ g_vars->scene25_sneezeFlipper = false;
+ }
+}
+
+void sceneHandler25_putBoard() {
+ if (g_fp->_aniMan->_statics->_staticsId == ST_MAN_STANDLADDER
+ || g_fp->_aniMan->_statics->_staticsId == ST_MAN_LADDERDOWN_R) {
+ g_fp->_aniMan->changeStatics2(ST_MAN_STANDLADDER);
+ g_fp->_aniMan->setOXY(281, 481);
+
+ chainQueue(QU_SC25_PUTBOARD, 1);
+
+ g_vars->scene25_dudeIsOnBoard = true;
+ g_vars->scene25_sneezeFlipper = false;
+ g_vars->scene25_boardIsSelectable = false;
+ }
+}
+
+void sceneHandler25_tryWater() {
+ if (g_fp->_aniMan->_statics->_staticsId == ST_MAN_STANDLADDER
+ || g_fp->_aniMan->_statics->_staticsId == ST_MAN_LADDERDOWN_R) {
+ g_fp->_aniMan->changeStatics2(ST_MAN_STANDLADDER);
+
+ chainQueue(QU_SC25_TRYWATER, 1);
+ }
+}
+
+void sceneHandler25_tryRow(int obj) {
+ PicAniInfo info;
+
+ g_fp->_aniMan->getPicAniInfo(&info);
+ g_fp->_aniMan->_messageQueueId = 0;
+ g_fp->_aniMan->changeStatics2(ST_MAN_RIGHT|0x4000);
+
+ int x = g_fp->_aniMan->_ox;
+ int y = g_fp->_aniMan->_oy;
+
+ g_fp->_aniMan->setPicAniInfo(&info);
+
+ int qid = 0;
+
+ if (x == 788 && y == 468) {
+ if (g_vars->scene25_board->_statics->_staticsId == ST_BRD25_RIGHT2) {
+ if (obj == ANI_INV_BROOM) {
+ g_fp->_aniMan->changeStatics2(ST_MAN_RIGHT|0x4000);
+
+ qid = QU_SC25_TRYBROOM;
+ }
+ if (obj == ANI_INV_LOPAT) {
+ g_fp->_aniMan->changeStatics2(ST_MAN_RIGHT|0x4000);
+
+ qid = QU_SC25_TRYSPADE;
+ }
+
+ if (qid) {
+ chainQueue(qid, 1);
+
+ g_fp->playSound(SND_25_028, 0);
+
+ return;
+ }
+
+ if (obj == ANI_INV_SWAB) {
+ g_fp->_aniMan->changeStatics2(ST_MAN_RIGHT|0x4000);
+
+ chainQueue(QU_SC25_TRYSWAB, 1);
+ } else if (!obj) {
+ g_fp->_aniMan->changeStatics2(ST_MAN_RIGHT|0x4000);
+
+ chainObjQueue(g_fp->_aniMan, QU_SC25_TRYHAND, 1);
+
+ g_fp->playSound(SND_25_028, 0);
+ }
+ } else if (g_vars->scene25_board->_statics->_staticsId == (ST_MAN_RIGHT|0x4000) && !obj) {
+ g_fp->_aniMan->changeStatics2(ST_MAN_RIGHT|0x4000);
+
+ chainQueue(QU_SC25_TRUBATOBOARD, 1);
+
+ g_vars->scene25_dudeIsOnBoard = true;
+ }
+ }
+}
+
+void sceneHandler25_ladderUp() {
+ if (g_fp->_aniMan->_statics->_staticsId == ST_MAN_STANDLADDER
+ || g_fp->_aniMan->_statics->_staticsId == ST_MAN_LADDERDOWN_R) {
+ g_fp->_aniMan->changeStatics2(ST_MAN_STANDLADDER);
+
+ chainQueue(QU_SC25_LADDERUP, 1);
+ }
+}
+
+void sceneHandler25_backToPipe() {
+ if (!g_fp->_aniMan->_movement && g_fp->_aniMan->_statics->_staticsId == (ST_MAN_RIGHT|0x4000)) {
+ g_fp->_aniMan->changeStatics2(ST_MAN_RIGHT|0x4000);
+
+ chainQueue(QU_SC25_BACKTOTRUBA, 1);
+ }
+}
+
+void sceneHandler25_walkOnLadder(StaticANIObject *ani, Common::Point *pnt, MessageQueue *mq, int flag) {
+ int aniY = ani->_oy;
+ int newx = 0, newy = 0;
+ Common::Point point;
+ ExCommand *ex;
+
+ if (flag) {
+ if (ani->_movement) {
+ ani->_movement->calcSomeXY(point, 0);
+ newx = point.x;
+ aniY = ani->_oy - point.y;
+ }
+ }
+
+ int pntx = pnt->x;
+ int pnty = pnt->y;
+ int numObsolete = -1;
+ int minDistance = 20000;
+ ExCommand *lastEx = 0;
+
+ for (uint i = 0; i < mq->getCount(); i++) {
+ int curDistance = abs(pnty - aniY);
+
+ ex = mq->getExCommandByIndex(i);
+
+ if (ex->_messageKind == 1 && ani->_id == ex->_parentId) {
+ if (ex->_excFlags & 0x10000) {
+ if (ex->_messageNum == MV_MAN_TOLADDER)
+ ex->_messageNum = MV_MAN_TOLADDER2;
+ if (ex->_messageNum == MV_MAN_STARTLADDER)
+ ex->_messageNum = MV_MAN_STARTLADDER2;
+ if (ex->_messageNum == MV_MAN_GOLADDER)
+ ex->_messageNum = MV_MAN_GOLADDER2;
+ if (ex->_messageNum == MV_MAN_STOPLADDER)
+ ex->_messageNum = MV_MAN_STOPLADDER2;
+ }
+
+ if (curDistance < minDistance || numObsolete < 0) {
+ numObsolete = i;
+ minDistance = curDistance;
+ lastEx = ex;
+ newx = pntx;
+ newy = pnty;
+ }
+
+ ani->getMovementById(ex->_messageNum)->calcSomeXY(point, 0);
+ pntx += point.x;
+ pnty += point.y;
+ }
+ }
+
+ for (int i = 0; i < numObsolete; i++)
+ mq->deleteExCommandByIndex(0, 1);
+
+ ex = new ExCommand(ani->_id, 34, 256, 0, 0, 0, 1, 0, 0, 0);
+
+ ex->_field_14 = 256;
+ ex->_messageNum = 0;
+ ex->_excFlags |= 3;
+
+ mq->addExCommandToEnd(ex);
+
+ if (flag && ani->_movement && ani->_movement->_id == mq->getExCommandByIndex(0)->_messageNum) {
+ mq->deleteExCommandByIndex(0, 1);
+
+ int movId = ani->_movement->_id;
+ int idx = ani->_movement->_currDynamicPhaseIndex;
+
+ ani->changeStatics2(ani->_movement->_staticsObj1->_staticsId);
+ ani->setOXY(newx, newy);
+
+ ani->startAnim(movId, mq->_id, -1);
+
+ ani->_movement->setDynamicPhaseIndex(idx);
+ } else {
+ if (!lastEx)
+ error("sceneHandler25_walkOnLadder(): Incorrect state. Please report this to sev");
+
+ ani->changeStatics2(ani->getMovementById(lastEx->_messageNum)->_staticsObj1->_staticsId);
+ ani->setOXY(newx, newy);
+ ani->restartMessageQueue(mq);
+ }
+
+ ani->_flags |= 1;
+}
+
+bool sceneHandler25_isOnLadder(ExCommand *cmd) {
+ if ((g_fp->_aniMan->_movement && g_fp->_aniMan->_movement->_id == MV_MAN_GOLADDERDOWN)
+ || g_fp->_aniMan->_statics->_staticsId == ST_MAN_GOLADDERD) {
+ Interaction *inter = getGameLoaderInteractionController()->getInteractionByObjectIds(PIC_SC25_LADDERDOWN, ANI_MAN, cmd->_keyCode);
+
+ if (!inter)
+ return 0;
+
+ MessageQueue *mq = new MessageQueue(inter->_messageQueue, 0, 1);
+ PictureObject *pic = g_fp->_currentScene->getPictureObjectById(PIC_SC25_LADDERDOWN, 0);
+ Common::Point point;
+
+ point.x = inter->_xOffs + pic->_ox;
+ point.y = inter->_yOffs + pic->_oy;
+
+ mq->setFlags(mq->getFlags() | 1);
+
+ sceneHandler25_walkOnLadder(g_fp->_aniMan, &point, mq, 0);
+
+ return true;
+ } else {
+ return false;
+ }
+}
+
+void sceneHandler25_sub03() {
+ warning("STUB: sceneHandler25_sub03()");
+}
+
+int sceneHandler25(ExCommand *cmd) {
+ if (cmd->_messageKind != 17)
+ return 0;
+
+ switch (cmd->_messageNum) {
+ case MSG_SC25_STOPBEARDEDS:
+ sceneHandler25_stopBearders();
+ break;
+
+ case MSG_SC25_STARTBEARDEDS:
+ sceneHandler25_startBearders();
+ break;
+
+ case MSG_SC25_ENTERMAN:
+ sceneHandler25_enterMan();
+ break;
+
+ case MSG_SC25_ENTERTRUBA:
+ sceneHandler25_enterTruba();
+ break;
+
+ case MSG_SC25_TOLADDER:
+ sceneHandler25_toLadder();
+ break;
+
+ case MSG_BRD_TURN:
+ switch (g_fp->_rnd->getRandomNumber(3)) {
+ case 0:
+ g_fp->playSound(SND_25_025, 0);
+ break;
+
+ case 1:
+ g_fp->playSound(SND_25_026, 0);
+ break;
+
+ default:
+ g_fp->playSound(SND_25_027, 0);
+ break;
+ }
+ break;
+
+ case 33:
+ if (g_fp->_aniMan2) {
+ int x = g_fp->_aniMan2->_ox;
+ int y = g_fp->_aniMan2->_oy;
+
+ if (x < g_fp->_sceneRect.left + 200)
+ g_fp->_currentScene->_x = x - 300 - g_fp->_sceneRect.left;
+
+ if (x > g_fp->_sceneRect.right - 200)
+ g_fp->_currentScene->_x = x + 300 - g_fp->_sceneRect.right;
+
+ if (!g_vars->scene25_waterIsPresent) {
+ if (y < g_fp->_sceneRect.top + 200)
+ g_fp->_currentScene->_y = y - 300 - g_fp->_sceneRect.top;
+
+ if (y > g_fp->_sceneRect.bottom - 200)
+ g_fp->_currentScene->_y = y + 300 - g_fp->_sceneRect.bottom;
+ }
+ }
+
+ if (g_vars->scene25_beardersAreThere) {
+ g_vars->scene25_beardersCounter++;
+
+ if (g_vars->scene25_beardersCounter >= 120)
+ sceneHandler25_animateBearders();
+ }
+
+ g_fp->_behaviorManager->updateBehaviors();
+ g_fp->startSceneTrack();
+
+ if (g_vars->scene25_waterIsPresent && !g_vars->scene25_water->_movement)
+ g_vars->scene25_water->startAnim(MV_WTR25_FLOW, 0, -1);
+
+ if (g_vars->scene25_dudeIsOnBoard && !g_fp->_aniMan->_movement && g_vars->scene25_sneezeFlipper)
+ sceneHandler25_sneeze();
+
+ g_vars->scene25_sneezeFlipper = true;
+
+ if (g_vars->scene25_board->_flags & 4) {
+ if (!g_vars->scene25_board->_movement) {
+ if (g_vars->scene25_board->_statics->_staticsId & 0x4000)
+ g_vars->scene25_board->startAnim(rMV_BRD25_RIGHT, 0, -1);
+ else
+ g_vars->scene25_board->startAnim(MV_BRD25_RIGHT, 0, -1);
+ }
+ }
+ break;
+
+ case 29:
+ {
+ int picId = g_fp->_currentScene->getPictureObjectIdAtPos(cmd->_sceneClickX, cmd->_sceneClickY);
+
+ if (!g_vars->scene25_waterIsPresent) {
+ if ((picId == PIC_SC25_LADDERUP || picId == PIC_SC25_LADDERDOWN) && sceneHandler25_isOnLadder(cmd))
+ cmd->_messageKind = 0;
+
+ break;
+ }
+
+ StaticANIObject *ani = g_fp->_currentScene->getStaticANIObjectAtPos(cmd->_sceneClickX, cmd->_sceneClickY);
+
+ if (ani) {
+ if (g_fp->_aniMan != ani) {
+ if (g_fp->_aniMan->isIdle()) {
+ if (!(g_fp->_aniMan->_flags & 0x100)) {
+ if (ani->_id == ANI_WATER25) {
+ if (g_vars->scene25_dudeIsOnBoard) {
+ if (cmd->_keyCode == ANI_INV_LOPAT)
+ sceneHandler25_rowShovel();
+
+ if (!cmd->_keyCode)
+ sceneHandler25_rowHand();
+ } else {
+ if (cmd->_keyCode == ANI_INV_BOARD)
+ sceneHandler25_putBoard();
+
+ if (!cmd->_keyCode)
+ sceneHandler25_tryWater();
+ }
+ } else if (ani->_id == ANI_BOARD25) {
+ sceneHandler25_tryRow(cmd->_keyCode);
+ break;
+ }
+ break;
+ }
+ }
+ }
+ }
+
+ if (picId == PIC_SC25_LADDERUP && sceneHandler25_isOnLadder(cmd))
+ cmd->_messageKind = 0;
+
+ if (!g_fp->_aniMan->isIdle() || (g_fp->_aniMan->_flags & 0x100))
+ break;
+
+ if (g_vars->scene25_dudeIsOnBoard) {
+ if (picId == PIC_SC25_RTRUBA && !cmd->_keyCode) {
+ sceneHandler25_enterTruba();
+ break;
+ }
+ } else {
+ if (picId != PIC_SC25_RTRUBA) {
+ if (picId == PIC_SC25_LADDERUP && !cmd->_keyCode)
+ sceneHandler25_ladderUp();
+ break;
+ }
+
+ if (!cmd->_keyCode) {
+ sceneHandler25_backToPipe();
+ break;
+ }
+ }
+ if (g_vars->scene25_dudeIsOnBoard) {
+ if (picId != PIC_SC25_LADDERUP || cmd->_keyCode)
+ break;
+
+ sceneHandler25_toLadder();
+ break;
+ }
+
+ if (picId == PIC_SC25_LADDERUP && !cmd->_keyCode)
+ sceneHandler25_ladderUp();
+
+ break;
+ }
+ }
+
+ return 0;
+}
+
+} // End of namespace Fullpipe
diff --git a/engines/fullpipe/scenes/scene26.cpp b/engines/fullpipe/scenes/scene26.cpp
new file mode 100644
index 0000000000..91679347e6
--- /dev/null
+++ b/engines/fullpipe/scenes/scene26.cpp
@@ -0,0 +1,355 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public 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 "fullpipe/fullpipe.h"
+
+#include "fullpipe/objectnames.h"
+#include "fullpipe/constants.h"
+
+#include "fullpipe/gameloader.h"
+#include "fullpipe/motion.h"
+#include "fullpipe/scenes.h"
+#include "fullpipe/statics.h"
+
+#include "fullpipe/interaction.h"
+#include "fullpipe/behavior.h"
+
+
+namespace Fullpipe {
+
+void scene26_initScene(Scene *sc) {
+ g_vars->scene26_chhi = sc->getStaticANIObject1ById(ANI_CHHI, -1);
+ g_vars->scene26_drop = sc->getStaticANIObject1ById(ANI_DROP_26, -1);
+ g_vars->scene26_sockPic = sc->getPictureObjectById(PIC_SC26_SOCK, 0);
+ g_vars->scene26_sock = sc->getStaticANIObject1ById(ANI_SOCK_26, -1);
+
+ if (g_fp->getObjectState(sO_Hatch_26) == g_fp->getObjectEnumState(sO_Hatch_26, sO_WithSock)) {
+ g_fp->setObjectState(sO_Hatch_26, g_fp->getObjectEnumState(sO_Hatch_26, sO_Closed));
+ g_fp->setObjectState(sO_Sock_26, g_fp->getObjectEnumState(sO_Sock_26, sO_HangsOnPipe));
+ }
+
+ Interaction *inter = getGameLoaderInteractionController()->getInteractionByObjectIds(ANI_LUK26, ANI_MAN, ANI_INV_SOCK);
+
+ if (getGameLoaderInventory()->getCountItemsWithId(ANI_INV_VENT) == 0)
+ inter->_flags &= 0xFFFDFFFF;
+ else
+ inter->_flags |= 0x20000;
+
+ if (g_fp->getObjectState(sO_Sock_26) == g_fp->getObjectEnumState(sO_Sock_26, sO_HangsOnPipe))
+ g_vars->scene26_sockPic->_flags |= 4;
+ else
+ g_vars->scene26_sockPic->_flags &= 0xFFFB;
+
+ if (g_fp->getObjectState(sO_Valve1_26) == g_fp->getObjectEnumState(sO_Valve1_26, sO_Opened))
+ g_fp->playSound(SND_26_018, 1);
+}
+
+int scene26_updateCursor() {
+ g_fp->updateCursorCommon();
+
+ if (g_fp->_objectIdAtCursor != ANI_VENT || g_fp->_cursorId != PIC_CSR_DEFAULT) {
+ if (g_fp->_cursorId == PIC_CSR_ITN && g_fp->_objectIdAtCursor == PIC_SC26_LTRUBA)
+ g_fp->_cursorId = PIC_CSR_GOL;
+ } else {
+ g_fp->_cursorId = PIC_CSR_ITN;
+ }
+
+ return g_fp->_cursorId;
+}
+
+void sceneHandler26_updateDrop() {
+ if (g_fp->getObjectState(sO_Valve5_26) == g_fp->getObjectEnumState(sO_Valve5_26, sO_Closed))
+ g_fp->_behaviorManager->setFlagByStaticAniObject(g_vars->scene26_drop, 0);
+ else
+ g_fp->_behaviorManager->setFlagByStaticAniObject(g_vars->scene26_drop, 1);
+}
+
+void scene26_setupDrop(Scene *sc) {
+ sceneHandler26_updateDrop();
+}
+
+void sceneHandler26_showChi() {
+ g_vars->scene26_chhi->changeStatics2(ST_CHI_EMPTY);
+
+ chainQueue(QU_CHI_SHOW, 1);
+}
+
+void sceneHandler26_updatePool() {
+ if (g_fp->getObjectState(sO_Valve1_26) == g_fp->getObjectEnumState(sO_Valve1_26, sO_Valve1_26))
+ g_fp->setObjectState(sO_Pool, g_fp->getObjectEnumState(sO_Pool, sO_Overfull));
+ else if (g_fp->getObjectState(sO_Pool) == g_fp->getObjectEnumState(sO_Pool, sO_Overfull))
+ g_fp->setObjectState(sO_Pool, g_fp->getObjectEnumState(sO_Pool, sO_Full));
+
+ if (g_fp->getObjectState(sO_Valve2_26) == g_fp->getObjectEnumState(sO_Valve2_26, sO_Valve1_26)) {
+ if (g_fp->getObjectState(sO_Pool) >= g_fp->getObjectEnumState(sO_Pool, sO_Full))
+ g_fp->setObjectState(sO_Pool, g_fp->getObjectEnumState(sO_Pool, sO_HalfFull));
+ }
+
+ if (g_fp->getObjectState(sO_Valve3_26) == g_fp->getObjectEnumState(sO_Valve3_26, sO_Valve1_26)) {
+ if (g_fp->getObjectState(sO_Pool) >= g_fp->getObjectEnumState(sO_Pool, sO_HalfFull))
+ g_fp->setObjectState(sO_Pool, g_fp->getObjectEnumState(sO_Pool, sO_Empty));
+ }
+}
+
+void sceneHandler26_hideChi() {
+ g_vars->scene26_chhi->changeStatics2(ST_CHI_NORM);
+
+ chainQueue(QU_CHI_HIDE, 1);
+}
+
+void sceneHandler26_testVent() {
+ if (!g_vars->scene26_activeVent)
+ return;
+
+ if (g_vars->scene26_activeVent->_okeyCode == 0) {
+ if (g_fp->getObjectState(sO_Valve1_26) == g_fp->getObjectEnumState(sO_Valve1_26, sO_Opened))
+ g_fp->stopAllSoundInstances(SND_26_018);
+ else
+ g_fp->playSound(SND_26_018, 1);
+
+ if (g_fp->getObjectState(sO_Valve2_26) == g_fp->getObjectEnumState(sO_Valve2_26, sO_Opened)) {
+ chainQueue(QU_SC26_AUTOCLOSE2, 0);
+
+ g_fp->playSound(SND_26_020, 0);
+ }
+
+ if (g_fp->getObjectState(sO_Valve3_26) == g_fp->getObjectEnumState(sO_Valve3_26, sO_Opened)) {
+ chainQueue(QU_SC26_AUTOCLOSE3, 0);
+
+ g_fp->playSound(SND_26_020, 0);
+ }
+ } else if (g_vars->scene26_activeVent->_okeyCode == 1) {
+ if (g_fp->getObjectState(sO_Valve2_26) == g_fp->getObjectEnumState(sO_Valve2_26, sO_Opened))
+ g_fp->playSound(SND_26_020, 0);
+ else
+ g_fp->playSound(SND_26_019, 0);
+
+ if (g_fp->getObjectState(sO_Pool) == g_fp->getObjectEnumState(sO_Pool, sO_Overfull)
+ || g_fp->getObjectState(sO_Pool) == g_fp->getObjectEnumState(sO_Pool, sO_Full))
+ g_fp->playSound(SND_26_003, 0);
+
+ if (g_fp->getObjectState(sO_Valve1_26) == g_fp->getObjectEnumState(sO_Valve1_26, sO_Opened)) {
+ g_fp->stopAllSoundInstances(SND_26_018);
+
+ chainQueue(QU_SC26_AUTOCLOSE1, 0);
+ }
+ } else if (g_vars->scene26_activeVent->_okeyCode == 2) {
+ if (g_fp->getObjectState(sO_Valve3_26) == g_fp->getObjectEnumState(sO_Valve3_26, sO_Opened))
+ g_fp->playSound(SND_26_020, 0);
+ else
+ g_fp->playSound(SND_26_019, 0);
+
+ if (g_fp->getObjectState(sO_Pool) == g_fp->getObjectEnumState(sO_Pool, sO_Overfull)
+ || g_fp->getObjectState(sO_Pool) == g_fp->getObjectEnumState(sO_Pool, sO_Full)
+ || g_fp->getObjectState(sO_Pool) == g_fp->getObjectEnumState(sO_Pool, sO_HalfFull))
+ g_fp->playSound(SND_26_003, 0);
+
+ if (g_fp->getObjectState(sO_Valve1_26) == g_fp->getObjectEnumState(sO_Valve1_26, sO_Opened)) {
+ g_fp->stopAllSoundInstances(SND_26_018);
+
+ chainQueue(QU_SC26_AUTOCLOSE1, 0);
+ }
+ }
+}
+
+void sceneHandler26_showVent() {
+ if (g_vars->scene26_activeVent) {
+ int id = g_vars->scene26_activeVent->_statics->_staticsId;
+
+ if (id == ST_VNT26_UP2) {
+ g_vars->scene26_activeVent->changeStatics2(ST_VNT26_RIGHT2);
+ } else {
+ if (id != ST_VNT26_RIGHT2)
+ return;
+
+ g_vars->scene26_activeVent->changeStatics2(ST_VNT26_UP2);
+ }
+ g_vars->scene26_activeVent->show1(-1, -1, -1, 0);
+ }
+}
+
+void sceneHandler26_hideVent() {
+ if (g_vars->scene26_activeVent)
+ g_vars->scene26_activeVent->hide();
+}
+
+void sceneHandler26_animateVents(StaticANIObject *ani) {
+ int qId = 0;
+
+ switch (ani->_okeyCode) {
+ case 0:
+ if (g_fp->getObjectState(sO_Valve1_26) == g_fp->getObjectEnumState(sO_Valve1_26, sO_Closed))
+ qId = QU_SC26_OPEN1;
+ else
+ qId = QU_SC26_CLOSE1;
+
+ break;
+
+ case 1:
+ if (g_fp->getObjectState(sO_Valve2_26) == g_fp->getObjectEnumState(sO_Valve2_26, sO_Closed))
+ qId = QU_SC26_OPEN2;
+ else
+ qId = QU_SC26_CLOSE2;
+
+ break;
+
+ case 2:
+ if (g_fp->getObjectState(sO_Valve3_26) == g_fp->getObjectEnumState(sO_Valve3_26, sO_Closed))
+ qId = QU_SC26_OPEN3;
+ else
+ qId = QU_SC26_CLOSE3;
+
+ break;
+
+ case 3:
+ if (g_fp->getObjectState(sO_Valve4_26) == g_fp->getObjectEnumState(sO_Valve4_26, sO_Closed))
+ qId = QU_SC26_OPEN4;
+ else
+ qId = QU_SC26_CLOSE4;
+
+ break;
+
+ case 4:
+ if (g_fp->getObjectState(sO_Valve5_26) == g_fp->getObjectEnumState(sO_Valve5_26, sO_Closed))
+ qId = QU_SC26_OPEN5;
+ else
+ qId = QU_SC26_CLOSE5;
+
+ break;
+
+ default:
+ return;
+ }
+
+ if (qId) {
+ MessageQueue *mq = g_fp->_currentScene->getMessageQueueById(qId);
+
+ mq->setFlags(mq->getFlags() | 1);
+ mq->chain(0);
+ }
+}
+
+void sceneHandler26_clickVent(StaticANIObject *ani, ExCommand *cmd) {
+ if (ani->_okeyCode || g_fp->getObjectState(sO_Hatch_26) == g_fp->getObjectEnumState(sO_Hatch_26, sO_Opened)) {
+ if (g_fp->_aniMan->isIdle() && !(g_fp->_aniMan->_flags & 0x100)) {
+ g_vars->scene26_activeVent = ani;
+
+ int x = ani->_ox - 20;
+ int y = ani->_oy + 61;
+
+ if (abs(x - g_fp->_aniMan->_ox) > 1 || abs(y - g_fp->_aniMan->_oy) > 1 || g_fp->_aniMan->_movement || g_fp->_aniMan->_statics->_staticsId != ST_MAN_UP) {
+ MessageQueue *mq = getCurrSceneSc2MotionController()->method34(g_fp->_aniMan, x, y, 1, ST_MAN_UP);
+
+ if (mq) {
+ ExCommand *ex = new ExCommand(0, 17, MSG_SC26_CLICKVENT, 0, 0, 0, 1, 0, 0, 0);
+
+ ex->_excFlags |= 3;
+ ex->_keyCode = ani->_okeyCode;
+
+ mq->addExCommandToEnd(ex);
+
+ postExCommand(g_fp->_aniMan->_id, 2, x, y, 0, -1);
+ }
+ } else {
+ sceneHandler26_animateVents(ani);
+ }
+ }
+ }
+
+ cmd->_messageKind = 0;
+}
+
+int sceneHandler26(ExCommand *cmd) {
+ if (cmd->_messageKind != 17)
+ return 0;
+
+ switch (cmd->_messageNum) {
+ case MSG_SC26_UPDATEDROP:
+ sceneHandler26_updateDrop();
+ break;
+
+ case MSG_SC26_SHOWCHI:
+ sceneHandler26_showChi();
+ break;
+
+ case MSG_SC26_UPDATEPOOL:
+ sceneHandler26_updatePool();
+ break;
+
+ case MSG_SC26_HIDECHI:
+ sceneHandler26_hideChi();
+ break;
+
+ case MSG_SC26_TESTVENT:
+ sceneHandler26_testVent();
+ break;
+
+ case MSG_SC26_SHOWVENT:
+ sceneHandler26_showVent();
+ break;
+
+ case MSG_SC26_CLICKVENT:
+ {
+ StaticANIObject *ani = g_fp->_currentScene->getStaticANIObject1ById(ANI_VENT, cmd->_keyCode);
+
+ if (ani && ani->_id == ANI_VENT)
+ sceneHandler26_clickVent(ani, cmd);
+
+ break;
+ }
+
+ case MSG_SC26_HIDEVENT:
+ sceneHandler26_hideVent();
+ break;
+
+ case 29:
+ {
+ StaticANIObject *ani = g_fp->_currentScene->getStaticANIObjectAtPos(cmd->_sceneClickX, cmd->_sceneClickY);
+
+ if (ani && ani->_id == ANI_VENT)
+ sceneHandler26_clickVent(ani, cmd);
+
+ break;
+ }
+
+ case 33:
+ if (g_fp->_aniMan2) {
+ int x = g_fp->_aniMan2->_ox;
+
+ if (x < g_fp->_sceneRect.left + 200)
+ g_fp->_currentScene->_x = x - 300 - g_fp->_sceneRect.left;
+
+ if (x > g_fp->_sceneRect.right - 200)
+ g_fp->_currentScene->_x = x + 300 - g_fp->_sceneRect.right;
+ }
+
+ g_fp->_behaviorManager->updateBehaviors();
+
+ g_fp->startSceneTrack();
+
+ break;
+ }
+
+ return 0;
+}
+
+} // End of namespace Fullpipe
diff --git a/engines/fullpipe/scenes/scene28.cpp b/engines/fullpipe/scenes/scene28.cpp
new file mode 100644
index 0000000000..62afd128c2
--- /dev/null
+++ b/engines/fullpipe/scenes/scene28.cpp
@@ -0,0 +1,474 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public 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 "fullpipe/fullpipe.h"
+
+#include "fullpipe/objectnames.h"
+#include "fullpipe/constants.h"
+
+#include "fullpipe/gameloader.h"
+#include "fullpipe/motion.h"
+#include "fullpipe/scenes.h"
+#include "fullpipe/statics.h"
+
+#include "fullpipe/interaction.h"
+#include "fullpipe/behavior.h"
+#include "fullpipe/floaters.h"
+
+namespace Fullpipe {
+
+void scene28_initScene(Scene *sc) {
+ g_vars->scene28_fliesArePresent = true;
+ g_vars->scene28_beardedDirection = true;
+ g_vars->scene28_darkeningObject = 0;
+ g_vars->scene28_lighteningObject = 0;
+ g_vars->scene28_headDirection = false;
+ g_vars->scene28_headBeardedFlipper = false;
+ g_vars->scene28_lift6inside = false;
+
+ g_fp->_floaters->init(g_fp->getGameLoaderGameVar()->getSubVarByName("SC_28"));
+
+ g_fp->initArcadeKeys("SC_28");
+}
+
+int scene28_updateCursor() {
+ g_fp->updateCursorCommon();
+ if (g_fp->_objectIdAtCursor == ANI_LIFT || g_fp->_objectIdAtCursor == ANI_LIFT_28)
+ if (g_fp->_cursorId == PIC_CSR_DEFAULT)
+ g_fp->_cursorId = PIC_CSR_ITN;
+
+ return g_fp->_cursorId;
+}
+
+void sceneHandler28_lift1ShowAfter() {
+ StaticANIObject *ani = g_fp->_currentScene->getStaticANIObject1ById(ANI_MAN_28, -1);
+
+ g_fp->_aniMan->_statics = g_fp->_aniMan->getStaticsById(ST_MAN_SIT|0x4000);
+ g_fp->_aniMan->setOXY(ani->_ox + 7, ani->_oy);
+ g_fp->_aniMan->_priority = ani->_priority;
+ g_fp->_aniMan->show1(-1, -1, -1, 0);
+}
+
+void sceneHandler28_makeFaces(ExCommand *cmd) {
+ g_fp->_currentScene->getPictureObjectById(PIC_SC28_DARK4, 0)->_flags &= 0xFFFB;
+
+ g_vars->scene28_lighteningObject = 0;
+
+ MessageQueue *mq = g_fp->_globalMessageQueueList->getMessageQueueById(cmd->_parId);
+ if (mq) {
+ int frames[5];
+
+ frames[0] = MV_WMN28_IN_1;
+ frames[1] = MV_WMN28_IN_2;
+ frames[2] = MV_WMN28_IN_3;
+ frames[3] = MV_WMN28_IN_4;
+ frames[4] = MV_WMN28_IN_5;
+
+ for (int i = 0; i < 5; i++) {
+ int pos;
+
+ while (frames[pos = g_fp->_rnd->getRandomNumber(4)] == 0)
+ ;
+
+ mq->getExCommandByIndex(i)->_messageNum = frames[pos];
+
+ frames[pos] = 0;
+ }
+ }
+}
+
+void sceneHandler28_trySecondaryPers() {
+ MessageQueue *mq;
+ int x;
+
+ if (g_vars->scene28_headBeardedFlipper) {
+ if (g_vars->scene28_beardedDirection) {
+ mq = new MessageQueue(g_fp->_currentScene->getMessageQueueById(QU_BRD28_GOR), 0, 1);
+
+ mq->getExCommandByIndex(0)->_x = g_fp->_sceneRect.left - 20;
+ mq->getExCommandByIndex(0)->_keyCode = 1;
+ mq->replaceKeyCode(-1, 1);
+ mq->chain(0);
+
+ mq = new MessageQueue(g_fp->_currentScene->getMessageQueueById(QU_BRD28_GOR), 0, 1);
+
+ mq->getExCommandByIndex(0)->_x = g_fp->_sceneRect.left - 40;
+ mq->getExCommandByIndex(0)->_y += 20;
+ mq->getExCommandByIndex(0)->_keyCode = 2;
+ mq->replaceKeyCode(-1, 2);
+ mq->chain(0);
+
+ mq = new MessageQueue(g_fp->_currentScene->getMessageQueueById(QU_BRD28_GOR), 0, 1);
+
+ x = g_fp->_sceneRect.left - 60;
+ } else {
+ mq = new MessageQueue(g_fp->_currentScene->getMessageQueueById(QU_BRD28_GOL), 0, 1);
+
+ mq->getExCommandByIndex(0)->_x = g_fp->_sceneRect.right + 20;
+ mq->getExCommandByIndex(0)->_keyCode = 1;
+ mq->replaceKeyCode(-1, 1);
+ mq->chain(0);
+
+ mq = new MessageQueue(g_fp->_currentScene->getMessageQueueById(QU_BRD28_GOL), 0, 1);
+
+ mq->getExCommandByIndex(0)->_x = g_fp->_sceneRect.right + 40;
+ mq->getExCommandByIndex(0)->_y += 20;
+ mq->getExCommandByIndex(0)->_keyCode = 2;
+ mq->replaceKeyCode(-1, 2);
+ mq->chain(0);
+
+ mq = new MessageQueue(g_fp->_currentScene->getMessageQueueById(QU_BRD28_GOL), 0, 1);
+
+ x = g_fp->_sceneRect.right + 60;
+ }
+
+ mq->getExCommandByIndex(0)->_x = x;
+ mq->getExCommandByIndex(0)->_y += 40;
+ mq->getExCommandByIndex(0)->_keyCode = 3;
+ mq->replaceKeyCode(-1, 3);
+ mq->chain( 0);
+
+ g_vars->scene28_beardedDirection = !g_vars->scene28_beardedDirection;
+ } else {
+ if (g_vars->scene28_headDirection) {
+ mq = new MessageQueue(g_fp->_currentScene->getMessageQueueById(QU_GLV28_GOR), 0, 1);
+
+ x = g_fp->_sceneRect.left - 40;
+ } else {
+ mq = new MessageQueue(g_fp->_currentScene->getMessageQueueById(QU_GLV28_GOL), 0, 1);
+
+ x = g_fp->_sceneRect.right + 40;
+ }
+
+ mq->getExCommandByIndex(0)->_x = x;
+ mq->chain(0);
+
+ g_vars->scene28_headDirection = !g_vars->scene28_headDirection;
+ }
+
+ g_vars->scene28_headBeardedFlipper = !g_vars->scene28_headBeardedFlipper;
+}
+
+void sceneHandler28_turnOn2() {
+ if (g_vars->scene28_fliesArePresent) {
+ g_fp->_floaters->genFlies(g_fp->_currentScene, 1013, 329, 60, 4);
+
+ g_fp->_floaters->_array2[g_fp->_floaters->_array2.size() - 1]->val15 = 30;
+ g_fp->_floaters->_array2[g_fp->_floaters->_array2.size() - 1]->countdown = g_fp->_rnd->getRandomNumber(12) + 12;
+
+ g_fp->_floaters->genFlies(g_fp->_currentScene, 1074, 311, 60, 4);
+
+ g_fp->_floaters->_array2[g_fp->_floaters->_array2.size() - 1]->val15 = 30;
+ g_fp->_floaters->_array2[g_fp->_floaters->_array2.size() - 1]->countdown = g_fp->_rnd->getRandomNumber(12) + 12;
+ }
+
+ g_vars->scene28_fliesArePresent = false;
+}
+
+void sceneHandler28_startWork1() {
+ g_fp->_aniMan->hide();
+
+ StaticANIObject *man = g_fp->_currentScene->getStaticANIObject1ById(ANI_MAN_28, -1);
+
+ man->_statics = man->getStaticsById(ST_MAN28_RIGHT);
+ man->setOXY(g_fp->_aniMan->_ox, g_fp->_aniMan->_oy);
+ man->_priority = g_fp->_aniMan->_priority;
+ man->show1(-1, -1, -1, 0);
+
+ chainQueue(QU_SC28_LIFT1_WORK, 1);
+}
+
+void sceneHandler28_lift0Start() {
+ chainQueue(QU_SC28_LIFT0_START, 1);
+}
+
+void sceneHandler28_lift1Start() {
+ g_fp->_aniMan->_flags |= 1;
+
+ g_fp->_behaviorManager->setFlagByStaticAniObject(g_fp->_aniMan, 0);
+
+ chainQueue(QU_SC28_LIFT1_START, 1);
+}
+
+void sceneHandler28_lift2Start() {
+ chainQueue(QU_SC28_LIFT2_START, 1);
+}
+
+void sceneHandler28_lift3Start() {
+ chainQueue(QU_SC28_LIFT3_START, 1);
+}
+
+void sceneHandler28_lift4Start() {
+ g_fp->_aniMan->_flags |= 1;
+
+ g_fp->_behaviorManager->setFlagByStaticAniObject(g_fp->_aniMan, 0);
+
+ chainQueue(QU_SC28_WMN_START, 1);
+}
+
+void sceneHandler28_lift5Start() {
+ chainQueue(QU_SC28_LIFT5_START, 1);
+}
+
+void sceneHandler28_lift6Start() {
+ g_fp->_aniMan->_flags |= 1;
+
+ g_fp->_behaviorManager->setFlagByStaticAniObject(g_fp->_aniMan, 0);
+
+ StaticANIObject *woman = g_fp->_currentScene->getStaticANIObject1ById(ANI_TIOTIA, -1);
+
+ if (woman && (woman->_flags & 4))
+ chainQueue(QU_SC28_LIFT6_START2, 1);
+ else
+ chainQueue(QU_SC28_LIFT6_START, 1);
+}
+
+void sceneHandler28_clickLift(int keycode) {
+ int x = 0;
+
+ switch (keycode) {
+ case 0: x = 600; break;
+ case 1: x = 824; break;
+ case 2: x = 1055; break;
+ case 3: x = 1286; break;
+ case 4: x = 1517; break;
+ case 5: x = 1748; break;
+ case 6: x = 1979; break;
+ }
+
+ if (abs(x - g_fp->_aniMan->_ox) > 1 || abs(472 - g_fp->_aniMan->_oy) > 1
+ || g_fp->_aniMan->_movement
+ || g_fp->_aniMan->_statics->_staticsId != ST_MAN_UP) {
+ MessageQueue *mq = getCurrSceneSc2MotionController()->method34(g_fp->_aniMan, x, 472, 1, ST_MAN_UP);
+ if (mq) {
+ ExCommand *ex = new ExCommand(0, 17, MSG_SC28_CLICKLIFT, 0, 0, 0, 1, 0, 0, 0);
+ ex->_excFlags |= 3;
+
+ mq->addExCommandToEnd(ex);
+
+ postExCommand(g_fp->_aniMan->_id, 2, x, 472, 0, -1);
+ }
+ } else {
+ switch (keycode) {
+ case 0:
+ sceneHandler28_lift0Start();
+ break;
+ case 1:
+ sceneHandler28_lift1Start();
+ break;
+ case 2:
+ sceneHandler28_lift2Start();
+ break;
+ case 3:
+ sceneHandler28_lift3Start();
+ break;
+ case 4:
+ sceneHandler28_lift4Start();
+ break;
+ case 5:
+ sceneHandler28_lift5Start();
+ break;
+ case 6:
+ sceneHandler28_lift6Start();
+ break;
+ default:
+ return;
+ }
+ }
+}
+
+int sceneHandler28(ExCommand *cmd) {
+ if (cmd->_messageKind != 17)
+ return 0;
+
+ switch (cmd->_messageNum) {
+ case MSG_SC28_LIFT6MUSIC:
+ g_fp->playTrack(g_fp->getGameLoaderGameVar()->getSubVarByName("SC_28"), "MUSIC_TIOTIA", 1);
+ break;
+
+ case MSG_SC28_LIFT6INSIDE:
+ g_vars->scene28_lift6inside = true;
+ break;
+
+ case MSG_SC28_LIFT1_SHOWAFTER:
+ sceneHandler28_lift1ShowAfter();
+ break;
+
+ case MSG_SC28_MAKEFACES:
+ sceneHandler28_makeFaces(cmd);
+ break;
+
+ case MSG_SC28_TRYVTORPERS:
+ sceneHandler28_trySecondaryPers();
+ break;
+
+ case MSG_SC28_TURNOFF_0:
+ g_vars->scene28_lighteningObject = g_fp->_currentScene->getPictureObjectById(PIC_SC28_DARK0, 0);
+ g_vars->scene28_lighteningObject->_flags |= 4;
+ break;
+
+ case MSG_SC28_TURNON_0:
+ g_vars->scene28_darkeningObject = g_fp->_currentScene->getPictureObjectById(PIC_SC28_DARK0, 0);
+ break;
+
+ case MSG_SC28_TURNON_1:
+ g_vars->scene28_darkeningObject = g_fp->_currentScene->getPictureObjectById(PIC_SC28_DARK1, 0);
+ break;
+
+ case MSG_SC28_TURNOFF_1:
+ g_vars->scene28_lighteningObject = g_fp->_currentScene->getPictureObjectById(PIC_SC28_DARK1, 0);
+ g_vars->scene28_lighteningObject->_flags |= 4;
+ break;
+
+ case MSG_SC28_TURNON_2:
+ g_vars->scene28_darkeningObject = g_fp->_currentScene->getPictureObjectById(PIC_SC28_DARK2, 0);
+ sceneHandler28_turnOn2();
+ break;
+
+ case MSG_SC28_TURNOFF_2:
+ g_vars->scene28_lighteningObject = g_fp->_currentScene->getPictureObjectById(PIC_SC28_DARK2, 0);
+ g_vars->scene28_lighteningObject->_flags |= 4;
+ break;
+
+ case MSG_SC28_TURNON_3:
+ g_vars->scene28_darkeningObject = g_fp->_currentScene->getPictureObjectById(PIC_SC28_DARK3, 0);
+ break;
+
+ case MSG_SC28_TURNOFF_3:
+ g_vars->scene28_lighteningObject = g_fp->_currentScene->getPictureObjectById(PIC_SC28_DARK3, 0);
+ g_vars->scene28_lighteningObject->_flags |= 4;
+ break;
+
+ case MSG_SC28_TURNON_4:
+ g_vars->scene28_darkeningObject = g_fp->_currentScene->getPictureObjectById(PIC_SC28_DARK4, 0);
+ break;
+
+ case MSG_SC28_TURNOFF_4:
+ g_vars->scene28_lighteningObject = g_fp->_currentScene->getPictureObjectById(PIC_SC28_DARK4, 0);
+ g_vars->scene28_lighteningObject->_flags |= 4;
+ break;
+
+ case MSG_SC28_TURNON_6:
+ g_vars->scene28_darkeningObject = g_fp->_currentScene->getPictureObjectById(PIC_SC28_DARK6, 0);
+ break;
+
+ case MSG_SC28_TURNOFF_6:
+ g_vars->scene28_lighteningObject = g_fp->_currentScene->getPictureObjectById(PIC_SC28_DARK6, 0);
+ g_vars->scene28_lighteningObject->_flags |= 4;
+ break;
+
+ case MSG_SC28_STARTWORK1:
+ sceneHandler28_startWork1();
+ break;
+
+ case MSG_SC28_CLICKLIFT:
+ sceneHandler28_clickLift(cmd->_keyCode);
+ break;
+
+ case MSG_SC28_ENDLIFT1:
+ case MSG_SC28_ENDLIFT6:
+ case MSG_SC28_ENDCABIN:
+ g_fp->_behaviorManager->setFlagByStaticAniObject(g_fp->_aniMan, 1);
+ g_fp->_aniMan->_flags &= 0xFEFF;
+ break;
+
+ case 29:
+ {
+ if (g_vars->scene28_lift6inside) {
+ chainObjQueue(g_fp->_aniMan, QU_SC28_LIFT6_END, 1);
+
+ g_fp->playTrack(g_fp->getGameLoaderGameVar()->getSubVarByName("SC_28"), "MUSIC", 1);
+
+ g_vars->scene28_lift6inside = false;
+ }
+
+ StaticANIObject *ani = g_fp->_currentScene->getStaticANIObjectAtPos(cmd->_sceneClickX, cmd->_sceneClickY);
+
+ if (ani)
+ if (ani->_id == ANI_LIFT || ani->_id == ANI_LIFT_28 ) {
+ sceneHandler28_clickLift(ani->_okeyCode);
+
+ cmd->_messageKind = 0;
+ break;
+ }
+
+ if (!ani || !canInteractAny(g_fp->_aniMan, ani, cmd->_keyCode)) {
+ int picId = g_fp->_currentScene->getPictureObjectIdAtPos(cmd->_sceneClickX, cmd->_sceneClickY);
+ PictureObject *pic = g_fp->_currentScene->getPictureObjectById(picId, 0);
+
+ if (!pic || !canInteractAny(g_fp->_aniMan, pic, cmd->_keyCode)) {
+ if ((g_fp->_sceneRect.right - cmd->_sceneClickX < 47 && g_fp->_sceneRect.right < g_fp->_sceneWidth - 1)
+ || (cmd->_sceneClickX - g_fp->_sceneRect.left < 47 && g_fp->_sceneRect.left > 0))
+ g_fp->processArcade(cmd);
+ }
+ }
+ break;
+ }
+
+ case 33:
+ if (g_fp->_aniMan2) {
+ int x = g_fp->_aniMan2->_ox;
+
+ if (x < g_fp->_sceneRect.left + 200)
+ g_fp->_currentScene->_x = x - 300 - g_fp->_sceneRect.left;
+
+ if (x > g_fp->_sceneRect.right - 200)
+ g_fp->_currentScene->_x = x + 300 - g_fp->_sceneRect.right;
+ }
+
+ if (g_vars->scene28_darkeningObject) {
+ if (g_vars->scene28_darkeningObject->_picture->getAlpha() > 10) {
+ g_vars->scene28_darkeningObject->_picture->setAlpha(g_vars->scene28_darkeningObject->_picture->getAlpha() - 10);
+ } else {
+ g_vars->scene28_darkeningObject->_flags &= 0xFFFB;
+
+ g_vars->scene28_darkeningObject = 0;
+ }
+ }
+
+ if (g_vars->scene28_lighteningObject) {
+ if (g_vars->scene28_lighteningObject->_picture->getAlpha() < 0xF9u) {
+ g_vars->scene28_lighteningObject->_picture->setAlpha(g_vars->scene28_lighteningObject->_picture->getAlpha() + 6);
+ } else {
+ g_vars->scene28_lighteningObject->_picture->setAlpha(0xff);
+
+ g_vars->scene28_lighteningObject = 0;
+ }
+ }
+
+ g_fp->_floaters->update();
+
+ for (uint i = 0; i < g_fp->_floaters->_array2.size(); i++)
+ if (g_fp->_floaters->_array2[i]->val13 == 1)
+ g_fp->_floaters->_array2[i]->ani->_priority = 15;
+
+ g_fp->_behaviorManager->updateBehaviors();
+
+ g_fp->startSceneTrack();
+
+ break;
+ }
+
+ return 0;
+}
+
+} // End of namespace Fullpipe
diff --git a/engines/fullpipe/scenes/scene30.cpp b/engines/fullpipe/scenes/scene30.cpp
new file mode 100644
index 0000000000..a807e692a7
--- /dev/null
+++ b/engines/fullpipe/scenes/scene30.cpp
@@ -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.
+ *
+ */
+
+#include "fullpipe/fullpipe.h"
+
+#include "fullpipe/objectnames.h"
+#include "fullpipe/constants.h"
+
+#include "fullpipe/gameloader.h"
+#include "fullpipe/motion.h"
+#include "fullpipe/scenes.h"
+#include "fullpipe/statics.h"
+
+#include "fullpipe/interaction.h"
+#include "fullpipe/behavior.h"
+
+
+namespace Fullpipe {
+
+void scene30_enablePass(Scene *sc) {
+ MovGraphLink *lnk = getSc2MctlCompoundBySceneId(sc->_sceneId)->getLinkByName(sO_WayToPipe);
+
+ if (g_fp->getObjectState(sO_Leg) == g_fp->getObjectEnumState(sO_Leg, sO_WithAll))
+ lnk->_flags &= 0xDFFFFFFF;
+ else
+ lnk->_flags |= 0x20000000;
+}
+
+void scene30_initScene(Scene *sc, int flag) {
+ Scene *oldsc = g_fp->_currentScene;
+
+ g_vars->scene30_leg = sc->getStaticANIObject1ById(ANI_LEG, -1);
+ g_fp->_currentScene = sc;
+
+ if (g_fp->getObjectState(sO_Leg) == g_fp->getObjectEnumState(sO_Leg, sO_ShowingHeel))
+ g_vars->scene30_leg->changeStatics2(ST_LEG_UP);
+ else if (g_fp->getObjectState(sO_Leg) == g_fp->getObjectEnumState(sO_Leg, sO_WithoutJugs))
+ g_vars->scene30_leg->changeStatics2(ST_LEG_DOWN);
+ else if (g_fp->getObjectState(sO_Leg) == g_fp->getObjectEnumState(sO_Leg, sO_WithBig))
+ g_vars->scene30_leg->changeStatics2(ST_LEG_DOWN1);
+ else if (g_fp->getObjectState(sO_Leg) == g_fp->getObjectEnumState(sO_Leg, sO_WithSmall))
+ g_vars->scene30_leg->changeStatics2(ST_LEG_DOWN2);
+ else if (g_fp->getObjectState(sO_Leg) == g_fp->getObjectEnumState(sO_Leg, sO_WithAll))
+ g_vars->scene30_leg->changeStatics2(ST_LEG_EMPTY);
+
+ g_fp->_currentScene = oldsc;
+
+ scene30_enablePass(sc);
+
+ if (flag == LiftUp || flag == LiftDown)
+ g_vars->scene30_liftFlag = 0;
+ else
+ g_vars->scene30_liftFlag = 1;
+
+ g_fp->lift_setButton(sO_Level8, ST_LBN_8N);
+
+ g_fp->lift_init(sc, QU_SC30_ENTERLIFT, QU_SC30_EXITLIFT);
+}
+
+int scene30_updateCursor() {
+ g_fp->updateCursorCommon();
+
+ if (g_fp->_cursorId == PIC_CSR_ITN && g_fp->_objectIdAtCursor == PIC_SC30_LTRUBA) {
+ g_fp->_cursorId = PIC_CSR_GOL;
+ }
+ return g_fp->_cursorId;
+}
+
+int sceneHandler30(ExCommand *cmd) {
+ if (cmd->_messageKind != 17)
+ return 0;
+
+ switch(cmd->_messageNum) {
+ case MSG_LIFT_CLOSEDOOR:
+ g_fp->lift_closedoorSeq();
+ break;
+
+ case MSG_LIFT_EXITLIFT:
+ g_fp->lift_exitSeq(cmd);
+ break;
+
+ case MSG_LIFT_STARTEXITQUEUE:
+ g_fp->lift_startExitQueue();
+ break;
+
+ case MSG_LIFT_CLICKBUTTON:
+ g_fp->lift_clickButton();
+ break;
+
+ case MSG_SC30_UPDATEPATH:
+ scene30_enablePass(g_fp->_currentScene);
+ break;
+
+ case 64:
+ g_fp->lift_sub05(cmd);
+ break;
+
+ case MSG_LIFT_GO:
+ g_fp->lift_goAnimation();
+ break;
+
+ case 29:
+ {
+ StaticANIObject *ani = g_fp->_currentScene->getStaticANIObjectAtPos(g_fp->_sceneRect.left + cmd->_x, g_fp->_sceneRect.top + cmd->_y);
+
+ if (ani && ani->_id == ANI_LIFTBUTTON) {
+ g_fp->lift_sub1(ani);
+
+ cmd->_messageKind = 0;
+ }
+ break;
+ }
+
+ case 33:
+ if (g_fp->_aniMan2) {
+ int x = g_fp->_aniMan2->_ox;
+
+ if (x < g_fp->_sceneRect.left + 200)
+ g_fp->_currentScene->_x = x - 300 - g_fp->_sceneRect.left;
+
+ if (x > g_fp->_sceneRect.right - 200)
+ g_fp->_currentScene->_x = x + 300 - g_fp->_sceneRect.right;
+ }
+
+ g_fp->_behaviorManager->updateBehaviors();
+
+ break;
+ }
+
+ return 0;
+}
+
+} // End of namespace Fullpipe
diff --git a/engines/fullpipe/scenes/scene31.cpp b/engines/fullpipe/scenes/scene31.cpp
new file mode 100644
index 0000000000..587fc6aaef
--- /dev/null
+++ b/engines/fullpipe/scenes/scene31.cpp
@@ -0,0 +1,126 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public 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 "fullpipe/fullpipe.h"
+
+#include "fullpipe/objectnames.h"
+#include "fullpipe/constants.h"
+
+#include "fullpipe/gameloader.h"
+#include "fullpipe/motion.h"
+#include "fullpipe/scenes.h"
+#include "fullpipe/statics.h"
+
+#include "fullpipe/interaction.h"
+#include "fullpipe/behavior.h"
+
+
+namespace Fullpipe {
+
+void scene31_initScene(Scene *sc) {
+ g_vars->scene31_chantingCountdown = 0;
+ g_vars->scene31_cactus = sc->getStaticANIObject1ById(ANI_CACTUS_31, -1);
+
+ if (g_fp->getObjectState(sO_Cactus) == g_fp->getObjectEnumState(sO_Cactus, sO_HasGrown)) {
+ Scene *oldsc = g_fp->_currentScene;
+ g_fp->_currentScene = sc;
+
+ g_vars->scene31_cactus->changeStatics2(ST_CTS31_GROWN2);
+ g_vars->scene31_cactus->_priority = 22;
+
+ g_fp->_currentScene = oldsc;
+ } else {
+ g_vars->scene31_cactus->hide();
+ }
+
+ g_vars->scene31_plusMinus = sc->getStaticANIObject1ById(ANI_PLUSMINUS, -1);
+
+ if (g_fp->getObjectState(sO_Guard_3) == g_fp->getObjectEnumState(sO_Guard_3, sO_Off))
+ g_vars->scene31_plusMinus->_statics = g_vars->scene31_plusMinus->getStaticsById(ST_PMS_MINUS);
+ else
+ g_vars->scene31_plusMinus->_statics = g_vars->scene31_plusMinus->getStaticsById(ST_PMS_PLUS);
+}
+
+void sceneHandler31_testCactus(ExCommand *cmd) {
+ if ((g_vars->scene31_cactus->_flags & 4) && g_vars->scene31_cactus->_statics->_staticsId == ST_CTS31_GROWN2) {
+ MessageQueue *mq = g_fp->_globalMessageQueueList->getMessageQueueById(cmd->_parId);
+
+ if (mq) {
+ mq->getExCommandByIndex(0)->_messageKind = 0;
+ mq->getExCommandByIndex(0)->_excFlags |= 1;
+
+ mq->getExCommandByIndex(1)->_messageKind = 0;
+ mq->getExCommandByIndex(1)->_excFlags |= 1;
+ }
+ }
+}
+
+int sceneHandler31(ExCommand *cmd) {
+ if (cmd->_messageKind != 17)
+ return 0;
+
+ switch (cmd->_messageNum) {
+ case MSG_SC31_TESTCACTUS:
+ sceneHandler31_testCactus(cmd);
+ break;
+
+ case MSG_SC15_STOPCHANTING:
+ g_fp->stopAllSoundInstances(SND_31_001);
+
+ g_vars->scene31_chantingCountdown = 120;
+ break;
+
+ case MSG_SC31_PULL:
+ if ( g_vars->scene31_plusMinus->_statics->_staticsId == ST_PMS_MINUS)
+ g_vars->scene31_plusMinus->_statics = g_vars->scene31_plusMinus->getStaticsById(ST_PMS_PLUS);
+ else
+ g_vars->scene31_plusMinus->_statics = g_vars->scene31_plusMinus->getStaticsById(ST_PMS_MINUS);
+
+ break;
+
+ case 33:
+ if (g_fp->_aniMan2) {
+ int x = g_fp->_aniMan2->_ox;
+
+ if (x < g_fp->_sceneRect.left + 200)
+ g_fp->_currentScene->_x = x - 300 - g_fp->_sceneRect.left;
+
+ if (x > g_fp->_sceneRect.right - 200)
+ g_fp->_currentScene->_x = x + 300 - g_fp->_sceneRect.right;
+ }
+
+ if (g_vars->scene31_chantingCountdown > 0) {
+ --g_vars->scene31_chantingCountdown;
+
+ if (!g_vars->scene31_chantingCountdown)
+ g_fp->playSound(SND_31_001, 1);
+ }
+
+ g_fp->_behaviorManager->updateBehaviors();
+
+ break;
+ }
+
+ return 0;
+}
+
+} // End of namespace Fullpipe
diff --git a/engines/fullpipe/scenes/scene32.cpp b/engines/fullpipe/scenes/scene32.cpp
new file mode 100644
index 0000000000..597d3422f6
--- /dev/null
+++ b/engines/fullpipe/scenes/scene32.cpp
@@ -0,0 +1,431 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public 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 "fullpipe/fullpipe.h"
+
+#include "fullpipe/objectnames.h"
+#include "fullpipe/constants.h"
+
+#include "fullpipe/gameloader.h"
+#include "fullpipe/motion.h"
+#include "fullpipe/scenes.h"
+#include "fullpipe/statics.h"
+
+#include "fullpipe/interaction.h"
+#include "fullpipe/behavior.h"
+
+
+namespace Fullpipe {
+
+void scene32_initScene(Scene *sc) {
+ g_vars->scene32_flagIsWaving = false;
+ g_vars->scene32_flagNeedsStopping = false;
+ g_vars->scene32_dudeIsSitting = false;
+ g_vars->scene32_cactusCounter = -1;
+ g_vars->scene32_dudeOnLadder = false;
+ g_vars->scene32_cactusIsGrowing = false;
+ g_vars->scene32_flag = sc->getStaticANIObject1ById(ANI_FLAG, -1);
+ g_vars->scene32_cactus = sc->getStaticANIObject1ById(ANI_CACTUS, -1);
+ g_vars->scene32_massOrange = sc->getStaticANIObject1ById(ANI_TESTO_ORANGE, -1);
+ g_vars->scene32_massBlue = sc->getStaticANIObject1ById(ANI_TESTO_BLUE, -1);
+ g_vars->scene32_massGreen = sc->getStaticANIObject1ById(ANI_TESTO_GREEN, -1);
+ g_vars->scene32_button = sc->getStaticANIObject1ById(ANI_BUTTON_32, -1);
+
+ g_vars->scene32_massOrange->startAnim(MV_TSTO_FLOW, 0, -1);
+ g_vars->scene32_massOrange->_movement->setDynamicPhaseIndex(15);
+
+ g_vars->scene32_massGreen->startAnim(MV_TSTG_FLOW, 0, -1);
+ g_vars->scene32_massGreen->_movement->setDynamicPhaseIndex(26);
+
+ Scene *oldsc = g_fp->_currentScene;
+ StaticANIObject *ani;
+
+ if (g_fp->getObjectState(sO_ClockHandle) == g_fp->getObjectEnumState(sO_ClockHandle, sO_In_32_Lies)) {
+ ani = sc->getStaticANIObject1ById(ANI_INV_HANDLE, -1);
+ if (ani) {
+ g_fp->_currentScene = sc;
+
+ ani->changeStatics2(ST_HDL_LAID);
+ }
+ } else {
+ if (g_fp->getObjectState(sO_ClockHandle) == g_fp->getObjectEnumState(sO_ClockHandle, sO_In_32_Sticks)) {
+ ani = sc->getStaticANIObject1ById(ANI_INV_HANDLE, -1);
+
+ g_fp->_currentScene = sc;
+
+ if (ani)
+ ani->changeStatics2(ST_HDL_PLUGGED);
+
+ g_vars->scene32_button->changeStatics2(ST_BTN32_ON);
+ }
+ }
+
+ g_fp->_currentScene = oldsc;
+
+ if (g_fp->getObjectState(sO_Cube) == g_fp->getObjectEnumState(sO_Cube, sO_In_32)) {
+ MessageQueue *mq = new MessageQueue(sc->getMessageQueueById(QU_KBK32_START), 0, 0);
+
+ mq->sendNextCommand();
+ }
+
+ g_fp->lift_setButton(sO_Level9, ST_LBN_9N);
+ g_fp->lift_init(sc, QU_SC32_ENTERLIFT, QU_SC32_EXITLIFT);
+
+ g_fp->initArcadeKeys("SC_32");
+}
+
+void scene32_setupMusic() {
+ if (g_fp->lift_checkButton(sO_Level6))
+ g_fp->playTrack(g_fp->getGameLoaderGameVar()->getSubVarByName("SC_32"), "MUSIC2", 1);
+}
+
+int scene32_updateCursor() {
+ g_fp->updateCursorCommon();
+
+ if (g_fp->_objectIdAtCursor == PIC_SC32_LADDER && g_fp->_cursorId == PIC_CSR_ITN)
+ g_fp->_cursorId = g_vars->scene32_dudeOnLadder ? PIC_CSR_GOD : PIC_CSR_GOU; // TODO FIXME doublecheck
+
+ return g_fp->_cursorId;
+}
+
+void sceneHandler32_tryCube() {
+ if (g_fp->getObjectState(sO_Cube) == g_fp->getObjectEnumState(sO_Cube, sO_In_33))
+ chainQueue(QU_KBK32_GO, 0);
+}
+
+void sceneHandler32_startCactus() {
+ g_vars->scene32_cactusCounter = 48;
+ g_vars->scene32_cactusIsGrowing = false;
+}
+
+void sceneHandler32_spin(ExCommand *cmd) {
+ MessageQueue *mq = g_fp->_globalMessageQueueList->getMessageQueueById(cmd->_parId);
+
+ if (!mq || mq->getCount() == 0)
+ return;
+
+ ExCommand *ex = mq->getExCommandByIndex(0);
+ ExCommand *newex;
+
+ if ((g_vars->scene32_cactus->_movement && g_vars->scene32_cactus->_movement->_id == MV_CTS_DEFAULT)
+ || g_vars->scene32_cactus->_statics->_staticsId == ST_CTS_GROWUP) {
+ for (int i = 0; i < 12; i++) {
+ newex = ex->createClone();
+ newex->_excFlags |= 2;
+ mq->insertExCommandAt(1, newex);
+ }
+
+ g_vars->scene32_cactus->changeStatics2(ST_CTS_GROWUP);
+
+ chainQueue(QU_CTS_BACK, 1);
+
+ g_vars->scene32_cactusIsGrowing = false;
+
+ return;
+ }
+
+ if (g_vars->scene32_cactus->_statics->_staticsId == ST_CTS_EMPTY && g_vars->scene32_cactusCounter < 0) {
+ for (int i = 0; i < 2; i++) {
+ newex = ex->createClone();
+ newex->_excFlags |= 2;
+ mq->insertExCommandAt(1, newex);
+ }
+
+ chainQueue(QU_KDK_DRIZZLE, 0);
+ }
+}
+
+void sceneHandler32_startFlagLeft() {
+ g_vars->scene32_flag->changeStatics2(ST_FLG_NORM);
+ g_vars->scene32_flag->startAnim(MV_FLG_STARTL, 0, -1);
+
+ g_vars->scene32_flagIsWaving = true;
+}
+
+void sceneHandler32_startFlagRight() {
+ g_vars->scene32_flag->changeStatics2(ST_FLG_NORM);
+ g_vars->scene32_flag->startAnim(MV_FLG_STARTR, 0, -1);
+
+ g_vars->scene32_flagIsWaving = true;
+}
+
+void sceneHandler32_trySit(ExCommand *cmd) {
+ MessageQueue *mq = g_fp->_globalMessageQueueList->getMessageQueueById(cmd->_parId);
+
+ if (!mq || mq->getCount() == 0)
+ return;
+
+ ExCommand *ex = mq->getExCommandByIndex(0);
+
+ if (g_vars->scene32_cactusIsGrowing || g_vars->scene32_cactus->_movement
+ || g_vars->scene32_cactus->_statics->_staticsId != ST_CTS_EMPTY
+ || (g_vars->scene32_cactusCounter >= 0 && g_vars->scene32_cactusCounter <= 20)) {
+ ex->_messageKind = 0;
+ ex->_excFlags |= 1;
+ } else {
+ ex->_parentId = ANI_MAN;
+ ex->_messageKind = 1;
+ ex->_messageNum = MV_MAN32_SITDOWN;
+ ex->_keyCode = g_fp->_aniMan->_okeyCode;
+
+ g_vars->scene32_dudeIsSitting = true;
+
+ getCurrSceneSc2MotionController()->clearEnabled();
+ getGameLoaderInteractionController()->disableFlag24();
+ }
+}
+
+void sceneHandler32_buttonPush() {
+ if (g_fp->getObjectState(sO_ClockHandle) == g_fp->getObjectEnumState(sO_ClockHandle, sO_In_32_Sticks)) {
+ StaticANIObject *ani = g_fp->_currentScene->getStaticANIObject1ById(ANI_INV_HANDLE, -1);
+ if (ani)
+ ani->changeStatics2(ST_HDL_PLUGGED);
+
+ chainQueue(QU_SC32_FALLHANDLE, 1);
+
+ g_vars->scene32_button->changeStatics2(ST_BTN32_OFF);
+ }
+}
+
+void sceneHandler32_installHandle() {
+ chainQueue(QU_SC32_SHOWHANDLE, 0);
+
+ g_vars->scene32_button->changeStatics2(ST_BTN32_ON);
+}
+
+void sceneHandler32_animateCactus() {
+ if (g_fp->_aniMan->_statics->_staticsId != ST_MAN32_SIT)
+ chainQueue(QU_CTS_GROW, 1);
+ else
+ chainQueue(QU_CTS_GROWMAN, 1);
+
+ g_vars->scene32_cactusCounter = -1;
+ g_vars->scene32_cactusIsGrowing = true;
+}
+
+void sceneHandler32_ladderLogic(ExCommand *cmd) {
+ MessageQueue *mq = new MessageQueue(g_fp->_currentScene->getMessageQueueById(QU_SC32_FROMLADDER), 0, 0);
+
+ if (g_fp->_currentScene->getPictureObjectIdAtPos(cmd->_sceneClickX, cmd->_sceneClickY) != PIC_SC32_LADDER)
+ mq->addExCommandToEnd(cmd->createClone());
+
+ mq->setFlags(mq->getFlags() | 1);
+
+ g_fp->_aniMan->changeStatics2(ST_MAN_STANDLADDER);
+ if (!mq->chain(g_fp->_aniMan))
+ delete mq;
+
+ g_vars->scene32_dudeOnLadder = false;
+
+ getCurrSceneSc2MotionController()->setEnabled();
+ getGameLoaderInteractionController()->enableFlag24();
+}
+
+void sceneHandler32_potLogic(ExCommand *cmd) {
+ if (g_vars->scene32_cactusCounter < 0 || g_vars->scene32_cactusCounter > 20) {
+ MessageQueue *mq = new MessageQueue(g_fp->_globalMessageQueueList->compact());
+
+ ExCommand *ex = new ExCommand(ANI_MAN, 1, MV_MAN32_STANDUP, 0, 0, 0, 1, 0, 0, 0);
+
+ ex->_excFlags |= 2;
+
+ mq->addExCommandToEnd(ex);
+
+ StaticANIObject *ani = g_fp->_currentScene->getStaticANIObjectAtPos(cmd->_sceneClickX, cmd->_sceneClickY);
+
+ if (!ani || ani->_id != ANI_KADKA)
+ mq->addExCommandToEnd(cmd->createClone());
+
+ mq->setFlags(mq->getFlags() | 1);
+ mq->chain(0);
+
+ getCurrSceneSc2MotionController()->setEnabled();
+ getGameLoaderInteractionController()->enableFlag24();
+
+ g_vars->scene32_dudeIsSitting = false;
+ }
+}
+
+int sceneHandler32(ExCommand *cmd) {
+ if (cmd->_messageKind != 17)
+ return 0;
+
+ switch (cmd->_messageNum) {
+ case MSG_LIFT_CLOSEDOOR:
+ g_fp->lift_closedoorSeq();
+ break;
+
+ case MSG_LIFT_EXITLIFT:
+ g_fp->lift_exitSeq(cmd);
+ break;
+
+ case MSG_LIFT_STARTEXITQUEUE:
+ g_fp->lift_startExitQueue();
+ break;
+
+ case MSG_SC32_TRUBATOBACK:
+ g_fp->_currentScene->getPictureObjectById(PIC_SC32_RTRUBA, 0)->_priority = 20;
+ break;
+
+ case MSG_SC32_TRUBATOFRONT:
+ g_fp->_currentScene->getPictureObjectById(PIC_SC32_RTRUBA, 0)->_priority = 0;
+ break;
+
+ case MSG_LIFT_CLICKBUTTON:
+ g_fp->lift_clickButton();
+ break;
+
+ case MSG_SC33_TRYKUBIK:
+ sceneHandler32_tryCube();
+ break;
+
+ case MSG_SC32_STARTCACTUS:
+ sceneHandler32_startCactus();
+ break;
+
+ case MSG_SC32_STOPFLAG:
+ g_vars->scene32_flagIsWaving = false;
+ g_vars->scene32_flagNeedsStopping = true;
+ break;
+
+ case MSG_SC32_SPIN:
+ sceneHandler32_spin(cmd);
+ break;
+
+ case MSG_SC32_STARTFLAGLEFT :
+ sceneHandler32_startFlagLeft();
+ break;
+
+ case MSG_SC32_STARTFLAGRIGHT:
+ sceneHandler32_startFlagRight();
+ break;
+
+ case MSG_SC32_TRYSIT:
+ sceneHandler32_trySit(cmd);
+ break;
+
+ case MSG_LIFT_GO:
+ g_fp->lift_goAnimation();
+ break;
+
+ case MSG_SC32_ONLADDER:
+ g_vars->scene32_dudeOnLadder = true;
+
+ getCurrSceneSc2MotionController()->clearEnabled();
+ getGameLoaderInteractionController()->disableFlag24();
+ break;
+
+ case MSG_SC6_BTNPUSH:
+ sceneHandler32_buttonPush();
+ break;
+
+ case 64:
+ g_fp->lift_sub05(cmd);
+ break;
+
+ case MSG_SC6_INSTHANDLE:
+ sceneHandler32_installHandle();
+ break;
+
+ case 33:
+ if (g_fp->_aniMan2) {
+ int x = g_fp->_aniMan2->_ox;
+
+ if (x < g_fp->_sceneRect.left + 200)
+ g_fp->_currentScene->_x = x - 300 - g_fp->_sceneRect.left;
+
+ if (x > g_fp->_sceneRect.right - 200)
+ g_fp->_currentScene->_x = x + 300 - g_fp->_sceneRect.right;
+ }
+
+ if (!g_vars->scene32_flag->_movement) {
+ if (g_vars->scene32_flagIsWaving) {
+ if (g_vars->scene32_flag->_statics->_staticsId == ST_FLG_RIGHT)
+ g_vars->scene32_flag->startAnim(MV_FLG_CYCLER, 0, -1);
+ else if (g_vars->scene32_flag->_statics->_staticsId == ST_FLG_LEFT)
+ g_vars->scene32_flag->startAnim(MV_FLG_CYCLEL, 0, -1);
+ }
+
+ if (g_vars->scene32_flagNeedsStopping && !g_vars->scene32_flagIsWaving) {
+ if (g_vars->scene32_flag->_statics->_staticsId == ST_FLG_RIGHT)
+ g_vars->scene32_flag->startAnim(MV_FLG_STOPR, 0, -1);
+ else if (g_vars->scene32_flag->_statics->_staticsId == ST_FLG_LEFT)
+ g_vars->scene32_flag->startAnim(MV_FLG_STOPL, 0, -1);
+
+ g_vars->scene32_flagNeedsStopping = false;
+ }
+ }
+
+ if (g_vars->scene32_cactusCounter) {
+ if (g_vars->scene32_cactusCounter > 0)
+ --g_vars->scene32_cactusCounter;
+
+ g_fp->_behaviorManager->updateBehaviors();
+
+ g_fp->startSceneTrack();
+ } else {
+ sceneHandler32_animateCactus();
+
+ g_fp->_behaviorManager->updateBehaviors();
+
+ g_fp->startSceneTrack();
+
+ }
+ break;
+
+ case 29:
+ if (g_vars->scene32_dudeOnLadder) {
+ sceneHandler32_ladderLogic(cmd);
+ cmd->_messageKind = 0;
+ break;
+ }
+
+ if (!g_vars->scene32_dudeIsSitting || g_fp->_aniMan->_movement) {
+ StaticANIObject *ani = g_fp->_currentScene->getStaticANIObjectAtPos(cmd->_sceneClickX, cmd->_sceneClickY);
+
+ if (ani && ani->_id == ANI_LIFTBUTTON) {
+ g_fp->lift_sub1(ani);
+
+ cmd->_messageKind = 0;
+ break;
+ }
+
+ if (g_fp->_cursorId == PIC_CSR_GOFAR_R || g_fp->_cursorId == PIC_CSR_GOFAR_L) {
+ if ((g_fp->_sceneRect.right - cmd->_sceneClickX < 47 && g_fp->_sceneRect.right < g_fp->_sceneWidth - 1)
+ || (cmd->_sceneClickX - g_fp->_sceneRect.left < 47 && g_fp->_sceneRect.left > 0))
+ g_fp->processArcade(cmd);
+ }
+ break;
+ }
+
+ if (!g_vars->scene32_cactusIsGrowing)
+ sceneHandler32_potLogic(cmd);
+
+ cmd->_messageKind = 0;
+
+ break;
+ }
+
+ return 0;
+}
+
+} // End of namespace Fullpipe
diff --git a/engines/fullpipe/scenes/scene33.cpp b/engines/fullpipe/scenes/scene33.cpp
new file mode 100644
index 0000000000..209198c0f3
--- /dev/null
+++ b/engines/fullpipe/scenes/scene33.cpp
@@ -0,0 +1,314 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public 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 "fullpipe/fullpipe.h"
+
+#include "fullpipe/objectnames.h"
+#include "fullpipe/constants.h"
+
+#include "fullpipe/gameloader.h"
+#include "fullpipe/motion.h"
+#include "fullpipe/scenes.h"
+#include "fullpipe/statics.h"
+
+#include "fullpipe/interaction.h"
+#include "fullpipe/behavior.h"
+
+
+namespace Fullpipe {
+
+const int ventsInit[9] = { 0, 0, 1, 0, 0, 1, 0, 0, 1 };
+
+void scene33_initScene(Scene *sc) {
+ g_vars->scene33_mug = sc->getStaticANIObject1ById(ANI_MUG_33, -1);
+ g_vars->scene33_jettie = sc->getStaticANIObject1ById(ANI_JETTIE_FLOW, -1);
+ g_vars->scene33_cube = 0;
+ g_vars->scene33_cubeX = -1;
+ g_vars->scene33_handleIsDown = false;
+
+ if (g_fp->getObjectState(sO_Cube) == g_fp->getObjectEnumState(sO_Cube, sO_In_33)) {
+ MessageQueue *mq = new MessageQueue(sc->getMessageQueueById(QU_KBK33_START), 0, 0);
+
+ mq->sendNextCommand();
+ }
+
+
+ for (int i = 0; i < 9; i++) {
+ g_vars->scene33_ventsX[i] = sc->getStaticANIObject1ById(ANI_VENT_33, i)->_ox;
+
+ g_vars->scene33_ventsState[i] = ventsInit[i];
+ }
+
+ g_fp->initArcadeKeys("SC_33");
+}
+
+void scene33_setupMusic() {
+ if (g_fp->lift_checkButton(sO_Level6))
+ g_fp->playTrack(g_fp->getGameLoaderGameVar()->getSubVarByName("SC_33"), "MUSIC2", 1);
+}
+
+int scene33_updateCursor() {
+ g_fp->updateCursorCommon();
+
+ if (g_fp->_objectIdAtCursor == PIC_SC33_ZONES && g_fp->_cursorId == PIC_CSR_DEFAULT)
+ g_fp->_cursorId = PIC_CSR_ITN;
+
+ return g_fp->_cursorId;
+}
+
+void sceneHandler33_processJettie(ExCommand *cmd) {
+ MessageQueue *mq = g_fp->_globalMessageQueueList->getMessageQueueById(cmd->_parId);
+
+ if (mq && g_vars->scene33_jettie->_movement) {
+ ExCommand *ex = mq->getExCommandByIndex(0);
+
+ if (ex) {
+ ex->_messageKind = 0;
+ ex->_excFlags |= 1;
+ }
+
+ ex = mq->getExCommandByIndex(1);
+
+ if (ex) {
+ ex->_messageKind = 0;
+ ex->_excFlags |= 1;
+ }
+ }
+}
+
+void sceneHandler33_switchVent(StaticANIObject *ani) {
+ int mv = 0;
+
+ if (ani->_statics->_staticsId == ST_VNT33_DOWN)
+ mv = MV_VNT33_TURNR;
+
+ if (ani->_statics->_staticsId == ST_VNT33_RIGHT)
+ mv = MV_VNT33_TURND;
+
+ if (mv)
+ ani->startAnim(mv, 0, -1);
+
+ g_vars->scene33_ventsState[ani->_okeyCode] = !g_vars->scene33_ventsState[ani->_okeyCode];
+}
+
+void sceneHandler33_processVents() {
+ for (int i = 0; i < 9; i++)
+ if (((g_vars->scene33_cubeX < g_vars->scene33_ventsX[i]) != (g_vars->scene33_cube->_ox < g_vars->scene33_ventsX[i]))
+ && g_vars->scene33_ventsState[i] != ventsInit[i])
+ sceneHandler33_switchVent(g_fp->_currentScene->getStaticANIObject1ById(ANI_VENT_33, i));
+
+ g_vars->scene33_cubeX = g_vars->scene33_cube->_ox;
+}
+
+void sceneHandler33_tryCube() {
+ if (g_fp->getObjectState(sO_Cube) == g_fp->getObjectEnumState(sO_Cube, sO_In_32))
+ chainQueue(QU_KBK33_GO, 0);
+}
+
+void sceneHandler33_pour() {
+ bool solved = true;
+
+ for (int i = 0; i < 9; i++)
+ if (g_vars->scene33_ventsState[i] != ventsInit[i])
+ solved = false;
+
+ if (solved) {
+ if ((g_vars->scene33_mug->_flags & 4) && g_vars->scene33_mug->_statics->_staticsId == ST_MUG33_EMPTY) {
+ g_vars->scene33_jettie->startAnim(MV_JTI33_POUR, 0, -1);
+
+ g_vars->scene33_handleIsDown = false;
+
+ return;
+ }
+
+ if ((g_vars->scene33_mug->_flags & 4) && g_vars->scene33_mug->_statics->_staticsId == ST_MUG33_FULL) {
+ g_vars->scene33_jettie->startAnim(MV_JTI33_POURFULL, 0, -1);
+
+ g_vars->scene33_handleIsDown = false;
+
+ return;
+ }
+
+ g_vars->scene33_jettie->startAnim(MV_JTI33_FLOW, 0, -1);
+ }
+
+ g_vars->scene33_handleIsDown = false;
+}
+
+void sceneHandler33_handleDown() {
+ if (!g_vars->scene33_handleIsDown && !g_vars->scene33_jettie->_movement && !g_vars->scene33_jettie->getMessageQueue() ) {
+ chainQueue(QU_SC33_STARTWATER, 0);
+
+ g_vars->scene33_handleIsDown = true;
+ }
+}
+
+void sceneHandler33_zoneClickProcess(StaticANIObject *ani) {
+ if (!ani->_movement) {
+ sceneHandler33_switchVent(ani);
+
+ StaticANIObject *vent1 = 0;
+ StaticANIObject *vent2 = 0;
+
+ switch (ani->_okeyCode) {
+ case 0:
+ vent1 = g_fp->_currentScene->getStaticANIObject1ById(ANI_VENT_33, 2);
+ vent2 = g_fp->_currentScene->getStaticANIObject1ById(ANI_VENT_33, 3);
+ break;
+
+ case 1:
+ vent1 = g_fp->_currentScene->getStaticANIObject1ById(ANI_VENT_33, 3);
+ vent2 = g_fp->_currentScene->getStaticANIObject1ById(ANI_VENT_33, 4);
+ break;
+
+ case 2:
+ vent1 = g_fp->_currentScene->getStaticANIObject1ById(ANI_VENT_33, 4);
+ vent2 = g_fp->_currentScene->getStaticANIObject1ById(ANI_VENT_33, 0);
+ break;
+
+ case 3:
+ vent1 = g_fp->_currentScene->getStaticANIObject1ById(ANI_VENT_33, 0);
+ vent2 = g_fp->_currentScene->getStaticANIObject1ById(ANI_VENT_33, 1);
+ break;
+
+ case 4:
+ vent1 = g_fp->_currentScene->getStaticANIObject1ById(ANI_VENT_33, 1);
+ vent2 = g_fp->_currentScene->getStaticANIObject1ById(ANI_VENT_33, 2);
+ break;
+
+ default:
+ return;
+ }
+
+ if (vent1) {
+ sceneHandler33_switchVent(vent1);
+ sceneHandler33_switchVent(vent2);
+ }
+ }
+}
+
+void sceneHandler33_clickZones(ExCommand *cmd) {
+ StaticANIObject *closest = 0;
+ double mindist = 1e10;
+
+ for (uint i = 0; i < g_fp->_currentScene->_staticANIObjectList1.size(); i++) {
+ StaticANIObject *ani = (StaticANIObject *)g_fp->_currentScene->_staticANIObjectList1[i];
+
+ if (ani->_id == ANI_VENT_33) {
+ int dx = ani->_ox - cmd->_sceneClickX;
+ int dy = ani->_oy - cmd->_sceneClickY;
+ double dist = sqrt((double)(dx * dx + dy * dy));
+
+ if (dist < mindist) {
+ mindist = dist;
+ closest = ani;
+ }
+ }
+ }
+
+ if (closest)
+ sceneHandler33_zoneClickProcess(closest);
+}
+
+int sceneHandler33(ExCommand *cmd) {
+ if (cmd->_messageKind != 17)
+ return 0;
+
+ switch (cmd->_messageNum) {
+ case MSG_SC32_TRUBATOFRONT:
+ g_fp->_currentScene->getPictureObjectById(PIC_SC33_LTRUBA, 0)->_priority = 0;
+ break;
+
+ case MSG_SC32_TRUBATOBACK:
+ g_fp->_currentScene->getPictureObjectById(PIC_SC33_LTRUBA, 0)->_priority = 20;
+ break;
+
+ case MSG_SC33_TESTMUG:
+ sceneHandler33_processJettie(cmd);
+ break;
+
+ case MSG_SC33_UPDATEKUBIK:
+ g_vars->scene33_cube = g_fp->_currentScene->getStaticANIObject1ById(ANI_KUBIK, -1);
+
+ if (g_vars->scene33_cube)
+ g_vars->scene33_cubeX = g_vars->scene33_cube->_ox;
+
+ break;
+
+ case MSG_SC33_TRYKUBIK:
+ sceneHandler33_tryCube();
+ break;
+
+ case MSG_SC33_POUR:
+ sceneHandler33_pour();
+ break;
+
+ case MSG_SC33_HANDLEDOWN:
+ sceneHandler33_handleDown();
+ break;
+
+ case 29:
+ {
+ StaticANIObject *ani = g_fp->_currentScene->getStaticANIObjectAtPos(g_fp->_sceneRect.left + cmd->_x, g_fp->_sceneRect.top + cmd->_y);
+
+ if (!ani || !canInteractAny(g_fp->_aniMan, ani, cmd->_keyCode)) {
+ int picId = g_fp->_currentScene->getPictureObjectIdAtPos(cmd->_sceneClickX, cmd->_sceneClickY);
+ PictureObject *pic = g_fp->_currentScene->getPictureObjectById(picId, 0);
+
+ if (pic && pic->_id == PIC_SC33_ZONES) {
+ sceneHandler33_clickZones(cmd);
+ break;
+ }
+
+ if (!pic || !canInteractAny(g_fp->_aniMan, pic, cmd->_keyCode)) {
+ if ((g_fp->_sceneRect.right - cmd->_sceneClickX < 47 && g_fp->_sceneRect.right < g_fp->_sceneWidth - 1) || (cmd->_sceneClickX - g_fp->_sceneRect.left < 47 && g_fp->_sceneRect.left > 0))
+ g_fp->processArcade(cmd);
+ }
+ }
+ break;
+ }
+
+ case 33:
+ if (g_fp->_aniMan2) {
+ int x = g_fp->_aniMan2->_ox;
+
+ if (x < g_fp->_sceneRect.left + 200)
+ g_fp->_currentScene->_x = x - 300 - g_fp->_sceneRect.left;
+
+ if (x > g_fp->_sceneRect.right - 200)
+ g_fp->_currentScene->_x = x + 300 - g_fp->_sceneRect.right;
+ }
+
+ if (g_vars->scene33_cube)
+ sceneHandler33_processVents();
+
+ g_fp->_behaviorManager->updateBehaviors();
+
+ g_fp->startSceneTrack();
+
+ break;
+ }
+
+ return 0;
+}
+
+} // End of namespace Fullpipe
diff --git a/engines/fullpipe/scenes/scene34.cpp b/engines/fullpipe/scenes/scene34.cpp
new file mode 100644
index 0000000000..b3e0db75af
--- /dev/null
+++ b/engines/fullpipe/scenes/scene34.cpp
@@ -0,0 +1,479 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public 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 "fullpipe/fullpipe.h"
+
+#include "fullpipe/objectnames.h"
+#include "fullpipe/constants.h"
+
+#include "fullpipe/gameloader.h"
+#include "fullpipe/motion.h"
+#include "fullpipe/scenes.h"
+#include "fullpipe/statics.h"
+
+#include "fullpipe/interaction.h"
+#include "fullpipe/behavior.h"
+#include "fullpipe/floaters.h"
+
+namespace Fullpipe {
+
+void sceneHandler34_setExits() {
+ int state;
+
+ if (g_fp->getObjectState(sO_Grandma) == g_fp->getObjectEnumState(sO_Grandma, sO_NearPipeWithStool)) {
+ if (g_fp->getObjectState(sO_Hatch_34) == g_fp->getObjectEnumState(sO_Hatch_34, sO_Closed))
+ state = g_fp->getObjectEnumState(sO_Plank_34, sO_ClosedWithBoot);
+ else
+ state = g_fp->getObjectEnumState(sO_Plank_34, sO_OpenedWithBoot);
+ } else {
+ if (g_fp->getObjectState(sO_Grandma) == g_fp->getObjectEnumState(sO_Grandma, sO_OnStool)) {
+ if (g_fp->getObjectState(sO_Hatch_34) == g_fp->getObjectEnumState(sO_Hatch_34, sO_Closed))
+ state = g_fp->getObjectEnumState(sO_Plank_34, sO_IsClosed);
+ else
+ state = g_fp->getObjectEnumState(sO_Plank_34, sO_IsOpened);
+ } else {
+ state = g_fp->getObjectEnumState(sO_Plank_34, sO_Passive);
+ }
+ }
+
+ g_fp->setObjectState(sO_Plank_34, state);
+}
+
+void scene34_initScene(Scene *sc) {
+ g_vars->scene34_cactus = sc->getStaticANIObject1ById(ANI_CACTUS_34, -1);
+ g_vars->scene34_vent = sc->getStaticANIObject1ById(ANI_VENT_34, -1);
+ g_vars->scene34_hatch = sc->getStaticANIObject1ById(ANI_LUK_34, -1);
+ g_vars->scene34_boot = sc->getStaticANIObject1ById(ANI_BOOT_34, -1);
+
+ if (g_fp->getObjectState(sO_Cactus) == g_fp->getObjectEnumState(sO_Cactus, sO_HasGrown)) {
+ Scene *oldsc = g_fp->_currentScene;
+
+ g_fp->_currentScene = sc;
+
+ g_vars->scene34_cactus->changeStatics2(ST_CTS34_EMPTY);
+ g_vars->scene34_cactus->setOXY(506, 674);
+ g_vars->scene34_cactus->_priority = 30;
+
+ g_vars->scene34_cactus->changeStatics2(ST_CTS34_GROWNEMPTY2);
+ g_vars->scene34_cactus->_flags |= 4;
+
+ g_fp->_currentScene = oldsc;
+ }
+
+ if (g_fp->getObjectState(sO_Grandma) == g_fp->getObjectEnumState(sO_Grandma, sO_Strolling))
+ g_fp->setObjectState(sO_Grandma, g_fp->getObjectEnumState(sO_Grandma, sO_OnStool));
+
+ sceneHandler34_setExits();
+
+ g_vars->scene34_dudeClimbed = false;
+ g_vars->scene34_dudeOnBoard = false;
+ g_vars->scene34_dudeOnCactus = false;
+ g_vars->scene34_fliesCountdown = g_fp->_rnd->getRandomNumber(500) + 500;
+
+ g_fp->_floaters->init(g_fp->getGameLoaderGameVar()->getSubVarByName("SC_34"));
+
+ g_fp->lift_setButton(sO_Level7, ST_LBN_7N);
+ g_fp->lift_init(sc, QU_SC34_ENTERLIFT, QU_SC34_EXITLIFT);
+
+ g_fp->initArcadeKeys("SC_34");
+}
+
+void scene34_initBeh() {
+ g_fp->_behaviorManager->setBehaviorEnabled(g_vars->scene34_cactus, ST_CTS34_GROWNEMPTY2, QU_CTS34_FALLEFT, 0);
+ g_fp->_behaviorManager->setBehaviorEnabled(g_vars->scene34_cactus, ST_CTS34_GROWNEMPTY2, QU_CTS34_FALLRIGHT, 0);
+}
+
+int scene34_updateCursor() {
+ g_fp->updateCursorCommon();
+
+ if ((g_fp->_objectIdAtCursor != ANI_STOOL_34 || getGameLoaderInventory()->getSelectedItemId() != ANI_INV_BOX)
+ && (g_fp->_objectIdAtCursor != ANI_BOX_34 || getGameLoaderInventory()->getSelectedItemId() != ANI_INV_STOOL))
+ ; // emtpy
+ else
+ g_fp->_cursorId = PIC_CSR_ITN_INV;
+
+ return g_fp->_cursorId;
+}
+
+void sceneHandler34_leaveBoard() {
+ getCurrSceneSc2MotionController()->setEnabled();
+ getGameLoaderInteractionController()->enableFlag24();
+
+ g_fp->_behaviorManager->setFlagByStaticAniObject(g_fp->_aniMan, 1);
+
+ g_vars->scene34_dudeOnBoard = false;
+}
+
+void sceneHandler34_onBoard() {
+ getCurrSceneSc2MotionController()->clearEnabled();
+ getGameLoaderInteractionController()->disableFlag24();
+
+ g_fp->_behaviorManager->setFlagByStaticAniObject(g_fp->_aniMan, 0);
+
+ g_vars->scene34_dudeOnBoard = true;
+}
+
+void sceneHandler34_testVent() {
+ if (g_fp->_aniMan->_movement->_id == MV_MAN34_TURNVENT_R) {
+ g_vars->scene34_hatch->changeStatics2(ST_LUK34_CLOSED);
+
+ chainQueue(QU_LUK34_OPEN, 0);
+ } else if (g_fp->_aniMan->_movement->_id == MV_MAN34_TURNVENT_L) {
+ g_vars->scene34_hatch->changeStatics2(ST_LUK34_OPEN);
+
+ chainQueue(QU_LUK34_CLOSE, 0);
+ }
+}
+
+void sceneHandler34_hideStool() {
+ g_fp->_currentScene->getStaticANIObject1ById(ANI_STOOL_34, -1)->hide();
+}
+
+void sceneHandler34_climb() {
+ getCurrSceneSc2MotionController()->clearEnabled();
+ getGameLoaderInteractionController()->disableFlag24();
+
+ g_fp->_behaviorManager->setFlagByStaticAniObject(g_fp->_aniMan, 0);
+
+ g_vars->scene34_dudeClimbed = true;
+}
+
+void sceneHandler34_genFlies() {
+ g_fp->_floaters->genFlies(g_fp->_currentScene, 1072, -50, 100, 4);
+
+ g_fp->_floaters->_array2[g_fp->_floaters->_array2.size() - 1]->countdown = 1;
+ g_fp->_floaters->_array2[g_fp->_floaters->_array2.size() - 1]->val6 = 1072;
+ g_fp->_floaters->_array2[g_fp->_floaters->_array2.size() - 1]->val7 = -50;
+
+ g_vars->scene34_fliesCountdown = g_fp->_rnd->getRandomNumber(500) + 500;
+}
+
+void sceneHandler34_fromCactus(ExCommand *cmd) {
+ if (g_fp->_aniMan->_movement || g_vars->scene34_cactus->_movement || (g_fp->_aniMan->_flags & 0x100)) {
+ cmd->_messageKind = 0;
+
+ return;
+ }
+
+ MessageQueue *mq = new MessageQueue(g_fp->_currentScene->getMessageQueueById(QU_SC34_FROMCACTUS), 0, 0);
+
+ ExCommand *ex = new ExCommand(ANI_MAN, 34, 256, 0, 0, 0, 1, 0, 0, 0);
+
+ ex->_messageNum = 0;
+ ex->_excFlags |= 3;
+ ex->_field_14 = 256;
+ mq->addExCommandToEnd(ex);
+
+ ex = cmd->createClone();
+ mq->addExCommandToEnd(ex);
+
+ mq->setFlags(mq->getFlags() | 1);
+ mq->chain(0);
+
+ g_fp->_aniMan->_flags |= 1;
+}
+
+void sceneHandler34_animateLeaveBoard(ExCommand *cmd) {
+ if (!g_fp->_aniMan->_movement) {
+ MessageQueue *mq = new MessageQueue(g_fp->_currentScene->getMessageQueueById(QU_SC34_LEAVEBOARD), 0, 0);
+
+ mq->addExCommandToEnd(cmd->createClone());
+ mq->setFlags(mq->getFlags() | 1);
+ mq->chain(0);
+ }
+
+ cmd->_messageKind = 0;
+}
+
+void sceneHandler34_animateAction(ExCommand *cmd) {
+ if (g_fp->_aniMan->_movement)
+ return;
+
+ int ox = g_fp->_aniMan->_ox;
+ int oy = g_fp->_aniMan->_oy;
+ StaticANIObject *ani = g_fp->_currentScene->getStaticANIObjectAtPos(g_fp->_sceneRect.left + cmd->_x, g_fp->_sceneRect.top + cmd->_y);
+
+ if (!ani || ani->_id != ANI_VENT_34) {
+ int qId = 0;
+
+ if (ox == 887) {
+ if (oy != 370)
+ return;
+
+ qId = QU_SC34_FROMSTOOL;
+ } else {
+ if (ox != 916)
+ return;
+
+ if (oy == 286) {
+ MessageQueue *mq = new MessageQueue(g_fp->_currentScene->getMessageQueueById(QU_SC34_FROMBOX), 0, 0);
+
+ mq->addExCommandToEnd(cmd->createClone());
+ mq->chain(0);
+
+ sceneHandler34_setExits();
+
+ return;
+ }
+
+ if (oy != 345)
+ return;
+
+ qId = QU_SC34_FROMBOX_FLOOR;
+ }
+
+ if (qId) {
+ MessageQueue *mq = new MessageQueue(g_fp->_currentScene->getMessageQueueById(qId), 0, 0);
+
+ mq->addExCommandToEnd(cmd->createClone());
+ mq->chain(0);
+ }
+
+ return;
+ }
+
+ if (ox == 887) {
+ if (oy == 370)
+ g_fp->_aniMan->startAnim(MV_MAN34_TRYTABUR, 0, -1);
+
+ } else if (ox == 916) {
+ if (oy == 286) {
+ int id = g_vars->scene34_vent->_statics->_staticsId;
+ if (id == ST_VNT34_UP2) {
+ g_fp->_aniMan->startAnim(MV_MAN34_TURNVENT_R, 0, -1);
+ } else if (id == ST_VNT34_RIGHT3) {
+ g_fp->_aniMan->startAnim(MV_MAN34_TURNVENT_L, 0, -1);
+ }
+ } else if (oy == 345) {
+ g_fp->_aniMan->startAnim(MV_MAN34_TRY, 0, -1);
+ }
+ }
+}
+
+void sceneHandler34_showVent() {
+ if (g_vars->scene34_vent->_statics->_staticsId == ST_VNT34_UP2)
+ g_vars->scene34_vent->changeStatics2(ST_VNT34_RIGHT3);
+ else if (g_vars->scene34_vent->_statics->_staticsId == ST_VNT34_RIGHT3)
+ g_vars->scene34_vent->changeStatics2(ST_VNT34_UP2);
+
+ g_vars->scene34_vent->show1(-1, -1, -1, 0);
+}
+
+void sceneHandler34_showBox() {
+ g_fp->_currentScene->getStaticANIObject1ById(ANI_STOOL_34, -1)->changeStatics2(ST_STL34_BOX2);
+}
+
+void sceneHandler34_showStool() {
+ chainQueue(QU_SC34_SHOWSTOOL, 0);
+}
+
+void sceneHandler34_unclimb() {
+ getCurrSceneSc2MotionController()->setEnabled();
+ getGameLoaderInteractionController()->enableFlag24();
+
+ g_fp->_behaviorManager->setFlagByStaticAniObject(g_fp->_aniMan, 1);
+
+ g_vars->scene34_dudeClimbed = false;
+}
+
+int sceneHandler34(ExCommand *cmd) {
+ if (cmd->_messageKind != 17)
+ return 0;
+
+ switch (cmd->_messageNum) {
+ case MSG_SC4_HIDEBOOT:
+ g_vars->scene34_boot->_flags &= 0xFFFB;
+ break;
+
+ case MSG_SC34_LEAVEBOARD:
+ sceneHandler34_leaveBoard();
+ break;
+
+ case MSG_SC34_ONBOARD:
+ sceneHandler34_onBoard();
+ break;
+
+ case MSG_SC34_TESTVENT:
+ sceneHandler34_testVent();
+ break;
+
+ case MSG_LIFT_CLICKBUTTON:
+ g_fp->lift_clickButton();
+ break;
+
+ case MSG_SC34_FROMCACTUS:
+ g_vars->scene34_dudeOnCactus = false;
+
+ getCurrSceneSc2MotionController()->setEnabled();
+ getGameLoaderInteractionController()->enableFlag24();
+
+ g_fp->_behaviorManager->setFlagByStaticAniObject(g_fp->_aniMan, 1);
+
+ break;
+
+ case MSG_SC34_RETRYVENT:
+ if (!g_fp->_aniMan->isIdle())
+ break;
+
+ g_fp->_aniMan->changeStatics2(ST_MAN_RIGHT);
+ g_fp->_aniMan->_flags &= 0xFEFF;
+
+ getGameLoaderInteractionController()->handleInteraction(g_fp->_aniMan, g_vars->scene34_vent, cmd->_keyCode);
+
+ break;
+
+ case MSG_SC34_ONBUMP:
+ g_fp->_behaviorManager->setBehaviorEnabled(g_vars->scene34_cactus, ST_CTS34_GROWNEMPTY2, QU_CTS34_FALLEFT, 1);
+ g_fp->_behaviorManager->setBehaviorEnabled(g_vars->scene34_cactus, ST_CTS34_GROWNEMPTY2, QU_CTS34_FALLRIGHT, 1);
+ break;
+
+ case MSG_LIFT_CLOSEDOOR:
+ g_fp->lift_closedoorSeq();
+ break;
+
+ case MSG_LIFT_EXITLIFT:
+ g_fp->lift_exitSeq(cmd);
+ break;
+
+ case MSG_LIFT_STARTEXITQUEUE:
+ g_fp->lift_startExitQueue();
+ break;
+
+ case MSG_SC22_HIDESTOOL:
+ sceneHandler34_hideStool();
+ break;
+
+ case MSG_SC34_CLIMB:
+ sceneHandler34_climb();
+ break;
+
+ case MSG_SC34_UNCLIMB:
+ sceneHandler34_unclimb();
+ break;
+
+ case MSG_SC22_SHOWSTOOL:
+ sceneHandler34_showStool();
+ break;
+
+ case MSG_SC34_SHOWBOX:
+ sceneHandler34_showBox();
+ break;
+
+ case MSG_SC34_ONCACTUS:
+ g_vars->scene34_dudeOnCactus = true;
+
+ getCurrSceneSc2MotionController()->clearEnabled();
+ getGameLoaderInteractionController()->disableFlag24();
+
+ g_fp->_behaviorManager->setFlagByStaticAniObject(g_fp->_aniMan, 0);
+ break;
+
+ case MSG_SC34_SHOWVENT:
+ sceneHandler34_showVent();
+ break;
+
+ case 64:
+ g_fp->lift_sub05(cmd);
+ break;
+
+ case MSG_LIFT_GO:
+ g_fp->lift_goAnimation();
+ break;
+
+ case 29:
+ {
+ if (g_vars->scene34_dudeClimbed) {
+ sceneHandler34_animateAction(cmd);
+ break;
+ }
+
+ if (g_vars->scene34_dudeOnBoard) {
+ sceneHandler34_animateLeaveBoard(cmd);
+ break;
+ }
+
+ if (g_vars->scene34_dudeOnCactus) {
+ sceneHandler34_fromCactus(cmd);
+ break;
+ }
+
+ StaticANIObject *ani = g_fp->_currentScene->getStaticANIObjectAtPos(g_fp->_sceneRect.left + cmd->_x, g_fp->_sceneRect.top + cmd->_y);
+
+ if (ani) {
+ if ((ani->_id == ANI_STOOL_34 && cmd->_keyCode == ANI_INV_BOX) || (ani->_id == ANI_BOX_34 && cmd->_keyCode == ANI_INV_STOOL)) {
+ getGameLoaderInteractionController()->handleInteraction(g_fp->_aniMan, g_vars->scene34_vent, cmd->_keyCode);
+
+ cmd->_messageKind = 0;
+ }
+
+ if (ani->_id == ANI_LIFTBUTTON) {
+ g_fp->lift_sub1(ani);
+
+ cmd->_messageKind = 0;
+
+ break;
+ }
+ }
+
+ if (!ani || !canInteractAny(g_fp->_aniMan, ani, cmd->_keyCode)) {
+ int picId = g_fp->_currentScene->getPictureObjectIdAtPos(cmd->_sceneClickX, cmd->_sceneClickY);
+ PictureObject *pic = g_fp->_currentScene->getPictureObjectById(picId, 0);
+
+ if (!pic || !canInteractAny(g_fp->_aniMan, pic, cmd->_keyCode)) {
+ if ((g_fp->_sceneRect.right - cmd->_sceneClickX < 47 && g_fp->_sceneRect.right < g_fp->_sceneWidth - 1) || (cmd->_sceneClickX - g_fp->_sceneRect.left < 47 && g_fp->_sceneRect.left > 0)) {
+ g_fp->processArcade(cmd);
+ break;
+ }
+ }
+ }
+ break;
+ }
+
+ case 33:
+ if (g_fp->_aniMan2) {
+ int x = g_fp->_aniMan2->_ox;
+
+ if (x < g_fp->_sceneRect.left + 200)
+ g_fp->_currentScene->_x = x - 300 - g_fp->_sceneRect.left;
+
+ if (x > g_fp->_sceneRect.right - 200)
+ g_fp->_currentScene->_x = x + 300 - g_fp->_sceneRect.right;
+ }
+
+ --g_vars->scene34_fliesCountdown;
+
+ if (!g_vars->scene34_fliesCountdown)
+ sceneHandler34_genFlies();
+
+ g_fp->_floaters->update();
+
+ g_fp->_behaviorManager->updateBehaviors();
+
+ g_fp->startSceneTrack();
+
+ break;
+ }
+
+ return 0;
+}
+
+} // End of namespace Fullpipe
diff --git a/engines/fullpipe/scenes/scene35.cpp b/engines/fullpipe/scenes/scene35.cpp
new file mode 100644
index 0000000000..f10786b821
--- /dev/null
+++ b/engines/fullpipe/scenes/scene35.cpp
@@ -0,0 +1,264 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public 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 "fullpipe/fullpipe.h"
+
+#include "fullpipe/objectnames.h"
+#include "fullpipe/constants.h"
+
+#include "fullpipe/gameloader.h"
+#include "fullpipe/motion.h"
+#include "fullpipe/scenes.h"
+#include "fullpipe/statics.h"
+
+#include "fullpipe/interaction.h"
+#include "fullpipe/behavior.h"
+
+#include "fullpipe/floaters.h"
+
+namespace Fullpipe {
+
+void scene35_initScene(Scene *sc) {
+ g_vars->scene35_hose = sc->getStaticANIObject1ById(ANI_HOSE, -1);
+ g_vars->scene35_bellyInflater = sc->getStaticANIObject1ById(ANI_PUZODUV, -1);
+ g_vars->scene35_flowCounter = 0;
+ g_vars->scene35_fliesCounter = 0;
+
+ MovGraphLink *lnk = getSc2MctlCompoundBySceneId(sc->_sceneId)->getLinkByName(sO_CloseThing);
+
+ if (g_vars->scene35_bellyInflater->_statics->_staticsId == ST_PDV_LARGE)
+ lnk->_flags |= 0x20000000;
+ else
+ lnk->_flags &= 0xDFFFFFFF;
+
+ int sndId = 0;
+
+ if (g_fp->getObjectState(sO_Valve_35) == g_fp->getObjectEnumState(sO_Valve_35, sO_TurnedOn)) {
+ if ((g_vars->scene35_hose->_flags & 4) && g_vars->scene35_hose->_statics->_staticsId == ST_HZE_NORM) {
+ sndId = SND_35_012;
+ } else if (g_vars->scene35_bellyInflater->_statics->_staticsId == ST_PDV_SMALL) {
+ sndId = SND_35_011;
+ }
+ }
+
+ if (sndId)
+ g_fp->playSound(sndId, 1);
+
+ g_fp->lift_setButton(sO_Level6, ST_LBN_6N);
+ g_fp->lift_init(sc, QU_SC35_ENTERLIFT, QU_SC35_EXITLIFT);
+
+ g_fp->initArcadeKeys("SC_35");
+
+ g_fp->_floaters->init(g_fp->getGameLoaderGameVar()->getSubVarByName("SC_35"));
+}
+
+void sceneHandler35_stopFlow() {
+ g_fp->setObjectState(sO_Valve_35, g_fp->getObjectEnumState(sO_Valve_35, sO_TurnedOff));
+ g_fp->stopAllSoundInstances(SND_35_011);
+ g_fp->playSound(SND_35_026, 0);
+}
+
+void sceneHandler35_shrink() {
+ getCurrSceneSc2MotionController()->enableLinks(sO_CloseThing, 0);
+}
+
+void sceneHandler35_startFlow() {
+ if (g_fp->getObjectState(sO_Valve_35) == g_fp->getObjectEnumState(sO_Valve_35, sO_TurnedOn)) {
+ if ((g_vars->scene35_hose->_flags & 4) && g_vars->scene35_hose->_statics->_staticsId == ST_HZE_NORM) {
+ g_fp->_behaviorManager->setBehaviorEnabled(g_vars->scene35_bellyInflater, ST_PDV_SMALL, QU_PDV_SML_BLINK, 0);
+ g_fp->_behaviorManager->setBehaviorEnabled(g_vars->scene35_bellyInflater, ST_PDV_SMALL, QU_PDV_SML_TRY, 0);
+
+ g_vars->scene35_bellyInflater->changeStatics2(ST_PDV_SMALL);
+ g_vars->scene35_bellyInflater->_flags &= 0xFEFF;
+
+ MessageQueue *mq = new MessageQueue(g_fp->_currentScene->getMessageQueueById(QU_SC35_EATHOZE), 0, 0);
+
+ mq->setFlags(mq->getFlags() | 1);
+
+ ExCommand *cmd = new ExCommand(g_vars->scene35_bellyInflater->_id, 34, 256, 0, 0, 0, 1, 0, 0, 0);
+
+ cmd->_excFlags |= 3;
+ cmd->_field_14 = 256;
+ cmd->_messageNum = 0;
+
+ mq->addExCommandToEnd(cmd);
+
+ if (!mq->chain(g_vars->scene35_bellyInflater))
+ delete mq;
+
+ g_vars->scene35_bellyInflater->_flags |= 1;
+
+ getCurrSceneSc2MotionController()->enableLinks(sO_CloseThing, 1);
+
+ g_fp->playSound(SND_35_012, 1);
+ } else {
+ if (!g_vars->scene35_flowCounter)
+ g_vars->scene35_flowCounter = 98;
+
+ g_fp->playSound(SND_35_011, 1);
+ }
+ }
+}
+
+void sceneHandler35_genFlies() {
+ StaticANIObject *fly = g_fp->_currentScene->getStaticANIObject1ById(ANI_FLY, -1);
+
+ int xoff = 0;
+ if ((!fly || !(fly->_flags & 4)) && !(g_fp->_rnd->getRandomNumber(32767) % 30)) {
+ int x, y;
+
+ if (g_fp->_rnd->getRandomNumber(1)) {
+ x = 600;
+ y = 0;
+ } else {
+ x = 0;
+ y = 600;
+ }
+
+ int numFlies = g_fp->_rnd->getRandomNumber(3) + 1;
+
+ while (numFlies--) {
+ g_fp->_floaters->genFlies(g_fp->_currentScene, g_fp->_rnd->getRandomNumber(55) + 1057, g_fp->_rnd->getRandomNumber(60) + x + xoff, 4, 1);
+
+ xoff += 40;
+
+ g_fp->_floaters->_array2[g_fp->_floaters->_array2.size() - 1]->val2 = 1084;
+ g_fp->_floaters->_array2[g_fp->_floaters->_array2.size() - 1]->val3 = y;
+ g_fp->_floaters->_array2[g_fp->_floaters->_array2.size() - 1]->val11 = 8.0;
+ }
+
+ g_vars->scene35_fliesCounter = 0;
+ }
+}
+
+int sceneHandler35(ExCommand *cmd) {
+ if (cmd->_messageKind != 17)
+ return 0;
+
+ switch (cmd->_messageNum) {
+ case MSG_LIFT_CLOSEDOOR:
+ g_fp->lift_closedoorSeq();
+ break;
+
+ case MSG_LIFT_EXITLIFT:
+ g_fp->lift_exitSeq(cmd);
+ break;
+
+ case MSG_LIFT_STARTEXITQUEUE:
+ g_fp->lift_startExitQueue();
+ break;
+
+ case MSG_LIFT_CLICKBUTTON:
+ g_fp->lift_clickButton();
+ break;
+
+ case MSG_SC35_STOPFLOW:
+ sceneHandler35_stopFlow();
+ break;
+
+ case MSG_SC35_CHECKPIPESOUND:
+ if (g_fp->getObjectState(sO_Valve_35) == g_fp->getObjectEnumState(sO_Valve_35, sO_TurnedOn)) {
+ g_fp->stopAllSoundInstances(SND_35_011);
+ g_fp->playSound(SND_35_012, 1);
+
+ g_vars->scene35_flowCounter = 0;
+ break;
+ }
+ break;
+
+ case MSG_SC35_SHRINK:
+ sceneHandler35_shrink();
+ break;
+
+ case MSG_LIFT_GO:
+ g_fp->lift_goAnimation();
+ break;
+
+ case MSG_SC35_STARTFLOW:
+ case MSG_SC35_PLUGHOSE:
+ sceneHandler35_startFlow();
+ break;
+
+ case 64:
+ g_fp->lift_sub05(cmd);
+ break;
+
+ case 29:
+ {
+ StaticANIObject *ani = g_fp->_currentScene->getStaticANIObjectAtPos(g_fp->_sceneRect.left + cmd->_x, g_fp->_sceneRect.top + cmd->_y);
+
+ if (ani)
+ if (ani->_id == ANI_LIFTBUTTON) {
+ g_fp->lift_sub1(ani);
+ cmd->_messageKind = 0;
+ break;
+ }
+
+ if (!ani || !canInteractAny(g_fp->_aniMan, ani, cmd->_keyCode)) {
+ int picId = g_fp->_currentScene->getPictureObjectIdAtPos(cmd->_sceneClickX, cmd->_sceneClickY);
+ PictureObject *pic = g_fp->_currentScene->getPictureObjectById(picId, 0);
+
+ if (!pic || !canInteractAny(g_fp->_aniMan, pic, cmd->_keyCode)) {
+ if ((g_fp->_sceneRect.right - cmd->_sceneClickX < 47 && g_fp->_sceneRect.right < g_fp->_sceneWidth - 1) || (cmd->_sceneClickX - g_fp->_sceneRect.left < 47 && g_fp->_sceneRect.left > 0)) {
+ g_fp->processArcade(cmd);
+ break;
+ }
+ }
+ }
+ break;
+ }
+
+ case 33:
+ if (g_fp->_aniMan2) {
+ int x = g_fp->_aniMan2->_ox;
+
+ if (x < g_fp->_sceneRect.left + 200)
+ g_fp->_currentScene->_x = x - 300 - g_fp->_sceneRect.left;
+
+ if (x > g_fp->_sceneRect.right - 200)
+ g_fp->_currentScene->_x = x + 300 - g_fp->_sceneRect.right;
+ }
+
+ if (g_vars->scene35_flowCounter > 0) {
+ --g_vars->scene35_flowCounter;
+
+ if (!g_vars->scene35_flowCounter)
+ sceneHandler35_stopFlow();
+ }
+
+ g_vars->scene35_fliesCounter++;
+
+ if (g_vars->scene35_fliesCounter >= 160)
+ sceneHandler35_genFlies();
+
+ g_fp->_floaters->update();
+
+ g_fp->_behaviorManager->updateBehaviors();
+ g_fp->startSceneTrack();
+
+ break;
+ }
+
+ return 0;
+}
+
+} // End of namespace Fullpipe
diff --git a/engines/fullpipe/scenes/scene36.cpp b/engines/fullpipe/scenes/scene36.cpp
new file mode 100644
index 0000000000..7d237fd395
--- /dev/null
+++ b/engines/fullpipe/scenes/scene36.cpp
@@ -0,0 +1,94 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public 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 "fullpipe/fullpipe.h"
+
+#include "fullpipe/objectnames.h"
+#include "fullpipe/constants.h"
+
+#include "fullpipe/gameloader.h"
+#include "fullpipe/motion.h"
+#include "fullpipe/scenes.h"
+#include "fullpipe/statics.h"
+
+#include "fullpipe/interaction.h"
+#include "fullpipe/behavior.h"
+
+
+namespace Fullpipe {
+
+void scene36_initScene(Scene *sc) {
+ g_vars->scene36_rotohrust = sc->getStaticANIObject1ById(ANI_ROTOHRUST, -1);
+ g_vars->scene36_scissors = sc->getStaticANIObject1ById(ANI_SCISSORS_36, -1);
+}
+
+int scene36_updateCursor() {
+ g_fp->updateCursorCommon();
+
+ if (g_fp->_cursorId != PIC_CSR_ITN || g_fp->_objectIdAtCursor != ANI_ROTOHRUST) {
+ if (g_fp->_objectIdAtCursor == PIC_SC36_MASK && g_fp->_cursorId == PIC_CSR_DEFAULT && (g_vars->scene36_scissors->_flags & 4))
+ g_fp->_cursorId = PIC_CSR_ITN;
+ } else if (g_vars->scene36_rotohrust->_statics->_staticsId == ST_RHT_OPEN)
+ g_fp->_cursorId = PIC_CSR_GOL;
+
+ return g_fp->_cursorId;
+}
+
+int sceneHandler36(ExCommand *cmd) {
+ if (cmd->_messageKind != 17)
+ return 0;
+
+ switch (cmd->_messageNum) {
+ case 29:
+ if (g_fp->_currentScene->getPictureObjectIdAtPos(cmd->_sceneClickX, cmd->_sceneClickY) == PIC_SC36_MASK)
+ if (g_vars->scene36_scissors)
+ if (g_vars->scene36_scissors->_flags & 4)
+ if (g_fp->_aniMan->isIdle())
+ if (!(g_fp->_aniMan->_flags & 0x100) && g_fp->_msgObjectId2 != g_vars->scene36_scissors->_id ) {
+ handleObjectInteraction(g_fp->_aniMan, g_vars->scene36_scissors, cmd->_keyCode);
+
+ cmd->_messageKind = 0;
+ }
+
+ break;
+
+ case 33:
+ if (g_fp->_aniMan2) {
+ int x = g_fp->_aniMan2->_ox;
+
+ if (x < g_fp->_sceneRect.left + 200)
+ g_fp->_currentScene->_x = x - 300 - g_fp->_sceneRect.left;
+
+ if (x > g_fp->_sceneRect.right - 200)
+ g_fp->_currentScene->_x = x + 300 - g_fp->_sceneRect.right;
+ }
+
+ g_fp->_behaviorManager->updateBehaviors();
+ g_fp->startSceneTrack();
+
+ break;
+ }
+
+ return 0;
+}
+
+} // End of namespace Fullpipe
diff --git a/engines/fullpipe/scenes/scene37.cpp b/engines/fullpipe/scenes/scene37.cpp
new file mode 100644
index 0000000000..8324e00af7
--- /dev/null
+++ b/engines/fullpipe/scenes/scene37.cpp
@@ -0,0 +1,316 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public 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 "fullpipe/fullpipe.h"
+
+#include "fullpipe/objectnames.h"
+#include "fullpipe/constants.h"
+
+#include "fullpipe/gameloader.h"
+#include "fullpipe/motion.h"
+#include "fullpipe/scenes.h"
+#include "fullpipe/statics.h"
+
+#include "fullpipe/interaction.h"
+#include "fullpipe/behavior.h"
+
+
+namespace Fullpipe {
+
+Ring::Ring() {
+ ani = 0;
+ x = 0;
+ y = 0;
+ numSubRings = 0;
+
+ for (int i = 0; i < 10; i++)
+ subRings[i] = 0;
+
+ state = false;
+}
+
+void scene37_initScene(Scene *sc) {
+ Ring *ring;
+ StaticANIObject *ani;
+
+ g_vars->scene37_lastDudeX = -1;
+
+ ring = new Ring();
+ ani = sc->getStaticANIObject1ById(ANI_GUARD_37, 0);
+ ring->ani = ani;
+ ring->x = ani->_ox - 40;
+ ring->y = ani->_ox + 40;
+ ring->numSubRings = 3;
+ ring->subRings[0] = 1;
+ ring->subRings[1] = 4;
+ ring->subRings[2] = 8;
+ ring->state = false;
+ g_vars->scene37_rings.push_back(ring);
+
+ ring = new Ring();
+ ani = sc->getStaticANIObject1ById(ANI_GUARD_37, 1);
+ ring->ani = ani;
+ ring->x = ani->_ox - 40;
+ ring->y = ani->_ox + 40;
+ ring->numSubRings = 3;
+ ring->subRings[0] = 2;
+ ring->subRings[1] = 5;
+ ring->subRings[2] = 9;
+ ring->state = false;
+ g_vars->scene37_rings.push_back(ring);
+
+ ring = new Ring();
+ ani = sc->getStaticANIObject1ById(ANI_GUARD_37, 2);
+ ring->ani = ani;
+ ring->x = ani->_ox - 40;
+ ring->y = ani->_ox + 40;
+ ring->numSubRings = 3;
+ ring->subRings[0] = 3;
+ ring->subRings[1] = 7;
+ ring->subRings[2] = 11;
+ ring->state = false;
+ 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;
+
+ g_vars->scene37_cursorIsLocked = false;
+
+ g_vars->scene37_plusMinus1 = sc->getStaticANIObject1ById(ANI_PLUSMINUS, 1);
+
+ for (int i = 0; i < g_vars->scene37_rings[0]->numSubRings; i++) {
+ ani = g_fp->_currentScene->getStaticANIObject1ById(ANI_RING, g_vars->scene37_rings[0]->subRings[i]);
+
+ if (g_fp->getObjectState(sO_Guard_1) == g_fp->getObjectEnumState(sO_Guard_1, sO_On)) {
+ g_vars->scene37_plusMinus1->_statics = g_vars->scene37_plusMinus1->getStaticsById(ST_PMS_PLUS);
+ ani->changeStatics2(ST_RNG_OPEN);
+ } else {
+ g_vars->scene37_plusMinus1->_statics = g_vars->scene37_plusMinus1->getStaticsById(ST_PMS_MINUS);
+ ani->changeStatics2(ST_RNG_CLOSED2);
+ }
+ }
+
+ g_vars->scene37_plusMinus2 = sc->getStaticANIObject1ById(ANI_PLUSMINUS, 2);
+
+ for (int i = 0; i < g_vars->scene37_rings[1]->numSubRings; i++) {
+ ani = g_fp->_currentScene->getStaticANIObject1ById(ANI_RING, g_vars->scene37_rings[1]->subRings[i]);
+
+ if (g_fp->getObjectState(sO_Guard_2) == g_fp->getObjectEnumState(sO_Guard_2, sO_On)) {
+ g_vars->scene37_plusMinus2->_statics = g_vars->scene37_plusMinus2->getStaticsById(ST_PMS_PLUS);
+ ani->changeStatics2(ST_RNG_OPEN);
+ } else {
+ g_vars->scene37_plusMinus2->_statics = g_vars->scene37_plusMinus2->getStaticsById(ST_PMS_MINUS);
+ ani->changeStatics2(ST_RNG_CLOSED2);
+ }
+ }
+
+ g_vars->scene37_plusMinus3 = sc->getStaticANIObject1ById(ANI_PLUSMINUS, 3);
+
+ for (int i = 0; i < g_vars->scene37_rings[2]->numSubRings; i++) {
+ ani = g_fp->_currentScene->getStaticANIObject1ById(ANI_RING, g_vars->scene37_rings[2]->subRings[i]);
+
+ if (g_fp->getObjectState(sO_Guard_3) == g_fp->getObjectEnumState(sO_Guard_3, sO_On)) {
+ g_vars->scene37_plusMinus3->_statics = g_vars->scene37_plusMinus3->getStaticsById(ST_PMS_PLUS);
+ ani->changeStatics2(ST_RNG_OPEN);
+ } else {
+ g_vars->scene37_plusMinus3->_statics = g_vars->scene37_plusMinus3->getStaticsById(ST_PMS_MINUS);
+ ani->changeStatics2(ST_RNG_CLOSED2);
+ }
+ }
+
+ g_fp->_currentScene = oldsc;
+
+ g_fp->initArcadeKeys("SC_37");
+}
+
+int scene37_updateCursor() {
+ g_fp->updateCursorCommon();
+
+ if (g_fp->_cursorId == PIC_CSR_ITN && g_fp->_objectIdAtCursor == PIC_SC37_MASK) {
+ if (g_vars->scene37_cursorIsLocked)
+ g_fp->_cursorId = PIC_CSR_GOL;
+ }
+
+ return g_fp->_cursorId;
+}
+
+void sceneHandler37_updateRing(int ringNum) {
+ g_vars->scene37_rings[ringNum]->ani->changeStatics2(ST_GRD37_STAND);
+ g_vars->scene37_rings[ringNum]->ani->startAnim(MV_GRD37_PULL, 0, -1);
+ g_vars->scene37_rings[ringNum]->state = !g_vars->scene37_rings[ringNum]->state;
+
+ StaticANIObject *ani;
+
+ for (int i = 0; i < g_vars->scene37_rings[ringNum]->numSubRings; i++) {
+ ani = g_fp->_currentScene->getStaticANIObject1ById(ANI_RING, g_vars->scene37_rings[ringNum]->subRings[i]);
+
+ if ((ani->_movement && ani->_movement->_id != MV_RNG_CLOSE) || ani->_statics->_staticsId != ST_RNG_CLOSED2) {
+ ani->changeStatics2(ST_RNG_OPEN);
+ ani->startAnim(MV_RNG_CLOSE, 0, -1);
+ } else {
+ ani->changeStatics2(ST_RNG_CLOSED2);
+ ani->startAnim(MV_RNG_OPEN, 0, -1);
+ }
+ }
+
+ g_vars->scene37_cursorIsLocked = true;
+
+ for (uint j = 0; j < g_vars->scene37_rings.size(); j++) {
+ for (int i = 0; i < g_vars->scene37_rings[ringNum]->numSubRings; i++) {
+ ani = g_fp->_currentScene->getStaticANIObject1ById(ANI_RING, g_vars->scene37_rings[j]->subRings[i]);
+
+ if ((ani->_movement && ani->_movement->_id != MV_RNG_CLOSE) || ani->_statics->_staticsId != ST_RNG_CLOSED2)
+ g_vars->scene37_cursorIsLocked = false;
+ }
+ }
+
+ int state;
+
+ if (g_vars->scene37_cursorIsLocked)
+ state = g_fp->getObjectEnumState(sO_LeftPipe_37, sO_IsOpened);
+ else
+ state = g_fp->getObjectEnumState(sO_LeftPipe_37, sO_IsClosed);
+
+ g_fp->setObjectState(sO_LeftPipe_37, state);
+}
+
+void sceneHandler37_setRingsState() {
+ if (g_vars->scene37_lastDudeX == -1) {
+ g_vars->scene37_lastDudeX = g_vars->scene37_dudeX;
+ } else {
+ for (uint i = 0; i < g_vars->scene37_rings.size(); i++) {
+ int x = g_vars->scene37_rings[i]->x;
+
+ if (g_vars->scene37_lastDudeX > x && g_vars->scene37_dudeX <= x && !g_vars->scene37_rings[i]->state)
+ sceneHandler37_updateRing(i);
+
+ x = g_vars->scene37_rings[i]->y;
+
+ if (g_vars->scene37_lastDudeX < x && g_vars->scene37_dudeX >= x) {
+ if (g_vars->scene37_rings[i]->state)
+ sceneHandler37_updateRing(i);
+ }
+ }
+
+ g_vars->scene37_lastDudeX = g_vars->scene37_dudeX;
+ }
+}
+
+int sceneHandler37(ExCommand *cmd) {
+ if (cmd->_messageKind != 17)
+ return 0;
+
+ switch(cmd->_messageNum) {
+ case MSG_SC37_EXITLEFT:
+ sceneHandler37_updateRing(0);
+ sceneHandler37_updateRing(1);
+ sceneHandler37_updateRing(2);
+
+ break;
+
+ case 29:
+ {
+ StaticANIObject *ani = g_fp->_currentScene->getStaticANIObjectAtPos(cmd->_sceneClickX, cmd->_sceneClickY);
+
+ if (!ani || !canInteractAny(g_fp->_aniMan, ani, cmd->_keyCode)) {
+ int picId = g_fp->_currentScene->getPictureObjectIdAtPos(cmd->_sceneClickX, cmd->_sceneClickY);
+ PictureObject *pic = g_fp->_currentScene->getPictureObjectById(picId, 0);
+
+ if (!pic || !canInteractAny(g_fp->_aniMan, pic, cmd->_keyCode)) {
+ if ((g_fp->_sceneRect.right - cmd->_sceneClickX < 47 && g_fp->_sceneRect.right < g_fp->_sceneWidth - 1)
+ || (cmd->_sceneClickX - g_fp->_sceneRect.left < 47 && g_fp->_sceneRect.left > 0)) {
+ g_fp->processArcade(cmd);
+ break;
+ }
+ }
+ }
+ }
+
+ break;
+
+ case 33:
+ if (g_fp->_aniMan2) {
+ int x = g_fp->_aniMan2->_ox;
+
+ g_vars->scene37_dudeX = x;
+
+ if (x >= 500) {
+ if (x < g_fp->_sceneRect.left + 200)
+ g_fp->_currentScene->_x = x - 300 - g_fp->_sceneRect.left;
+ } else {
+ g_fp->_currentScene->_x = -g_fp->_sceneRect.left;
+ }
+ x = g_vars->scene37_dudeX;
+
+ if (x > g_fp->_sceneRect.right - 200)
+ g_fp->_currentScene->_x = x + 300 - g_fp->_sceneRect.right;
+ }
+
+ sceneHandler37_setRingsState();
+
+ g_fp->_behaviorManager->updateBehaviors();
+ g_fp->startSceneTrack();
+
+ ++g_vars->scene37_soundFlipper;
+
+ break;
+
+ case MSG_SC37_PULL:
+ if (g_vars->scene37_rings[0]->ani->_movement && g_vars->scene37_rings[0]->ani->_movement->_id == MV_GRD37_PULL) {
+ if ((g_fp->getObjectState(sO_Guard_1) == g_fp->getObjectEnumState(sO_Guard_1, sO_On) && !g_vars->scene37_rings[0]->state)
+ || (g_fp->getObjectState(sO_Guard_1) == g_fp->getObjectEnumState(sO_Guard_1, sO_Off) && g_vars->scene37_rings[0]->state)) {
+ g_vars->scene37_plusMinus1->_statics = g_vars->scene37_plusMinus1->getStaticsById(ST_PMS_PLUS);
+ } else {
+ g_vars->scene37_plusMinus1->_statics = g_vars->scene37_plusMinus1->getStaticsById(ST_PMS_MINUS);
+ }
+ } else if (g_vars->scene37_rings[1]->ani->_movement && g_vars->scene37_rings[1]->ani->_movement->_id == MV_GRD37_PULL) {
+ if ((g_fp->getObjectState(sO_Guard_2) == g_fp->getObjectEnumState(sO_Guard_2, sO_On) && !g_vars->scene37_rings[1]->state)
+ || (g_fp->getObjectState(sO_Guard_2) == g_fp->getObjectEnumState(sO_Guard_2, sO_Off) && g_vars->scene37_rings[1]->state)) {
+ g_vars->scene37_plusMinus2->_statics = g_vars->scene37_plusMinus2->getStaticsById(ST_PMS_PLUS);
+ } else {
+ g_vars->scene37_plusMinus2->_statics = g_vars->scene37_plusMinus2->getStaticsById(ST_PMS_MINUS);
+ }
+ } else if (g_vars->scene37_rings[2]->ani->_movement && g_vars->scene37_rings[2]->ani->_movement->_id == MV_GRD37_PULL) {
+ if ((g_fp->getObjectState(sO_Guard_3) == g_fp->getObjectEnumState(sO_Guard_3, sO_On) && !g_vars->scene37_rings[2]->state)
+ || (g_fp->getObjectState(sO_Guard_3) == g_fp->getObjectEnumState(sO_Guard_3, sO_Off) && g_vars->scene37_rings[2]->state)) {
+ g_vars->scene37_plusMinus3->_statics = g_vars->scene37_plusMinus3->getStaticsById(ST_PMS_PLUS);
+ } else {
+ g_vars->scene37_plusMinus3->_statics = g_vars->scene37_plusMinus3->getStaticsById(ST_PMS_MINUS);
+ }
+ }
+
+ if (g_vars->scene37_soundFlipper) {
+ g_fp->playSound(SND_37_007, 0);
+
+ g_vars->scene37_soundFlipper = 0;
+ }
+
+ break;
+ }
+
+ return 0;
+}
+
+} // End of namespace Fullpipe
diff --git a/engines/fullpipe/scenes/scene38.cpp b/engines/fullpipe/scenes/scene38.cpp
new file mode 100644
index 0000000000..016dc83c1b
--- /dev/null
+++ b/engines/fullpipe/scenes/scene38.cpp
@@ -0,0 +1,409 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public 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 "fullpipe/fullpipe.h"
+
+#include "fullpipe/objectnames.h"
+#include "fullpipe/constants.h"
+
+#include "fullpipe/gameloader.h"
+#include "fullpipe/motion.h"
+#include "fullpipe/scenes.h"
+#include "fullpipe/statics.h"
+
+#include "fullpipe/interaction.h"
+#include "fullpipe/behavior.h"
+
+
+namespace Fullpipe {
+
+void scene38_setBottleState(Scene *sc) {
+ ExCommand *ex = sc->getMessageQueueById(QU_SC38_SHOWBOTTLE_ONTABLE)->getExCommandByIndex(0);
+
+ if (g_vars->scene38_bottle->_ox == ex->_x && g_vars->scene38_bottle->_oy == ex->_y) {
+ if (g_fp->lift_checkButton(sO_Level5) ) {
+ ex = sc->getMessageQueueById(QU_SC38_SHOWBOTTLE)->getExCommandByIndex(0);
+
+ g_vars->scene38_bottle->setOXY(ex->_x, ex->_y);
+ g_vars->scene38_bottle->_priority = ex->_field_14;
+
+ g_fp->setObjectState(sO_Bottle_38, g_fp->getObjectEnumState(sO_Bottle_38, sO_Blocked));
+ }
+ }
+}
+
+void scene38_initScene(Scene *sc) {
+ g_vars->scene38_boss = sc->getStaticANIObject1ById(ANI_GLAVAR, -1);
+ g_vars->scene38_tally = sc->getStaticANIObject1ById(ANI_DYLDA, -1);
+ g_vars->scene38_shorty = sc->getStaticANIObject1ById(ANI_MALYSH, -1);
+ g_vars->scene38_domino0 = sc->getStaticANIObject1ById(ANI_DOMINO38, 0);
+ g_vars->scene38_dominos = sc->getStaticANIObject1ById(ANI_DOMINOS, 0);
+ g_vars->scene38_domino1 = sc->getStaticANIObject1ById(ANI_DOMINO38, 1);
+ g_vars->scene38_bottle = sc->getStaticANIObject1ById(ANI_BOTTLE38, 0);
+ g_vars->scene38_bossCounter = 0;
+ g_vars->scene38_lastBossAnim = 0;
+ g_vars->scene38_bossAnimCounter = 0;
+ g_vars->scene38_tallyCounter = 15;
+ g_vars->scene38_lastTallyAnim = 0;
+ g_vars->scene38_tallyAnimCounter = 0;
+ g_vars->scene38_shortyCounter = 30;
+ g_vars->scene38_lastShortyAnim = 0;
+ g_vars->scene38_shortyAnimCounter = 0;
+
+ scene38_setBottleState(sc);
+
+ if (g_fp->getObjectState(sO_Boss) == g_fp->getObjectEnumState(sO_Boss, sO_IsSleeping)) {
+ g_vars->scene38_shorty->_flags &= 0xFFFB;
+
+ g_vars->scene38_tally->stopAnim_maybe();
+ g_vars->scene38_tally->_flags &= 0xFFFB;
+
+ g_vars->scene38_domino0->_flags &= 0xFFFB;
+ g_vars->scene38_dominos->_flags &= 0xFFFB;
+ g_vars->scene38_domino1->_flags &= 0xFFFB;
+ }
+
+ g_fp->lift_init(sc, QU_SC38_ENTERLIFT, QU_SC38_EXITLIFT);
+ g_fp->lift_setButtonStatics(sc, ST_LBN_0N);
+}
+
+void sceneHandler38_tryTakeBottle() {
+ g_vars->scene38_boss->changeStatics2(ST_GLV_NOHAMMER);
+ g_vars->scene38_boss->startAnim(MV_GLV_LOOKMAN, 0, -1);
+
+ g_vars->scene38_bossCounter = 0;
+}
+
+void sceneHandler38_postHammerKick() {
+ g_vars->scene38_domino1->setOXY(g_vars->scene38_domino1->_ox, g_vars->scene38_domino1->_oy + 2);
+}
+
+void sceneHandler38_propose() {
+ if (!g_vars->scene38_tally->_movement) {
+ if (g_vars->scene38_tally->_flags & 4) {
+ if (!(g_vars->scene38_tally->_flags & 2) && g_vars->scene38_tallyCounter > 0
+ && g_fp->_rnd->getRandomNumber(32767) < 32767) {
+ chainQueue(QU_DLD_DENY, 0);
+ g_vars->scene38_tallyCounter = 0;
+ }
+ }
+ }
+}
+
+void sceneHandler38_point() {
+ if ((!g_vars->scene38_boss->_movement && ((g_vars->scene38_boss->_flags & 4) || !(g_vars->scene38_boss->_flags & 2)))
+ && g_vars->scene38_bossCounter > 0
+ && g_fp->_rnd->getRandomNumber(32767) < 32767) {
+ if (g_vars->scene38_boss->_statics->_staticsId == ST_GLV_HAMMER) {
+ chainQueue(QU_GLV_TOSMALL, 0);
+ g_vars->scene38_bossCounter = 0;
+ } else {
+ if (g_vars->scene38_boss->_statics->_staticsId == ST_GLV_NOHAMMER)
+ chainQueue(QU_GLV_TOSMALL_NOHMR, 0);
+
+ g_vars->scene38_bossCounter = 0;
+ }
+ }
+}
+
+void sceneHandler38_hammerKick() {
+ if (!g_vars->scene38_shorty->_movement) {
+ if (g_vars->scene38_shorty->_flags & 4) {
+ if (!(g_vars->scene38_shorty->_flags & 2) && g_vars->scene38_shortyCounter > 1
+ && g_vars->scene38_shorty->_statics->_staticsId == ST_MLS_LEFT2
+ && g_fp->_rnd->getRandomNumber(32767) < 3276) {
+ chainQueue(QU_MLS_TURNR, 0);
+ g_vars->scene38_shortyCounter = 0;
+ }
+ }
+ }
+
+ g_vars->scene38_domino1->setOXY(g_vars->scene38_domino1->_ox, g_vars->scene38_domino1->_oy - 2);
+
+ if (g_vars->scene38_dominos->_statics->_staticsId == ST_DMS_3)
+ g_vars->scene38_dominos->startAnim(MV_DMS_THREE, 0, -1);
+ else if (g_vars->scene38_dominos->_statics->_staticsId == ST_DMS_4)
+ g_vars->scene38_dominos->startAnim(MV_DMS_FOUR, 0, -1);
+}
+
+void sceneHandler38_drink() {
+ if (!g_vars->scene38_shorty->_movement) {
+ if (g_vars->scene38_shorty->_flags & 4) {
+ if (!(g_vars->scene38_shorty->_flags & 2) && g_vars->scene38_shortyCounter > 0
+ && g_vars->scene38_shorty->_statics->_staticsId == ST_MLS_LEFT2
+ && g_fp->_rnd->getRandomNumber(32767) < 3276) {
+ chainQueue(QU_MLS_TURNR, 0);
+ g_vars->scene38_shortyCounter = 0;
+ }
+ }
+ }
+}
+
+void sceneHandler38_animateAlcoholics() {
+ MessageQueue *mq;
+
+ if (g_vars->scene38_boss->_movement || !(g_vars->scene38_boss->_flags & 4) || (g_vars->scene38_boss->_flags & 2)) {
+ g_vars->scene38_bossCounter = 0;
+ } else {
+ g_vars->scene38_bossCounter++;
+ }
+
+ if (g_vars->scene38_bossCounter >= 50) {
+ int bossSt = g_vars->scene38_boss->_statics->_staticsId;
+
+ if (bossSt == ST_GLV_SLEEP2) {
+ g_vars->scene38_bossCounter = 0;
+ } else if ((g_vars->scene38_domino0->_flags & 4) && g_vars->scene38_domino0->_statics->_staticsId == ST_DMN38_6) {
+ if (bossSt == ST_GLV_HAMMER) {
+ chainQueue(QU_GLV_TAKEDOMINO, 1);
+ g_vars->scene38_bossCounter = 0;
+ }
+
+ if (bossSt == ST_GLV_NOHAMMER) {
+ chainQueue(QU_GLV_TAKEDOMINO_NOHMR, 1);
+ g_vars->scene38_bossCounter = 0;
+ }
+ } else {
+ if ((g_vars->scene38_bottle->_flags & 4) && g_vars->scene38_bottle->_statics->_staticsId == ST_BTL38_FULL && bossSt == ST_GLV_NOHAMMER) {
+ chainQueue(QU_GLV_DRINKBOTTLE, 1);
+ g_vars->scene38_bossCounter = 0;
+ } else {
+ int bossAnim = 0;
+
+ if (g_fp->_rnd->getRandomNumber(32767) >= 1310 || g_vars->scene38_boss->_statics->_staticsId != ST_GLV_HAMMER) {
+ if (g_fp->_rnd->getRandomNumber(32767) >= 1310) {
+ if (g_fp->_rnd->getRandomNumber(32767) < 1310) {
+ if (bossSt == ST_GLV_HAMMER)
+ bossAnim = QU_GLV_DRINK;
+ else if (bossSt == ST_GLV_NOHAMMER)
+ bossAnim = QU_GLV_DRINK_NOHMR;
+ }
+ } else {
+ if (bossSt == ST_GLV_HAMMER)
+ bossAnim = QU_GLV_PROPOSE;
+ else if (bossSt == ST_GLV_NOHAMMER)
+ bossAnim = QU_GLV_PROPOSE_NOHMR;
+ }
+ } else {
+ bossAnim = QU_GLV_HMRKICK;
+ }
+
+ if (g_vars->scene38_lastBossAnim == bossAnim) {
+ g_vars->scene38_bossAnimCounter++;
+
+ if (g_vars->scene38_bossAnimCounter > 2)
+ bossAnim = 0;
+ } else {
+ g_vars->scene38_lastBossAnim = bossAnim;
+ g_vars->scene38_bossAnimCounter = 1;
+ }
+
+ if (bossAnim > 0) {
+ mq = new MessageQueue(g_fp->_currentScene->getMessageQueueById(bossAnim), 0, 0);
+
+ mq->chain(0);
+
+ g_vars->scene38_bossCounter = 0;
+ }
+ }
+ }
+ }
+
+ if (g_vars->scene38_tally->_movement || !(g_vars->scene38_tally->_flags & 4) || (g_vars->scene38_tally->_flags & 2)) {
+ g_vars->scene38_tallyCounter = 0;
+ } else {
+ g_vars->scene38_tallyCounter++;
+ }
+
+ if (g_vars->scene38_tallyCounter >= 50) {
+ int tallyAnim = 0;
+
+ if (g_fp->_rnd->getRandomNumber(32767) >= 1310) {
+ if (g_fp->_rnd->getRandomNumber(32767) >= 1310) {
+ if (g_fp->_rnd->getRandomNumber(32767) >= 1310) {
+ if (g_fp->_rnd->getRandomNumber(32767) < 1310)
+ tallyAnim = QU_DLD_ICK;
+ } else {
+ tallyAnim = QU_DLD_GLOT;
+ }
+ } else {
+ tallyAnim = QU_DLD_BLINK;
+ }
+ } else {
+ if (g_vars->scene38_domino1->_statics->_staticsId == ST_DMN38_NORM3) {
+ tallyAnim = QU_DLD_TAKE1;
+ } else if (g_vars->scene38_domino1->_statics->_staticsId == ST_DMN38_NORM4) {
+ tallyAnim = QU_DLD_TAKE2;
+ }
+ }
+
+ if (g_vars->scene38_lastTallyAnim == tallyAnim) {
+ g_vars->scene38_tallyAnimCounter++;
+
+ if (g_vars->scene38_tallyAnimCounter++ > 2)
+ tallyAnim = 0;
+ } else {
+ g_vars->scene38_lastTallyAnim = tallyAnim;
+ g_vars->scene38_tallyAnimCounter = 1;
+ }
+ if (tallyAnim > 0) {
+ mq = new MessageQueue(g_fp->_currentScene->getMessageQueueById(tallyAnim), 0, 0);
+
+ mq->chain(0);
+ g_vars->scene38_tallyCounter = 0;
+ }
+ }
+
+ if (g_vars->scene38_shorty->_movement || !(g_vars->scene38_shorty->_flags & 4) || (g_vars->scene38_shorty->_flags & 2)) {
+ g_vars->scene38_shortyCounter = 0;
+ return;
+ }
+
+ g_vars->scene38_shortyCounter++;
+
+ if (g_vars->scene38_shortyCounter < 50)
+ return;
+
+ int shortyAnim = 0;
+
+ if (g_fp->_rnd->getRandomNumber(32767) >= 1310) {
+ if (g_fp->_rnd->getRandomNumber(32767) >= 1310 || g_vars->scene38_shorty->_statics->_staticsId != ST_MLS_LEFT2) {
+ if (g_vars->scene38_boss->_statics->_staticsId != ST_GLV_SLEEP2 && g_vars->scene38_bossCounter > 30 && g_fp->_rnd->getRandomNumber(32767) < 0x3FFF && g_vars->scene38_shorty->_statics->_staticsId == ST_MLS_LEFT2)
+ shortyAnim = QU_MLS_HAND;
+ } else {
+ shortyAnim = QU_MLS_BLINK;
+ }
+ } else {
+ if (g_vars->scene38_shorty->_statics->_staticsId == ST_MLS_RIGHT2) {
+ shortyAnim = QU_MLS_TURNL;
+ } else if (g_vars->scene38_shorty->_statics->_staticsId == ST_MLS_LEFT2) {
+ shortyAnim = QU_MLS_TURNR;
+ }
+ }
+
+ if (g_vars->scene38_lastShortyAnim == shortyAnim) {
+ g_vars->scene38_shortyAnimCounter++;
+ if (g_vars->scene38_shortyAnimCounter > 2)
+ return;
+ } else {
+ g_vars->scene38_lastShortyAnim = shortyAnim;
+ g_vars->scene38_shortyAnimCounter = 1;
+ }
+
+ if (shortyAnim > 0) {
+ mq = new MessageQueue(g_fp->_currentScene->getMessageQueueById(shortyAnim), 0, 0);
+
+ mq->chain(0);
+
+ g_vars->scene38_shortyCounter = 0;
+ }
+}
+
+int sceneHandler38(ExCommand *cmd) {
+ if (cmd->_messageKind != 17)
+ return 0;
+
+ switch (cmd->_messageNum) {
+ case MSG_LIFT_EXITLIFT:
+ g_fp->lift_exitSeq(cmd);
+ break;
+
+ case MSG_LIFT_CLOSEDOOR:
+ g_fp->lift_closedoorSeq();
+ break;
+
+ case MSG_LIFT_STARTEXITQUEUE:
+ g_fp->lift_startExitQueue();
+ break;
+
+ case MSG_SC38_TRYTAKEBOTTLE:
+ sceneHandler38_tryTakeBottle();
+ break;
+
+ case MSG_SC38_POSTHMRKICK:
+ sceneHandler38_postHammerKick();
+ break;
+
+ case MSG_SC38_PROPOSE:
+ sceneHandler38_propose();
+ break;
+
+ case MSG_LIFT_CLICKBUTTON:
+ g_fp->lift_clickButton();
+ break;
+
+ case MSG_SC38_POINT:
+ sceneHandler38_point();
+ break;
+
+ case MSG_LIFT_GO:
+ g_fp->lift_goAnimation();
+ break;
+
+ case MSG_SC38_HMRKICK:
+ sceneHandler38_hammerKick();
+ break;
+
+ case MSG_SC38_DRINK:
+ sceneHandler38_drink();
+ break;
+
+ case 64:
+ g_fp->lift_sub05(cmd);
+ break;
+
+ case 29:
+ {
+ StaticANIObject *ani = g_fp->_currentScene->getStaticANIObjectAtPos(g_fp->_sceneRect.left + cmd->_x, g_fp->_sceneRect.top + cmd->_y);
+
+ if (ani && ani->_id == ANI_LIFTBUTTON) {
+ g_fp->lift_sub1(ani);
+
+ cmd->_messageKind = 0;
+ }
+ break;
+ }
+
+ case 33:
+ if (g_fp->_aniMan2) {
+ int x = g_fp->_aniMan2->_ox;
+
+ if (x < g_fp->_sceneRect.left + 200)
+ g_fp->_currentScene->_x = x - 300 - g_fp->_sceneRect.left;
+
+ if (x > g_fp->_sceneRect.right - 200)
+ g_fp->_currentScene->_x = x + 300 - g_fp->_sceneRect.right;
+ }
+
+ sceneHandler38_animateAlcoholics();
+
+ g_fp->_behaviorManager->updateBehaviors();
+
+ g_fp->startSceneTrack();
+
+ break;
+ }
+
+ return 0;
+}
+
+} // End of namespace Fullpipe
diff --git a/engines/fullpipe/scenes/sceneDbg.cpp b/engines/fullpipe/scenes/sceneDbg.cpp
new file mode 100644
index 0000000000..4a3751940f
--- /dev/null
+++ b/engines/fullpipe/scenes/sceneDbg.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 "fullpipe/fullpipe.h"
+
+#include "fullpipe/constants.h"
+
+#include "fullpipe/gameloader.h"
+#include "fullpipe/motion.h"
+#include "fullpipe/scenes.h"
+#include "fullpipe/statics.h"
+#include "fullpipe/input.h"
+
+#include "fullpipe/interaction.h"
+
+namespace Fullpipe {
+
+void sceneDbgMenu_initScene(Scene *sc) {
+ g_vars->selector = sc->getPictureObjectById(PIC_SCD_SEL, 0);
+ getGameLoaderInteractionController()->disableFlag24();
+ setInputDisabled(0);
+}
+
+GameObject *sceneHandlerDbgMenu_getObjectAtXY(int x, int y) {
+ if (g_fp->_currentScene)
+ for (uint i = 0; i < g_fp->_currentScene->_picObjList.size(); i++) {
+ PictureObject *pic = (PictureObject *)g_fp->_currentScene->_picObjList[i];
+
+ if (x >= pic->_ox && y >= pic->_oy) {
+ Common::Point point;
+
+ pic->getDimensions(&point);
+
+ if (x <= pic->_ox + point.x && y <= pic->_oy + point.y && pic != g_vars->selector)
+ return pic;
+ }
+ }
+
+ return 0;
+}
+
+int sceneHandlerDbgMenu(ExCommand *ex) {
+ if (ex->_messageKind != 17)
+ return 0;
+
+ int mx = g_fp->_mouseScreenPos.x + g_fp->_sceneRect.left;
+ int my = g_fp->_mouseScreenPos.y + g_fp->_sceneRect.top;
+
+ if (ex->_messageNum == 29) {
+ GameObject *obj = sceneHandlerDbgMenu_getObjectAtXY(mx, my);
+ if (obj && canInteractAny(0, obj, -3) ) {
+ getGameLoaderInteractionController()->enableFlag24();
+ handleObjectInteraction(0, obj, 0);
+ }
+ return 0;
+ }
+ if (ex->_messageNum != 33) {
+ if (ex->_messageNum == MSG_RESTARTGAME) {
+ g_fp->_needRestart = true;
+ return 0;
+ }
+ return 0;
+ }
+
+ g_fp->_cursorId = PIC_CSR_DEFAULT;
+ GameObject *obj = g_fp->_currentScene->getStaticANIObjectAtPos(mx, my);
+ if (obj) {
+ if (canInteractAny(0, obj, -3)) {
+ g_fp->_cursorId = PIC_CSR_DEFAULT;
+ g_fp->setCursor(PIC_CSR_DEFAULT);
+ return 0;
+ }
+ } else {
+ obj = sceneHandlerDbgMenu_getObjectAtXY(mx, my);
+ if (obj && canInteractAny(0, obj, -3) ) {
+ g_vars->selector->_flags |= 4;
+ g_vars->selector->setOXY(obj->_ox, obj->_oy);
+ g_fp->_cursorId = PIC_CSR_DEFAULT;
+ g_fp->setCursor(PIC_CSR_DEFAULT);
+ return 0;
+ }
+ g_vars->selector->_flags &= 0xFFFB;
+ }
+ g_fp->setCursor(g_fp->_cursorId);
+
+ return 0;
+}
+
+} // End of namespace Fullpipe
diff --git a/engines/fullpipe/scenes/sceneFinal.cpp b/engines/fullpipe/scenes/sceneFinal.cpp
new file mode 100644
index 0000000000..e483e8bab7
--- /dev/null
+++ b/engines/fullpipe/scenes/sceneFinal.cpp
@@ -0,0 +1,174 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public 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 "fullpipe/fullpipe.h"
+
+#include "fullpipe/objectnames.h"
+#include "fullpipe/constants.h"
+
+#include "fullpipe/gameloader.h"
+#include "fullpipe/motion.h"
+#include "fullpipe/scenes.h"
+#include "fullpipe/statics.h"
+
+#include "fullpipe/interaction.h"
+#include "fullpipe/behavior.h"
+
+#include "fullpipe/modal.h"
+
+
+namespace Fullpipe {
+
+void sceneFinal_initScene() {
+ g_fp->_gameLoader->loadScene(SC_FINAL2);
+ g_fp->accessScene(SC_FINAL2)->setPictureObjectsFlag4();
+ g_fp->_gameLoader->loadScene(SC_FINAL3);
+ g_fp->accessScene(SC_FINAL3)->setPictureObjectsFlag4();
+ g_fp->_gameLoader->loadScene(SC_FINAL4);
+ g_fp->accessScene(SC_FINAL4)->setPictureObjectsFlag4();
+
+ getGameLoaderInventory()->setIsLocked(0);
+ getGameLoaderInventory()->slideIn();
+
+ g_fp->_updateFlag = 0;
+ g_fp->_flgCanOpenMap = 0;
+
+ g_vars->sceneFinal_var01 = 0;
+ g_vars->sceneFinal_var02 = 0;
+ g_vars->sceneFinal_var03 = 0;
+}
+
+int sceneFinal_updateCursor() {
+ if (g_vars->sceneFinal_var01)
+ g_fp->_cursorId = 0;
+ else
+ g_fp->updateCursorCommon();
+
+ return g_fp->_cursorId;
+}
+
+void sceneHandlerFinal_endFinal() {
+ g_vars->sceneFinal_var01 = 0;
+}
+
+void sceneHandlerFinal_startMusic(const char *track) {
+ warning("STUB: sceneHandlerFinal_startMusic()");
+}
+
+void sceneHandlerFinal_goto4() {
+ g_fp->_currentScene = g_fp->accessScene(SC_FINAL4);
+
+ g_fp->_gameLoader->loadScene(SC_FINAL4);
+
+ chainQueue(QU_FN4_DOFINAL, 1);
+}
+
+void sceneHandlerFinal_goto3() {
+ g_fp->_currentScene = g_fp->accessScene(SC_FINAL3);
+
+ chainQueue(QU_FN3_DOFINAL, 1);
+}
+
+void sceneHandlerFinal_goto2() {
+ g_fp->_currentScene = g_fp->accessScene(SC_FINAL2);
+
+ chainQueue(QU_FN2_DOFINAL, 1);
+}
+
+void sceneHandlerFinal_startFinal() {
+ g_vars->sceneFinal_var01 = 1;
+
+ getCurrSceneSc2MotionController()->clearEnabled();
+ getGameLoaderInteractionController()->disableFlag24();
+
+ g_fp->_aniMan2 = 0;
+
+ g_fp->_aniMan->_flags &= 0xFFFB;
+
+ chainQueue(QU_FIN1_TAKECOIN, 1);
+
+ g_fp->playTrack(g_fp->getGameLoaderGameVar()->getSubVarByName("SC_FINAL1"), "MUSIC2", 1);
+
+ g_fp->_modalObject = new ModalFinal;
+}
+
+void sceneHandlerFinal_fallCoin() {
+ StaticANIObject *coin = g_fp->_currentScene->getStaticANIObject1ById(ANI_FIN_COIN, -1);
+
+ if (!coin->_movement) {
+ if (!coin->_statics || coin->_statics->_staticsId != ST_FCN_NORM)
+ chainQueue(QU_FIN1_FALLCOIN, 1);
+ }
+}
+
+int sceneHandlerFinal(ExCommand *cmd) {
+ if (cmd->_messageKind != 17)
+ return 0;
+
+ switch (cmd->_messageNum) {
+ case MSG_FIN_ENDFINAL:
+ sceneHandlerFinal_endFinal();
+ break;
+
+ case MSG_FN4_STARTMUSIC:
+ sceneHandlerFinal_startMusic("track16.ogg");
+ break;
+
+ case MSG_FIN_GOTO4:
+ sceneHandlerFinal_goto4();
+
+ g_fp->playTrack(g_fp->getGameLoaderGameVar()->getSubVarByName("SC_FINAL1"), "MUSIC3", 1);
+ break;
+
+ case MSG_FIN_GOTO3:
+ sceneHandlerFinal_goto3();
+ break;
+
+ case MSG_FIN_GOTO2:
+ sceneHandlerFinal_goto2();
+ break;
+
+ case MSG_FIN_STARTFINAL:
+ sceneHandlerFinal_startFinal();
+ break;
+
+ case 33:
+ if (g_fp->_aniMan2) {
+ g_vars->sceneFinal_var03 = g_fp->_aniMan2->_ox;
+
+ if (g_vars->sceneFinal_var03 < 450 && g_vars->sceneFinal_var02 >= 450 )
+ sceneHandlerFinal_fallCoin();
+
+ g_vars->sceneFinal_var02 = g_vars->sceneFinal_var03;
+ }
+
+ g_fp->_behaviorManager->updateBehaviors();
+
+ g_fp->startSceneTrack();
+
+ break;
+ }
+
+ return 0;
+}
+
+} // End of namespace Fullpipe
diff --git a/engines/fullpipe/scenes/sceneIntro.cpp b/engines/fullpipe/scenes/sceneIntro.cpp
new file mode 100644
index 0000000000..c9f19f3724
--- /dev/null
+++ b/engines/fullpipe/scenes/sceneIntro.cpp
@@ -0,0 +1,110 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public 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 "fullpipe/fullpipe.h"
+
+#include "fullpipe/constants.h"
+#include "fullpipe/gameloader.h"
+#include "fullpipe/motion.h"
+#include "fullpipe/scenes.h"
+#include "fullpipe/modal.h"
+#include "fullpipe/statics.h"
+
+namespace Fullpipe {
+
+int sceneIntro_updateCursor() {
+ g_fp->_cursorId = 0;
+
+ return 0;
+}
+
+void sceneIntro_initScene(Scene *sc) {
+ g_fp->_gameLoader->loadScene(SC_INTRO2);
+
+ g_vars->sceneIntro_aniin1man = sc->getStaticANIObject1ById(ANI_IN1MAN, -1);
+ g_vars->sceneIntro_needSleep = true;
+ g_vars->sceneIntro_needGetup = false;
+ g_vars->sceneIntro_playing = true;
+ g_vars->sceneIntro_needBlackout = false;
+
+ if (g_fp->_recordEvents || g_fp->_inputArFlag)
+ g_vars->sceneIntro_skipIntro = false;
+
+ g_fp->_modalObject = new ModalIntro;
+}
+
+void sceneHandlerIntro_part1() {
+ g_fp->_currentScene = g_fp->accessScene(SC_INTRO1);
+ chainQueue(QU_INTR_FINISH, 0);
+}
+
+void sceneHandlerIntro_part2() {
+ g_fp->_currentScene = g_fp->accessScene(SC_INTRO2);
+ chainQueue(QU_IN2_DO, 0);
+}
+
+int sceneHandlerIntro(ExCommand *ex) {
+ if (ex->_messageKind != 17)
+ return 0;
+
+ switch (ex->_messageNum) {
+ case MSG_INTR_ENDINTRO:
+ g_vars->sceneIntro_playing = 0;
+ return 0;
+
+ case MSG_INTR_SWITCHTO1:
+ sceneHandlerIntro_part1();
+ return 0;
+
+ case MSG_INTR_GETUPMAN:
+ g_vars->sceneIntro_needSleep = 0;
+ g_vars->sceneIntro_needGetup = 1;
+ return 0;
+
+ case MSG_INTR_SWITCHTO2:
+ sceneHandlerIntro_part2();
+ return 0;
+
+ case 33:
+ // fall through
+ break;
+
+ default:
+ return 0;
+ }
+
+ if (g_vars->sceneIntro_needSleep) {
+ if (!g_vars->sceneIntro_aniin1man->_movement && g_vars->sceneIntro_aniin1man->_statics->_staticsId == ST_IN1MAN_SLEEP)
+ g_vars->sceneIntro_aniin1man->startAnim(MV_IN1MAN_SLEEP, 0, -1);
+ } else if (g_vars->sceneIntro_needGetup && !g_vars->sceneIntro_aniin1man->_movement &&
+ g_vars->sceneIntro_aniin1man->_statics->_staticsId == ST_IN1MAN_SLEEP) {
+ g_vars->sceneIntro_needGetup = 0;
+
+ chainQueue(QU_INTR_GETUPMAN, 0);
+ }
+
+ g_fp->startSceneTrack();
+
+ return 0;
+}
+
+} // End of namespace Fullpipe
diff --git a/engines/fullpipe/sound.cpp b/engines/fullpipe/sound.cpp
index 6da848a621..fd25e2c903 100644
--- a/engines/fullpipe/sound.cpp
+++ b/engines/fullpipe/sound.cpp
@@ -23,8 +23,13 @@
#include "fullpipe/fullpipe.h"
#include "fullpipe/objects.h"
+#include "fullpipe/scene.h"
#include "fullpipe/sound.h"
#include "fullpipe/ngiarchive.h"
+#include "common/memstream.h"
+#include "audio/audiostream.h"
+#include "audio/decoders/vorbis.h"
+#include "audio/decoders/wave.h"
namespace Fullpipe {
@@ -77,6 +82,9 @@ Sound::Sound() {
_description = 0;
}
+Sound::~Sound() {
+ warning("STUB: Sound::~Sound()");
+}
bool Sound::load(MfcArchive &file, NGIArchive *archive) {
debug(5, "Sound::load()");
@@ -86,7 +94,7 @@ bool Sound::load(MfcArchive &file, NGIArchive *archive) {
_id = file.readUint32LE();
_description = file.readPascalString();
- assert(g_fullpipe->_gameProjectVersion >= 6);
+ assert(g_fp->_gameProjectVersion >= 6);
_objectId = file.readUint16LE();
@@ -113,14 +121,36 @@ void Sound::setPanAndVolumeByStaticAni() {
void FullpipeEngine::setSceneMusicParameters(GameVar *var) {
warning("STUB: FullpipeEngine::setSceneMusicParameters()");
+ // TODO: Finish this (MINDELAY, MAXDELAY, LOCAL, SEQUENCE, STARTDELAY etc)
+ stopAllSoundStreams();
+ _musicGameVar = var;
}
void FullpipeEngine::startSceneTrack() {
- debug(3, "STUB: FullpipeEngine::startSceneTrack()");
+ // TODO: Finish this
+#ifdef USE_VORBIS
+ if (g_fp->_mixer->isSoundHandleActive(_sceneTrackHandle))
+ return;
+
+ GameVar *musicTrackVar = _musicGameVar->getSubVarByName("MUSIC")->getSubVarByName("TRACKS")->_subVars;
+ if (!musicTrackVar)
+ return;
+
+ char *trackName = musicTrackVar->_varName;
+ Common::File *track = new Common::File();
+ if (!track->open(trackName)) {
+ warning("Could not open %s", trackName);
+ delete track;
+ return;
+ }
+ Audio::RewindableAudioStream *ogg = Audio::makeVorbisStream(track, DisposeAfterUse::YES);
+ g_fp->_mixer->playStream(Audio::Mixer::kMusicSoundType, &_sceneTrackHandle, ogg);
+#endif
}
void FullpipeEngine::stopAllSounds() {
- warning("STUB: FullpipeEngine::stopAllSounds()");
+ // TODO: Differences from stopAllSoundStreams()
+ g_fp->_mixer->stopAll();
}
void FullpipeEngine::toggleMute() {
@@ -128,13 +158,49 @@ void FullpipeEngine::toggleMute() {
}
void FullpipeEngine::playSound(int id, int flag) {
- warning("STUB: FullpipeEngine::playSounds(%d, %d)", id, flag);
+ SoundList *soundList = g_fp->_currentScene->_soundList;
+ Sound *sound = soundList->getSoundById(id);
+ if (!sound) {
+ warning("playSound: Can't find sound with ID %d", id);
+ return;
+ }
+ byte *soundData = sound->loadData();
+ Common::MemoryReadStream *dataStream = new Common::MemoryReadStream(soundData, sound->getDataSize());
+ Audio::RewindableAudioStream *wav = Audio::makeWAVStream(dataStream, DisposeAfterUse::YES);
+ Audio::AudioStream *audioStream = new Audio::LoopingAudioStream(wav, (flag == 1) ? 0 : 1);
+ Audio::SoundHandle handle = sound->getHandle();
+ g_fp->_mixer->playStream(Audio::Mixer::kSFXSoundType, &handle, audioStream);
+}
+
+void FullpipeEngine::playTrack(GameVar *sceneVar, const char *name, bool delayed) {
+ warning("STUB: FullpipeEngine::playTrack(var, %s, %d)", name, delayed);
}
void global_messageHandler_handleSound(ExCommand *cmd) {
debug(0, "STUB: global_messageHandler_handleSound()");
}
+void FullpipeEngine::stopSoundStream2() {
+ warning("STUB: FullpipeEngine::stopSoundStream2()");
+}
+
+void FullpipeEngine::stopAllSoundStreams() {
+ // TODO: Differences from stopAllSounds()
+ g_fp->_mixer->stopAll();
+}
+
+void FullpipeEngine::stopAllSoundInstances(int id) {
+ SoundList *soundList = g_fp->_currentScene->_soundList;
+ for (int i = 0; i < soundList->getCount(); i++) {
+ Sound *sound = soundList->getSoundByIndex(i);
+ if (sound->getId() == id) {
+ g_fp->_mixer->stopHandle(sound->getHandle());
+ }
+ }
+}
+void FullpipeEngine::updateSoundVolume() {
+ debug(3, "STUB FullpipeEngine::updateSoundVolume()");
+}
} // End of namespace Fullpipe
diff --git a/engines/fullpipe/sound.h b/engines/fullpipe/sound.h
index ea6987aae6..ca64832c04 100644
--- a/engines/fullpipe/sound.h
+++ b/engines/fullpipe/sound.h
@@ -32,11 +32,17 @@ class Sound : public MemoryObject {
int _directSoundBuffer;
int _directSoundBuffers[7];
byte *_soundData;
+ Audio::SoundHandle _handle;
- public:
+public:
Sound();
- bool load(MfcArchive &file, NGIArchive *archive);
+ virtual ~Sound();
+
+ virtual bool load(MfcArchive &file, NGIArchive *archive);
+ virtual bool load(MfcArchive &file) { assert(0); return false; } // Disable base class
void updateVolume();
+ int getId() const { return _id; }
+ Audio::SoundHandle getHandle() const { return _handle; }
void setPanAndVolumeByStaticAni();
};
@@ -48,11 +54,19 @@ class SoundList : public CObject {
public:
SoundList();
- bool load(MfcArchive &file, char *fname);
+ virtual bool load(MfcArchive &file, char *fname);
+ virtual bool load(MfcArchive &file) { assert(0); return false; } // Disable base class
bool loadFile(const char *fname, char *libname);
int getCount() { return _soundItemsCount; }
Sound *getSoundByIndex(int idx) { return _soundItems[idx]; }
+ Sound *getSoundById(int id) {
+ for (int i = 0; i < _soundItemsCount; i++) {
+ if (_soundItems[i]->getId() == id)
+ return _soundItems[i];
+ }
+ return NULL;
+ }
};
} // End of namespace Fullpipe
diff --git a/engines/fullpipe/stateloader.cpp b/engines/fullpipe/stateloader.cpp
index 747015e9a1..ccf77ff81a 100644
--- a/engines/fullpipe/stateloader.cpp
+++ b/engines/fullpipe/stateloader.cpp
@@ -31,6 +31,7 @@
#include "fullpipe/scene.h"
#include "fullpipe/statics.h"
#include "fullpipe/interaction.h"
+#include "fullpipe/gameloader.h"
#include "fullpipe/constants.h"
@@ -82,8 +83,11 @@ bool FullpipeEngine::loadGam(const char *fname, int scene) {
setMusicAllowed(_gameLoader->_gameVar->getSubVarAsInt("MUSIC_ALLOWED"));
if (scene) {
- _gameLoader->loadScene(scene);
- _gameLoader->gotoScene(scene, TrubaLeft);
+ _gameLoader->loadScene(726);
+ _gameLoader->gotoScene(726, TrubaLeft);
+
+ if (scene != 726)
+ _gameLoader->preloadScene(726, getSceneEntrance(scene));
} else {
if (_flgPlayIntro) {
_gameLoader->loadScene(SC_INTRO1);
@@ -115,25 +119,25 @@ bool GameProject::load(MfcArchive &file) {
_headerFilename = 0;
_field_10 = 12;
- g_fullpipe->_gameProjectVersion = file.readUint32LE();
- g_fullpipe->_pictureScale = file.readUint16LE();
- g_fullpipe->_scrollSpeed = file.readUint32LE();
+ g_fp->_gameProjectVersion = file.readUint32LE();
+ g_fp->_pictureScale = file.readUint16LE();
+ g_fp->_scrollSpeed = file.readUint32LE();
_headerFilename = file.readPascalString();
- debug(1, "_gameProjectVersion = %d", g_fullpipe->_gameProjectVersion);
- debug(1, "_pictureScale = %d", g_fullpipe->_pictureScale);
- debug(1, "_scrollSpeed = %d", g_fullpipe->_scrollSpeed);
+ debug(1, "_gameProjectVersion = %d", g_fp->_gameProjectVersion);
+ debug(1, "_pictureScale = %d", g_fp->_pictureScale);
+ debug(1, "_scrollSpeed = %d", g_fp->_scrollSpeed);
debug(1, "_headerFilename = %s", _headerFilename);
_sceneTagList = new SceneTagList();
_sceneTagList->load(file);
- if (g_fullpipe->_gameProjectVersion >= 3)
+ if (g_fp->_gameProjectVersion >= 3)
_field_4 = file.readUint32LE();
- if (g_fullpipe->_gameProjectVersion >= 5) {
+ if (g_fp->_gameProjectVersion >= 5) {
file.readUint32LE();
file.readUint32LE();
}
@@ -143,6 +147,8 @@ bool GameProject::load(MfcArchive &file) {
GameProject::~GameProject() {
free(_headerFilename);
+
+ delete _sceneTagList;
}
GameVar::GameVar() {
@@ -156,6 +162,10 @@ GameVar::GameVar() {
_varName = 0;
}
+GameVar::~GameVar() {
+ warning("STUB: GameVar::~GameVar()");
+}
+
bool GameVar::load(MfcArchive &file) {
_varName = file.readPascalString();
_varType = file.readUint32LE();
diff --git a/engines/fullpipe/statics.cpp b/engines/fullpipe/statics.cpp
index e33eb1139e..10d9b4dfdf 100644
--- a/engines/fullpipe/statics.cpp
+++ b/engines/fullpipe/statics.cpp
@@ -27,6 +27,7 @@
#include "fullpipe/statics.h"
#include "fullpipe/messages.h"
#include "fullpipe/interaction.h"
+#include "fullpipe/motion.h"
#include "fullpipe/constants.h"
#include "fullpipe/objectnames.h"
@@ -73,6 +74,27 @@ Common::Point *StepArray::getCurrPoint(Common::Point *point) {
return point;
}
+Common::Point *StepArray::getPoint(Common::Point *point, int index, int offset) {
+ if (index == -1)
+ index = _currPointIndex;
+
+ if (index + offset > _maxPointIndex - 1)
+ offset = _maxPointIndex - index;
+
+ point->x = 0;
+ point->y = 0;
+
+ while (offset >= 1) {
+ point->x += _points[index]->x;
+ point->y += _points[index]->y;
+
+ index++;
+ offset--;
+ }
+
+ return point;
+}
+
bool StepArray::gotoNextPoint() {
if (_currPointIndex < _maxPointIndex) {
_currPointIndex++;
@@ -105,6 +127,10 @@ StaticANIObject::StaticANIObject() {
_objtype = kObjTypeStaticANIObject;
}
+StaticANIObject::~StaticANIObject() {
+ warning("STUB: StaticANIObject::~StaticANIObject()");
+}
+
StaticANIObject::StaticANIObject(StaticANIObject *src) : GameObject(src) {
_shadowsOn = src->_shadowsOn;
_field_30 = src->_field_30;
@@ -131,15 +157,19 @@ StaticANIObject::StaticANIObject(StaticANIObject *src) : GameObject(src) {
_statics = 0;
for (uint i = 0; i < src->_movements.size(); i++) {
- Movement *mov;
- if (((Movement *)src->_movements[i])->_currMovement) {
- mov = new Movement(getMovementById(src->getMovementIdById(((Movement *)src->_movements[i])->_id)), this);
- mov->_id = ((Movement *)src->_movements[i])->_id;
+ Movement *newmov;
+ Movement *mov = (Movement *)src->_movements[i];
+
+ if (mov->_currMovement) {
+ // WORKAROUND: Original uses weird construction here:
+ // new Movement(getMovementById(src->getMovementIdById(mov->_id)), this);
+ newmov = new Movement(src->getMovementById(src->getMovementIdById(mov->_id)), this);
+ newmov->_id = mov->_id;
} else {
- mov = new Movement(((Movement *)src->_movements[i]), 0, -1, this);
+ newmov = new Movement(mov, 0, -1, this);
}
- _movements.push_back(mov);
+ _movements.push_back(newmov);
}
}
@@ -165,7 +195,7 @@ bool StaticANIObject::load(MfcArchive &file) {
char *movname = genFileName(_id, movNum, "mov");
- Common::SeekableReadStream *f = g_fullpipe->_currArchive->createReadStreamForMember(movname);
+ Common::SeekableReadStream *f = g_fp->_currArchive->createReadStreamForMember(movname);
Movement *mov = new Movement();
@@ -223,11 +253,11 @@ void StaticANIObject::setFlags40(bool state) {
void StaticANIObject::deleteFromGlobalMessageQueue() {
while (_messageQueueId) {
- if (g_fullpipe->_globalMessageQueueList->getMessageQueueById(_messageQueueId)) {
+ if (g_fp->_globalMessageQueueList->getMessageQueueById(_messageQueueId)) {
if (!isIdle())
return;
- g_fullpipe->_globalMessageQueueList->deleteQueueById(_messageQueueId);
+ g_fp->_globalMessageQueueList->deleteQueueById(_messageQueueId);
} else {
_messageQueueId = 0;
}
@@ -255,11 +285,34 @@ void StaticANIObject::queueMessageQueue(MessageQueue *mq) {
}
}
+void StaticANIObject::restartMessageQueue(MessageQueue *mq) {
+ ExCommand *ex = mq->getExCommandByIndex(0);
+ if (ex) {
+ while (ex->_messageKind != 1 || ex->_parentId != _id) {
+ ex->_parId = 0;
+ ex->_excFlags |= 2;
+ ex->handleMessage();
+
+ mq->deleteExCommandByIndex(0, 0);
+
+ ex = mq->getExCommandByIndex(0);
+
+ if (!ex)
+ return;
+ }
+
+ if (ex) {
+ startAnim(ex->_messageNum, mq->_id, -1);
+ mq->deleteExCommandByIndex(0, 1);
+ }
+ }
+}
+
MessageQueue *StaticANIObject::getMessageQueue() {
if (this->_messageQueueId <= 0)
return 0;
- return g_fullpipe->_globalMessageQueueList->getMessageQueueById(_messageQueueId);
+ return g_fp->_globalMessageQueueList->getMessageQueueById(_messageQueueId);
}
bool StaticANIObject::trySetMessageQueue(int msgNum, int qId) {
@@ -276,9 +329,13 @@ bool StaticANIObject::trySetMessageQueue(int msgNum, int qId) {
return true;
}
+void StaticANIObject::startMQIfIdle(int qId, int flag) {
+ warning("STUB: StaticANIObject::startMQIfIdle()");
+}
+
bool StaticANIObject::isIdle() {
if (_messageQueueId) {
- MessageQueue *m = g_fullpipe->_globalMessageQueueList->getMessageQueueById(_messageQueueId);
+ MessageQueue *m = g_fp->_globalMessageQueueList->getMessageQueueById(_messageQueueId);
if (m && m->getFlags() & 1)
return false;
@@ -403,7 +460,7 @@ void Movement::draw(bool flipFlag, int angle) {
int y = _oy - point.y;
if (_currDynamicPhase->getPaletteData())
- g_fullpipe->_globalPalette = _currDynamicPhase->getPaletteData();
+ g_fp->_globalPalette = _currDynamicPhase->getPaletteData();
if (_currDynamicPhase->getAlpha() < 0xFF) {
warning("Movement::draw: alpha < 0xff: %d", _currDynamicPhase->getAlpha());
@@ -471,9 +528,9 @@ void StaticANIObject::draw() {
Common::Point point;
Common::Rect rect;
- debug(0, "StaticANIObject::draw() (%s) [%d] [%d, %d]", transCyrillic((byte *)_objectName), _id, _ox, _oy);
+ debug(6, "StaticANIObject::draw() (%s) [%d] [%d, %d]", transCyrillic((byte *)_objectName), _id, _ox, _oy);
- if (_shadowsOn && g_fullpipe->_currentScene && g_fullpipe->_currentScene->_shadows
+ if (_shadowsOn && g_fp->_currentScene && g_fp->_currentScene->_shadows
&& (getCurrDimensions(point)->x != 1 || getCurrDimensions(point)->y != 1)) {
DynamicPhase *dyn;
@@ -491,7 +548,7 @@ void StaticANIObject::draw() {
if (dyn->getDynFlags() & 4) {
rect = *dyn->_rect;
- DynamicPhase *shd = g_fullpipe->_currentScene->_shadows->findSize(rect.width(), rect.height());
+ DynamicPhase *shd = g_fp->_currentScene->_shadows->findSize(rect.width(), rect.height());
if (shd) {
shd->getDimensions(&point);
int midx = _ox - point.x / 2 - dyn->_someX;
@@ -531,7 +588,7 @@ void StaticANIObject::draw() {
}
void StaticANIObject::draw2() {
- debug(0, "StatciANIObject::draw2(): id: (%s) %d [%d, %d]", transCyrillic((byte *)_objectName), _id, _ox, _oy);
+ debug(6, "StatciANIObject::draw2(): id: (%s) %d [%d, %d]", transCyrillic((byte *)_objectName), _id, _ox, _oy);
if ((_flags & 4) && (_flags & 0x10)) {
if (_movement) {
@@ -547,7 +604,7 @@ void StaticANIObject::draw2() {
}
MovTable *StaticANIObject::countMovements() {
- GameVar *preloadSubVar = g_fullpipe->getGameLoaderGameVar()->getSubVarByName(getName())->getSubVarByName("PRELOAD");
+ GameVar *preloadSubVar = g_fp->getGameLoaderGameVar()->getSubVarByName(getName())->getSubVarByName("PRELOAD");
if (!preloadSubVar || preloadSubVar->getSubVarsCount() == 0)
return 0;
@@ -573,7 +630,7 @@ MovTable *StaticANIObject::countMovements() {
}
void StaticANIObject::setSpeed(int speed) {
- GameVar *var = g_fullpipe->getGameLoaderGameVar()->getSubVarByName(getName())->getSubVarByName("SpeedUp");
+ GameVar *var = g_fp->getGameLoaderGameVar()->getSubVarByName(getName())->getSubVarByName("SpeedUp");
if (!var)
return;
@@ -606,6 +663,19 @@ void StaticANIObject::initMovements() {
((Movement *)_movements[i])->removeFirstPhase();
}
+void StaticANIObject::preloadMovements(MovTable *mt) {
+ if ( mt ) {
+ for (uint i = 0; i < _movements.size(); i++) {
+ Movement *mov = (Movement *)_movements[i];
+
+ if (mt->movs[i] == 1)
+ mov->loadPixelData();
+ else if (mt->movs[i] == 2)
+ mov->freePixelData();
+ }
+ }
+}
+
Common::Point *StaticANIObject::getCurrDimensions(Common::Point &p) {
Picture *pic;
@@ -628,6 +698,19 @@ Common::Point *StaticANIObject::getCurrDimensions(Common::Point &p) {
return &p;
}
+Common::Point *StaticANIObject::getSomeXY(Common::Point &p) {
+ if (_movement) {
+ _movement->getCurrDynamicPhaseXY(p);
+
+ return &p;
+ }
+
+ if (_statics)
+ _statics->getSomeXY(p);
+
+ return &p;
+}
+
void StaticANIObject::update(int counterdiff) {
int mqid;
@@ -669,7 +752,7 @@ void StaticANIObject::update(int counterdiff) {
ex = dyn->getExCommand();
if (ex && ex->_messageKind != 35) {
- newex = new ExCommand(ex);
+ newex = ex->createClone();
newex->_excFlags |= 2;
if (newex->_messageKind == 17) {
newex->_parentId = _id;
@@ -702,7 +785,7 @@ void StaticANIObject::update(int counterdiff) {
ex = dyn->getExCommand();
if (ex) {
if (ex->_messageKind == 35) {
- newex = new ExCommand(ex);
+ newex = ex->createClone();
newex->_excFlags |= 2;
newex->sendMessage();
}
@@ -744,6 +827,64 @@ void StaticANIObject::update(int counterdiff) {
}
}
+void StaticANIObject::updateStepPos() {
+ Common::Point point;
+
+ int ox = _movement->_ox;
+ int oy = _movement->_oy;
+
+ _movement->calcSomeXY(point, 1);
+ int x = point.x;
+ int y = point.y;
+
+ _stepArray.getPoint(&point, -1, _stepArray.getPointsCount());
+ x += point.x;
+ y += point.y;
+
+ _statics = _movement->_staticsObj2;
+ _movement = 0;
+
+ setOXY(ox + x, oy + y);
+}
+
+Common::Point *StaticANIObject::calcNextStep(Common::Point *pRes) {
+ if (!_movement) {
+ pRes->x = 0;
+ pRes->y = 0;
+
+ return pRes;
+ }
+
+ Common::Point point;
+
+ _movement->calcSomeXY(point, 1);
+
+ int resX = point.x;
+ int resY = point.y;
+
+ int pointN, offset;
+
+ if (_someDynamicPhaseIndex <= 0) {
+ pointN = _stepArray.getCurrPointIndex();
+ offset = _stepArray.getPointsCount() - _stepArray.getCurrPointIndex();
+ } else {
+ pointN = _stepArray.getCurrPointIndex();
+ offset = 1 - _movement->_currDynamicPhaseIndex + _someDynamicPhaseIndex;
+ }
+
+ if (pointN >= 0) {
+ _stepArray.getPoint(&point, pointN, offset);
+
+ resX += point.x;
+ resY += point.y;
+ }
+
+ pRes->x = resX;
+ pRes->y = resY;
+
+ return pRes;
+}
+
void StaticANIObject::stopAnim_maybe() {
debug(6, "StaticANIObject::stopAnim_maybe()");
@@ -812,7 +953,24 @@ void StaticANIObject::stopAnim_maybe() {
}
void StaticANIObject::adjustSomeXY() {
- warning("STUB: StaticANIObject::adjustSomeXY()");
+ if (_movement) {
+ Common::Point point;
+
+ _movement->calcSomeXY(point, 0);
+
+ int diff = abs(point.y) - abs(point.x);
+
+ _movement->calcSomeXY(point, 1);
+
+ if (diff > 0)
+ _ox += point.x;
+ else
+ _oy += point.y;
+
+ _statics = _movement->_staticsObj2;
+ _movement = 0;
+ _someDynamicPhaseIndex = -1;
+ }
}
MessageQueue *StaticANIObject::changeStatics1(int msgNum) {
@@ -822,7 +980,23 @@ MessageQueue *StaticANIObject::changeStatics1(int msgNum) {
}
void StaticANIObject::changeStatics2(int objId) {
- warning("STUB: StaticANIObject::changeStatics2(%d)", objId);
+ _animExFlag = 0;
+
+ deleteFromGlobalMessageQueue();
+
+ if (_movement || _statics) {
+ g_fp->_mgm->addItem(_id);
+ g_fp->_mgm->updateAnimStatics(this, objId);
+ } else {
+ _statics = getStaticsById(objId);
+ }
+
+ if (_messageQueueId) {
+ if (g_fp->_globalMessageQueueList->getMessageQueueById(_messageQueueId))
+ g_fp->_globalMessageQueueList->deleteQueueById(_messageQueueId);
+
+ _messageQueueId = 0;
+ }
}
void StaticANIObject::hide() {
@@ -833,7 +1007,7 @@ void StaticANIObject::hide() {
}
void StaticANIObject::show1(int x, int y, int movId, int mqId) {
- debug(0, "StaticANIObject::show1(%d, %d, %d, %d)", x, y, movId, mqId);
+ debug(6, "StaticANIObject::show1(%d, %d, %d, %d)", x, y, movId, mqId);
if (_messageQueueId)
return;
@@ -940,20 +1114,17 @@ bool StaticANIObject::startAnim(int movementId, int messageQueueId, int dynPhase
int newy = _oy;
Common::Point point;
- debug(0, "0 %d %d", newx, newy);
if (_movement) {
_movement->getCurrDynamicPhaseXY(point);
newx -= point.x;
newy -= point.y;
- debug(0, "1 %d %d", newx, newy);
} else if (_statics) {
_statics->getSomeXY(point);
newx -= point.x;
newy -= point.y;
- debug(0, "2 %d %d - %d %d assa", newx, newy, point.x, point.y);
}
_movement = mov;
@@ -971,13 +1142,12 @@ bool StaticANIObject::startAnim(int movementId, int messageQueueId, int dynPhase
newx += point.x + _movement->_mx;
newy += point.y + _movement->_my;
- debug(0, "3 %d %d", newx, newy);
_stepArray.gotoNextPoint();
ExCommand *ex = _movement->_currDynamicPhase->getExCommand();
if (ex) {
if (ex->_messageKind == 35) {
- ExCommand *newex = new ExCommand(ex);
+ ExCommand *newex = ex->createClone();
newex->_excFlags |= 2;
newex->sendMessage();
}
@@ -1108,8 +1278,12 @@ Movement::Movement() {
_counter = 0;
_counterMax = 83;
- _field_24 = 0;
- _field_28 = 0;
+ _somePoint.x = 0;
+ _somePoint.y = 0;
+}
+
+Movement::~Movement() {
+ warning("STUB: Movement::~Movement()");
}
Movement::Movement(Movement *src, StaticANIObject *ani) {
@@ -1131,8 +1305,8 @@ Movement::Movement(Movement *src, StaticANIObject *ani) {
_currDynamicPhaseIndex = src->_currDynamicPhaseIndex;
_field_94 = 0;
- _field_24 = 0;
- _field_28 = 0;
+ _somePoint.x = 0;
+ _somePoint.y = 0;
_currMovement = src;
_ox = src->_ox;
@@ -1147,8 +1321,89 @@ Movement::Movement(Movement *src, StaticANIObject *ani) {
updateCurrDynamicPhase();
}
-Movement::Movement(Movement *src, int *flag1, int flag2, StaticANIObject *ani) {
- warning("STUB: Movement(src, %p, %d, ani)", (void *)flag1, flag2);
+Movement::Movement(Movement *src, int *oldIdxs, int newSize, StaticANIObject *ani) : GameObject(src) {
+ _lastFrameSpecialFlag = 0;
+ _updateFlag1 = 1;
+ _staticsObj1 = 0;
+ _staticsObj2 = 0;
+ _mx = 0;
+ _my = 0;
+ _m2x = 0;
+ _m2y = 0;
+
+ _field_78 = 0;
+ _framePosOffsets = 0;
+ _field_84 = 0;
+ _currDynamicPhase = 0;
+ _field_8C = 0;
+ _currDynamicPhaseIndex = 0;
+ _field_94 = 0;
+
+ _somePoint.x = 0;
+ _somePoint.y = 0;
+
+ _field_50 = src->_field_50;
+ _flipFlag = src->_flipFlag;
+ _currMovement = 0;
+ _mx = src->_mx;
+ _my = src->_my;
+ _m2x = src->_m2x;
+ _m2y = src->_m2y;
+
+ if (newSize != -1) {
+ if (newSize >= (int)src->_dynamicPhases.size() + 1)
+ newSize = src->_dynamicPhases.size() + 1;
+ } else {
+ newSize = src->_dynamicPhases.size();
+ }
+
+ _framePosOffsets = (Common::Point **)calloc(newSize, sizeof(Common::Point *));
+
+ for (int i = 0; i < newSize; i++)
+ _framePosOffsets[i] = new Common::Point();
+
+ if (oldIdxs) {
+ for (int i = 0; i < newSize - 1; i++, oldIdxs++) {
+ if (oldIdxs[i] == -1) {
+ _dynamicPhases.push_back(src->_staticsObj1);
+
+ _framePosOffsets[i]->x = 0;
+ _framePosOffsets[i]->y = 0;
+ } else {
+ src->setDynamicPhaseIndex(oldIdxs[i]);
+
+ _dynamicPhases.push_back(src->_currDynamicPhase);
+
+ _framePosOffsets[i]->x = src->_framePosOffsets[oldIdxs[i]]->x;
+ _framePosOffsets[i]->y = src->_framePosOffsets[oldIdxs[i]]->y;
+ }
+ }
+ _staticsObj1 = (Statics *)_dynamicPhases.front();
+ _staticsObj2 = (Statics *)_dynamicPhases.back();
+ } else {
+ for (int i = 0; i < newSize; i++) {
+ src->setDynamicPhaseIndex(i);
+
+ if (i < newSize - 1)
+ _dynamicPhases.push_back(new DynamicPhase(src->_currDynamicPhase, 0));
+
+ _framePosOffsets[i]->x = src->_framePosOffsets[i]->x;
+ _framePosOffsets[i]->y = src->_framePosOffsets[i]->y;
+ }
+
+ _staticsObj1 = ani->getStaticsById(src->_staticsObj1->_staticsId);
+ _staticsObj2 = ani->getStaticsById(src->_staticsObj2->_staticsId);
+
+ _dynamicPhases.push_back(_staticsObj2);
+
+ this->_updateFlag1 = src->_updateFlag1;
+ }
+
+ updateCurrDynamicPhase();
+ removeFirstPhase();
+
+ _counterMax = src->_counterMax;
+ _counter = src->_counter;
}
bool Movement::load(MfcArchive &file) {
@@ -1224,10 +1479,10 @@ bool Movement::load(MfcArchive &file, StaticANIObject *ani) {
_flipFlag = 1;
}
- if (g_fullpipe->_gameProjectVersion >= 8)
+ if (g_fp->_gameProjectVersion >= 8)
_field_50 = file.readUint32LE();
- if (g_fullpipe->_gameProjectVersion < 12)
+ if (g_fp->_gameProjectVersion < 12)
_counterMax = 83;
else
_counterMax = file.readUint32LE();
@@ -1245,6 +1500,41 @@ Common::Point *Movement::getCurrDynamicPhaseXY(Common::Point &p) {
return &p;
}
+Common::Point *Movement::calcSomeXY(Common::Point &p, int idx) {
+ int oldox = _ox;
+ int oldoy = _oy;
+ int oldidx = _currDynamicPhaseIndex;
+
+ int x = 0;
+ int y = 0;
+
+ if (!idx) {
+ Common::Point point;
+
+ _staticsObj1->getSomeXY(point);
+ int y1 = _my - point.y;
+ int x1 = _mx - point.x;
+
+ setDynamicPhaseIndex(0);
+
+ x = _currDynamicPhase->_someX + x1;
+ y = _currDynamicPhase->_someY + y1;
+ }
+
+ setOXY(x, y);
+
+ while (_currDynamicPhaseIndex != idx)
+ gotoNextFrame(0, 0);
+
+ p.x = _ox;
+ p.y = _oy;
+
+ setDynamicPhaseIndex(oldidx);
+ setOXY(oldox, oldoy);
+
+ return &p;
+}
+
void Movement::setAlpha(int alpha) {
if (_currMovement)
for (uint i = 0; i < _currMovement->_dynamicPhases.size(); i++) {
@@ -1341,6 +1631,25 @@ int Movement::calcDuration() {
return res;
}
+int Movement::countPhasesWithFlag(int maxidx, int flag) {
+ int res = 0;
+ int sz;
+
+ if (_currMovement)
+ sz = _currMovement->_dynamicPhases.size();
+ else
+ sz = _dynamicPhases.size();
+
+ if (maxidx < 0)
+ maxidx = sz;
+
+ for (int i = 0; i < maxidx && i < sz; i++)
+ if (getDynamicPhaseByIndex(i)->_dynFlags & flag)
+ res++;
+
+ return res;
+}
+
void Movement::setDynamicPhaseIndex(int index) {
debug(7, "Movement::setDynamicPhaseIndex(%d)", index);
while (_currDynamicPhaseIndex < index)
@@ -1380,6 +1689,15 @@ void Movement::loadPixelData() {
mov->_staticsObj1->getPixelData();
}
+void Movement::freePixelData() {
+ if (!_currMovement)
+ for (uint i = 0; i < _dynamicPhases.size(); i++)
+ ((DynamicPhase *)_dynamicPhases[i])->freePixelData();
+
+ if (_staticsObj1)
+ _staticsObj1->freePixelData();
+}
+
void Movement::removeFirstPhase() {
if (_updateFlag1) {
if (!_currDynamicPhaseIndex)
@@ -1400,7 +1718,7 @@ void Movement::removeFirstPhase() {
_updateFlag1 = 0;
}
-bool Movement::gotoNextFrame(int callback1, void (*callback2)(int *)) {
+bool Movement::gotoNextFrame(void (*callback1)(int, Common::Point *point, int, int), void (*callback2)(int *)) {
debug(8, "Movement::gotoNextFrame()");
if (!callback2) {
@@ -1452,7 +1770,7 @@ bool Movement::gotoNextFrame(int callback1, void (*callback2)(int *)) {
if (_currMovement->_framePosOffsets) {
if (callback1) {
point = *_currMovement->_framePosOffsets[_currDynamicPhaseIndex];
- //callback1(_currDynamicPhaseIndex, &point, _ox, _oy);
+ callback1(_currDynamicPhaseIndex, &point, _ox, _oy);
_ox += deltax - point.x;
_oy += point.y;
@@ -1494,7 +1812,7 @@ bool Movement::gotoNextFrame(int callback1, void (*callback2)(int *)) {
point.x = _framePosOffsets[_currDynamicPhaseIndex]->x;
point.y = _framePosOffsets[_currDynamicPhaseIndex]->y;
- //callback1(_currDynamicPhaseIndex, &point, _ox, _oy);
+ callback1(_currDynamicPhaseIndex, &point, _ox, _oy);
_ox += point.x;
_oy += point.y;
} else if (oldDynIndex >= _currDynamicPhaseIndex) {
@@ -1620,7 +1938,7 @@ DynamicPhase::DynamicPhase(DynamicPhase *src, bool reverse) {
_field_7E = 0;
_rect = new Common::Rect();
- debug(0, "DynamicPhase::DynamicPhase(src, %d)", reverse);
+ debug(1, "DynamicPhase::DynamicPhase(src, %d)", reverse);
if (reverse) {
if (!src->_bitmap)
@@ -1630,9 +1948,9 @@ DynamicPhase::DynamicPhase(DynamicPhase *src, bool reverse) {
_data = _bitmap->_pixels;
_dataSize = src->_dataSize;
- if (g_fullpipe->_currArchive) {
+ if (g_fp->_currArchive) {
_mfield_14 = 0;
- _libHandle = g_fullpipe->_currArchive;
+ _libHandle = g_fp->_currArchive;
}
_mflags |= 1;
@@ -1665,7 +1983,7 @@ DynamicPhase::DynamicPhase(DynamicPhase *src, bool reverse) {
_field_7C = src->_field_7C;
if (src->getExCommand())
- _exCommand = new ExCommand(src->getExCommand());
+ _exCommand = src->getExCommand()->createClone();
else
_exCommand = 0;
@@ -1690,12 +2008,12 @@ bool DynamicPhase::load(MfcArchive &file) {
_rect->right = file.readUint32LE();
_rect->bottom = file.readUint32LE();
- assert (g_fullpipe->_gameProjectVersion >= 1);
+ assert (g_fp->_gameProjectVersion >= 1);
_someX = file.readUint32LE();
_someY = file.readUint32LE();
- assert (g_fullpipe->_gameProjectVersion >= 12);
+ assert (g_fp->_gameProjectVersion >= 12);
_dynFlags = file.readUint32LE();
@@ -1722,13 +2040,15 @@ bool StaticPhase::load(MfcArchive &file) {
_initialCountdown = file.readUint16LE();
_field_6A = file.readUint16LE();
- if (g_fullpipe->_gameProjectVersion >= 12) {
+ if (g_fp->_gameProjectVersion >= 12) {
_exCommand = (ExCommand *)file.readClass();
return true;
}
- assert (g_fullpipe->_gameProjectVersion >= 12);
+ assert (g_fp->_gameProjectVersion >= 12);
+
+ warning("StaticPhase::load(): Code continues here");
return true;
}
diff --git a/engines/fullpipe/statics.h b/engines/fullpipe/statics.h
index 1767a5720e..a620daa528 100644
--- a/engines/fullpipe/statics.h
+++ b/engines/fullpipe/statics.h
@@ -42,7 +42,10 @@ class StepArray : public CObject {
void clear();
int getCurrPointIndex() { return _currPointIndex; }
+ int getPointsCount() { return _maxPointIndex; }
+
Common::Point *getCurrPoint(Common::Point *point);
+ Common::Point *getPoint(Common::Point *point, int index, int offset);
bool gotoNextPoint();
};
@@ -104,8 +107,7 @@ class StaticANIObject;
class Movement : public GameObject {
public:
- int _field_24;
- int _field_28;
+ Common::Point _somePoint;
int _lastFrameSpecialFlag;
int _flipFlag;
int _updateFlag1;
@@ -130,6 +132,8 @@ class Movement : public GameObject {
public:
Movement();
+ virtual ~Movement();
+
Movement(Movement *src, StaticANIObject *ani);
Movement(Movement *src, int *flag1, int flag2, StaticANIObject *ani);
@@ -140,6 +144,8 @@ class Movement : public GameObject {
Common::Point *getCenter(Common::Point *p);
Common::Point *getDimensionsOfPhase(Common::Point *p, int phaseIndex);
+ Common::Point *calcSomeXY(Common::Point &p, int idx);
+
void initStatics(StaticANIObject *ani);
void updateCurrDynamicPhase();
@@ -149,14 +155,16 @@ class Movement : public GameObject {
DynamicPhase *getDynamicPhaseByIndex(int idx);
int calcDuration();
+ int countPhasesWithFlag(int maxidx, int flag);
void removeFirstPhase();
- bool gotoNextFrame(int callback1, void (*callback2)(int *));
+ bool gotoNextFrame(void (*_callback1)(int, Common::Point *point, int, int), void (*callback2)(int *));
bool gotoPrevFrame();
void gotoFirstFrame();
void gotoLastFrame();
void loadPixelData();
+ void freePixelData();
void draw(bool flipFlag, int angle);
};
@@ -170,7 +178,7 @@ class StaticANIObject : public GameObject {
int16 _field_32;
int _field_34;
int _initialCounter;
- int _callback1;
+ void (*_callback1)(int, Common::Point *point, int, int);
void (*_callback2)(int *);
PtrList _movements;
PtrList _staticsList;
@@ -182,11 +190,12 @@ class StaticANIObject : public GameObject {
int _counter;
int _someDynamicPhaseIndex;
- public:
+public:
int16 _sceneId;
- public:
+public:
StaticANIObject();
+ virtual ~StaticANIObject();
StaticANIObject(StaticANIObject *src);
virtual bool load(MfcArchive &file);
@@ -199,6 +208,8 @@ class StaticANIObject : public GameObject {
Movement *getMovementByName(char *name);
Common::Point *getCurrDimensions(Common::Point &p);
+ Common::Point *getSomeXY(Common::Point &p);
+
void clearFlags();
void setFlags40(bool state);
bool isIdle();
@@ -206,11 +217,14 @@ class StaticANIObject : public GameObject {
void deleteFromGlobalMessageQueue();
void queueMessageQueue(MessageQueue *msg);
+ void restartMessageQueue(MessageQueue *msg);
MessageQueue *getMessageQueue();
bool trySetMessageQueue(int msgNum, int qId);
+ void startMQIfIdle(int qId, int flag);
void initMovements();
void loadMovementsPixelData();
+ void preloadMovements(MovTable *mt);
void setSomeDynamicPhaseIndex(int val) { _someDynamicPhaseIndex = val; }
void adjustSomeXY();
@@ -232,7 +246,9 @@ class StaticANIObject : public GameObject {
MovTable *countMovements();
void setSpeed(int speed);
+ void updateStepPos();
void stopAnim_maybe();
+ Common::Point *calcNextStep(Common::Point *point);
MessageQueue *changeStatics1(int msgNum);
void changeStatics2(int objId);
@@ -243,6 +259,9 @@ class StaticANIObject : public GameObject {
struct MovTable {
int count;
int16 *movs;
+
+ MovTable() { count = 0; movs = 0; }
+ ~MovTable() { free(movs); }
};
} // End of namespace Fullpipe
diff --git a/engines/fullpipe/utils.cpp b/engines/fullpipe/utils.cpp
index 3304a93667..b3668ea362 100644
--- a/engines/fullpipe/utils.cpp
+++ b/engines/fullpipe/utils.cpp
@@ -138,9 +138,9 @@ bool MemoryObject::load(MfcArchive &file) {
}
}
- if (g_fullpipe->_currArchive) {
+ if (g_fp->_currArchive) {
_mfield_14 = 0;
- _libHandle = g_fullpipe->_currArchive;
+ _libHandle = g_fp->_currArchive;
}
return true;
@@ -148,8 +148,17 @@ bool MemoryObject::load(MfcArchive &file) {
void MemoryObject::loadFile(char *filename) {
debug(5, "MemoryObject::loadFile(<%s>)", filename);
+
+ if (!*filename)
+ return;
+
if (!_data) {
- Common::SeekableReadStream *s = g_fullpipe->_currArchive->createReadStreamForMember(filename);
+ NGIArchive *arr = g_fp->_currArchive;
+
+ if (g_fp->_currArchive != _libHandle && _libHandle)
+ g_fp->_currArchive = _libHandle;
+
+ Common::SeekableReadStream *s = g_fp->_currArchive->createReadStreamForMember(filename);
if (s) {
assert(s->size() > 0);
@@ -161,7 +170,11 @@ void MemoryObject::loadFile(char *filename) {
s->read(_data, _dataSize);
delete s;
+ } else {
+ warning("MemoryObject::loadFile(): reading failure");
}
+
+ g_fp->_currArchive = arr;
}
}
@@ -181,6 +194,8 @@ byte *MemoryObject::loadData() {
}
void MemoryObject::freeData() {
+ debug(8, "MemoryObject::freeData(): file: %s", _memfilename);
+
if (_data)
free(_data);
diff --git a/engines/fullpipe/utils.h b/engines/fullpipe/utils.h
index e593bd9f18..5714fd3b4c 100644
--- a/engines/fullpipe/utils.h
+++ b/engines/fullpipe/utils.h
@@ -66,15 +66,19 @@ class MfcArchive : public Common::SeekableReadStream {
enum ObjType {
kObjTypeDefault,
+ kObjTypeExCommand,
+ kObjTypeExCommand2,
+ kObjTypeMovGraph,
+ kObjTypeMovGraphLink,
+ kObjTypeMovGraphNode,
+ kObjTypeMctlCompound,
kObjTypeObjstateCommand,
- kObjTypeStaticANIObject,
kObjTypePictureObject,
- kObjTypeMovGraph,
- kObjTypeMctlCompound
+ kObjTypeStaticANIObject
};
class CObject {
- public:
+public:
ObjType _objtype;
CObject() : _objtype(kObjTypeDefault) {}
@@ -113,6 +117,7 @@ class MemoryObject : CObject {
void load() { loadFile(_memfilename); }
byte *getData();
byte *loadData();
+ int getDataSize() const { return _dataSize; }
bool testFlags();
diff --git a/engines/gob/configure.engine b/engines/gob/configure.engine
new file mode 100644
index 0000000000..8e012f5815
--- /dev/null
+++ b/engines/gob/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 gob "Gobli*ns" yes
diff --git a/engines/groovie/configure.engine b/engines/groovie/configure.engine
new file mode 100644
index 0000000000..84e95a70df
--- /dev/null
+++ b/engines/groovie/configure.engine
@@ -0,0 +1,4 @@
+# This file is included from the main "configure" script
+# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps]
+add_engine groovie "Groovie" yes "groovie2" "7th Guest"
+add_engine groovie2 "Groovie 2 games" no "" "" "jpeg"
diff --git a/engines/groovie/font.cpp b/engines/groovie/font.cpp
index d29c22dd02..a55d8fad95 100644
--- a/engines/groovie/font.cpp
+++ b/engines/groovie/font.cpp
@@ -112,7 +112,7 @@ bool T7GFont::load(Common::SeekableReadStream &stream) {
return true;
}
-void T7GFont::drawChar(Graphics::Surface *dst, byte chr, int x, int y, uint32 color) const {
+void T7GFont::drawChar(Graphics::Surface *dst, uint32 chr, int x, int y, uint32 color) const {
// We ignore the color, as the font is already colored
const Glyph *glyph = getGlyph(chr);
const byte *src = glyph->pixels;
@@ -125,7 +125,7 @@ void T7GFont::drawChar(Graphics::Surface *dst, byte chr, int x, int y, uint32 co
}
}
-const T7GFont::Glyph *T7GFont::getGlyph(byte chr) const {
+const T7GFont::Glyph *T7GFont::getGlyph(uint32 chr) const {
assert (chr < 128);
byte numGlyph = _mapChar2Glyph[chr];
diff --git a/engines/groovie/font.h b/engines/groovie/font.h
index 20aaa4cf23..49cf4b7b06 100644
--- a/engines/groovie/font.h
+++ b/engines/groovie/font.h
@@ -37,8 +37,8 @@ public:
int getFontHeight() const { return _maxHeight; }
int getMaxCharWidth() const { return _maxWidth; }
- int getCharWidth(byte chr) const { return getGlyph(chr)->width; }
- void drawChar(Graphics::Surface *dst, byte chr, int x, int y, uint32 color) const;
+ int getCharWidth(uint32 chr) const { return getGlyph(chr)->width; }
+ void drawChar(Graphics::Surface *dst, uint32 chr, int x, int y, uint32 color) const;
private:
int _maxHeight, _maxWidth;
@@ -55,7 +55,7 @@ private:
byte _mapChar2Glyph[128];
Glyph *_glyphs;
- const Glyph *getGlyph(byte chr) const;
+ const Glyph *getGlyph(uint32 chr) const;
};
} // End of Groovie namespace
diff --git a/engines/hopkins/computer.cpp b/engines/hopkins/computer.cpp
index c09d748b97..f9e3ecafcd 100644
--- a/engines/hopkins/computer.cpp
+++ b/engines/hopkins/computer.cpp
@@ -349,15 +349,21 @@ void ComputerManager::loadMenu() {
char *ptr;
if (_vm->_fileIO->fileExists("COMPUTAN.TXT")) {
ptr = (char *)_vm->_fileIO->loadFile("COMPUTAN.TXT");
- } else if (_vm->_globals->_language == LANG_FR) {
- ptr = (char *)_vm->_globals->allocMemory(sizeof(_frenchText));
- strcpy(ptr, _frenchText);
- } else if (_vm->_globals->_language == LANG_SP) {
- ptr = (char *)_vm->_globals->allocMemory(sizeof(_spanishText));
- strcpy(ptr, _spanishText);
} else {
- ptr = (char *)_vm->_globals->allocMemory(sizeof(_englishText));
- strcpy(ptr, _englishText);
+ switch (_vm->_globals->_language) {
+ case LANG_FR:
+ ptr = (char *)_vm->_globals->allocMemory(sizeof(_frenchText));
+ strcpy(ptr, _frenchText);
+ break;
+ case LANG_SP:
+ ptr = (char *)_vm->_globals->allocMemory(sizeof(_spanishText));
+ strcpy(ptr, _spanishText);
+ break;
+ default:
+ ptr = (char *)_vm->_globals->allocMemory(sizeof(_englishText));
+ strcpy(ptr, _englishText);
+ break;
+ }
}
char *tmpPtr = ptr;
@@ -479,12 +485,17 @@ void ComputerManager::readText(int idx) {
_vm->_events->_escKeyFl = false;
Common::String filename;
- if (_vm->_globals->_language == LANG_EN)
+ switch (_vm->_globals->_language) {
+ case LANG_EN:
filename = "THOPKAN.TXT";
- else if (_vm->_globals->_language == LANG_FR)
+ break;
+ case LANG_FR:
filename = "THOPK.TXT";
- else if (_vm->_globals->_language == LANG_SP)
+ break;
+ case LANG_SP:
filename = "THOPKES.TXT";
+ break;
+ }
byte *ptr = _vm->_fileIO->loadFile(filename);
uint16 fileSize = _vm->_fileIO->fileSize(filename);
diff --git a/engines/hopkins/configure.engine b/engines/hopkins/configure.engine
new file mode 100644
index 0000000000..c38ecd4cd2
--- /dev/null
+++ b/engines/hopkins/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 hopkins "Hopkins FBI" yes "" "" "16bit"
diff --git a/engines/hopkins/dialogs.cpp b/engines/hopkins/dialogs.cpp
index 3b8fedf0ee..8c944167ae 100644
--- a/engines/hopkins/dialogs.cpp
+++ b/engines/hopkins/dialogs.cpp
@@ -84,12 +84,17 @@ void DialogsManager::showOptionsDialog() {
if (_vm->getPlatform() == Common::kPlatformOS2 || _vm->getPlatform() == Common::kPlatformBeOS)
filename = "OPTION.SPR";
else {
- if (_vm->_globals->_language == LANG_FR)
+ switch (_vm->_globals->_language) {
+ case LANG_FR:
filename = "OPTIFR.SPR";
- else if (_vm->_globals->_language == LANG_EN)
+ break;
+ case LANG_EN:
filename = "OPTIAN.SPR";
- else if (_vm->_globals->_language == LANG_SP)
+ break;
+ case LANG_SP:
filename = "OPTIES.SPR";
+ break;
+ }
}
_vm->_globals->_optionDialogSpr = _vm->_fileIO->loadFile(filename);
diff --git a/engines/hopkins/events.cpp b/engines/hopkins/events.cpp
index 51c66c4f92..d0c1dcea4d 100644
--- a/engines/hopkins/events.cpp
+++ b/engines/hopkins/events.cpp
@@ -271,7 +271,7 @@ void EventsManager::pollEvents() {
_mouseButton = 0;
return;
default:
- break;
+ break;
}
}
diff --git a/engines/hopkins/globals.cpp b/engines/hopkins/globals.cpp
index a9a0a81f08..cd66a84b73 100644
--- a/engines/hopkins/globals.cpp
+++ b/engines/hopkins/globals.cpp
@@ -148,7 +148,7 @@ void Globals::setConfig() {
_language = LANG_SP;
break;
default:
- warning("Unknown language in internal language mapping");
+ error("Hopkins - SetConfig(): Unknown language in internal language mapping");
break;
}
// End of CHECKME
diff --git a/engines/hopkins/graphics.cpp b/engines/hopkins/graphics.cpp
index de9f043763..a64e81fcc9 100644
--- a/engines/hopkins/graphics.cpp
+++ b/engines/hopkins/graphics.cpp
@@ -1359,7 +1359,7 @@ void GraphicsManager::drawCompressedSprite(byte *surface, const byte *srcData, i
_posYClipped = 0;
_clipX1 = 0;
_clipY1 = 0;
- if ((xp300 <= _minX) || (yp300 <= _minY) || (xp300 >= _maxX + 300) || (yp300 >= _maxY + 300))
+ if ((xp300 <= _minX) || (yp300 <= _minY) || (xp300 >= _maxX + 300) || (yp300 >= _maxY + 300))
return;
// Clipped values are greater or equal to zero, thanks to the previous test
@@ -1781,7 +1781,7 @@ void GraphicsManager::initScreen(const Common::String &file, int mode, bool init
do {
int dataVal1 = _vm->_script->handleOpcode(ptr + 20 * dataOffset);
- if (_vm->shouldQuit())
+ if (dataVal1 == -1 || _vm->shouldQuit())
return;
if (dataVal1 == 2)
diff --git a/engines/hopkins/hopkins.cpp b/engines/hopkins/hopkins.cpp
index 96131f2968..0e86fa26a9 100644
--- a/engines/hopkins/hopkins.cpp
+++ b/engines/hopkins/hopkins.cpp
@@ -166,7 +166,7 @@ bool HopkinsEngine::runWin95Demo() {
_globals->_characterType = CHARACTER_HOPKINS;
_objectsMan->_mapCarPosX = _objectsMan->_mapCarPosY = 0;
- memset(_globals->_saveData, 0, 2000);
+ memset(_globals->_saveData, 0, sizeof(Savegame));
_globals->_exitId = 0;
if (getLanguage() != Common::PL_POL)
@@ -210,12 +210,17 @@ bool HopkinsEngine::runWin95Demo() {
if (getPlatform() == Common::kPlatformOS2 || getPlatform() == Common::kPlatformBeOS)
_graphicsMan->loadImage("fond");
else {
- if (_globals->_language == LANG_FR)
+ switch (_globals->_language) {
+ case LANG_FR:
_graphicsMan->loadImage("fondfr");
- else if (_globals->_language == LANG_EN)
+ break;
+ case LANG_EN:
_graphicsMan->loadImage("fondan");
- else if (_globals->_language == LANG_SP)
+ break;
+ case LANG_SP:
_graphicsMan->loadImage("fondes");
+ break;
+ }
}
_graphicsMan->fadeInLong();
_events->delay(500);
@@ -465,7 +470,7 @@ bool HopkinsEngine::runLinuxDemo() {
_globals->_characterSpriteBuf = _fileIO->loadFile("PERSO.SPR");
_globals->_characterType = CHARACTER_HOPKINS;
_objectsMan->_mapCarPosX = _objectsMan->_mapCarPosY = 0;
- memset(_globals->_saveData, 0, 2000);
+ memset(_globals->_saveData, 0, sizeof(Savegame));
_globals->_exitId = 0;
if (_startGameSlot != -1)
@@ -521,12 +526,17 @@ bool HopkinsEngine::runLinuxDemo() {
if (getPlatform() == Common::kPlatformOS2 || getPlatform() == Common::kPlatformBeOS)
_graphicsMan->loadImage("fond");
else {
- if (_globals->_language == LANG_FR)
+ switch (_globals->_language) {
+ case LANG_FR:
_graphicsMan->loadImage("fondfr");
- else if (_globals->_language == LANG_EN)
+ break;
+ case LANG_EN:
_graphicsMan->loadImage("fondan");
- else if (_globals->_language == LANG_SP)
+ break;
+ case LANG_SP:
_graphicsMan->loadImage("fondes");
+ break;
+ }
}
_graphicsMan->fadeInLong();
_events->delay(500);
@@ -826,7 +836,7 @@ bool HopkinsEngine::runFull() {
_globals->_characterSpriteBuf = _fileIO->loadFile("PERSO.SPR");
_globals->_characterType = CHARACTER_HOPKINS;
_objectsMan->_mapCarPosX = _objectsMan->_mapCarPosY = 0;
- memset(_globals->_saveData, 0, 2000);
+ memset(_globals->_saveData, 0, sizeof(Savegame));
_globals->_exitId = 0;
@@ -867,12 +877,17 @@ bool HopkinsEngine::runFull() {
if (getPlatform() == Common::kPlatformOS2 || getPlatform() == Common::kPlatformBeOS)
_graphicsMan->loadImage("fond");
else {
- if (_globals->_language == LANG_FR)
+ switch (_globals->_language) {
+ case LANG_FR:
_graphicsMan->loadImage("fondfr");
- else if (_globals->_language == LANG_EN)
+ break;
+ case LANG_EN:
_graphicsMan->loadImage("fondan");
- else if (_globals->_language == LANG_SP)
+ break;
+ case LANG_SP:
_graphicsMan->loadImage("fondes");
+ break;
+ }
}
_graphicsMan->fadeInLong();
_events->delay(500);
@@ -1908,7 +1923,6 @@ void HopkinsEngine::bombExplosion() {
}
void HopkinsEngine::restoreSystem() {
- quitGame();
_events->refreshEvents();
}
diff --git a/engines/hopkins/hopkins.h b/engines/hopkins/hopkins.h
index d8c30e5004..615eace374 100644
--- a/engines/hopkins/hopkins.h
+++ b/engines/hopkins/hopkins.h
@@ -48,6 +48,7 @@
#include "common/util.h"
#include "engines/engine.h"
#include "graphics/surface.h"
+#include "gui/debugger.h"
/**
* This is the namespace of the Hopkins engine.
@@ -59,10 +60,6 @@
*/
namespace Hopkins {
-#define DEBUG_BASIC 1
-#define DEBUG_INTERMEDIATE 2
-#define DEBUG_DETAILED 3
-
#define SCREEN_WIDTH 640
#define SCREEN_HEIGHT 480
@@ -136,6 +133,8 @@ protected:
virtual Common::Error run();
virtual bool hasFeature(EngineFeature f) const;
+ GUI::Debugger *getDebugger() { return _debug; }
+
public:
AnimationManager *_animMan;
ComputerManager *_computer;
diff --git a/engines/hopkins/menu.cpp b/engines/hopkins/menu.cpp
index 455f4ad8d4..048d1b2cef 100644
--- a/engines/hopkins/menu.cpp
+++ b/engines/hopkins/menu.cpp
@@ -69,23 +69,37 @@ int MenuManager::menu() {
if (_vm->getPlatform() == Common::kPlatformOS2 || _vm->getPlatform() == Common::kPlatformBeOS)
_vm->_graphicsMan->loadImage("MENU");
- else if (_vm->_globals->_language == LANG_EN)
- _vm->_graphicsMan->loadImage("MENUAN");
- else if (_vm->_globals->_language == LANG_FR)
- _vm->_graphicsMan->loadImage("MENUFR");
- else if (_vm->_globals->_language == LANG_SP)
- _vm->_graphicsMan->loadImage("MENUES");
+ else {
+ switch (_vm->_globals->_language) {
+ case LANG_EN:
+ _vm->_graphicsMan->loadImage("MENUAN");
+ break;
+ case LANG_FR:
+ _vm->_graphicsMan->loadImage("MENUFR");
+ break;
+ case LANG_SP:
+ _vm->_graphicsMan->loadImage("MENUES");
+ break;
+ }
+ }
_vm->_graphicsMan->fadeInLong();
if (_vm->getPlatform() == Common::kPlatformOS2 || _vm->getPlatform() == Common::kPlatformBeOS)
spriteData = _vm->_objectsMan->loadSprite("MENU.SPR");
- else if (_vm->_globals->_language == LANG_EN)
- spriteData = _vm->_objectsMan->loadSprite("MENUAN.SPR");
- else if (_vm->_globals->_language == LANG_FR)
- spriteData = _vm->_objectsMan->loadSprite("MENUFR.SPR");
- else if (_vm->_globals->_language == LANG_SP)
- spriteData = _vm->_objectsMan->loadSprite("MENUES.SPR");
+ else {
+ switch (_vm->_globals->_language) {
+ case LANG_EN:
+ spriteData = _vm->_objectsMan->loadSprite("MENUAN.SPR");
+ break;
+ case LANG_FR:
+ spriteData = _vm->_objectsMan->loadSprite("MENUFR.SPR");
+ break;
+ case LANG_SP:
+ spriteData = _vm->_objectsMan->loadSprite("MENUES.SPR");
+ break;
+ }
+ }
_vm->_events->mouseOn();
_vm->_events->changeMouseCursor(0);
diff --git a/engines/hopkins/objects.cpp b/engines/hopkins/objects.cpp
index f2f547557f..347a6aabe8 100644
--- a/engines/hopkins/objects.cpp
+++ b/engines/hopkins/objects.cpp
@@ -2629,7 +2629,7 @@ void ObjectsManager::loadObjectIniFile() {
for (;;) {
int opcodeType = _vm->_script->handleOpcode(data + 20 * lastOpcodeResult);
- if (_vm->shouldQuit())
+ if (opcodeType == -1 || _vm->shouldQuit())
return;
if (opcodeType == 2)
diff --git a/engines/hopkins/script.cpp b/engines/hopkins/script.cpp
index 7e150624b8..09b0641a12 100644
--- a/engines/hopkins/script.cpp
+++ b/engines/hopkins/script.cpp
@@ -148,12 +148,18 @@ int ScriptManager::handleOpcode(const byte *dataP) {
_vm->_soundMan->mixVoice(635, 4, displayedTxtFl);
} else {
int textPosX = READ_LE_INT16(dataP + 9);
- if (_vm->_globals->_language == LANG_FR && !_vm->_soundMan->_textOffFl)
- _vm->_fontMan->initTextBuffers(9, mesgId, "OBJET1.TXT", 2 * textPosX, 60, 6, dataP[7], 253);
- else if (_vm->_globals->_language == LANG_EN && !_vm->_soundMan->_textOffFl)
- _vm->_fontMan->initTextBuffers(9, mesgId, "OBJETAN.TXT", 2 * textPosX, 60, 6, dataP[7], 253);
- else if (_vm->_globals->_language == LANG_SP && !_vm->_soundMan->_textOffFl) {
- _vm->_fontMan->initTextBuffers(9, mesgId, "OBJETES.TXT", 2 * textPosX, 60, 6, dataP[7], 253);
+ if (!_vm->_soundMan->_textOffFl) {
+ switch (_vm->_globals->_language) {
+ case LANG_FR:
+ _vm->_fontMan->initTextBuffers(9, mesgId, "OBJET1.TXT", 2 * textPosX, 60, 6, dataP[7], 253);
+ break;
+ case LANG_EN:
+ _vm->_fontMan->initTextBuffers(9, mesgId, "OBJETAN.TXT", 2 * textPosX, 60, 6, dataP[7], 253);
+ break;
+ case LANG_SP:
+ _vm->_fontMan->initTextBuffers(9, mesgId, "OBJETES.TXT", 2 * textPosX, 60, 6, dataP[7], 253);
+ break;
+ }
}
bool displayedTxtFl = false;
diff --git a/engines/hopkins/sound.cpp b/engines/hopkins/sound.cpp
index bf816c08a4..92c5f51462 100644
--- a/engines/hopkins/sound.cpp
+++ b/engines/hopkins/sound.cpp
@@ -520,12 +520,19 @@ bool SoundManager::mixVoice(int voiceId, int voiceMode, bool dispTxtFl) {
if (_vm->getPlatform() == Common::kPlatformOS2 || _vm->getPlatform() == Common::kPlatformBeOS)
filename = "ENG_VOI.RES";
// Win95 and Linux versions uses another set of names
- else if (_vm->_globals->_language == LANG_FR)
- filename = "RES_VFR.RES";
- else if (_vm->_globals->_language == LANG_EN)
- filename = "RES_VAN.RES";
- else if (_vm->_globals->_language == LANG_SP)
- filename = "RES_VES.RES";
+ else {
+ switch (_vm->_globals->_language) {
+ case LANG_FR:
+ filename = "RES_VFR.RES";
+ break;
+ case LANG_EN:
+ filename = "RES_VAN.RES";
+ break;
+ case LANG_SP:
+ filename = "RES_VES.RES";
+ break;
+ }
+ }
catPos = _vm->_fileIO->_catalogPos;
catLen = _vm->_fileIO->_catalogSize;
@@ -535,12 +542,19 @@ bool SoundManager::mixVoice(int voiceId, int voiceMode, bool dispTxtFl) {
if (_vm->getPlatform() == Common::kPlatformOS2 || _vm->getPlatform() == Common::kPlatformBeOS)
filename = "ENG_VOI.RES";
// Win95 and Linux versions uses another set of names
- else if (_vm->_globals->_language == LANG_FR)
- filename = "RES_VFR.RES";
- else if (_vm->_globals->_language == LANG_EN)
- filename = "RES_VAN.RES";
- else if (_vm->_globals->_language == LANG_SP)
- filename = "RES_VES.RES";
+ else {
+ switch (_vm->_globals->_language) {
+ case LANG_FR:
+ filename = "RES_VFR.RES";
+ break;
+ case LANG_EN:
+ filename = "RES_VAN.RES";
+ break;
+ case LANG_SP:
+ filename = "RES_VES.RES";
+ break;
+ }
+ }
catPos = _vm->_fileIO->_catalogPos;
catLen = _vm->_fileIO->_catalogSize;
@@ -550,12 +564,19 @@ bool SoundManager::mixVoice(int voiceId, int voiceMode, bool dispTxtFl) {
if (_vm->getPlatform() == Common::kPlatformOS2 || _vm->getPlatform() == Common::kPlatformBeOS)
filename = "ENG_VOI.RES";
// Win95 and Linux versions uses another set of names
- else if (_vm->_globals->_language == LANG_FR)
- filename = "RES_VFR.RES";
- else if (_vm->_globals->_language == LANG_EN)
- filename = "RES_VAN.RES";
- else if (_vm->_globals->_language == LANG_SP)
- filename = "RES_VES.RES";
+ else {
+ switch (_vm->_globals->_language) {
+ case LANG_FR:
+ filename = "RES_VFR.RES";
+ break;
+ case LANG_EN:
+ filename = "RES_VAN.RES";
+ break;
+ case LANG_SP:
+ filename = "RES_VES.RES";
+ break;
+ }
+ }
catPos = _vm->_fileIO->_catalogPos;
catLen = _vm->_fileIO->_catalogSize;
diff --git a/engines/hopkins/talk.cpp b/engines/hopkins/talk.cpp
index 736ec9865c..c80ea15554 100644
--- a/engines/hopkins/talk.cpp
+++ b/engines/hopkins/talk.cpp
@@ -68,12 +68,17 @@ 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);
- if (_vm->_globals->_language == LANG_FR) {
+
+ switch (_vm->_globals->_language) {
+ case LANG_FR:
_answersFilename = _questionsFilename = "RUE.TXT";
- } else if (_vm->_globals->_language == LANG_EN) {
+ break;
+ case LANG_EN:
_answersFilename = _questionsFilename = "RUEAN.TXT";
- } else if (_vm->_globals->_language == LANG_SP) {
+ break;
+ case LANG_SP:
_answersFilename = _questionsFilename = "RUEES.TXT";
+ break;
}
_dialogueMesgId1 = READ_LE_INT16((uint16 *)_characterBuffer + 40);
_paletteBufferIdx = 20 * READ_LE_INT16((uint16 *)_characterBuffer + 42) + 110;
@@ -261,7 +266,7 @@ int TalkManager::dialogQuestion(bool animatedFl) {
int retVal = -1;
bool loopCond = false;
- do {
+ do {
int mousePosY = _vm->_events->getMouseY();
if (sentence1PosY < mousePosY && mousePosY < (sentence2PosY - 1)) {
_vm->_fontMan->setOptimalColor(6, 7, 8, 5);
@@ -820,7 +825,7 @@ void TalkManager::handleAnswer(int zone, int verb) {
int lastOpcodeResult = 1;
do {
int opcodeType = _vm->_script->handleOpcode(ptr + 20 * lastOpcodeResult);
- if (_vm->shouldQuit())
+ if (opcodeType == -1 || _vm->shouldQuit())
return;
if (opcodeType == 2)
diff --git a/engines/hugo/configure.engine b/engines/hugo/configure.engine
new file mode 100644
index 0000000000..9ab5c54e1e
--- /dev/null
+++ b/engines/hugo/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 hugo "Hugo Trilogy" yes
diff --git a/engines/hugo/dialogs.cpp b/engines/hugo/dialogs.cpp
index 5dcee3ae94..23e04dc479 100644
--- a/engines/hugo/dialogs.cpp
+++ b/engines/hugo/dialogs.cpp
@@ -34,8 +34,10 @@
namespace Hugo {
-TopMenu::TopMenu(HugoEngine *vm) : Dialog(0, 0, kMenuWidth, kMenuHeight), _arrayBmp(0), _arraySize(0),
- _vm(vm) {
+TopMenu::TopMenu(HugoEngine *vm) : Dialog(0, 0, kMenuWidth, kMenuHeight), _vm(vm) {
+ _arrayBmp = nullptr;
+ _arraySize = 0;
+
init();
}
@@ -140,12 +142,10 @@ void TopMenu::loadBmpArr(Common::SeekableReadStream &in) {
_arrayBmp[i * 2] = bitmapSrc->convertTo(g_system->getOverlayFormat());
_arrayBmp[i * 2 + 1] = new Graphics::Surface();
_arrayBmp[i * 2 + 1]->create(_arrayBmp[i * 2]->w * 2, _arrayBmp[i * 2]->h * 2, g_system->getOverlayFormat());
- byte *src = (byte *)_arrayBmp[i * 2]->getPixels();
- byte *dst = (byte *)_arrayBmp[i * 2 + 1]->getPixels();
for (int j = 0; j < _arrayBmp[i * 2]->h; j++) {
- src = (byte *)_arrayBmp[i * 2]->getBasePtr(0, j);
- dst = (byte *)_arrayBmp[i * 2 + 1]->getBasePtr(0, j * 2);
+ byte *src = (byte *)_arrayBmp[i * 2]->getBasePtr(0, j);
+ byte *dst = (byte *)_arrayBmp[i * 2 + 1]->getBasePtr(0, j * 2);
for (int k = _arrayBmp[i * 2]->w; k > 0; k--) {
for (int m = _arrayBmp[i * 2]->format.bytesPerPixel; m > 0; m--) {
*dst++ = *src++;
diff --git a/engines/hugo/display.cpp b/engines/hugo/display.cpp
index fbe39b3a0c..3dc9c9a1c3 100644
--- a/engines/hugo/display.cpp
+++ b/engines/hugo/display.cpp
@@ -75,13 +75,13 @@ static const byte stdMouseCursor[] = {
Screen::Screen(HugoEngine *vm) : _vm(vm) {
- _mainPalette = 0;
- _curPalette = 0;
+ _mainPalette = nullptr;
+ _curPalette = nullptr;
_dlAddIndex = 0;
_dlRestoreIndex = 0;
for (int i = 0; i < kNumFonts; i++) {
- _arrayFont[i] = 0;
+ _arrayFont[i] = nullptr;
fontLoadedFl[i] = false;
}
for (int i = 0; i < kBlitListSize; i++) {
@@ -100,6 +100,8 @@ Screen::Screen(HugoEngine *vm) : _vm(vm) {
_dlRestoreList[i]._dx = 0;
_dlRestoreList[i]._dy = 0;
}
+ _fnt = 0;
+ _paletteSize = 0;
}
Screen::~Screen() {
diff --git a/engines/hugo/file.cpp b/engines/hugo/file.cpp
index e58c2e57d6..aa128048af 100644
--- a/engines/hugo/file.cpp
+++ b/engines/hugo/file.cpp
@@ -246,13 +246,13 @@ SoundPtr FileManager::getSound(const int16 sound, uint16 *size) {
// No more to do if SILENCE (called for cleanup purposes)
if (sound == _vm->_soundSilence)
- return 0;
+ return nullptr;
// Open sounds file
Common::File fp; // Handle to SOUND_FILE
if (!fp.open(getSoundFilename())) {
warning("Hugo Error: File not found %s", getSoundFilename());
- return 0;
+ return nullptr;
}
if (!_hasReadHeader) {
@@ -519,6 +519,7 @@ void FileManager::readBootFile() {
ofp.read(_vm->_boot._pbswitch, sizeof(_vm->_boot._pbswitch));
ofp.read(_vm->_boot._distrib, sizeof(_vm->_boot._distrib));
_vm->_boot._exitLen = ofp.readUint16LE();
+ ofp.close();
byte *p = (byte *)&_vm->_boot;
@@ -527,7 +528,6 @@ void FileManager::readBootFile() {
checksum ^= p[i];
p[i] ^= s_bootCypher[i % s_bootCypherLen];
}
- ofp.close();
if (checksum) {
Utils::notifyBox(Common::String::format("Corrupted startup file '%s'", getBootFilename()));
diff --git a/engines/hugo/hugo.cpp b/engines/hugo/hugo.cpp
index b140cfdba2..88e2e4372b 100644
--- a/engines/hugo/hugo.cpp
+++ b/engines/hugo/hugo.cpp
@@ -46,11 +46,11 @@
namespace Hugo {
-HugoEngine *HugoEngine::s_Engine = 0;
+HugoEngine *HugoEngine::s_Engine = nullptr;
HugoEngine::HugoEngine(OSystem *syst, const HugoGameDescription *gd) : Engine(syst), _gameDescription(gd),
- _hero(0), _heroImage(0), _defltTunes(0), _numScreens(0), _tunesNbr(0), _soundSilence(0), _soundTest(0),
- _screenStates(0), _numStates(0), _score(0), _maxscore(0), _lastTime(0), _curTime(0), _episode(0)
+ _hero(nullptr), _heroImage(0), _defltTunes(nullptr), _numScreens(0), _tunesNbr(0), _soundSilence(0), _soundTest(0),
+ _screenStates(nullptr), _numStates(0), _score(0), _maxscore(0), _lastTime(0), _curTime(0), _episode(nullptr)
{
_system = syst;
DebugMan.addDebugChannel(kDebugSchedule, "Schedule", "Script Schedule debug level");
@@ -67,16 +67,16 @@ HugoEngine::HugoEngine(OSystem *syst, const HugoGameDescription *gd) : Engine(sy
_console = new HugoConsole(this);
_rnd = 0;
- _screen = NULL;
- _mouse = NULL;
- _inventory = NULL;
- _parser = NULL;
- _route = NULL;
- _sound = NULL;
- _intro = NULL;
- _object = NULL;
- _text = NULL;
- _topMenu = NULL;
+ _screen = nullptr;
+ _mouse = nullptr;
+ _inventory = nullptr;
+ _parser = nullptr;
+ _route = nullptr;
+ _sound = nullptr;
+ _intro = nullptr;
+ _object = nullptr;
+ _text = nullptr;
+ _topMenu = nullptr;
_status._storyModeFl = false;
_status._gameOverFl = false;
_status._lookFl = false;
@@ -93,6 +93,26 @@ HugoEngine::HugoEngine(OSystem *syst, const HugoGameDescription *gd) : Engine(sy
_gameType = kGameTypeNone;
_platform = Common::kPlatformUnknown;
_packedFl = false;
+
+ _numVariant = 0;
+ _gameVariant = kGameVariantNone;
+ _normalTPS = 0;
+ _screenPtr = nullptr;
+ _config._musicFl = true;
+ _config._soundFl = true;
+ _config._turboFl = false;
+ _look = 0;
+ _take = 0;
+ _drop = 0;
+ _maze._enabledFl = false;
+ _maze._size = 0;
+ _maze._x1 = _maze._y1 = _maze._x2 = _maze._y2 = _maze._x3 = _maze._x4 = 0;
+ _maze._firstScreenIndex = 0;
+ _boot._checksum = 0;
+ _boot._registered = kRegShareware;
+ _boot._exitLen = 0;
+ _file = nullptr;
+ _scheduler = nullptr;
}
HugoEngine::~HugoEngine() {
diff --git a/engines/hugo/hugo.h b/engines/hugo/hugo.h
index 9f495a9037..6adb5f95d0 100644
--- a/engines/hugo/hugo.h
+++ b/engines/hugo/hugo.h
@@ -106,7 +106,8 @@ enum GameVariant {
kGameVariantH3Win,
kGameVariantH1Dos,
kGameVariantH2Dos,
- kGameVariantH3Dos
+ kGameVariantH3Dos,
+ kGameVariantNone
};
enum HugoDebugChannels {
@@ -259,7 +260,7 @@ public:
// Used by the qsort function
static HugoEngine &get() {
- assert(s_Engine != 0);
+ assert(s_Engine != nullptr);
return *s_Engine;
}
diff --git a/engines/hugo/intro.cpp b/engines/hugo/intro.cpp
index 6f314c8774..5db6c39078 100644
--- a/engines/hugo/intro.cpp
+++ b/engines/hugo/intro.cpp
@@ -39,9 +39,10 @@
namespace Hugo {
-IntroHandler::IntroHandler(HugoEngine *vm) : _vm(vm), _introX(0), _introY(0) {
+IntroHandler::IntroHandler(HugoEngine *vm) : _vm(vm) {
_introXSize = 0;
_introTicks = 0;
+ _introX = _introY = nullptr;
}
IntroHandler::~IntroHandler() {
@@ -74,6 +75,7 @@ void IntroHandler::loadIntroData(Common::SeekableReadStream &in) {
void IntroHandler::freeIntroData() {
free(_introX);
free(_introY);
+ _introX = _introY = nullptr;
}
intro_v1d::intro_v1d(HugoEngine *vm) : IntroHandler(vm) {
diff --git a/engines/hugo/inventory.cpp b/engines/hugo/inventory.cpp
index c2495beadb..03df997866 100644
--- a/engines/hugo/inventory.cpp
+++ b/engines/hugo/inventory.cpp
@@ -44,7 +44,8 @@ namespace Hugo {
static const int kMaxDisp = (kXPix / kInvDx); // Max icons displayable
-InventoryHandler::InventoryHandler(HugoEngine *vm) : _vm(vm), _invent(0) {
+InventoryHandler::InventoryHandler(HugoEngine *vm) : _vm(vm) {
+ _invent = nullptr;
_firstIconId = 0;
_inventoryState = kInventoryOff; // Inventory icon bar state
_inventoryHeight = 0; // Inventory icon bar pos
@@ -62,6 +63,7 @@ void InventoryHandler::setInventoryState(Istate state) {
void InventoryHandler::freeInvent() {
free(_invent);
+ _invent = nullptr;
}
int16 InventoryHandler::getInventoryObjId() const {
diff --git a/engines/hugo/mouse.cpp b/engines/hugo/mouse.cpp
index ae286c8afb..4ef3db3e2b 100644
--- a/engines/hugo/mouse.cpp
+++ b/engines/hugo/mouse.cpp
@@ -45,7 +45,8 @@
namespace Hugo {
-MouseHandler::MouseHandler(HugoEngine *vm) : _vm(vm), _hotspots(0) {
+MouseHandler::MouseHandler(HugoEngine *vm) : _vm(vm) {
+ _hotspots = nullptr;
_leftButtonFl = false;
_rightButtonFl = false;
_jumpExitFl = false; // Can't jump to a screen exit
@@ -83,6 +84,7 @@ void MouseHandler::setMouseY(int y) {
void MouseHandler::freeHotspots() {
free(_hotspots);
+ _hotspots = nullptr;
}
bool MouseHandler::getJumpExitFl() const {
@@ -169,7 +171,7 @@ void MouseHandler::processRightClick(const int16 objId, const int16 cx, const in
_vm->_object->useObject(objId); // Use status.objid on object
} else { // Clicked over viewport object
Object *obj = &_vm->_object->_objects[objId];
- int16 x = 0, y = 0;
+ int16 x, y;
switch (obj->_viewx) { // Where to walk to
case -1: // Walk to object position
if (_vm->_object->findObjectSpace(obj, &x, &y))
diff --git a/engines/hugo/object.cpp b/engines/hugo/object.cpp
index 7b4783e4d8..44f46d2d79 100644
--- a/engines/hugo/object.cpp
+++ b/engines/hugo/object.cpp
@@ -44,7 +44,9 @@
namespace Hugo {
-ObjectHandler::ObjectHandler(HugoEngine *vm) : _vm(vm), _objects(0), _uses(0) {
+ObjectHandler::ObjectHandler(HugoEngine *vm) : _vm(vm) {
+ _uses = nullptr;
+ _objects = nullptr;
_numObj = 0;
_objCount = 0;
_usesSize = 0;
@@ -249,47 +251,49 @@ void ObjectHandler::lookObject(Object *obj) {
void ObjectHandler::freeObjects() {
debugC(1, kDebugObject, "freeObjects");
- if (_vm->_hero != 0 && _vm->_hero->_seqList[0]._seqPtr != 0) {
+ if (_vm->_hero != nullptr && _vm->_hero->_seqList[0]._seqPtr != nullptr) {
// Free all sequence lists and image data
for (int16 i = 0; i < _numObj; i++) {
Object *obj = &_objects[i];
for (int16 j = 0; j < obj->_seqNumb; j++) {
Seq *seq = obj->_seqList[j]._seqPtr;
Seq *next;
- if (seq == 0) // Failure during database load
+ if (seq == nullptr) // Failure during database load
break;
- if (seq->_imagePtr != 0) {
+ if (seq->_imagePtr != nullptr) {
free(seq->_imagePtr);
- seq->_imagePtr = 0;
+ seq->_imagePtr = nullptr;
}
seq = seq->_nextSeqPtr;
while (seq != obj->_seqList[j]._seqPtr) {
- if (seq->_imagePtr != 0) {
+ if (seq->_imagePtr != nullptr) {
free(seq->_imagePtr);
- seq->_imagePtr = 0;
+ seq->_imagePtr = nullptr;
}
next = seq->_nextSeqPtr;
free(seq);
seq = next;
}
free(seq);
+ seq = nullptr;
}
}
}
- if (_uses) {
+ if (_uses != nullptr) {
for (int16 i = 0; i < _usesSize; i++)
free(_uses[i]._targets);
free(_uses);
+ _uses = nullptr;
}
for (int16 i = 0; i < _objCount; i++) {
free(_objects[i]._stateDataIndex);
- _objects[i]._stateDataIndex = 0;
+ _objects[i]._stateDataIndex = nullptr;
}
free(_objects);
- _objects = 0;
+ _objects = nullptr;
}
/**
@@ -358,7 +362,7 @@ void ObjectHandler::showTakeables() {
* Find a clear space around supplied object that hero can walk to
*/
bool ObjectHandler::findObjectSpace(Object *obj, int16 *destx, int16 *desty) {
- debugC(1, kDebugObject, "findObjectSpace(obj, %d, %d)", *destx, *desty);
+ debugC(1, kDebugObject, "findObjectSpace(...)");
Seq *curImage = obj->_currImagePtr;
int16 y = obj->_y + curImage->_y2 - 1;
@@ -414,7 +418,7 @@ void ObjectHandler::readUse(Common::ReadStream &in, Uses &curUse) {
*/
void ObjectHandler::loadObjectUses(Common::ReadStream &in) {
Uses tmpUse;
- tmpUse._targets = 0;
+ tmpUse._targets = nullptr;
//Read _uses
for (int varnt = 0; varnt < _vm->_numVariant; varnt++) {
@@ -430,7 +434,7 @@ void ObjectHandler::loadObjectUses(Common::ReadStream &in) {
else {
readUse(in, tmpUse);
free(tmpUse._targets);
- tmpUse._targets = 0;
+ tmpUse._targets = nullptr;
}
}
}
@@ -442,7 +446,7 @@ void ObjectHandler::readObject(Common::ReadStream &in, Object &curObject) {
uint16 numSubElem = in.readUint16BE();
if (numSubElem == 0)
- curObject._stateDataIndex = 0;
+ curObject._stateDataIndex = nullptr;
else
curObject._stateDataIndex = (uint16 *)malloc(sizeof(uint16) * numSubElem);
for (int j = 0; j < numSubElem; j++)
@@ -453,16 +457,16 @@ void ObjectHandler::readObject(Common::ReadStream &in, Object &curObject) {
curObject._vyPath = in.readSint16BE();
curObject._actIndex = in.readUint16BE();
curObject._seqNumb = in.readByte();
- curObject._currImagePtr = 0;
+ curObject._currImagePtr = nullptr;
if (curObject._seqNumb == 0) {
curObject._seqList[0]._imageNbr = 0;
- curObject._seqList[0]._seqPtr = 0;
+ curObject._seqList[0]._seqPtr = nullptr;
}
for (int j = 0; j < curObject._seqNumb; j++) {
curObject._seqList[j]._imageNbr = in.readUint16BE();
- curObject._seqList[j]._seqPtr = 0;
+ curObject._seqList[j]._seqPtr = nullptr;
}
curObject._cycling = (Cycle)in.readByte();
@@ -498,7 +502,7 @@ void ObjectHandler::readObject(Common::ReadStream &in, Object &curObject) {
void ObjectHandler::loadObjectArr(Common::ReadStream &in) {
debugC(6, kDebugObject, "loadObject(&in)");
Object tmpObject;
- tmpObject._stateDataIndex = 0;
+ tmpObject._stateDataIndex = nullptr;
for (int varnt = 0; varnt < _vm->_numVariant; varnt++) {
uint16 numElem = in.readUint16BE();
@@ -515,7 +519,7 @@ void ObjectHandler::loadObjectArr(Common::ReadStream &in) {
// Skip over uneeded objects.
readObject(in, tmpObject);
free(tmpObject._stateDataIndex);
- tmpObject._stateDataIndex = 0;
+ tmpObject._stateDataIndex = nullptr;
}
}
}
diff --git a/engines/hugo/parser.cpp b/engines/hugo/parser.cpp
index 2585c64fd8..57938ec371 100644
--- a/engines/hugo/parser.cpp
+++ b/engines/hugo/parser.cpp
@@ -44,14 +44,20 @@
namespace Hugo {
-Parser::Parser(HugoEngine *vm) : _vm(vm), _putIndex(0), _getIndex(0), _arrayReqs(0), _catchallList(0), _backgroundObjects(0), _cmdList(0) {
+Parser::Parser(HugoEngine *vm) : _vm(vm), _putIndex(0), _getIndex(0) {
+ _catchallList = nullptr;
+ _arrayReqs = nullptr;
+
+ _backgroundObjects = nullptr;
+ _backgroundObjectsSize = 0;
+ _cmdList = nullptr;
+ _cmdListSize = 0;
+
_cmdLineIndex = 0;
_cmdLineTick = 0;
_cmdLineCursor = '_';
_cmdLine[0] = '\0';
- _cmdListSize = 0;
_checkDoubleF1Fl = false;
- _backgroundObjectsSize = 0;
}
Parser::~Parser() {
@@ -172,7 +178,7 @@ const char *Parser::useBG(const char *name) {
return _vm->_text->getVerb(p[i]._verbIndex, 0);
}
- return 0;
+ return nullptr;
}
void Parser::freeParser() {
@@ -180,20 +186,24 @@ void Parser::freeParser() {
for (int i = 0; _arrayReqs[i] != 0; i++)
free(_arrayReqs[i]);
free(_arrayReqs);
+ _arrayReqs = nullptr;
}
free(_catchallList);
+ _catchallList = nullptr;
if (_backgroundObjects) {
for (int i = 0; i < _backgroundObjectsSize; i++)
free(_backgroundObjects[i]);
free(_backgroundObjects);
+ _backgroundObjects = nullptr;
}
if (_cmdList) {
for (int i = 0; i < _cmdListSize; i++)
free(_cmdList[i]);
free(_cmdList);
+ _cmdList = nullptr;
}
}
@@ -398,9 +408,9 @@ void Parser::command(const char *format, ...) {
* Locate any member of object name list appearing in command line
*/
bool Parser::isWordPresent(char **wordArr) const {
- debugC(1, kDebugParser, "isWordPresent(%s)", wordArr[0]);
-
if (wordArr != 0) {
+ debugC(1, kDebugParser, "isWordPresent(%s)", wordArr[0]);
+
for (int i = 0; strlen(wordArr[i]); i++) {
if (strstr(_vm->_line, wordArr[i]))
return true;
@@ -421,7 +431,7 @@ const char *Parser::findNoun() const {
return _vm->_text->getNoun(i, 0);
}
}
- return 0;
+ return nullptr;
}
/**
@@ -436,7 +446,7 @@ const char *Parser::findVerb() const {
return _vm->_text->getVerb(i, 0);
}
}
- return 0;
+ return nullptr;
}
/**
diff --git a/engines/hugo/route.cpp b/engines/hugo/route.cpp
index 54dae88c28..dc3c41de9c 100644
--- a/engines/hugo/route.cpp
+++ b/engines/hugo/route.cpp
@@ -45,6 +45,17 @@ Route::Route(HugoEngine *vm) : _vm(vm) {
_routeIndex = -1; // Hero not following a route
_routeType = kRouteSpace; // Hero walking to space
_routeObjId = -1; // Hero not walking to anything
+
+ for (int i = 0; i < kMaxSeg; i++)
+ _segment[i]._y = _segment[i]._x1 = _segment[i]._x2 = 0;
+
+ _segmentNumb = 0;
+ _routeListIndex = 0;
+ _destX = _destY = 0;
+ _heroWidth = 0;
+ _routeFoundFl = false;
+ _fullStackFl = false;
+ _fullSegmentFl = false;
}
void Route::resetRoute() {
@@ -303,7 +314,7 @@ Common::Point *Route::newNode() {
_routeListIndex++;
if (_routeListIndex >= kMaxNodes) // Too many nodes
- return 0; // Incomplete route - failure
+ return nullptr; // Incomplete route - failure
_route[_routeListIndex] = _route[_routeListIndex - 1]; // Initialize with previous node
return &_route[_routeListIndex];
diff --git a/engines/hugo/route.h b/engines/hugo/route.h
index 716829a201..71db1e2583 100644
--- a/engines/hugo/route.h
+++ b/engines/hugo/route.h
@@ -79,9 +79,11 @@ private:
int16 _destY;
int16 _heroWidth; // Hero width
bool _routeFoundFl; // TRUE when path found
- bool _fullStackFl; // TRUE if stack exhausted
bool _fullSegmentFl; // Segments exhausted
+ // CHECKME: Never set to true, could be removed
+ bool _fullStackFl; // TRUE if stack exhausted
+
void segment(int16 x, int16 y);
bool findRoute(const int16 cx, const int16 cy);
Common::Point *newNode();
diff --git a/engines/hugo/schedule.cpp b/engines/hugo/schedule.cpp
index 32b8a47df7..17ffa9d391 100644
--- a/engines/hugo/schedule.cpp
+++ b/engines/hugo/schedule.cpp
@@ -47,10 +47,23 @@
namespace Hugo {
-Scheduler::Scheduler(HugoEngine *vm) : _vm(vm), _actListArr(0), _curTick(0), _oldTime(0), _refreshTimeout(0), _points(0), _screenActs(0) {
+Scheduler::Scheduler(HugoEngine *vm) : _vm(vm) {
+ _actListArr = nullptr;
+ _curTick = 0;
+ _oldTime = 0;
+ _refreshTimeout = 0;
+ _points = nullptr;
+ _screenActs = nullptr;
+
memset(_events, 0, sizeof(_events));
_numBonuses = 0;
_screenActsSize = 0;
+
+ _actListArrSize = 0;
+ _alNewscrIndex = 0;
+ _freeEvent = nullptr;
+ _headEvent = nullptr;
+ _tailEvent = nullptr;
}
Scheduler::~Scheduler() {
@@ -69,14 +82,14 @@ void Scheduler::initEventQueue() {
// Chain nextEvent from first to last
for (int i = kMaxEvents; --i;)
_events[i - 1]._nextEvent = &_events[i];
- _events[kMaxEvents - 1]._nextEvent = 0;
+ _events[kMaxEvents - 1]._nextEvent = nullptr;
// Chain prevEvent from last to first
for (int i = 1; i < kMaxEvents; i++)
_events[i]._prevEvent = &_events[i - 1];
- _events[0]._prevEvent = 0;
+ _events[0]._prevEvent = nullptr;
- _headEvent = _tailEvent = 0; // Event list is empty
+ _headEvent = _tailEvent = nullptr; // Event list is empty
_freeEvent = _events; // Free list is full
}
@@ -90,7 +103,7 @@ Event *Scheduler::getQueue() {
error("An error has occurred: %s", "getQueue");
Event *resEvent = _freeEvent;
_freeEvent = _freeEvent->_nextEvent;
- resEvent->_nextEvent = 0;
+ resEvent->_nextEvent = nullptr;
return resEvent;
}
@@ -597,7 +610,7 @@ void Scheduler::loadScreenAct(Common::SeekableReadStream &in) {
for (int i = 0; i < numElem; i++) {
uint16 numSubElem = in.readUint16BE();
if (numSubElem == 0) {
- _screenActs[i] = 0;
+ _screenActs[i] = nullptr;
} else {
_screenActs[i] = (uint16 *)malloc(sizeof(uint16) * numSubElem);
for (int j = 0; j < numSubElem; j++)
@@ -617,11 +630,14 @@ void Scheduler::freeScheduler() {
debugC(6, kDebugSchedule, "freeActListArr()");
free(_points);
+ _points = nullptr;
if (_screenActs) {
for (int i = 0; i < _screenActsSize; i++)
free(_screenActs[i]);
free(_screenActs);
+ _screenActs = nullptr;
+ _screenActsSize = 0;
}
if (_actListArr) {
@@ -633,6 +649,8 @@ void Scheduler::freeScheduler() {
free(_actListArr[i]);
}
free(_actListArr);
+ _actListArr = nullptr;
+ _actListArrSize = 0;
}
}
@@ -698,9 +716,9 @@ void Scheduler::saveEvents(Common::WriteStream *f) {
f->writeUint32BE(getTicks());
- int16 freeIndex = (_freeEvent == 0) ? -1 : _freeEvent - _events;
- int16 headIndex = (_headEvent == 0) ? -1 : _headEvent - _events;
- int16 tailIndex = (_tailEvent == 0) ? -1 : _tailEvent - _events;
+ int16 freeIndex = (_freeEvent == nullptr) ? -1 : _freeEvent - _events;
+ int16 headIndex = (_headEvent == nullptr) ? -1 : _headEvent - _events;
+ int16 tailIndex = (_tailEvent == nullptr) ? -1 : _tailEvent - _events;
f->writeSint16BE(freeIndex);
f->writeSint16BE(headIndex);
@@ -717,8 +735,8 @@ void Scheduler::saveEvents(Common::WriteStream *f) {
f->writeSint16BE(subElem);
f->writeByte((wrkEvent->_localActionFl) ? 1 : 0);
f->writeUint32BE(wrkEvent->_time);
- f->writeSint16BE((wrkEvent->_prevEvent == 0) ? -1 : (wrkEvent->_prevEvent - _events));
- f->writeSint16BE((wrkEvent->_nextEvent == 0) ? -1 : (wrkEvent->_nextEvent - _events));
+ f->writeSint16BE((wrkEvent->_prevEvent == nullptr) ? -1 : (wrkEvent->_prevEvent - _events));
+ f->writeSint16BE((wrkEvent->_nextEvent == nullptr) ? -1 : (wrkEvent->_nextEvent - _events));
}
}
@@ -1102,7 +1120,7 @@ void Scheduler::restoreEvents(Common::ReadStream *f) {
// fix up action pointer (to do better)
if ((index == -1) && (subElem == -1))
- _events[i]._action = 0;
+ _events[i]._action = nullptr;
else
_events[i]._action = (Act *)&_actListArr[index][subElem];
@@ -1112,12 +1130,12 @@ void Scheduler::restoreEvents(Common::ReadStream *f) {
int16 prevIndex = f->readSint16BE();
int16 nextIndex = f->readSint16BE();
- _events[i]._prevEvent = (prevIndex == -1) ? (Event *)0 : &_events[prevIndex];
- _events[i]._nextEvent = (nextIndex == -1) ? (Event *)0 : &_events[nextIndex];
+ _events[i]._prevEvent = (prevIndex == -1) ? nullptr : &_events[prevIndex];
+ _events[i]._nextEvent = (nextIndex == -1) ? nullptr : &_events[nextIndex];
}
- _freeEvent = (freeIndex == -1) ? 0 : &_events[freeIndex];
- _headEvent = (headIndex == -1) ? 0 : &_events[headIndex];
- _tailEvent = (tailIndex == -1) ? 0 : &_events[tailIndex];
+ _freeEvent = (freeIndex == -1) ? nullptr : &_events[freeIndex];
+ _headEvent = (headIndex == -1) ? nullptr : &_events[headIndex];
+ _tailEvent = (tailIndex == -1) ? nullptr : &_events[tailIndex];
// Adjust times to fit our time
uint32 curTime = getTicks();
@@ -1156,7 +1174,7 @@ void Scheduler::insertAction(Act *action) {
// Now find the place to insert the event
if (!_tailEvent) { // Empty queue
_tailEvent = _headEvent = curEvent;
- curEvent->_nextEvent = curEvent->_prevEvent = 0;
+ curEvent->_nextEvent = curEvent->_prevEvent = nullptr;
} else {
Event *wrkEvent = _tailEvent; // Search from latest time back
bool found = false;
@@ -1178,7 +1196,7 @@ void Scheduler::insertAction(Act *action) {
if (!found) { // Must be earliest in list
_headEvent->_prevEvent = curEvent; // So insert as new head
curEvent->_nextEvent = _headEvent;
- curEvent->_prevEvent = 0;
+ curEvent->_prevEvent = nullptr;
_headEvent = curEvent;
}
}
@@ -1424,7 +1442,7 @@ Event *Scheduler::doAction(Event *curEvent) {
}
if (action->_a0._actType == NEW_SCREEN) { // New_screen() deletes entire list
- return 0; // nextEvent = 0 since list now empty
+ return nullptr; // nextEvent = nullptr since list now empty
} else {
wrkEvent = curEvent->_nextEvent;
delQueue(curEvent); // Return event to free list
@@ -1455,9 +1473,9 @@ void Scheduler::delQueue(Event *curEvent) {
}
if (_headEvent)
- _headEvent->_prevEvent = 0; // Mark end of list
+ _headEvent->_prevEvent = nullptr; // Mark end of list
else
- _tailEvent = 0; // Empty queue
+ _tailEvent = nullptr; // Empty queue
curEvent->_nextEvent = _freeEvent; // Return p to free list
if (_freeEvent) // Special case, if free list was empty
diff --git a/engines/hugo/sound.cpp b/engines/hugo/sound.cpp
index aefa03cd5e..28dcdc83d6 100644
--- a/engines/hugo/sound.cpp
+++ b/engines/hugo/sound.cpp
@@ -123,11 +123,12 @@ SoundHandler::SoundHandler(HugoEngine *vm) : _vm(vm) {
_speakerStream = new Audio::PCSpeaker(_vm->_mixer->getOutputRate());
_vm->_mixer->playStream(Audio::Mixer::kSFXSoundType, &_speakerHandle,
_speakerStream, -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO, true);
- _DOSSongPtr = 0;
+ _DOSSongPtr = nullptr;
_curPriority = 0;
_pcspkrTimer = 0;
_pcspkrOctave = 3;
_pcspkrNoteDuration = 2;
+ _DOSIntroSong = nullptr;
}
SoundHandler::~SoundHandler() {
@@ -210,7 +211,7 @@ void SoundHandler::playSound(int16 sound, const byte priority) {
_curPriority = priority;
// Get sound data
- if ((soundPtr = _vm->_file->getSound(sound, &size)) == 0)
+ if ((soundPtr = _vm->_file->getSound(sound, &size)) == nullptr)
return;
Audio::AudioStream *stream = Audio::makeRawStream(soundPtr, size, 11025, Audio::FLAG_UNSIGNED);
diff --git a/engines/hugo/text.cpp b/engines/hugo/text.cpp
index f8b02bdf68..538a0341e2 100644
--- a/engines/hugo/text.cpp
+++ b/engines/hugo/text.cpp
@@ -26,9 +26,17 @@
namespace Hugo {
-TextHandler::TextHandler(HugoEngine *vm) : _vm(vm), _textData(0), _stringtData(0),
- _textEngine(0), _textIntro(0), _textMouse(0), _textParser(0), _textUtil(0),
- _screenNames(0), _arrayNouns(0), _arrayVerbs(0) {
+TextHandler::TextHandler(HugoEngine *vm) : _vm(vm) {
+ _textData = nullptr;
+ _stringtData = nullptr;
+ _textEngine = nullptr;
+ _textIntro = nullptr;
+ _textMouse = nullptr;
+ _textParser = nullptr;
+ _textUtil = nullptr;
+ _screenNames = nullptr;
+ _arrayNouns = nullptr;
+ _arrayVerbs = nullptr;
}
TextHandler::~TextHandler() {
@@ -86,9 +94,9 @@ char **TextHandler::loadTextsVariante(Common::ReadStream &in, uint16 *arraySize)
int numTexts;
int entryLen;
int len;
- char **res = 0;
- char *pos = 0;
- char *posBck = 0;
+ char **res = nullptr;
+ char *pos = nullptr;
+ char *posBck = nullptr;
for (int varnt = 0; varnt < _vm->_numVariant; varnt++) {
numTexts = in.readUint16BE();
@@ -126,21 +134,21 @@ char **TextHandler::loadTextsVariante(Common::ReadStream &in, uint16 *arraySize)
}
char ***TextHandler::loadTextsArray(Common::ReadStream &in) {
- char ***resArray = 0;
+ char ***resArray = nullptr;
uint16 arraySize;
for (int varnt = 0; varnt < _vm->_numVariant; varnt++) {
arraySize = in.readUint16BE();
if (varnt == _vm->_gameVariant) {
resArray = (char ***)malloc(sizeof(char **) * (arraySize + 1));
- resArray[arraySize] = 0;
+ resArray[arraySize] = nullptr;
}
for (int i = 0; i < arraySize; i++) {
int numTexts = in.readUint16BE();
int entryLen = in.readUint16BE();
char *pos = (char *)malloc(entryLen);
- char *posBck = 0;
- char **res = 0;
+ char *posBck = nullptr;
+ char **res = nullptr;
if (varnt == _vm->_gameVariant) {
res = (char **)malloc(sizeof(char *) * numTexts);
res[0] = pos;
@@ -232,6 +240,7 @@ void TextHandler::freeTexts(char **ptr) {
free(*ptr - DATAALIGNMENT);
free(ptr);
+ ptr = nullptr;
}
void TextHandler::freeAllTexts() {
@@ -242,12 +251,14 @@ void TextHandler::freeAllTexts() {
for (int i = 0; _arrayNouns[i]; i++)
freeTexts(_arrayNouns[i]);
free(_arrayNouns);
+ _arrayNouns = nullptr;
}
if (_arrayVerbs) {
for (int i = 0; _arrayVerbs[i]; i++)
freeTexts(_arrayVerbs[i]);
free(_arrayVerbs);
+ _arrayVerbs = nullptr;
}
freeTexts(_screenNames);
diff --git a/engines/kyra/animator_lok.cpp b/engines/kyra/animator_lok.cpp
index c246eebd46..945a51a4ec 100644
--- a/engines/kyra/animator_lok.cpp
+++ b/engines/kyra/animator_lok.cpp
@@ -491,7 +491,7 @@ Animator_LoK::AnimObject *Animator_LoK::objectAddHead(AnimObject *queue, AnimObj
}
Animator_LoK::AnimObject *Animator_LoK::objectQueue(AnimObject *queue, AnimObject *add) {
- if (add->drawY <= queue->drawY || !queue) {
+ if (!queue || add->drawY <= queue->drawY) {
add->nextAnimObject = queue;
return add;
}
diff --git a/engines/kyra/chargen.cpp b/engines/kyra/chargen.cpp
index 80a95da047..80ff42e2c5 100644
--- a/engines/kyra/chargen.cpp
+++ b/engines/kyra/chargen.cpp
@@ -155,8 +155,10 @@ CharacterGenerator::~CharacterGenerator() {
}
bool CharacterGenerator::start(EoBCharacter *characters, uint8 ***faceShapes) {
- if (!characters && !faceShapes)
+ if (!characters || !faceShapes) {
+ warning("CharacterGenerator::start: Called without character data");
return true;
+ }
_characters = characters;
_faceShapes = *faceShapes;
diff --git a/engines/kyra/configure.engine b/engines/kyra/configure.engine
new file mode 100644
index 0000000000..b7d6334fcc
--- /dev/null
+++ b/engines/kyra/configure.engine
@@ -0,0 +1,5 @@
+# This file is included from the main "configure" script
+# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps]
+add_engine kyra "Kyra" yes "lol eob" "Legend of Kyrandia 1-3"
+add_engine lol "Lands of Lore" yes
+add_engine eob "Eye of the Beholder" yes
diff --git a/engines/kyra/kyra_mr.cpp b/engines/kyra/kyra_mr.cpp
index 48ba96ec8b..a485ae47e4 100644
--- a/engines/kyra/kyra_mr.cpp
+++ b/engines/kyra/kyra_mr.cpp
@@ -378,7 +378,6 @@ void KyraEngine_MR::playVQA(const char *name) {
_screen->fadeToBlack(60);
_screen->clearPage(0);
- vqa.setDrawPage(0);
vqa.play();
vqa.close();
diff --git a/engines/kyra/resource.cpp b/engines/kyra/resource.cpp
index c350c81742..7a1abe8dd9 100644
--- a/engines/kyra/resource.cpp
+++ b/engines/kyra/resource.cpp
@@ -74,10 +74,14 @@ bool Resource::reset() {
loadProtectedFiles(list);
} else {
+ // We only search in the game path to avoid any invalid PAK or
+ // APK files from being picked up. This might happen, for example,
+ // when the user has an Android package file in the CWD.
+ Common::FSDirectory gameDir(dir);
Common::ArchiveMemberList files;
- _files.listMatchingMembers(files, "*.PAK");
- _files.listMatchingMembers(files, "*.APK");
+ gameDir.listMatchingMembers(files, "*.PAK");
+ gameDir.listMatchingMembers(files, "*.APK");
for (Common::ArchiveMemberList::const_iterator i = files.begin(); i != files.end(); ++i) {
Common::String name = (*i)->getName();
diff --git a/engines/kyra/screen_v2.cpp b/engines/kyra/screen_v2.cpp
index cc7d526ffe..23eb94cb53 100644
--- a/engines/kyra/screen_v2.cpp
+++ b/engines/kyra/screen_v2.cpp
@@ -280,7 +280,7 @@ void Screen_v2::setTextColorMap(const uint8 *cmap) {
void Screen_v2::wsaFrameAnimationStep(int x1, int y1, int x2, int y2,
int w1, int h1, int w2, int h2, int srcPage, int dstPage, int dim) {
- if (!(w1 || h1 || w2 || h2))
+ if (!w1 || !h1 || !w2 || !h2)
return;
ScreenDim cdm = *getScreenDim(dim);
diff --git a/engines/kyra/sequences_lok.cpp b/engines/kyra/sequences_lok.cpp
index 2a2f9a5493..51f1ea51cf 100644
--- a/engines/kyra/sequences_lok.cpp
+++ b/engines/kyra/sequences_lok.cpp
@@ -1722,9 +1722,10 @@ int KyraEngine_LoK::handleBeadState() {
_screen->addBitBlitRect(_beadState1.x, _beadState1.y, _beadState1.width2, _beadState1.height);
++_beadState1.tableIndex;
- if (_beadState1.tableIndex > 24)
+ if (_beadState1.tableIndex > 24) {
_beadState1.tableIndex = 0;
_unkEndSeqVar4 = 1;
+ }
if (_system->getMillis() > _beadStateTimer2 && _malcolmFlag == 7 && !_unkAmuletVar && !_text->printed()) {
snd_playSoundEffect(0x0B);
if (_currentCharacter->x1 > 233 && _currentCharacter->x1 < 305 && _currentCharacter->y1 > 85 && _currentCharacter->y1 < 105 &&
diff --git a/engines/kyra/sound_towns.cpp b/engines/kyra/sound_towns.cpp
index af741a1ebe..e4752f33de 100644
--- a/engines/kyra/sound_towns.cpp
+++ b/engines/kyra/sound_towns.cpp
@@ -225,6 +225,7 @@ void SoundTowns::playSoundEffect(uint8 track, uint8) {
_driver->chanPanPos(_sfxChannel, 0x40);
_driver->chanPitch(_sfxChannel, 0);
_driver->playSoundEffect(_sfxChannel, note, 127, sfxPlaybackBuffer);
+ delete[] sfxPlaybackBuffer;
}
void SoundTowns::updateVolumeSettings() {
diff --git a/engines/kyra/staticres.cpp b/engines/kyra/staticres.cpp
index c52b0a04ad..522e12faa4 100644
--- a/engines/kyra/staticres.cpp
+++ b/engines/kyra/staticres.cpp
@@ -1172,7 +1172,7 @@ void GUI_LoK::initStaticResource() {
GUI_V1_MENU_ITEM(_menu[5].item[2], 1, 0, 0, 0, 0xA5, 0, 0x40, 0x80, 0x0F, 252, 253, 5, 0, 248, 249, 250, -1, 0, 0x10, 0x42, 0, 0);
GUI_V1_MENU_ITEM(_menu[5].item[3], 1, 0, 0, 0, 0xA5, 0, 0x51, 0x80, 0x0F, 252, 253, 5, 0, 248, 249, 250, -1, 0, 0x10, 0x53, 0, 0);
GUI_V1_MENU_ITEM(_menu[5].item[4], 1, 0, 0, 0, 0xA5, 0, 0x62, 0x80, 0x0F, 252, 253, 5, 0, 248, 249, 250, -1, 0, 0x10, 0x65, 0, 0);
- GUI_V1_MENU_ITEM(_menu[5].item[5], 1, 0, 0, 0, -1, 0, 0x7F, 0x6C, 0x0F, 252, 253, -1, 255, 248, 249, 250, -1, -0, 0, 0, 0, 0);
+ GUI_V1_MENU_ITEM(_menu[5].item[5], 1, 0, 0, 0, -1, 0, 0x7F, 0x6C, 0x0F, 252, 253, -1, 255, 248, 249, 250, -1, 0, 0, 0, 0, 0);
_menu[5].item[0].callback = BUTTON_FUNCTOR(GUI_LoK, this, &GUI_LoK::controlsChangeMusic);
_menu[5].item[1].callback = BUTTON_FUNCTOR(GUI_LoK, this, &GUI_LoK::controlsChangeSounds);
_menu[5].item[2].callback = BUTTON_FUNCTOR(GUI_LoK, this, &GUI_LoK::controlsChangeWalk);
diff --git a/engines/kyra/vqa.cpp b/engines/kyra/vqa.cpp
index 081d94a050..d9564e1306 100644
--- a/engines/kyra/vqa.cpp
+++ b/engines/kyra/vqa.cpp
@@ -28,644 +28,606 @@
//
// The jung2.vqa movie does work, but only thanks to a grotesque hack.
-
+#include "kyra/kyra_v1.h"
#include "kyra/vqa.h"
-#include "kyra/resource.h"
-
-#include "common/system.h"
+#include "kyra/screen.h"
#include "audio/audiostream.h"
-#include "audio/mixer.h"
#include "audio/decoders/raw.h"
-namespace Kyra {
-
-VQAMovie::VQAMovie(KyraEngine_v1 *vm, OSystem *system) {
- _system = system;
- _vm = vm;
- _screen = _vm->screen();
- _opened = false;
- _x = _y = _drawPage = -1;
- _frame = 0;
- _vectorPointers = 0;
- _numPartialCodeBooks = 0;
- _partialCodeBookSize = 0;
- _compressedCodeBook = 0;
- _partialCodeBook = 0;
- _codeBook = 0;
- _frameInfo = 0;
- memset(_buffers, 0, sizeof(_buffers));
-}
-
-VQAMovie::~VQAMovie() {
- close();
-}
-
-void VQAMovie::initBuffers() {
- for (int i = 0; i < ARRAYSIZE(_buffers); i++) {
- _buffers[i].data = 0;
- _buffers[i].size = 0;
- }
-}
-
-void *VQAMovie::allocBuffer(int num, uint32 size) {
- assert(num >= 0 && num < ARRAYSIZE(_buffers));
- assert(size > 0);
-
- if (size > _buffers[num].size) {
- /*
- * We could use realloc() here, but we don't actually need the
- * old contents of the buffer.
- */
- delete[] _buffers[num].data;
- _buffers[num].data = new uint8[size];
- _buffers[num].size = size;
- }
-
- assert(_buffers[num].data);
+#include "common/system.h"
+#include "common/events.h"
- return _buffers[num].data;
-}
+#include "graphics/palette.h"
+#include "graphics/surface.h"
-void VQAMovie::freeBuffers() {
- for (int i = 0; i < ARRAYSIZE(_buffers); i++) {
- delete[] _buffers[i].data;
- _buffers[i].data = NULL;
- _buffers[i].size = 0;
- }
-}
+namespace Kyra {
-uint32 VQAMovie::readTag() {
+static uint32 readTag(Common::SeekableReadStream *stream) {
// Some tags have to be on an even offset, so they are padded with a
// zero byte. Skip that.
- uint32 tag = _file->readUint32BE();
+ uint32 tag = stream->readUint32BE();
- if (_file->eos())
+ if (stream->eos())
return 0;
if (!(tag & 0xFF000000)) {
- tag = (tag << 8) | _file->readByte();
+ tag = (tag << 8) | stream->readByte();
}
return tag;
}
-void VQAMovie::decodeSND1(byte *inbuf, uint32 insize, byte *outbuf, uint32 outsize) {
- const int8 WSTable2Bit[] = { -2, -1, 0, 1 };
- const int8 WSTable4Bit[] = {
- -9, -8, -6, -5, -4, -3, -2, -1,
- 0, 1, 2, 3, 4, 5, 6, 8
- };
-
- byte code;
- int8 count;
- uint16 input;
-
- int16 curSample = 0x80;
-
- while (outsize > 0) {
- input = *inbuf++ << 2;
- code = (input >> 8) & 0xFF;
- count = (input & 0xFF) >> 2;
-
- switch (code) {
- case 2:
- if (count & 0x20) {
- /* NOTE: count is signed! */
- count <<= 3;
- curSample += (count >> 3);
- *outbuf++ = curSample;
- outsize--;
- } else {
- for (; count >= 0; count--) {
- *outbuf++ = *inbuf++;
- outsize--;
- }
- curSample = *(outbuf - 1);
- }
- break;
- case 1:
- for (; count >= 0; count--) {
- code = *inbuf++;
-
- curSample += WSTable4Bit[code & 0x0F];
- curSample = CLIP<int16>(curSample, 0, 255);
- *outbuf++ = curSample;
-
- curSample += WSTable4Bit[code >> 4];
- curSample = CLIP<int16>(curSample, 0, 255);
- *outbuf++ = curSample;
-
- outsize -= 2;
- }
- break;
- case 0:
- for (; count >= 0; count--) {
- code = *inbuf++;
-
- curSample += WSTable2Bit[code & 0x03];
- curSample = CLIP<int16>(curSample, 0, 255);
- *outbuf++ = curSample;
-
- curSample += WSTable2Bit[(code >> 2) & 0x03];
- curSample = CLIP<int16>(curSample, 0, 255);
- *outbuf++ = curSample;
-
- curSample += WSTable2Bit[(code >> 4) & 0x03];
- curSample = CLIP<int16>(curSample, 0, 255);
- *outbuf++ = curSample;
-
- curSample += WSTable2Bit[(code >> 6) & 0x03];
- curSample = CLIP<int16>(curSample, 0, 255);
- *outbuf++ = curSample;
-
- outsize -= 4;
- }
- break;
- default:
- for (; count >= 0; count--) {
- *outbuf++ = curSample;
- outsize--;
- }
- }
- }
+VQADecoder::VQADecoder() {
+ memset(&_header, 0, sizeof(_header));
}
-bool VQAMovie::open(const char *filename) {
+VQADecoder::~VQADecoder() {
close();
+ delete[] _frameInfo;
+}
- _file = _vm->resource()->createReadStream(filename);
- if (!_file)
- return false;
+bool VQADecoder::loadStream(Common::SeekableReadStream *stream) {
+ close();
+ _fileStream = stream;
- if (_file->readUint32BE() != MKTAG('F','O','R','M')) {
- warning("VQAMovie::open: Cannot find `FORM' tag");
+ if (_fileStream->readUint32BE() != MKTAG('F','O','R','M')) {
+ warning("VQADecoder::loadStream(): Cannot find `FORM' tag");
return false;
}
- // For now, we ignore the size of the FORM chunk.
- _file->readUint32BE();
+ // Ignore the size of the FORM chunk. We're only interested in its
+ // children.
+ _fileStream->readUint32BE();
- if (_file->readUint32BE() != MKTAG('W','V','Q','A')) {
- warning("WQAMovie::open: Cannot find `WVQA' tag");
+ if (_fileStream->readUint32BE() != MKTAG('W','V','Q','A')) {
+ warning("VQADecoder::loadStream(): Cannot find `WVQA' tag");
return false;
}
- bool foundHeader = false;
- bool foundFrameInfo = false;
+ // We want to find both a VQHD chunk containing the header, and a FINF
+ // chunk containing the frame offsets.
+
+ bool foundVQHD = false;
+ bool foundFINF = false;
+
+ VQAAudioTrack *audioTrack = NULL;
// The information we need is stored in two chunks: VQHD and FINF. We
// need both of them before we can begin decoding the movie.
- while (!foundHeader || !foundFrameInfo) {
- uint32 tag = readTag();
- uint32 size = _file->readUint32BE();
+ while (!foundVQHD || !foundFINF) {
+ uint32 tag = readTag(stream);
+ uint32 size = _fileStream->readUint32BE();
switch (tag) {
- case MKTAG('V','Q','H','D'): // VQA header
- _header.version = _file->readUint16LE();
- _header.flags = _file->readUint16LE();
- _header.numFrames = _file->readUint16LE();
- _header.width = _file->readUint16LE();
- _header.height = _file->readUint16LE();
- _header.blockW = _file->readByte();
- _header.blockH = _file->readByte();
- _header.frameRate = _file->readByte();
- _header.cbParts = _file->readByte();
- _header.colors = _file->readUint16LE();
- _header.maxBlocks = _file->readUint16LE();
- _header.unk1 = _file->readUint32LE();
- _header.unk2 = _file->readUint16LE();
- _header.freq = _file->readUint16LE();
- _header.channels = _file->readByte();
- _header.bits = _file->readByte();
- _header.unk3 = _file->readUint32LE();
- _header.unk4 = _file->readUint16LE();
- _header.maxCBFZSize = _file->readUint32LE();
- _header.unk5 = _file->readUint32LE();
-
- // Kyrandia 3 uses version 1 VQA files, and is the only
- // known game to do so. This version of the format has
- // some implicit default values.
-
- if (_header.version == 1) {
- if (_header.freq == 0)
- _header.freq = 22050;
- if (_header.channels == 0)
- _header.channels = 1;
- if (_header.bits == 0)
- _header.bits = 8;
- }
-
- _x = (Screen::SCREEN_W - _header.width) / 2;
- _y = (Screen::SCREEN_H - _header.height) / 2;
-
- _frameInfo = new uint32[_header.numFrames];
- _frame = new byte[_header.width * _header.height];
-
- _codeBookSize = 0xF00 * _header.blockW * _header.blockH;
- _codeBook = new byte[_codeBookSize];
- _partialCodeBook = new byte[_codeBookSize];
- memset(_codeBook, 0, _codeBookSize);
- memset(_partialCodeBook, 0, _codeBookSize);
-
- _numVectorPointers = (_header.width / _header.blockW) * (_header.height * _header.blockH);
- _vectorPointers = new uint16[_numVectorPointers];
- memset(_vectorPointers, 0, _numVectorPointers * sizeof(uint16));
-
- _partialCodeBookSize = 0;
- _numPartialCodeBooks = 0;
-
+ case MKTAG('V','Q','H','D'):
+ handleVQHD(_fileStream);
if (_header.flags & 1) {
- // This VQA movie has sound. Kyrandia 3 uses
- // 8-bit sound, and so far testing indicates
- // that it's all mono.
- //
- // This is good, because it means we won't have
- // to worry about the confusing parts of the
- // VQA spec, where 8- and 16-bit data have
- // different signedness and stereo sample
- // layout varies between different games.
-
- assert(_header.bits == 8);
- assert(_header.channels == 1);
-
- _stream = Audio::makeQueuingAudioStream(_header.freq, false);
- } else {
- _stream = NULL;
+ audioTrack = new VQAAudioTrack(&_header);
+ addTrack(audioTrack);
}
-
- foundHeader = true;
+ foundVQHD = true;
break;
-
- case MKTAG('F','I','N','F'): // Frame info
- if (!foundHeader) {
- warning("VQAMovie::open: Found `FINF' before `VQHD'");
+ case MKTAG('F','I','N','F'):
+ if (!foundVQHD) {
+ warning("VQADecoder::loadStream(): Found `FINF' before `VQHD'");
return false;
}
-
- if (size != 4 * (uint32)_header.numFrames) {
- warning("VQAMovie::open: Expected size %d for `FINF' chunk, but got %u", 4 * _header.numFrames, size);
+ if (size != 4 * getFrameCount()) {
+ warning("VQADecoder::loadStream(): Expected size %d for `FINF' chunk, but got %u", 4 * getFrameCount(), size);
return false;
}
+ handleFINF(_fileStream);
+ foundFINF = true;
+ break;
+ default:
+ warning("VQADecoder::loadStream(): Unknown tag `%s'", tag2str(tag));
+ _fileStream->seek(size, SEEK_CUR);
+ break;
+ }
+ }
- foundFrameInfo = true;
+ return true;
+}
- for (int i = 0; i < _header.numFrames; i++) {
- _frameInfo[i] = 2 * _file->readUint32LE();
- }
+void VQADecoder::handleVQHD(Common::SeekableReadStream *stream) {
+ _header.version = stream->readUint16LE();
+ _header.flags = stream->readUint16LE();
+ _header.numFrames = stream->readUint16LE();
+ _header.width = stream->readUint16LE();
+ _header.height = stream->readUint16LE();
+ _header.blockW = stream->readByte();
+ _header.blockH = stream->readByte();
+ _header.frameRate = stream->readByte();
+ _header.cbParts = stream->readByte();
+ _header.colors = stream->readUint16LE();
+ _header.maxBlocks = stream->readUint16LE();
+ _header.unk1 = stream->readUint32LE();
+ _header.unk2 = stream->readUint16LE();
+ _header.freq = stream->readUint16LE();
+ _header.channels = stream->readByte();
+ _header.bits = stream->readByte();
+ _header.unk3 = stream->readUint32LE();
+ _header.unk4 = stream->readUint16LE();
+ _header.maxCBFZSize = stream->readUint32LE();
+ _header.unk5 = stream->readUint32LE();
+
+ _frameInfo = new uint32[_header.numFrames + 1];
+
+ VQAVideoTrack *videoTrack = new VQAVideoTrack(&_header);
+ addTrack(videoTrack);
+
+ // Kyrandia 3 uses version 1 VQA files, and is the only known game to
+ // do so. This version of the format has some implicit default values.
+
+ if (_header.version == 1) {
+ if (_header.freq == 0)
+ _header.freq = 22050;
+ if (_header.channels == 0)
+ _header.channels = 1;
+ if (_header.bits == 0)
+ _header.bits = 8;
+ }
- // HACK: This flag is set in jung2.vqa, and its
- // purpose, if it has one, is unknown. It can't be a
- // general purpose flag, because in large movies the
- // frame offsets can be large enough to set this flag,
- // though of course never for the first frame.
- //
- // At least in my copy of Kyrandia 3, _frameInfo[0] is
- // 0x81000098, and the desired index is 0x4716. So the
- // value should be 0x80004716, but I don't want to
- // hard-code it. Instead, scan the file for the offset
- // to the first VQFR chunk.
-
- if (_frameInfo[0] & 0x01000000) {
- uint32 oldPos = _file->pos();
-
- while (1) {
- uint32 scanTag = readTag();
- uint32 scanSize = _file->readUint32BE();
-
- if (_file->eos())
- break;
-
- if (scanTag == MKTAG('V','Q','F','R')) {
- _frameInfo[0] = (_file->pos() - 8) | 0x80000000;
- break;
- }
+ if (_header.flags & 1) {
+ // Kyrandia 3 uses 8-bit sound, and so far testing indicates
+ // that it's all mono.
+ //
+ // This is good, because it means we won't have to worry about
+ // the confusing parts of the VQA spec, where 8- and 16-bit
+ // data have different signedness and stereo sample layout
+ // varies between different games.
+
+ assert(_header.bits == 8);
+ assert(_header.channels == 1);
+ }
+}
- _file->seek(scanSize, SEEK_CUR);
- }
+void VQADecoder::handleFINF(Common::SeekableReadStream *stream) {
+ for (int i = 0; i < _header.numFrames; i++) {
+ _frameInfo[i] = 2 * stream->readUint32LE();
+ }
- _file->seek(oldPos);
- }
+ // HACK: This flag is set in jung2.vqa, and its purpose - if it has
+ // one - is currently unknown. It can't be a general purpose flag,
+ // because in large movies the frame offset can be large enough to
+ // set this flag, though of course never for the first frame.
+ //
+ // At least in my copy of Kyrandia 3, _frameInfo[0] is 0x81000098, and
+ // the desired index is 0x4716. So the value should be 0x80004716, but
+ // I don't want to hard-code it. Instead, scan the file for the offset
+ // to the first VQFR chunk.
- break;
+ if (_frameInfo[0] & 0x01000000) {
+ uint32 oldPos = stream->pos();
- default:
- warning("VQAMovie::open: Unknown tag `%c%c%c%c'", char((tag >> 24) & 0xFF), char((tag >> 16) & 0xFF), char((tag >> 8) & 0xFF), char(tag & 0xFF));
- _file->seek(size, SEEK_CUR);
- }
- }
+ while (1) {
+ uint32 scanTag = readTag(stream);
+ uint32 scanSize = stream->readUint32BE();
- initBuffers();
+ if (stream->eos())
+ break;
- _opened = true;
- return true;
-}
+ if (scanTag == MKTAG('V','Q','F','R')) {
+ _frameInfo[0] = (stream->pos() - 8) | 0x80000000;
+ break;
+ }
-void VQAMovie::close() {
- if (_opened) {
- delete[] _frameInfo;
- delete[] _frame;
- delete[] _codeBook;
- delete[] _partialCodeBook;
- delete[] _vectorPointers;
-
- if (_vm->_mixer->isSoundHandleActive(_sound))
- _vm->_mixer->stopHandle(_sound);
-
- _frameInfo = NULL;
- _frame = NULL;
- _codeBookSize = 0;
- _codeBook = NULL;
- _partialCodeBook = NULL;
- _vectorPointers = NULL;
- _stream = NULL;
-
- delete _file;
- _file = 0;
-
- freeBuffers();
-
- _opened = false;
+ stream->seek(scanSize, SEEK_CUR);
+ }
+
+ stream->seek(oldPos);
}
+
+ _frameInfo[_header.numFrames] = 0x7FFFFFFF;
}
-void VQAMovie::displayFrame(uint frameNum) {
- if (frameNum >= _header.numFrames || !_opened)
- return;
+void VQADecoder::readNextPacket() {
+ VQAVideoTrack *videoTrack = (VQAVideoTrack *)getTrack(0);
+ VQAAudioTrack *audioTrack = (VQAAudioTrack *)getTrack(1);
- bool foundSound = !_stream;
- bool foundFrame = false;
- uint i;
+ assert(videoTrack);
- _file->seek(_frameInfo[frameNum] & 0x7FFFFFFF);
+ int curFrame = videoTrack->getCurFrame();
- while (!foundSound || !foundFrame) {
- uint32 tag = readTag();
- uint32 size = _file->readUint32BE();
+ // Stop if reading the tag is enough to put us ahead of the next frame
+ int32 end = (_frameInfo[curFrame + 1] & 0x7FFFFFFF) - 7;
- if (_file->eos()) {
- // This happens at the last frame. Apparently it has
- // no sound?
- break;
+ // At this point, we probably only need to adjust for the offset in the
+ // stream to be even. But we may as well do this to really make sure
+ // we have the correct offset.
+ if (curFrame >= 0) {
+ _fileStream->seek(_frameInfo[curFrame] & 0x7FFFFFFF);
+ if (_frameInfo[curFrame] & 0x80000000) {
+ videoTrack->setHasDirtyPalette();
}
+ }
- byte *inbuf, *outbuf;
- uint32 insize, outsize;
- int32 end;
+ while (!_fileStream->eos() && _fileStream->pos() < end) {
+ uint32 tag = readTag(_fileStream);
+ uint32 size;
switch (tag) {
case MKTAG('S','N','D','0'): // Uncompressed sound
- foundSound = true;
- inbuf = (byte *)malloc(size);
- _file->read(inbuf, size);
- assert(_stream);
- _stream->queueBuffer(inbuf, size, DisposeAfterUse::YES, Audio::FLAG_UNSIGNED);
+ assert(audioTrack);
+ audioTrack->handleSND0(_fileStream);
break;
-
case MKTAG('S','N','D','1'): // Compressed sound, almost like AUD
- foundSound = true;
- outsize = _file->readUint16LE();
- insize = _file->readUint16LE();
-
- inbuf = (byte *)malloc(insize);
- _file->read(inbuf, insize);
-
- if (insize == outsize) {
- assert(_stream);
- _stream->queueBuffer(inbuf, insize, DisposeAfterUse::YES, Audio::FLAG_UNSIGNED);
- } else {
- outbuf = (byte *)malloc(outsize);
- decodeSND1(inbuf, insize, outbuf, outsize);
- assert(_stream);
- _stream->queueBuffer(outbuf, outsize, DisposeAfterUse::YES, Audio::FLAG_UNSIGNED);
- free(inbuf);
- }
+ assert(audioTrack);
+ audioTrack->handleSND1(_fileStream);
break;
-
case MKTAG('S','N','D','2'): // Compressed sound
- foundSound = true;
- warning("VQAMovie::displayFrame: `SND2' is not implemented");
- _file->seek(size, SEEK_CUR);
+ assert(audioTrack);
+ audioTrack->handleSND2(_fileStream);
break;
-
case MKTAG('V','Q','F','R'):
- foundFrame = true;
- end = _file->pos() + size - 8;
-
- while (_file->pos() < end) {
- tag = readTag();
- size = _file->readUint32BE();
-
- switch (tag) {
- case MKTAG('C','B','F','0'): // Full codebook
- _file->read(_codeBook, size);
- break;
+ videoTrack->handleVQFR(_fileStream);
+ break;
+ case MKTAG('C','M','D','S'):
+ // The purpose of this is unknown, but it's known to
+ // exist so don't warn about it.
+ size = _fileStream->readUint32BE();
+ _fileStream->seek(size, SEEK_CUR);
+ break;
+ default:
+ warning("VQADecoder::readNextPacket(): Unknown tag `%s'", tag2str(tag));
+ size = _fileStream->readUint32BE();
+ _fileStream->seek(size, SEEK_CUR);
+ break;
+ }
+ }
+}
- case MKTAG('C','B','F','Z'): // Full codebook
- inbuf = (byte *)allocBuffer(0, size);
- _file->read(inbuf, size);
- Screen::decodeFrame4(inbuf, _codeBook, _codeBookSize);
- break;
+// -----------------------------------------------------------------------
- case MKTAG('C','B','P','0'): // Partial codebook
- _compressedCodeBook = false;
- _file->read(_partialCodeBook + _partialCodeBookSize, size);
- _partialCodeBookSize += size;
- _numPartialCodeBooks++;
- break;
+VQADecoder::VQAAudioTrack::VQAAudioTrack(const VQAHeader *header) {
+ _audioStream = Audio::makeQueuingAudioStream(header->freq, false);
+}
- case MKTAG('C','B','P','Z'): // Partial codebook
- _compressedCodeBook = true;
- _file->read(_partialCodeBook + _partialCodeBookSize, size);
- _partialCodeBookSize += size;
- _numPartialCodeBooks++;
- break;
+VQADecoder::VQAAudioTrack::~VQAAudioTrack() {
+ delete _audioStream;
+}
- case MKTAG('C','P','L','0'): // Palette
- assert(size <= 3 * 256);
- _file->read(_screen->getPalette(0).getData(), size);
- break;
+Audio::AudioStream *VQADecoder::VQAAudioTrack::getAudioStream() const {
+ return _audioStream;
+}
- case MKTAG('C','P','L','Z'): // Palette
- inbuf = (byte *)allocBuffer(0, size);
- _file->read(inbuf, size);
- Screen::decodeFrame4(inbuf, _screen->getPalette(0).getData(), 768);
- break;
+void VQADecoder::VQAAudioTrack::handleSND0(Common::SeekableReadStream *stream) {
+ uint32 size = stream->readUint32BE();
+ byte *buf = (byte *)malloc(size);
+ stream->read(buf, size);
+ _audioStream->queueBuffer(buf, size, DisposeAfterUse::YES, Audio::FLAG_UNSIGNED);
+}
- case MKTAG('V','P','T','0'): // Frame data
- assert(size / 2 <= _numVectorPointers);
+void VQADecoder::VQAAudioTrack::handleSND1(Common::SeekableReadStream *stream) {
+ stream->readUint32BE();
+ uint16 outsize = stream->readUint16LE();
+ uint16 insize = stream->readUint16LE();
+ byte *inbuf = (byte *)malloc(insize);
+
+ stream->read(inbuf, insize);
+
+ if (insize == outsize) {
+ _audioStream->queueBuffer(inbuf, insize, DisposeAfterUse::YES, Audio::FLAG_UNSIGNED);
+ } else {
+ const int8 WSTable2Bit[] = { -2, -1, 0, 1 };
+ const int8 WSTable4Bit[] = {
+ -9, -8, -6, -5, -4, -3, -2, -1,
+ 0, 1, 2, 3, 4, 5, 6, 8
+ };
+
+ byte *outbuf = (byte *)malloc(outsize);
+ byte *in = inbuf;
+ byte *out = outbuf;
+ int16 curSample = 0x80;
+ uint16 bytesLeft = outsize;
+
+ while (bytesLeft > 0) {
+ uint16 input = *in++ << 2;
+ byte code = (input >> 8) & 0xFF;
+ int8 count = (input & 0xFF) >> 2;
+ int i;
+
+ switch (code) {
+ case 2:
+ if (count & 0x20) {
+ /* NOTE: count is signed! */
+ count <<= 3;
+ curSample += (count >> 3);
+ *out++ = curSample;
+ bytesLeft--;
+ } else {
+ for (; count >= 0; count--) {
+ *out++ = *in++;
+ bytesLeft--;
+ }
+ curSample = *(out - 1);
+ }
+ break;
+ case 1:
+ for (; count >= 0; count--) {
+ code = *in++;
- for (i = 0; i < size / 2; i++)
- _vectorPointers[i] = _file->readUint16LE();
- break;
+ for (i = 0; i < 2; i++) {
+ curSample += WSTable4Bit[code & 0x0F];
+ curSample = CLIP<int16>(curSample, 0, 255);
+ code >>= 4;
+ *out++ = curSample;
+ }
- case MKTAG('V','P','T','Z'): // Frame data
- inbuf = (byte *)allocBuffer(0, size);
- outbuf = (byte *)allocBuffer(1, 2 * _numVectorPointers);
+ bytesLeft -= 2;
+ }
+ break;
+ case 0:
+ for (; count >= 0; count--) {
+ code = *in++;
- _file->read(inbuf, size);
- size = Screen::decodeFrame4(inbuf, outbuf, 2 * _numVectorPointers);
+ for (i = 0; i < 4; i++) {
+ curSample += WSTable2Bit[code & 0x03];
+ curSample = CLIP<int16>(curSample, 0, 255);
+ code >>= 2;
+ *out++ = curSample;
+ }
- assert(size / 2 <= _numVectorPointers);
+ bytesLeft -= 4;
+ }
+ break;
+ default:
+ for (; count >= 0; count--) {
+ *out++ = curSample;
+ bytesLeft--;
+ }
+ break;
+ }
+ }
+ _audioStream->queueBuffer(outbuf, outsize, DisposeAfterUse::YES, Audio::FLAG_UNSIGNED);
+ free(inbuf);
+ }
+}
- for (i = 0; i < size / 2; i++)
- _vectorPointers[i] = READ_LE_UINT16(outbuf + 2 * i);
- break;
+void VQADecoder::VQAAudioTrack::handleSND2(Common::SeekableReadStream *stream) {
+ uint32 size = stream->readUint32BE();
+ warning("VQADecoder::VQAAudioTrack::handleSND2(): `SND2' is not implemented");
+ stream->seek(size, SEEK_CUR);
+}
- default:
- warning("VQAMovie::displayFrame: Unknown `VQFR' sub-tag `%c%c%c%c'", char((tag >> 24) & 0xFF), char((tag >> 16) & 0xFF), char((tag >> 8) & 0xFF), char(tag & 0xFF));
- _file->seek(size, SEEK_CUR);
- }
+// -----------------------------------------------------------------------
- }
+VQADecoder::VQAVideoTrack::VQAVideoTrack(const VQAHeader *header) {
+ memset(_palette, 0, sizeof(_palette));
+ _dirtyPalette = false;
- break;
+ _width = header->width;
+ _height = header->height;
+ _blockW = header->blockW;
+ _blockH = header->blockH;
+ _cbParts = header->cbParts;
- default:
- warning("VQAMovie::displayFrame: Unknown tag `%c%c%c%c'", char((tag >> 24) & 0xFF), char((tag >> 16) & 0xFF), char((tag >> 8) & 0xFF), char(tag & 0xFF));
- _file->seek(size, SEEK_CUR);
- }
- }
+ _newFrame = false;
- // The frame has been decoded
+ _curFrame = -1;
+ _frameCount = header->numFrames;
+ _frameRate = header->frameRate;
- if (_frameInfo[frameNum] & 0x80000000)
- _screen->setScreenPalette(_screen->getPalette(0));
+ _codeBookSize = 0xF00 * header->blockW * header->blockH;
+ _compressedCodeBook = false;
+ _codeBook = new byte[_codeBookSize];
+ _partialCodeBookSize = 0;
+ _numPartialCodeBooks = 0;
+ _partialCodeBook = new byte[_codeBookSize];
+ _numVectorPointers = (header->width / header->blockW) * (header->height * header->blockH);
+ _vectorPointers = new uint16[_numVectorPointers];
- int blockPitch = _header.width / _header.blockW;
+ memset(_codeBook, 0, _codeBookSize);
+ memset(_partialCodeBook, 0, _codeBookSize);
+ memset(_vectorPointers, 0, _numVectorPointers);
- for (int by = 0; by < _header.height / _header.blockH; by++) {
- for (int bx = 0; bx < blockPitch; bx++) {
- byte *dst = _frame + by * _header.width * _header.blockH + bx * _header.blockW;
- int val = _vectorPointers[by * blockPitch + bx];
+ _surface = new Graphics::Surface();
+ _surface->create(header->width, header->height, Graphics::PixelFormat::createFormatCLUT8());
+}
- if ((val & 0xFF00) == 0xFF00) {
- // Solid color
- for (i = 0; i < _header.blockH; i++) {
- memset(dst, 255 - (val & 0xFF), _header.blockW);
- dst += _header.width;
- }
- } else {
- // Copy data from _vectorPointers. I'm not sure
- // why we don't use the three least significant
- // bits of 'val'.
- byte *src = &_codeBook[(val >> 3) * _header.blockW * _header.blockH];
-
- for (i = 0; i < _header.blockH; i++) {
- memcpy(dst, src, _header.blockW);
- src += _header.blockW;
- dst += _header.width;
- }
- }
- }
- }
+VQADecoder::VQAVideoTrack::~VQAVideoTrack() {
+ _surface->free();
+ delete _surface;
+ delete[] _codeBook;
+ delete[] _partialCodeBook;
+ delete[] _vectorPointers;
+}
- if (_numPartialCodeBooks == _header.cbParts) {
- if (_compressedCodeBook) {
- Screen::decodeFrame4(_partialCodeBook, _codeBook, _codeBookSize);
- } else {
- memcpy(_codeBook, _partialCodeBook, _partialCodeBookSize);
- }
- _numPartialCodeBooks = 0;
- _partialCodeBookSize = 0;
- }
+uint16 VQADecoder::VQAVideoTrack::getWidth() const {
+ return _width;
+}
- _screen->copyBlockToPage(_drawPage, _x, _y, _header.width, _header.height, _frame);
+uint16 VQADecoder::VQAVideoTrack::getHeight() const {
+ return _height;
}
-void VQAMovie::play() {
- uint32 startTick;
+Graphics::PixelFormat VQADecoder::VQAVideoTrack::getPixelFormat() const {
+ return _surface->format;
+}
- if (!_opened)
- return;
+int VQADecoder::VQAVideoTrack::getCurFrame() const {
+ return _curFrame;
+}
- startTick = _system->getMillis();
+int VQADecoder::VQAVideoTrack::getFrameCount() const {
+ return _frameCount;
+}
- // First, handle any sound chunk that appears before the first frame.
- // At least in some versions, it will contain half a second of audio,
- // presumably to lessen the risk of audio underflow.
- //
- // In most movies, we will find a CMDS tag. The purpose of this is
- // currently unknown.
- //
- // In cow1_0.vqa, cow1_1.vqa, jung0.vqa, and jung1.vqa we will find a
- // VQFR tag. A frame before the first frame? Weird. It doesn't seem to
- // be needed, though.
+Common::Rational VQADecoder::VQAVideoTrack::getFrameRate() const {
+ return _frameRate;
+}
- byte *inbuf, *outbuf;
- uint32 insize, outsize;
+void VQADecoder::VQAVideoTrack::setHasDirtyPalette() {
+ _dirtyPalette = true;
+}
- if (_stream) {
- while ((uint)_file->pos() < (_frameInfo[0] & 0x7FFFFFFF)) {
- uint32 tag = readTag();
- uint32 size = _file->readUint32BE();
+bool VQADecoder::VQAVideoTrack::hasDirtyPalette() const {
+ return _dirtyPalette;
+}
- if (_file->eos()) {
- warning("VQAMovie::play: Unexpected EOF");
- break;
- }
+const byte *VQADecoder::VQAVideoTrack::getPalette() const {
+ _dirtyPalette = false;
+ return _palette;
+}
- switch (tag) {
- case MKTAG('S','N','D','0'): // Uncompressed sound
- inbuf = (byte *)malloc(size);
- _file->read(inbuf, size);
- _stream->queueBuffer(inbuf, size, DisposeAfterUse::YES, Audio::FLAG_UNSIGNED);
- break;
+const Graphics::Surface *VQADecoder::VQAVideoTrack::decodeNextFrame() {
+ if (_newFrame) {
+ _newFrame = false;
- case MKTAG('S','N','D','1'): // Compressed sound
- outsize = _file->readUint16LE();
- insize = _file->readUint16LE();
+ int blockPitch = _width / _blockW;
- inbuf = (byte *)malloc(insize);
- _file->read(inbuf, insize);
+ for (int by = 0; by < _height / _blockH; by++) {
+ for (int bx = 0; bx < blockPitch; bx++) {
+ byte *dst = (byte *)_surface->getBasePtr(bx * _blockW, by * _blockH);
+ int val = _vectorPointers[by * blockPitch + bx];
+ int i;
- if (insize == outsize) {
- _stream->queueBuffer(inbuf, insize, DisposeAfterUse::YES, Audio::FLAG_UNSIGNED);
+ if ((val & 0xFF00) == 0xFF00) {
+ // Solid color
+ for (i = 0; i < _blockH; i++) {
+ memset(dst, 255 - (val & 0xFF), _blockW);
+ dst += _width;
+ }
} else {
- outbuf = (byte *)malloc(outsize);
- decodeSND1(inbuf, insize, outbuf, outsize);
- _stream->queueBuffer(outbuf, outsize, DisposeAfterUse::YES, Audio::FLAG_UNSIGNED);
- free(inbuf);
+ // Copy data from _vectorPointers. I'm not sure
+ // why we don't use the three least significant
+ // bits of 'val'.
+ byte *src = &_codeBook[(val >> 3) * _blockW * _blockH];
+
+ for (i = 0; i < _blockH; i++) {
+ memcpy(dst, src, _blockW);
+ src += _blockW;
+ dst += _width;
+ }
}
- break;
+ }
+ }
- case MKTAG('S','N','D','2'): // Compressed sound
- warning("VQAMovie::play: `SND2' is not implemented");
- _file->seek(size, SEEK_CUR);
- break;
+ if (_numPartialCodeBooks == _cbParts) {
+ if (_compressedCodeBook) {
+ Screen::decodeFrame4(_partialCodeBook, _codeBook, _codeBookSize);
+ } else {
+ memcpy(_codeBook, _partialCodeBook, _partialCodeBookSize);
+ }
+ _numPartialCodeBooks = 0;
+ _partialCodeBookSize = 0;
+ }
+ }
- case MKTAG('C','M','D','S'): // Unused tag, always empty in kyra3
- _file->seek(size, SEEK_CUR);
- break;
+ _curFrame++;
+ return _surface;
+}
- default:
- warning("VQAMovie::play: Unknown tag `%c%c%c%c'", char((tag >> 24) & 0xFF), char((tag >> 16) & 0xFF), char((tag >> 8) & 0xFF), char(tag & 0xFF));
- _file->seek(size, SEEK_CUR);
- }
+void VQADecoder::VQAVideoTrack::handleVQFR(Common::SeekableReadStream *stream) {
+ uint32 size = stream->readUint32BE();
+ int32 end = stream->pos() + size - 8;
+ byte *inbuf;
+
+ _newFrame = true;
+
+ while (stream->pos() < end) {
+ uint32 tag = readTag(stream);
+ uint32 i;
+ size = stream->readUint32BE();
+
+ switch (tag) {
+ case MKTAG('C','B','F','0'): // Full codebook
+ stream->read(_codeBook, size);
+ break;
+ case MKTAG('C','B','F','Z'): // Full codebook
+ inbuf = (byte *)malloc(size);
+ stream->read(inbuf, size);
+ Screen::decodeFrame4(inbuf, _codeBook, _codeBookSize);
+ free(inbuf);
+ break;
+ case MKTAG('C','B','P','0'): // Partial codebook
+ _compressedCodeBook = false;
+ stream->read(_partialCodeBook + _partialCodeBookSize, size);
+ _partialCodeBookSize += size;
+ _numPartialCodeBooks++;
+ break;
+ case MKTAG('C','B','P','Z'): // Partial codebook
+ _compressedCodeBook = true;
+ stream->read(_partialCodeBook + _partialCodeBookSize, size);
+ _partialCodeBookSize += size;
+ _numPartialCodeBooks++;
+ break;
+ case MKTAG('C','P','L','0'): // Palette
+ assert(size <= 3 * 256);
+ stream->read(_palette, size);
+ break;
+ case MKTAG('C','P','L','Z'): // Palette
+ inbuf = (byte *)malloc(size);
+ stream->read(inbuf, size);
+ Screen::decodeFrame4(inbuf, _palette, 3 * 256);
+ free(inbuf);
+ break;
+ case MKTAG('V','P','T','0'): // Frame data
+ assert(size / 2 <= _numVectorPointers);
+ for (i = 0; i < size / 2; i++)
+ _vectorPointers[i] = stream->readUint16LE();
+ break;
+ case MKTAG('V','P','T','Z'): // Frame data
+ inbuf = (byte *)malloc(size);
+ stream->read(inbuf, size);
+ size = Screen::decodeFrame4(inbuf, (uint8 *)_vectorPointers, 2 * _numVectorPointers);
+ for (i = 0; i < size / 2; i++)
+ _vectorPointers[i] = TO_LE_16(_vectorPointers[i]);
+ free(inbuf);
+ break;
+ default:
+ warning("VQADecoder::VQAVideoTrack::handleVQFR(): Unknown `VQFR' sub-tag `%s'", tag2str(tag));
+ stream->seek(size, SEEK_CUR);
+ break;
}
}
+}
- _vm->_mixer->playStream(Audio::Mixer::kSFXSoundType, &_sound, _stream);
- Common::EventManager *eventMan = _vm->getEventManager();
+// -----------------------------------------------------------------------
- for (uint i = 0; i < _header.numFrames; i++) {
- displayFrame(i);
+VQAMovie::VQAMovie(KyraEngine_v1 *vm, OSystem *system) {
+ _system = system;
+ _vm = vm;
+ _screen = _vm->screen();
+ _decoder = new VQADecoder();
+}
- // TODO: Implement frame skipping?
+VQAMovie::~VQAMovie() {
+ close();
+ delete _decoder;
+}
- while (1) {
- uint32 elapsedTime;
+bool VQAMovie::open(const char *filename) {
+ if (_file.open(filename)) {
+ return true;
+ }
+ return false;
+}
+
+void VQAMovie::close() {
+ if (_file.isOpen()) {
+ _file.close();
+ }
+}
+
+void VQAMovie::play() {
+ if (_decoder->loadStream(&_file)) {
+ Common::EventManager *eventMan = _vm->getEventManager();
+ int width = _decoder->getWidth();
+ int height = _decoder->getHeight();
+ int x = (Screen::SCREEN_W - width) / 2;
+ int y = (Screen::SCREEN_H - height) / 2;
- if (_vm->_mixer->isSoundHandleActive(_sound))
- elapsedTime = _vm->_mixer->getSoundElapsedTime(_sound);
- else
- elapsedTime = _system->getMillis() - startTick;
+ _decoder->start();
- if (elapsedTime >= (i * 1000) / _header.frameRate)
- break;
+ // Note that decoding starts at frame -1. That's because there
+ // is usually sound data before the first frame, probably to
+ // avoid sound underflow.
+ while (!_decoder->endOfVideo()) {
Common::Event event;
while (eventMan->pollEvent(event)) {
switch (event.type) {
@@ -673,23 +635,32 @@ void VQAMovie::play() {
if (event.kbd.keycode == Common::KEYCODE_ESCAPE)
return;
break;
-
case Common::EVENT_RTL:
case Common::EVENT_QUIT:
return;
-
default:
break;
}
}
+ if (_decoder->needsUpdate()) {
+ const Graphics::Surface *surface = _decoder->decodeNextFrame();
+ if (_decoder->hasDirtyPalette()) {
+ const byte *decoderPalette = _decoder->getPalette();
+ byte systemPalette[256 * 3];
+ for (int i = 0; i < ARRAYSIZE(systemPalette); i++) {
+ systemPalette[i] = (decoderPalette[i] * 0xFF) / 0x3F;
+ }
+ _system->getPaletteManager()->setPalette(systemPalette, 0, 256);
+ }
+
+ _system->copyRectToScreen((const byte *)surface->getBasePtr(0, 0), surface->pitch, x, y, width, height);
+ }
+
+ _system->updateScreen();
_system->delayMillis(10);
}
-
- _screen->updateScreen();
}
-
- // TODO: Wait for the sound to finish?
}
} // End of namespace Kyra
diff --git a/engines/kyra/vqa.h b/engines/kyra/vqa.h
index 839bf5ac48..f3890107a8 100644
--- a/engines/kyra/vqa.h
+++ b/engines/kyra/vqa.h
@@ -23,9 +23,9 @@
#ifndef KYRA_VQA_H
#define KYRA_VQA_H
-#include "common/scummsys.h"
-
-#include "audio/mixer.h"
+#include "video/video_decoder.h"
+#include "common/file.h"
+#include "common/rational.h"
class OSystem;
@@ -33,40 +33,24 @@ namespace Audio {
class QueuingAudioStream;
} // End of namespace Audio
-namespace Common {
-class SeekableReadStream;
-} // End of namespace Common
-
namespace Kyra {
class KyraEngine_v1;
class Screen;
-class VQAMovie {
+class VQADecoder : public Video::VideoDecoder {
public:
- VQAMovie(KyraEngine_v1 *vm, OSystem *system);
- ~VQAMovie();
+ VQADecoder();
+ virtual ~VQADecoder();
- bool opened() { return _opened; }
- int frames() { return _opened ? _header.numFrames : -1; }
+ bool loadStream(Common::SeekableReadStream *stream);
+ void readNextPacket();
- // It's unlikely that we ever want to change the movie position from
- // its default.
+private:
+ Common::SeekableReadStream *_fileStream;
- void setDrawPage(int page) { _drawPage = page; }
-
- bool open(const char *filename);
- void close();
- void play();
-
-protected:
- OSystem *_system;
- KyraEngine_v1 *_vm;
- Screen *_screen;
-
- bool _opened;
- int _x, _y;
- int _drawPage;
+ void handleVQHD(Common::SeekableReadStream *stream);
+ void handleFINF(Common::SeekableReadStream *stream);
struct VQAHeader {
uint16 version;
@@ -91,40 +75,85 @@ protected:
uint32 unk5;
};
- struct Buffer {
- uint8 *data;
- uint32 size;
- };
-
- Buffer _buffers[2];
-
- void initBuffers();
- void *allocBuffer(int num, uint32 size);
- void freeBuffers();
+ VQAHeader _header;
+ uint32 *_frameInfo;
- void decodeSND1(byte *inbuf, uint32 insize, byte *outbuf, uint32 outsize);
+ class VQAAudioTrack : public AudioTrack {
+ public:
+ VQAAudioTrack(const VQAHeader *header);
+ ~VQAAudioTrack();
- void displayFrame(uint frameNum);
+ void handleSND0(Common::SeekableReadStream *stream);
+ void handleSND1(Common::SeekableReadStream *stream);
+ void handleSND2(Common::SeekableReadStream *stream);
- Common::SeekableReadStream *_file;
+ protected:
+ Audio::AudioStream *getAudioStream() const;
- VQAHeader _header;
- uint32 *_frameInfo;
- uint32 _codeBookSize;
- byte *_codeBook;
- byte *_partialCodeBook;
- bool _compressedCodeBook;
- int _partialCodeBookSize;
- int _numPartialCodeBooks;
- uint32 _numVectorPointers;
- uint16 *_vectorPointers;
+ private:
+ Audio::QueuingAudioStream *_audioStream;
+ };
- byte *_frame;
+ class VQAVideoTrack : public FixedRateVideoTrack {
+ public:
+ VQAVideoTrack(const VQAHeader *header);
+ ~VQAVideoTrack();
+
+ uint16 getWidth() const;
+ uint16 getHeight() const;
+ Graphics::PixelFormat getPixelFormat() const;
+ int getCurFrame() const;
+ int getFrameCount() const;
+ const Graphics::Surface *decodeNextFrame();
+
+ void setHasDirtyPalette();
+ bool hasDirtyPalette() const;
+ const byte *getPalette() const;
+
+ void handleVQFR(Common::SeekableReadStream *stream);
+
+ protected:
+ Common::Rational getFrameRate() const;
+
+ private:
+ Graphics::Surface *_surface;
+ byte _palette[3 * 256];
+ mutable bool _dirtyPalette;
+
+ bool _newFrame;
+
+ uint16 _width, _height;
+ uint8 _blockW, _blockH;
+ uint8 _cbParts;
+ int _frameCount;
+ int _curFrame;
+ byte _frameRate;
+
+ uint32 _codeBookSize;
+ bool _compressedCodeBook;
+ byte *_codeBook;
+ int _partialCodeBookSize;
+ int _numPartialCodeBooks;
+ byte *_partialCodeBook;
+ uint32 _numVectorPointers;
+ uint16 *_vectorPointers;
+ };
+};
- Audio::QueuingAudioStream *_stream;
- Audio::SoundHandle _sound;
+class VQAMovie {
+public:
+ VQAMovie(KyraEngine_v1 *vm, OSystem *system);
+ ~VQAMovie();
- uint32 readTag();
+ bool open(const char *filename);
+ void close();
+ void play();
+private:
+ OSystem *_system;
+ KyraEngine_v1 *_vm;
+ Screen *_screen;
+ VQADecoder *_decoder;
+ Common::File _file;
};
} // End of namespace Kyra
diff --git a/engines/lastexpress/configure.engine b/engines/lastexpress/configure.engine
new file mode 100644
index 0000000000..807b1a088b
--- /dev/null
+++ b/engines/lastexpress/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 lastexpress "The Last Express" no "" "" "16bit"
diff --git a/engines/lastexpress/entities/abbot.cpp b/engines/lastexpress/entities/abbot.cpp
index 406b017d3a..cdd9d8e712 100644
--- a/engines/lastexpress/entities/abbot.cpp
+++ b/engines/lastexpress/entities/abbot.cpp
@@ -57,42 +57,42 @@ Abbot::Abbot(LastExpressEngine *engine) : Entity(engine, kEntityAbbot) {
ADD_CALLBACK_FUNCTION(Abbot, chapter1);
ADD_CALLBACK_FUNCTION(Abbot, chapter2);
ADD_CALLBACK_FUNCTION(Abbot, chapter3);
- ADD_CALLBACK_FUNCTION(Abbot, chapter3Handler);
- ADD_CALLBACK_FUNCTION(Abbot, conversationWithBoutarel);
+ ADD_CALLBACK_FUNCTION(Abbot, inKitchen);
+ ADD_CALLBACK_FUNCTION(Abbot, openCompartment);
ADD_CALLBACK_FUNCTION(Abbot, readPaper);
ADD_CALLBACK_FUNCTION(Abbot, goToLunch);
ADD_CALLBACK_FUNCTION(Abbot, haveLunch);
- ADD_CALLBACK_FUNCTION(Abbot, function23);
- ADD_CALLBACK_FUNCTION(Abbot, function24);
- ADD_CALLBACK_FUNCTION(Abbot, function25);
- ADD_CALLBACK_FUNCTION(Abbot, function26);
- ADD_CALLBACK_FUNCTION(Abbot, function27);
- ADD_CALLBACK_FUNCTION(Abbot, function28);
- ADD_CALLBACK_FUNCTION(Abbot, function29);
- ADD_CALLBACK_FUNCTION(Abbot, function30);
- ADD_CALLBACK_FUNCTION(Abbot, function31);
- ADD_CALLBACK_FUNCTION(Abbot, function32);
- ADD_CALLBACK_FUNCTION(Abbot, function33);
- ADD_CALLBACK_FUNCTION(Abbot, function34);
- ADD_CALLBACK_FUNCTION(Abbot, function35);
- ADD_CALLBACK_FUNCTION(Abbot, function36);
- ADD_CALLBACK_FUNCTION(Abbot, function37);
- ADD_CALLBACK_FUNCTION(Abbot, function38);
+ ADD_CALLBACK_FUNCTION(Abbot, leaveLunch);
+ ADD_CALLBACK_FUNCTION(Abbot, closedCompartment);
+ ADD_CALLBACK_FUNCTION(Abbot, goSalon1);
+ ADD_CALLBACK_FUNCTION(Abbot, inSalon1);
+ ADD_CALLBACK_FUNCTION(Abbot, goCompartment);
+ ADD_CALLBACK_FUNCTION(Abbot, openCompartment2);
+ ADD_CALLBACK_FUNCTION(Abbot, goWander);
+ ADD_CALLBACK_FUNCTION(Abbot, goSalon2);
+ ADD_CALLBACK_FUNCTION(Abbot, inSalon2);
+ ADD_CALLBACK_FUNCTION(Abbot, goCompartment3);
+ ADD_CALLBACK_FUNCTION(Abbot, openCompartment3);
+ ADD_CALLBACK_FUNCTION(Abbot, goSalon3);
+ ADD_CALLBACK_FUNCTION(Abbot, inSalon3);
+ ADD_CALLBACK_FUNCTION(Abbot, withAugust);
+ ADD_CALLBACK_FUNCTION(Abbot, goCompartment4);
+ ADD_CALLBACK_FUNCTION(Abbot, inCompartment4);
ADD_CALLBACK_FUNCTION(Abbot, chapter4);
- ADD_CALLBACK_FUNCTION(Abbot, function40);
+ ADD_CALLBACK_FUNCTION(Abbot, doWalkSearchingForCath);
ADD_CALLBACK_FUNCTION(Abbot, chapter4Handler);
- ADD_CALLBACK_FUNCTION(Abbot, function42);
- ADD_CALLBACK_FUNCTION(Abbot, function43);
+ ADD_CALLBACK_FUNCTION(Abbot, leaveDinner);
+ ADD_CALLBACK_FUNCTION(Abbot, inCompartment);
ADD_CALLBACK_FUNCTION(Abbot, function44);
- ADD_CALLBACK_FUNCTION(Abbot, function45);
- ADD_CALLBACK_FUNCTION(Abbot, function46);
- ADD_CALLBACK_FUNCTION(Abbot, drinkAfterDefuse);
- ADD_CALLBACK_FUNCTION(Abbot, function48);
- ADD_CALLBACK_FUNCTION(Abbot, pickBomb);
+ ADD_CALLBACK_FUNCTION(Abbot, conferring);
+ ADD_CALLBACK_FUNCTION(Abbot, goSalon4);
+ ADD_CALLBACK_FUNCTION(Abbot, beforeBomb);
+ ADD_CALLBACK_FUNCTION(Abbot, afterBomb);
+ ADD_CALLBACK_FUNCTION(Abbot, catchCath);
ADD_CALLBACK_FUNCTION(Abbot, chapter5);
ADD_CALLBACK_FUNCTION(Abbot, chapter5Handler);
ADD_CALLBACK_FUNCTION(Abbot, function52);
- ADD_CALLBACK_FUNCTION(Abbot, function53);
+ ADD_CALLBACK_FUNCTION(Abbot, runningTrain);
}
//////////////////////////////////////////////////////////////////////////
@@ -196,7 +196,7 @@ IMPLEMENT_FUNCTION(17, Abbot, chapter3)
break;
case kActionNone:
- setup_chapter3Handler();
+ setup_inKitchen();
break;
case kActionDefault:
@@ -213,7 +213,7 @@ IMPLEMENT_FUNCTION(17, Abbot, chapter3)
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION(18, Abbot, chapter3Handler)
+IMPLEMENT_FUNCTION(18, Abbot, inKitchen)
switch (savepoint.action) {
default:
break;
@@ -259,7 +259,7 @@ IMPLEMENT_FUNCTION(18, Abbot, chapter3Handler)
getData()->entityPosition = kPosition_6470;
getData()->location = kLocationInsideCompartment;
- setup_conversationWithBoutarel();
+ setup_openCompartment();
break;
}
break;
@@ -272,7 +272,7 @@ IMPLEMENT_FUNCTION(18, Abbot, chapter3Handler)
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION(19, Abbot, conversationWithBoutarel)
+IMPLEMENT_FUNCTION(19, Abbot, openCompartment)
switch (savepoint.action) {
default:
break;
@@ -419,7 +419,7 @@ IMPLEMENT_FUNCTION(22, Abbot, haveLunch)
if (getState()->time > kTime1989000 && getEntities()->isSomebodyInsideRestaurantOrSalon()) {
getData()->inventoryItem = kItemNone;
- setup_function23();
+ setup_leaveLunch();
}
break;
@@ -456,7 +456,7 @@ IMPLEMENT_FUNCTION(22, Abbot, haveLunch)
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION(23, Abbot, function23)
+IMPLEMENT_FUNCTION(23, Abbot, leaveLunch)
switch (savepoint.action) {
default:
break;
@@ -500,7 +500,7 @@ IMPLEMENT_FUNCTION(23, Abbot, function23)
case 4:
getData()->location = kLocationInsideCompartment;
- setup_function24();
+ setup_closedCompartment();
break;
}
break;
@@ -508,7 +508,7 @@ IMPLEMENT_FUNCTION(23, Abbot, function23)
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION(24, Abbot, function24)
+IMPLEMENT_FUNCTION(24, Abbot, closedCompartment)
switch (savepoint.action) {
default:
break;
@@ -517,7 +517,7 @@ IMPLEMENT_FUNCTION(24, Abbot, function24)
if (!Entity::updateParameter(params->param1, getState()->time, 900))
break;
- setup_function25();
+ setup_goSalon1();
break;
case kActionKnock:
@@ -561,7 +561,7 @@ IMPLEMENT_FUNCTION(24, Abbot, function24)
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION(25, Abbot, function25)
+IMPLEMENT_FUNCTION(25, Abbot, goSalon1)
switch (savepoint.action) {
default:
break;
@@ -602,7 +602,7 @@ IMPLEMENT_FUNCTION(25, Abbot, function25)
getData()->location = kLocationInsideCompartment;
getScenes()->loadSceneFromItemPosition(kItem3);
- setup_function26();
+ setup_inSalon1();
break;
}
break;
@@ -610,7 +610,7 @@ IMPLEMENT_FUNCTION(25, Abbot, function25)
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION(26, Abbot, function26)
+IMPLEMENT_FUNCTION(26, Abbot, inSalon1)
switch (savepoint.action) {
default:
break;
@@ -620,7 +620,7 @@ IMPLEMENT_FUNCTION(26, Abbot, function26)
break;
if (getEntities()->isSomebodyInsideRestaurantOrSalon())
- setup_function27();
+ setup_goCompartment();
break;
case kActionDefault:
@@ -636,7 +636,7 @@ IMPLEMENT_FUNCTION(26, Abbot, function26)
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION(27, Abbot, function27)
+IMPLEMENT_FUNCTION(27, Abbot, goCompartment)
switch (savepoint.action) {
default:
break;
@@ -677,7 +677,7 @@ IMPLEMENT_FUNCTION(27, Abbot, function27)
getData()->entityPosition = kPosition_6470;
getData()->location = kLocationInsideCompartment;
- setup_function28();
+ setup_openCompartment2();
break;
}
break;
@@ -685,13 +685,13 @@ IMPLEMENT_FUNCTION(27, Abbot, function27)
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION(28, Abbot, function28)
+IMPLEMENT_FUNCTION(28, Abbot, openCompartment2)
switch (savepoint.action) {
default:
break;
case kActionNone:
- Entity::timeCheckCallback(kTime2052000, params->param1, 1, WRAP_SETUP_FUNCTION(Abbot, setup_function29));
+ Entity::timeCheckCallback(kTime2052000, params->param1, 1, WRAP_SETUP_FUNCTION(Abbot, setup_goWander));
break;
case kActionDefault:
@@ -708,12 +708,12 @@ IMPLEMENT_FUNCTION(28, Abbot, function28)
break;
case kAction222609266:
- setup_function30();
+ setup_goSalon2();
}
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION(29, Abbot, function29)
+IMPLEMENT_FUNCTION(29, Abbot, goWander)
switch (savepoint.action) {
default:
break;
@@ -778,7 +778,7 @@ IMPLEMENT_FUNCTION(29, Abbot, function29)
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION(30, Abbot, function30)
+IMPLEMENT_FUNCTION(30, Abbot, goSalon2)
switch (savepoint.action) {
default:
break;
@@ -826,7 +826,7 @@ switch (savepoint.action) {
getScenes()->loadSceneFromItemPosition(kItem3);
getData()->location = kLocationInsideCompartment;
- setup_function31();
+ setup_inSalon2();
break;
}
break;
@@ -834,7 +834,7 @@ switch (savepoint.action) {
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION(31, Abbot, function31)
+IMPLEMENT_FUNCTION(31, Abbot, inSalon2)
switch (savepoint.action) {
default:
break;
@@ -936,7 +936,7 @@ IMPLEMENT_FUNCTION(31, Abbot, function31)
break;
case 7:
- setup_function32();
+ setup_goCompartment3();
break;
}
break;
@@ -944,7 +944,7 @@ IMPLEMENT_FUNCTION(31, Abbot, function31)
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION(32, Abbot, function32)
+IMPLEMENT_FUNCTION(32, Abbot, goCompartment3)
switch (savepoint.action) {
default:
break;
@@ -972,7 +972,7 @@ IMPLEMENT_FUNCTION(32, Abbot, function32)
getData()->location = kLocationInsideCompartment;
getSavePoints()->push(kEntityAbbot, kEntityBoutarel, kAction122358304);
- setup_function33();
+ setup_openCompartment3();
break;
}
break;
@@ -980,7 +980,7 @@ IMPLEMENT_FUNCTION(32, Abbot, function32)
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION(33, Abbot, function33)
+IMPLEMENT_FUNCTION(33, Abbot, openCompartment3)
switch (savepoint.action) {
default:
break;
@@ -1012,13 +1012,13 @@ IMPLEMENT_FUNCTION(33, Abbot, function33)
break;
case kAction123712592:
- setup_function34();
+ setup_goSalon3();
break;
}
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION(34, Abbot, function34)
+IMPLEMENT_FUNCTION(34, Abbot, goSalon3)
switch (savepoint.action) {
default:
break;
@@ -1066,7 +1066,7 @@ IMPLEMENT_FUNCTION(34, Abbot, function34)
getScenes()->loadSceneFromItemPosition(kItem3);
getData()->location = kLocationInsideCompartment;
- setup_function35();
+ setup_inSalon3();
break;
}
break;
@@ -1074,7 +1074,7 @@ IMPLEMENT_FUNCTION(34, Abbot, function34)
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION(35, Abbot, function35)
+IMPLEMENT_FUNCTION(35, Abbot, inSalon3)
switch (savepoint.action) {
default:
break;
@@ -1128,7 +1128,7 @@ IMPLEMENT_FUNCTION(35, Abbot, function35)
getInventory()->setLocationAndProcess(kItem3, kObjectLocation1);
getData()->location = kLocationInsideCompartment;
- setup_function36();
+ setup_withAugust();
break;
}
break;
@@ -1136,7 +1136,7 @@ IMPLEMENT_FUNCTION(35, Abbot, function35)
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION(36, Abbot, function36)
+IMPLEMENT_FUNCTION(36, Abbot, withAugust)
switch (savepoint.action) {
default:
break;
@@ -1198,14 +1198,14 @@ IMPLEMENT_FUNCTION(36, Abbot, function36)
case kActionCallback:
if (getCallback() == 1) {
getEntities()->updatePositionExit(kEntityAbbot, kCarRestaurant, 57);
- setup_function37();
+ setup_goCompartment4();
}
break;
}
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION(37, Abbot, function37)
+IMPLEMENT_FUNCTION(37, Abbot, goCompartment4)
switch (savepoint.action) {
default:
break;
@@ -1233,7 +1233,7 @@ IMPLEMENT_FUNCTION(37, Abbot, function37)
getData()->location = kLocationInsideCompartment;
getSavePoints()->push(kEntityAbbot, kEntityBoutarel, kAction122358304);
- setup_function38();
+ setup_inCompartment4();
break;
}
break;
@@ -1241,7 +1241,7 @@ IMPLEMENT_FUNCTION(37, Abbot, function37)
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION(38, Abbot, function38)
+IMPLEMENT_FUNCTION(38, Abbot, inCompartment4)
switch (savepoint.action) {
default:
break;
@@ -1283,7 +1283,7 @@ IMPLEMENT_FUNCTION(39, Abbot, chapter4)
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION_II(40, Abbot, function40, CarIndex, EntityPosition)
+IMPLEMENT_FUNCTION_II(40, Abbot, doWalkSearchingForCath, CarIndex, EntityPosition)
switch (savepoint.action) {
default:
break;
@@ -1327,7 +1327,7 @@ IMPLEMENT_FUNCTION(41, Abbot, chapter4Handler)
Entity::timeCheckSavepoint(kTime2358000, params->param1, kEntityAbbot, kEntityServers0, kAction218128129);
if (getState()->time > kTime2389500 && getEntities()->isSomebodyInsideRestaurantOrSalon())
- setup_function42();
+ setup_leaveDinner();
break;
@@ -1348,7 +1348,7 @@ IMPLEMENT_FUNCTION(41, Abbot, chapter4Handler)
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION(42, Abbot, function42)
+IMPLEMENT_FUNCTION(42, Abbot, leaveDinner)
switch (savepoint.action) {
default:
break;
@@ -1392,7 +1392,7 @@ IMPLEMENT_FUNCTION(42, Abbot, function42)
getData()->location = kLocationInsideCompartment;
getEntities()->clearSequences(kEntityAbbot);
- setup_function43();
+ setup_inCompartment();
break;
}
break;
@@ -1400,7 +1400,7 @@ IMPLEMENT_FUNCTION(42, Abbot, function42)
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION(43, Abbot, function43)
+IMPLEMENT_FUNCTION(43, Abbot, inCompartment)
switch (savepoint.action) {
default:
break;
@@ -1531,13 +1531,13 @@ IMPLEMENT_FUNCTION(44, Abbot, function44)
break;
case kAction104060776:
- setup_function45();
+ setup_conferring();
break;
}
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION(45, Abbot, function45)
+IMPLEMENT_FUNCTION(45, Abbot, conferring)
switch (savepoint.action) {
default:
break;
@@ -1570,7 +1570,7 @@ IMPLEMENT_FUNCTION(45, Abbot, function45)
getEntities()->exitCompartment(kEntityAbbot, kObjectCompartmentC, true);
getSavePoints()->push(kEntityAbbot, kEntityVerges, kAction125233040);
- setup_function46();
+ setup_goSalon4();
break;
}
break;
@@ -1578,7 +1578,7 @@ IMPLEMENT_FUNCTION(45, Abbot, function45)
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION(46, Abbot, function46)
+IMPLEMENT_FUNCTION(46, Abbot, goSalon4)
switch (savepoint.action) {
default:
break;
@@ -1587,18 +1587,18 @@ IMPLEMENT_FUNCTION(46, Abbot, function46)
getData()->entityPosition = kPosition_6471;
setCallback(1);
- setup_function40(kCarRestaurant, kPosition_850);
+ setup_doWalkSearchingForCath(kCarRestaurant, kPosition_850);
break;
case kActionCallback:
if (getCallback() == 1)
- setup_drinkAfterDefuse();
+ setup_beforeBomb();
break;
}
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION(47, Abbot, drinkAfterDefuse)
+IMPLEMENT_FUNCTION(47, Abbot, beforeBomb)
switch (savepoint.action) {
default:
break;
@@ -1642,7 +1642,7 @@ IMPLEMENT_FUNCTION(47, Abbot, drinkAfterDefuse)
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION(48, Abbot, function48)
+IMPLEMENT_FUNCTION(48, Abbot, afterBomb)
switch (savepoint.action) {
default:
break;
@@ -1749,7 +1749,7 @@ IMPLEMENT_FUNCTION(48, Abbot, function48)
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION(49, Abbot, pickBomb)
+IMPLEMENT_FUNCTION(49, Abbot, catchCath)
switch (savepoint.action) {
default:
break;
@@ -1791,7 +1791,7 @@ IMPLEMENT_FUNCTION(49, Abbot, pickBomb)
break;
case 1:
- getAction()->playAnimation(getObjects()->get(kObjectCompartment2).location2 < kObjectLocation2 ? kEventAbbotWrongCompartmentBed : kEventAbbotWrongCompartment);
+ getAction()->playAnimation(getObjects()->get(kObjectCompartment2).model < kObjectModel2 ? kEventAbbotWrongCompartmentBed : kEventAbbotWrongCompartment);
getEntities()->updateEntity(kEntityAbbot, kCarRedSleeping, kPosition_6470);
getSound()->playSound(kEntityPlayer, "LIB015");
getScenes()->loadSceneFromObject(kObjectCompartment2, true);
@@ -1810,7 +1810,7 @@ IMPLEMENT_FUNCTION(49, Abbot, pickBomb)
getEntities()->clearSequences(kEntityAbbot);
getObjects()->update(kObjectCompartmentC, kEntityAbbot, kObjectLocation1, kCursorHandKnock, kCursorHand);
- setup_function43();
+ setup_inCompartment();
break;
}
break;
@@ -1860,13 +1860,13 @@ IMPLEMENT_FUNCTION(52, Abbot, function52)
break;
case kAction135600432:
- setup_function53();
+ setup_runningTrain();
break;
}
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION(53, Abbot, function53)
+IMPLEMENT_FUNCTION(53, Abbot, runningTrain)
switch (savepoint.action) {
default:
break;
diff --git a/engines/lastexpress/entities/abbot.h b/engines/lastexpress/entities/abbot.h
index dc3e86db54..ba993fdbc9 100644
--- a/engines/lastexpress/entities/abbot.h
+++ b/engines/lastexpress/entities/abbot.h
@@ -155,27 +155,27 @@ public:
/**
* Handle Chapter 3 events
*/
- DECLARE_FUNCTION(chapter3Handler)
- DECLARE_FUNCTION(conversationWithBoutarel)
+ DECLARE_FUNCTION(inKitchen)
+ DECLARE_FUNCTION(openCompartment)
DECLARE_FUNCTION(readPaper)
DECLARE_FUNCTION(goToLunch)
DECLARE_FUNCTION(haveLunch)
- DECLARE_FUNCTION(function23)
- DECLARE_FUNCTION(function24)
- DECLARE_FUNCTION(function25)
- DECLARE_FUNCTION(function26)
- DECLARE_FUNCTION(function27)
- DECLARE_FUNCTION(function28)
- DECLARE_FUNCTION(function29)
- DECLARE_FUNCTION(function30)
- DECLARE_FUNCTION(function31)
- DECLARE_FUNCTION(function32)
- DECLARE_FUNCTION(function33)
- DECLARE_FUNCTION(function34)
- DECLARE_FUNCTION(function35)
- DECLARE_FUNCTION(function36)
- DECLARE_FUNCTION(function37)
- DECLARE_FUNCTION(function38)
+ DECLARE_FUNCTION(leaveLunch)
+ DECLARE_FUNCTION(closedCompartment)
+ DECLARE_FUNCTION(goSalon1)
+ DECLARE_FUNCTION(inSalon1)
+ DECLARE_FUNCTION(goCompartment)
+ DECLARE_FUNCTION(openCompartment2)
+ DECLARE_FUNCTION(goWander)
+ DECLARE_FUNCTION(goSalon2)
+ DECLARE_FUNCTION(inSalon2)
+ DECLARE_FUNCTION(goCompartment3)
+ DECLARE_FUNCTION(openCompartment3)
+ DECLARE_FUNCTION(goSalon3)
+ DECLARE_FUNCTION(inSalon3)
+ DECLARE_FUNCTION(withAugust)
+ DECLARE_FUNCTION(goCompartment4)
+ DECLARE_FUNCTION(inCompartment4)
/**
* Setup Chapter 4
@@ -183,25 +183,25 @@ public:
DECLARE_FUNCTION(chapter4)
/**
- * ???
+ * Search Cath by walking around
*
* @param car The car
* @param entityPosition The entity position
*/
- DECLARE_FUNCTION_2(function40, CarIndex car, EntityPosition position)
+ DECLARE_FUNCTION_2(doWalkSearchingForCath, CarIndex car, EntityPosition position)
/**
* Handle Chapter 4 events
*/
DECLARE_FUNCTION(chapter4Handler)
- DECLARE_FUNCTION(function42)
- DECLARE_FUNCTION(function43)
+ DECLARE_FUNCTION(leaveDinner)
+ DECLARE_FUNCTION(inCompartment)
DECLARE_FUNCTION(function44)
- DECLARE_FUNCTION(function45)
- DECLARE_FUNCTION(function46)
- DECLARE_FUNCTION(drinkAfterDefuse)
- DECLARE_FUNCTION(function48)
- DECLARE_FUNCTION(pickBomb)
+ DECLARE_FUNCTION(conferring)
+ DECLARE_FUNCTION(goSalon4)
+ DECLARE_FUNCTION(beforeBomb)
+ DECLARE_FUNCTION(afterBomb)
+ DECLARE_FUNCTION(catchCath)
/**
* Setup Chapter 5
@@ -213,7 +213,7 @@ public:
*/
DECLARE_FUNCTION(chapter5Handler)
DECLARE_FUNCTION(function52)
- DECLARE_FUNCTION(function53)
+ DECLARE_FUNCTION(runningTrain)
};
} // End of namespace LastExpress
diff --git a/engines/lastexpress/entities/alexei.cpp b/engines/lastexpress/entities/alexei.cpp
index 115c890f6f..b8ae62e7c4 100644
--- a/engines/lastexpress/entities/alexei.cpp
+++ b/engines/lastexpress/entities/alexei.cpp
@@ -48,40 +48,40 @@ Alexei::Alexei(LastExpressEngine *engine) : Entity(engine, kEntityAlexei) {
ADD_CALLBACK_FUNCTION(Alexei, updateEntity);
ADD_CALLBACK_FUNCTION(Alexei, draw2);
ADD_CALLBACK_FUNCTION(Alexei, callbackActionRestaurantOrSalon);
- ADD_CALLBACK_FUNCTION(Alexei, function13);
- ADD_CALLBACK_FUNCTION(Alexei, function14);
- ADD_CALLBACK_FUNCTION(Alexei, function15);
- ADD_CALLBACK_FUNCTION(Alexei, function16);
+ ADD_CALLBACK_FUNCTION(Alexei, enterComparment);
+ ADD_CALLBACK_FUNCTION(Alexei, exitCompartment);
+ ADD_CALLBACK_FUNCTION(Alexei, pacingAtWindow);
+ ADD_CALLBACK_FUNCTION(Alexei, compartmentLogic);
ADD_CALLBACK_FUNCTION(Alexei, chapter1);
- ADD_CALLBACK_FUNCTION(Alexei, chapter1Handler);
- ADD_CALLBACK_FUNCTION(Alexei, function19);
- ADD_CALLBACK_FUNCTION(Alexei, function20);
- ADD_CALLBACK_FUNCTION(Alexei, function21);
- ADD_CALLBACK_FUNCTION(Alexei, function22);
- ADD_CALLBACK_FUNCTION(Alexei, function23);
- ADD_CALLBACK_FUNCTION(Alexei, function24);
- ADD_CALLBACK_FUNCTION(Alexei, function25);
+ ADD_CALLBACK_FUNCTION(Alexei, atDinner);
+ ADD_CALLBACK_FUNCTION(Alexei, returnCompartment);
+ ADD_CALLBACK_FUNCTION(Alexei, goSalon);
+ ADD_CALLBACK_FUNCTION(Alexei, sitting);
+ ADD_CALLBACK_FUNCTION(Alexei, standingAtWindow);
+ ADD_CALLBACK_FUNCTION(Alexei, waitingForTatiana);
+ ADD_CALLBACK_FUNCTION(Alexei, upset);
+ ADD_CALLBACK_FUNCTION(Alexei, returnCompartmentNight);
ADD_CALLBACK_FUNCTION(Alexei, function26);
ADD_CALLBACK_FUNCTION(Alexei, function27);
ADD_CALLBACK_FUNCTION(Alexei, chapter2);
- ADD_CALLBACK_FUNCTION(Alexei, chapter2Handler);
- ADD_CALLBACK_FUNCTION(Alexei, function30);
- ADD_CALLBACK_FUNCTION(Alexei, function31);
+ ADD_CALLBACK_FUNCTION(Alexei, inCompartment2);
+ ADD_CALLBACK_FUNCTION(Alexei, atBreakfast);
+ ADD_CALLBACK_FUNCTION(Alexei, returnCompartment2);
ADD_CALLBACK_FUNCTION(Alexei, chapter3);
- ADD_CALLBACK_FUNCTION(Alexei, chapter3Handler);
- ADD_CALLBACK_FUNCTION(Alexei, function34);
- ADD_CALLBACK_FUNCTION(Alexei, function35);
- ADD_CALLBACK_FUNCTION(Alexei, function36);
+ ADD_CALLBACK_FUNCTION(Alexei, playingChess);
+ ADD_CALLBACK_FUNCTION(Alexei, inPart3);
+ ADD_CALLBACK_FUNCTION(Alexei, pacing3);
+ ADD_CALLBACK_FUNCTION(Alexei, goSalon3);
ADD_CALLBACK_FUNCTION(Alexei, chapter4);
- ADD_CALLBACK_FUNCTION(Alexei, chapter4Handler);
- ADD_CALLBACK_FUNCTION(Alexei, function39);
- ADD_CALLBACK_FUNCTION(Alexei, function40);
- ADD_CALLBACK_FUNCTION(Alexei, function41);
- ADD_CALLBACK_FUNCTION(Alexei, function42);
- ADD_CALLBACK_FUNCTION(Alexei, function43);
- ADD_CALLBACK_FUNCTION(Alexei, function44);
- ADD_CALLBACK_FUNCTION(Alexei, function45);
- ADD_CALLBACK_FUNCTION(Alexei, function46);
+ ADD_CALLBACK_FUNCTION(Alexei, inCompartment4);
+ ADD_CALLBACK_FUNCTION(Alexei, meetTatiana);
+ ADD_CALLBACK_FUNCTION(Alexei, leavePlatform);
+ ADD_CALLBACK_FUNCTION(Alexei, inCompartmentAgain);
+ ADD_CALLBACK_FUNCTION(Alexei, goSalon4);
+ ADD_CALLBACK_FUNCTION(Alexei, pacing);
+ ADD_CALLBACK_FUNCTION(Alexei, goToPlatform);
+ ADD_CALLBACK_FUNCTION(Alexei, returnCompartment4);
+ ADD_CALLBACK_FUNCTION(Alexei, bombPlanB);
ADD_CALLBACK_FUNCTION(Alexei, function47);
ADD_CALLBACK_FUNCTION(Alexei, chapter5);
}
@@ -169,7 +169,7 @@ IMPLEMENT_FUNCTION(12, Alexei, callbackActionRestaurantOrSalon)
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION(13, Alexei, function13)
+IMPLEMENT_FUNCTION(13, Alexei, enterComparment)
switch (savepoint.action) {
default:
break;
@@ -216,7 +216,7 @@ IMPLEMENT_FUNCTION(13, Alexei, function13)
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION(14, Alexei, function14)
+IMPLEMENT_FUNCTION(14, Alexei, exitCompartment)
switch (savepoint.action) {
default:
break;
@@ -245,7 +245,7 @@ IMPLEMENT_FUNCTION(14, Alexei, function14)
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION(15, Alexei, function15)
+IMPLEMENT_FUNCTION(15, Alexei, pacingAtWindow)
switch (savepoint.action) {
default:
break;
@@ -297,7 +297,7 @@ IMPLEMENT_FUNCTION(15, Alexei, function15)
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION_IS(16, Alexei, function16, TimeValue)
+IMPLEMENT_FUNCTION_IS(16, Alexei, compartmentLogic, TimeValue)
switch (savepoint.action) {
default:
break;
@@ -446,7 +446,7 @@ IMPLEMENT_FUNCTION(17, Alexei, chapter1)
break;
case kActionNone:
- Entity::timeCheck(kTimeChapter1, params->param1, WRAP_SETUP_FUNCTION(Alexei, setup_chapter1Handler));
+ Entity::timeCheck(kTimeChapter1, params->param1, WRAP_SETUP_FUNCTION(Alexei, setup_atDinner));
break;
case kActionDefault:
@@ -462,7 +462,7 @@ IMPLEMENT_FUNCTION(17, Alexei, chapter1)
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION(18, Alexei, chapter1Handler)
+IMPLEMENT_FUNCTION(18, Alexei, atDinner)
switch (savepoint.action) {
default:
break;
@@ -519,7 +519,7 @@ IMPLEMENT_FUNCTION(18, Alexei, chapter1Handler)
case 1:
getEntities()->updatePositionExit(kEntityAlexei, kCarRestaurant, 63);
- setup_function19();
+ setup_returnCompartment();
break;
case 2:
@@ -533,7 +533,7 @@ IMPLEMENT_FUNCTION(18, Alexei, chapter1Handler)
getInventory()->get(kItem17)->location = kObjectLocation1;
getScenes()->loadSceneFromPosition(kCarRestaurant, 63);
- setup_function19();
+ setup_returnCompartment();
break;
}
break;
@@ -553,7 +553,7 @@ IMPLEMENT_FUNCTION(18, Alexei, chapter1Handler)
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION(19, Alexei, function19)
+IMPLEMENT_FUNCTION(19, Alexei, returnCompartment)
switch (savepoint.action) {
default:
break;
@@ -620,7 +620,7 @@ IMPLEMENT_FUNCTION(19, Alexei, function19)
case 9:
setCallback(10);
- setup_function13();
+ setup_enterComparment();
break;
case 10:
@@ -628,11 +628,11 @@ IMPLEMENT_FUNCTION(19, Alexei, function19)
getScenes()->loadSceneFromPosition(kCarGreenSleeping, 49);
setCallback(11);
- setup_function16(kTime1098000, "411");
+ setup_compartmentLogic(kTime1098000, "411");
break;
case 11:
- setup_function20();
+ setup_goSalon();
break;
}
break;
@@ -640,14 +640,14 @@ IMPLEMENT_FUNCTION(19, Alexei, function19)
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION(20, Alexei, function20)
+IMPLEMENT_FUNCTION(20, Alexei, goSalon)
switch (savepoint.action) {
default:
break;
case kActionDefault:
setCallback(1);
- setup_function14();
+ setup_exitCompartment();
break;
case kActionCallback:
@@ -683,7 +683,7 @@ IMPLEMENT_FUNCTION(20, Alexei, function20)
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION(21, Alexei, function21)
+IMPLEMENT_FUNCTION(21, Alexei, sitting)
switch (savepoint.action) {
default:
break;
@@ -720,7 +720,7 @@ IMPLEMENT_FUNCTION(21, Alexei, function21)
case 1:
getData()->location = kLocationInsideCompartment;
- setup_function22();
+ setup_standingAtWindow();
break;
case 2:
@@ -745,7 +745,7 @@ IMPLEMENT_FUNCTION(21, Alexei, function21)
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION(22, Alexei, function22)
+IMPLEMENT_FUNCTION(22, Alexei, standingAtWindow)
switch (savepoint.action) {
default:
break;
@@ -779,7 +779,7 @@ IMPLEMENT_FUNCTION(22, Alexei, function22)
getData()->inventoryItem = kItemNone;
- setup_function23();
+ setup_waitingForTatiana();
break;
case kAction1:
@@ -801,7 +801,7 @@ IMPLEMENT_FUNCTION(22, Alexei, function22)
case 1:
getData()->location = kLocationInsideCompartment;
- setup_function21();
+ setup_sitting();
break;
case 2:
@@ -821,7 +821,7 @@ IMPLEMENT_FUNCTION(22, Alexei, function22)
getEntities()->updatePositionExit(kEntityAlexei, kCarRestaurant, 52);
getData()->location = kLocationInsideCompartment;
- setup_function21();
+ setup_standingAtWindow();
break;
}
break;
@@ -829,7 +829,7 @@ IMPLEMENT_FUNCTION(22, Alexei, function22)
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION(23, Alexei, function23)
+IMPLEMENT_FUNCTION(23, Alexei, waitingForTatiana)
switch (savepoint.action) {
default:
break;
@@ -861,7 +861,7 @@ IMPLEMENT_FUNCTION(23, Alexei, function23)
getEntities()->drawSequenceLeft(kEntityAlexei, "103F");
getScenes()->processScene();
- setup_function24();
+ setup_upset();
break;
case 2:
@@ -879,18 +879,18 @@ IMPLEMENT_FUNCTION(23, Alexei, function23)
setCallback(1);
setup_savegame(kSavegameTypeEvent, kEventAlexeiSalonVassili);
} else {
- setup_function24();
+ setup_upset();
}
break;
case kAction188784532:
- setup_function24();
+ setup_upset();
break;
}
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION(24, Alexei, function24)
+IMPLEMENT_FUNCTION(24, Alexei, upset)
switch (savepoint.action) {
default:
break;
@@ -917,11 +917,11 @@ IMPLEMENT_FUNCTION(24, Alexei, function24)
getData()->entityPosition = kPosition_9460;
getEntities()->clearSequences(kEntityAlexei);
getScenes()->loadSceneFromPosition(kCarRestaurant, 55);
- setup_function25();
+ setup_returnCompartmentNight();
break;
case 2:
- setup_function25();
+ setup_returnCompartmentNight();
break;
}
break;
@@ -935,14 +935,14 @@ IMPLEMENT_FUNCTION(24, Alexei, function24)
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION(25, Alexei, function25)
+IMPLEMENT_FUNCTION(25, Alexei, returnCompartmentNight)
switch (savepoint.action) {
default:
break;
case kActionDefault:
setCallback(1);
- setup_function13();
+ setup_enterComparment();
break;
case kActionCallback:
@@ -955,12 +955,12 @@ IMPLEMENT_FUNCTION(25, Alexei, function25)
getScenes()->loadSceneFromPosition(kCarGreenSleeping, 49);
setCallback(2);
- setup_function16(kTime1179000, "411");
+ setup_compartmentLogic(kTime1179000, "411");
break;
case 2:
setCallback(3);
- setup_function16(kTime1323000, "412");
+ setup_compartmentLogic(kTime1323000, "412");
break;
case 3:
@@ -1017,7 +1017,7 @@ IMPLEMENT_FUNCTION(28, Alexei, chapter2)
break;
case kActionNone:
- setup_chapter2Handler();
+ setup_inCompartment2();
break;
case kActionDefault:
@@ -1037,14 +1037,14 @@ IMPLEMENT_FUNCTION(28, Alexei, chapter2)
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION(29, Alexei, chapter2Handler)
+IMPLEMENT_FUNCTION(29, Alexei, inCompartment2)
switch (savepoint.action) {
default:
break;
case kActionDefault:
setCallback(1);
- setup_function16(kTime1791000, "411");
+ setup_compartmentLogic(kTime1791000, "411");
break;
case kActionCallback:
@@ -1054,7 +1054,7 @@ IMPLEMENT_FUNCTION(29, Alexei, chapter2Handler)
case 1:
setCallback(2);
- setup_function14();
+ setup_exitCompartment();
break;
case 2:
@@ -1085,7 +1085,7 @@ IMPLEMENT_FUNCTION(29, Alexei, chapter2Handler)
case 6:
getEntities()->updatePositionExit(kEntityAlexei, kCarRestaurant, 63);
getSavePoints()->push(kEntityAlexei, kEntityTatiana, kAction290869168);
- setup_function30();
+ setup_atBreakfast();
break;
}
break;
@@ -1093,7 +1093,7 @@ IMPLEMENT_FUNCTION(29, Alexei, chapter2Handler)
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION(30, Alexei, function30)
+IMPLEMENT_FUNCTION(30, Alexei, atBreakfast)
switch (savepoint.action) {
default:
break;
@@ -1134,7 +1134,7 @@ IMPLEMENT_FUNCTION(30, Alexei, function30)
case 3:
getEntities()->updatePositionExit(kEntityAlexei, kCarRestaurant, 63);
- setup_function31();
+ setup_returnCompartment2();
break;
}
break;
@@ -1154,7 +1154,7 @@ IMPLEMENT_FUNCTION(30, Alexei, function30)
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION(31, Alexei, function31)
+IMPLEMENT_FUNCTION(31, Alexei, returnCompartment2)
switch (savepoint.action) {
default:
break;
@@ -1175,7 +1175,7 @@ IMPLEMENT_FUNCTION(31, Alexei, function31)
case 1:
setCallback(2);
- setup_function13();
+ setup_enterComparment();
break;
case 2:
@@ -1183,7 +1183,7 @@ IMPLEMENT_FUNCTION(31, Alexei, function31)
getScenes()->loadSceneFromPosition(kCarGreenSleeping, 49);
setCallback(3);
- setup_function16(kTimeEnd, "411");
+ setup_compartmentLogic(kTimeEnd, "411");
break;
}
break;
@@ -1197,7 +1197,7 @@ IMPLEMENT_FUNCTION(32, Alexei, chapter3)
break;
case kActionNone:
- setup_chapter3Handler();
+ setup_playingChess();
break;
case kActionDefault:
@@ -1216,14 +1216,14 @@ IMPLEMENT_FUNCTION(32, Alexei, chapter3)
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION(33, Alexei, chapter3Handler)
+IMPLEMENT_FUNCTION(33, Alexei, playingChess)
switch (savepoint.action) {
default:
break;
case kActionCallback:
if (getCallback() == 1)
- setup_function34();
+ setup_inPart3();
break;
case kAction122288808:
@@ -1232,7 +1232,7 @@ IMPLEMENT_FUNCTION(33, Alexei, chapter3Handler)
getData()->car = kCarRedSleeping;
setCallback(1);
- setup_function13();
+ setup_enterComparment();
break;
case kAction122358304:
@@ -1242,7 +1242,7 @@ IMPLEMENT_FUNCTION(33, Alexei, chapter3Handler)
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION(34, Alexei, function34)
+IMPLEMENT_FUNCTION(34, Alexei, inPart3)
switch (savepoint.action) {
default:
break;
@@ -1252,7 +1252,7 @@ IMPLEMENT_FUNCTION(34, Alexei, function34)
getScenes()->loadSceneFromPosition(kCarGreenSleeping, 49);
setCallback(1);
- setup_function16(kTime2083500, "411");
+ setup_compartmentLogic(kTime2083500, "411");
break;
case kActionCallback:
@@ -1262,7 +1262,7 @@ IMPLEMENT_FUNCTION(34, Alexei, function34)
case 1:
setCallback(2);
- setup_function14();
+ setup_exitCompartment();
break;
case 2:
@@ -1285,12 +1285,12 @@ IMPLEMENT_FUNCTION(34, Alexei, function34)
case 5:
setCallback(6);
- setup_function35();
+ setup_pacing3();
break;
case 6:
setCallback(7);
- setup_function13();
+ setup_enterComparment();
break;
case 7:
@@ -1299,17 +1299,17 @@ IMPLEMENT_FUNCTION(34, Alexei, function34)
getScenes()->loadSceneFromPosition(kCarGreenSleeping, 66);
setCallback(8);
- setup_function16(kTime2124000, "NONE");
+ setup_compartmentLogic(kTime2124000, "NONE");
break;
case 8:
setCallback(9);
- setup_function14();
+ setup_exitCompartment();
break;
case 9:
setCallback(10);
- setup_function36();
+ setup_goSalon3();
break;
case 10:
@@ -1318,7 +1318,7 @@ IMPLEMENT_FUNCTION(34, Alexei, function34)
getScenes()->loadSceneFromPosition(kCarGreenSleeping, 49);
setCallback(11);
- setup_function16(kTime16451100, "411");
+ setup_compartmentLogic(kTime16451100, "411");
break;
}
break;
@@ -1326,7 +1326,7 @@ IMPLEMENT_FUNCTION(34, Alexei, function34)
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION(35, Alexei, function35)
+IMPLEMENT_FUNCTION(35, Alexei, pacing3)
switch (savepoint.action) {
default:
break;
@@ -1345,7 +1345,7 @@ IMPLEMENT_FUNCTION(35, Alexei, function35)
if (Entity::updateParameter(params->param3, getState()->time, params->param1)) {
if (getEntities()->isSomebodyInsideRestaurantOrSalon()) {
setCallback(3);
- setup_function15();
+ setup_pacingAtWindow();
break;
}
}
@@ -1392,7 +1392,7 @@ label_callback_3:
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION(36, Alexei, function36)
+IMPLEMENT_FUNCTION(36, Alexei, goSalon3)
switch (savepoint.action) {
default:
break;
@@ -1457,7 +1457,7 @@ IMPLEMENT_FUNCTION(36, Alexei, function36)
case kAction122288808:
setCallback(4);
- setup_function13();
+ setup_enterComparment();
break;
case kAction122358304:
@@ -1474,7 +1474,7 @@ IMPLEMENT_FUNCTION(37, Alexei, chapter4)
break;
case kActionNone:
- setup_chapter4Handler();
+ setup_inCompartment4();
break;
case kActionDefault:
@@ -1493,25 +1493,25 @@ IMPLEMENT_FUNCTION(37, Alexei, chapter4)
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION(38, Alexei, chapter4Handler)
+IMPLEMENT_FUNCTION(38, Alexei, inCompartment4)
switch (savepoint.action) {
default:
break;
case kActionDefault:
setCallback(1);
- setup_function16(kTime2354400, "411");
+ setup_compartmentLogic(kTime2354400, "411");
break;
case kActionCallback:
if (getCallback() == 1)
- setup_function39();
+ setup_meetTatiana();
break;
}
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION(39, Alexei, function39)
+IMPLEMENT_FUNCTION(39, Alexei, meetTatiana)
switch (savepoint.action) {
default:
break;
@@ -1547,7 +1547,7 @@ IMPLEMENT_FUNCTION(39, Alexei, function39)
getScenes()->loadSceneFromPosition(kCarGreenSleeping, 72);
}
- setup_function40();
+ setup_leavePlatform();
}
break;
@@ -1571,7 +1571,7 @@ IMPLEMENT_FUNCTION(39, Alexei, function39)
break;
}
- setup_function40();
+ setup_leavePlatform();
}
break;
@@ -1616,7 +1616,7 @@ IMPLEMENT_FUNCTION(39, Alexei, function39)
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION(40, Alexei, function40)
+IMPLEMENT_FUNCTION(40, Alexei, leavePlatform)
switch (savepoint.action) {
default:
break;
@@ -1653,7 +1653,7 @@ IMPLEMENT_FUNCTION(40, Alexei, function40)
getData()->location = kLocationInsideCompartment;
getEntities()->clearSequences(kEntityAlexei);
- setup_function41();
+ setup_inCompartmentAgain();
break;
}
break;
@@ -1661,7 +1661,7 @@ IMPLEMENT_FUNCTION(40, Alexei, function40)
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION(41, Alexei, function41)
+IMPLEMENT_FUNCTION(41, Alexei, inCompartmentAgain)
switch (savepoint.action) {
default:
break;
@@ -1671,25 +1671,25 @@ IMPLEMENT_FUNCTION(41, Alexei, function41)
getScenes()->loadSceneFromPosition(kCarGreenSleeping, 49);
setCallback(1);
- setup_function16(kTime2403000, "411");
+ setup_compartmentLogic(kTime2403000, "411");
break;
case kActionCallback:
if (getCallback() == 1)
- setup_function42();
+ setup_goSalon4();
break;
}
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION(42, Alexei, function42)
+IMPLEMENT_FUNCTION(42, Alexei, goSalon4)
switch (savepoint.action) {
default:
break;
case kActionDefault:
setCallback(1);
- setup_function14();
+ setup_exitCompartment();
break;
case kActionCallback:
@@ -1711,7 +1711,7 @@ IMPLEMENT_FUNCTION(42, Alexei, function42)
case 3:
getData()->location = kLocationInsideCompartment;
- setup_function43();
+ setup_pacing();
break;
}
break;
@@ -1719,7 +1719,7 @@ IMPLEMENT_FUNCTION(42, Alexei, function42)
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION(43, Alexei, function43)
+IMPLEMENT_FUNCTION(43, Alexei, pacing)
switch (savepoint.action) {
default:
break;
@@ -1731,7 +1731,7 @@ IMPLEMENT_FUNCTION(43, Alexei, function43)
if (getEntities()->isSomebodyInsideRestaurantOrSalon()) {
setCallback(1);
- setup_function15();
+ setup_pacingAtWindow();
break;
}
}
@@ -1768,7 +1768,7 @@ label_callback_1:
break;
case 3:
- setup_function44();
+ setup_goToPlatform();
break;
}
break;
@@ -1776,7 +1776,7 @@ label_callback_1:
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION(44, Alexei, function44)
+IMPLEMENT_FUNCTION(44, Alexei, goToPlatform)
switch (savepoint.action) {
default:
break;
@@ -1794,7 +1794,7 @@ IMPLEMENT_FUNCTION(44, Alexei, function44)
if (getEntities()->isPlayerPosition(kCarGreenSleeping, 62))
getScenes()->loadSceneFromPosition(kCarGreenSleeping, 72);
- setup_function45();
+ setup_returnCompartment4();
}
}
break;
@@ -1843,14 +1843,14 @@ IMPLEMENT_FUNCTION(44, Alexei, function44)
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION(45, Alexei, function45)
+IMPLEMENT_FUNCTION(45, Alexei, returnCompartment4)
switch (savepoint.action) {
default:
break;
case kActionDefault:
setCallback(1);
- setup_function13();
+ setup_enterComparment();
break;
case kActionCallback:
@@ -1859,10 +1859,10 @@ IMPLEMENT_FUNCTION(45, Alexei, function45)
getScenes()->loadSceneFromPosition(kCarGreenSleeping, 49);
if (getInventory()->hasItem(kItemBomb)) {
- setup_function46();
+ setup_bombPlanB();
} else {
setCallback(2);
- setup_function16(kTimeEnd, "412");
+ setup_compartmentLogic(kTimeEnd, "412");
}
}
break;
@@ -1870,7 +1870,7 @@ IMPLEMENT_FUNCTION(45, Alexei, function45)
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION(46, Alexei, function46)
+IMPLEMENT_FUNCTION(46, Alexei, bombPlanB)
switch (savepoint.action) {
default:
break;
@@ -1899,12 +1899,12 @@ IMPLEMENT_FUNCTION(46, Alexei, function46)
}
setCallback(4);
- setup_function13();
+ setup_enterComparment();
break;
case kActionDefault:
setCallback(1);
- setup_function16(kTime2488500, "411");
+ setup_compartmentLogic(kTime2488500, "411");
break;
case kActionCallback:
@@ -1914,7 +1914,7 @@ IMPLEMENT_FUNCTION(46, Alexei, function46)
case 1:
setCallback(2);
- setup_function14();
+ setup_exitCompartment();
break;
case 2:
@@ -1927,7 +1927,7 @@ IMPLEMENT_FUNCTION(46, Alexei, function46)
getScenes()->loadSceneFromPosition(kCarGreenSleeping, 49);
setCallback(5);
- setup_function16(kTime2507400, "412");
+ setup_compartmentLogic(kTime2507400, "412");
break;
case 5:
diff --git a/engines/lastexpress/entities/alexei.h b/engines/lastexpress/entities/alexei.h
index 9792385863..9a316ec574 100644
--- a/engines/lastexpress/entities/alexei.h
+++ b/engines/lastexpress/entities/alexei.h
@@ -123,9 +123,9 @@ public:
*/
DECLARE_FUNCTION(callbackActionRestaurantOrSalon)
- DECLARE_FUNCTION(function13)
- DECLARE_FUNCTION(function14)
- DECLARE_FUNCTION(function15)
+ DECLARE_FUNCTION(enterComparment)
+ DECLARE_FUNCTION(exitCompartment)
+ DECLARE_FUNCTION(pacingAtWindow)
/**
* ???
@@ -133,7 +133,7 @@ public:
* @param timeValue The time value
* @param sequence The sequence to draw
*/
- DECLARE_FUNCTION_2(function16, TimeValue timeValue, const char *sequence)
+ DECLARE_FUNCTION_2(compartmentLogic, TimeValue timeValue, const char *sequence)
/**
* Setup Chapter 1
@@ -143,14 +143,14 @@ public:
/**
* Handle Chapter 1 events
*/
- DECLARE_FUNCTION(chapter1Handler)
- DECLARE_FUNCTION(function19)
- DECLARE_FUNCTION(function20)
- DECLARE_FUNCTION(function21)
- DECLARE_FUNCTION(function22)
- DECLARE_FUNCTION(function23)
- DECLARE_FUNCTION(function24)
- DECLARE_FUNCTION(function25)
+ DECLARE_FUNCTION(atDinner)
+ DECLARE_FUNCTION(returnCompartment)
+ DECLARE_FUNCTION(goSalon)
+ DECLARE_FUNCTION(sitting)
+ DECLARE_FUNCTION(standingAtWindow)
+ DECLARE_FUNCTION(waitingForTatiana)
+ DECLARE_FUNCTION(upset)
+ DECLARE_FUNCTION(returnCompartmentNight)
DECLARE_FUNCTION(function26)
DECLARE_FUNCTION(function27)
@@ -162,9 +162,9 @@ public:
/**
* Handle Chapter 2 events
*/
- DECLARE_FUNCTION(chapter2Handler)
- DECLARE_FUNCTION(function30)
- DECLARE_FUNCTION(function31)
+ DECLARE_FUNCTION(inCompartment2)
+ DECLARE_FUNCTION(atBreakfast)
+ DECLARE_FUNCTION(returnCompartment2)
/**
* Setup Chapter 3
@@ -174,10 +174,10 @@ public:
/**
* Handle Chapter 3 events
*/
- DECLARE_FUNCTION(chapter3Handler)
- DECLARE_FUNCTION(function34)
- DECLARE_FUNCTION(function35)
- DECLARE_FUNCTION(function36)
+ DECLARE_FUNCTION(playingChess)
+ DECLARE_FUNCTION(inPart3)
+ DECLARE_FUNCTION(pacing3)
+ DECLARE_FUNCTION(goSalon3)
/**
* Setup Chapter 4
@@ -187,15 +187,15 @@ public:
/**
* Handle Chapter 4 events
*/
- DECLARE_FUNCTION(chapter4Handler)
- DECLARE_FUNCTION(function39)
- DECLARE_FUNCTION(function40)
- DECLARE_FUNCTION(function41)
- DECLARE_FUNCTION(function42)
- DECLARE_FUNCTION(function43)
- DECLARE_FUNCTION(function44)
- DECLARE_FUNCTION(function45)
- DECLARE_FUNCTION(function46)
+ DECLARE_FUNCTION(inCompartment4)
+ DECLARE_FUNCTION(meetTatiana)
+ DECLARE_FUNCTION(leavePlatform)
+ DECLARE_FUNCTION(inCompartmentAgain)
+ DECLARE_FUNCTION(goSalon4)
+ DECLARE_FUNCTION(pacing)
+ DECLARE_FUNCTION(goToPlatform)
+ DECLARE_FUNCTION(returnCompartment4)
+ DECLARE_FUNCTION(bombPlanB)
DECLARE_FUNCTION(function47)
/**
diff --git a/engines/lastexpress/entities/alouan.cpp b/engines/lastexpress/entities/alouan.cpp
index e834e1f7cb..86d5512cb9 100644
--- a/engines/lastexpress/entities/alouan.cpp
+++ b/engines/lastexpress/entities/alouan.cpp
@@ -38,10 +38,10 @@ Alouan::Alouan(LastExpressEngine *engine) : Entity(engine, kEntityAlouan) {
ADD_CALLBACK_FUNCTION(Alouan, playSound);
ADD_CALLBACK_FUNCTION(Alouan, updateFromTime);
ADD_CALLBACK_FUNCTION(Alouan, updateEntity);
- ADD_CALLBACK_FUNCTION(Alouan, compartment6);
- ADD_CALLBACK_FUNCTION(Alouan, compartment8);
- ADD_CALLBACK_FUNCTION(Alouan, compartment6to8);
- ADD_CALLBACK_FUNCTION(Alouan, compartment8to6);
+ ADD_CALLBACK_FUNCTION(Alouan, peekF);
+ ADD_CALLBACK_FUNCTION(Alouan, peekH);
+ ADD_CALLBACK_FUNCTION(Alouan, goFtoH);
+ ADD_CALLBACK_FUNCTION(Alouan, goHtoF);
ADD_CALLBACK_FUNCTION(Alouan, chapter1);
ADD_CALLBACK_FUNCTION(Alouan, chapter1Handler);
ADD_CALLBACK_FUNCTION(Alouan, function12);
@@ -55,7 +55,7 @@ Alouan::Alouan(LastExpressEngine *engine) : Entity(engine, kEntityAlouan) {
ADD_CALLBACK_FUNCTION(Alouan, chapter5);
ADD_CALLBACK_FUNCTION(Alouan, chapter5Handler);
ADD_CALLBACK_FUNCTION(Alouan, function22);
- ADD_CALLBACK_FUNCTION(Alouan, function23);
+ ADD_CALLBACK_FUNCTION(Alouan, hiding);
ADD_NULL_FUNCTION();
}
@@ -85,22 +85,22 @@ IMPLEMENT_FUNCTION_II(5, Alouan, updateEntity, CarIndex, EntityPosition)
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION(6, Alouan, compartment6)
+IMPLEMENT_FUNCTION(6, Alouan, peekF)
Entity::goToCompartment(savepoint, kObjectCompartment6, kPosition_4070, "621Cf", "621Df");
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION(7, Alouan, compartment8)
+IMPLEMENT_FUNCTION(7, Alouan, peekH)
Entity::goToCompartment(savepoint, kObjectCompartment8, kPosition_2740, "621Ch", "621Dh");
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION(8, Alouan, compartment6to8)
+IMPLEMENT_FUNCTION(8, Alouan, goFtoH)
Entity::goToCompartmentFromCompartment(savepoint, kObjectCompartment6, kPosition_4070, "621Bf", kObjectCompartment8, kPosition_2740, "621Ah");
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION(9, Alouan, compartment8to6)
+IMPLEMENT_FUNCTION(9, Alouan, goHtoF)
Entity::goToCompartmentFromCompartment(savepoint, kObjectCompartment8, kPosition_2740, "621Bh", kObjectCompartment6, kPosition_4070, "621Af");
IMPLEMENT_FUNCTION_END
@@ -131,7 +131,7 @@ IMPLEMENT_FUNCTION(11, Alouan, chapter1Handler)
case kActionNone:
- if (Entity::timeCheckCallback(kTime1096200, params->param1, 1, WRAP_SETUP_FUNCTION(Alouan, setup_compartment8to6)))
+ if (Entity::timeCheckCallback(kTime1096200, params->param1, 1, WRAP_SETUP_FUNCTION(Alouan, setup_goHtoF)))
break;
label_callback1:
@@ -146,7 +146,7 @@ label_callback1:
getSavePoints()->push(kEntityAlouan, kEntityTrain, kAction191070912, kPosition_4840);
setCallback(2);
- setup_compartment6to8();
+ setup_goFtoH();
}
break;
@@ -215,9 +215,9 @@ IMPLEMENT_FUNCTION(14, Alouan, chapter2Handler)
setCallback(params->param1 ? 1 : 2);
if (params->param1)
- setup_compartment8();
+ setup_peekH();
else
- setup_compartment6();
+ setup_peekF();
break;
case kActionDefault:
@@ -249,7 +249,7 @@ IMPLEMENT_FUNCTION(14, Alouan, chapter2Handler)
case kAction189489753:
setCallback(3);
- setup_compartment8to6();
+ setup_goHtoF();
break;
}
IMPLEMENT_FUNCTION_END
@@ -282,12 +282,12 @@ IMPLEMENT_FUNCTION(16, Alouan, chapter3Handler)
break;
case kActionNone:
- if (Entity::timeCheckCallback(kTimeCitySalzbourg, params->param1, 1, WRAP_SETUP_FUNCTION(Alouan, setup_compartment8to6)))
+ if (Entity::timeCheckCallback(kTimeCitySalzbourg, params->param1, 1, WRAP_SETUP_FUNCTION(Alouan, setup_goHtoF)))
break;
label_callback1:
if (params->param2 != kTimeInvalid && getState()->time > kTime1989000) {
- if (Entity::timeCheckCar(kTime2119500, params->param5, 5, WRAP_SETUP_FUNCTION(Alouan, setup_compartment8)))
+ if (Entity::timeCheckCar(kTime2119500, params->param5, 5, WRAP_SETUP_FUNCTION(Alouan, setup_peekH)))
break;
}
@@ -296,12 +296,12 @@ label_callback2:
break;
label_callback3:
- if (Entity::timeCheckCallback(kTime2133000, params->param4, 4, WRAP_SETUP_FUNCTION(Alouan, setup_compartment6to8)))
+ if (Entity::timeCheckCallback(kTime2133000, params->param4, 4, WRAP_SETUP_FUNCTION(Alouan, setup_goFtoH)))
break;
label_callback4:
if (params->param5 != kTimeInvalid && getState()->time > kTime2151000) {
- if (Entity::timeCheckCar(kTime2241000, params->param5, 5, WRAP_SETUP_FUNCTION(Alouan, setup_compartment8)))
+ if (Entity::timeCheckCar(kTime2241000, params->param5, 5, WRAP_SETUP_FUNCTION(Alouan, setup_peekH)))
break;
}
break;
@@ -361,12 +361,12 @@ IMPLEMENT_FUNCTION(18, Alouan, chapter4Handler)
case kActionNone:
if (params->param1 != kTimeInvalid) {
- if (Entity::timeCheckCar(kTime2443500, params->param1, 1, WRAP_SETUP_FUNCTION(Alouan, setup_compartment8)))
+ if (Entity::timeCheckCar(kTime2443500, params->param1, 1, WRAP_SETUP_FUNCTION(Alouan, setup_peekH)))
break;
}
label_callback1:
- if (Entity::timeCheckCallback(kTime2455200, params->param2, 2, WRAP_SETUP_FUNCTION(Alouan, setup_compartment8to6)))
+ if (Entity::timeCheckCallback(kTime2455200, params->param2, 2, WRAP_SETUP_FUNCTION(Alouan, setup_goHtoF)))
break;
label_callback2:
@@ -375,7 +375,7 @@ label_callback2:
getSavePoints()->push(kEntityAlouan, kEntityTrain, kAction191070912, kPosition_4840);
setCallback(3);
- setup_compartment6to8();
+ setup_goFtoH();
}
break;
@@ -452,7 +452,7 @@ IMPLEMENT_FUNCTION(22, Alouan, function22)
if (!Entity::updateParameter(params->param1, getState()->time, 2700))
break;
- setup_function23();
+ setup_hiding();
break;
case kActionDefault:
@@ -463,13 +463,13 @@ IMPLEMENT_FUNCTION(22, Alouan, function22)
case kActionDrawScene:
if (getEntities()->isInsideTrainCar(kEntityPlayer, kCarGreenSleeping))
- setup_function23();
+ setup_hiding();
break;
}
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION(23, Alouan, function23)
+IMPLEMENT_FUNCTION(23, Alouan, hiding)
switch (savepoint.action) {
default:
break;
diff --git a/engines/lastexpress/entities/alouan.h b/engines/lastexpress/entities/alouan.h
index 91254a449a..371e4f20d9 100644
--- a/engines/lastexpress/entities/alouan.h
+++ b/engines/lastexpress/entities/alouan.h
@@ -69,10 +69,10 @@ public:
*/
DECLARE_FUNCTION_2(updateEntity, CarIndex car, EntityPosition entityPosition)
- DECLARE_FUNCTION(compartment6)
- DECLARE_FUNCTION(compartment8)
- DECLARE_FUNCTION(compartment6to8)
- DECLARE_FUNCTION(compartment8to6)
+ DECLARE_FUNCTION(peekF)
+ DECLARE_FUNCTION(peekH)
+ DECLARE_FUNCTION(goFtoH)
+ DECLARE_FUNCTION(goHtoF)
/**
* Setup Chapter 1
@@ -126,7 +126,7 @@ public:
*/
DECLARE_FUNCTION(chapter5Handler)
DECLARE_FUNCTION(function22)
- DECLARE_FUNCTION(function23)
+ DECLARE_FUNCTION(hiding)
DECLARE_NULL_FUNCTION()
};
diff --git a/engines/lastexpress/entities/anna.cpp b/engines/lastexpress/entities/anna.cpp
index f8768032b5..4889f66c69 100644
--- a/engines/lastexpress/entities/anna.cpp
+++ b/engines/lastexpress/entities/anna.cpp
@@ -51,76 +51,76 @@ Anna::Anna(LastExpressEngine *engine) : Entity(engine, kEntityAnna) {
ADD_CALLBACK_FUNCTION(Anna, savegame);
ADD_CALLBACK_FUNCTION(Anna, updateEntity);
ADD_CALLBACK_FUNCTION(Anna, updateFromTime);
- ADD_CALLBACK_FUNCTION(Anna, function12);
+ ADD_CALLBACK_FUNCTION(Anna, practiceMusic);
ADD_CALLBACK_FUNCTION(Anna, draw2);
ADD_CALLBACK_FUNCTION(Anna, updateFromTicks);
- ADD_CALLBACK_FUNCTION(Anna, function15);
+ ADD_CALLBACK_FUNCTION(Anna, compartmentLogic);
ADD_CALLBACK_FUNCTION(Anna, chapter1);
- ADD_CALLBACK_FUNCTION(Anna, function17);
- ADD_CALLBACK_FUNCTION(Anna, function18);
- ADD_CALLBACK_FUNCTION(Anna, chapter1Handler);
- ADD_CALLBACK_FUNCTION(Anna, function20);
- ADD_CALLBACK_FUNCTION(Anna, function21);
+ ADD_CALLBACK_FUNCTION(Anna, doWalkP1);
+ ADD_CALLBACK_FUNCTION(Anna, diningLogic);
+ ADD_CALLBACK_FUNCTION(Anna, fleeTyler);
+ ADD_CALLBACK_FUNCTION(Anna, waitDinner);
+ ADD_CALLBACK_FUNCTION(Anna, goDinner);
ADD_CALLBACK_FUNCTION(Anna, function22);
- ADD_CALLBACK_FUNCTION(Anna, function23);
- ADD_CALLBACK_FUNCTION(Anna, function24);
- ADD_CALLBACK_FUNCTION(Anna, function25);
- ADD_CALLBACK_FUNCTION(Anna, function26);
- ADD_CALLBACK_FUNCTION(Anna, function27);
- ADD_CALLBACK_FUNCTION(Anna, function28);
- ADD_CALLBACK_FUNCTION(Anna, function29);
+ ADD_CALLBACK_FUNCTION(Anna, waitingDinner);
+ ADD_CALLBACK_FUNCTION(Anna, waitingDinner2);
+ ADD_CALLBACK_FUNCTION(Anna, eatingDinner);
+ ADD_CALLBACK_FUNCTION(Anna, leaveDinner);
+ ADD_CALLBACK_FUNCTION(Anna, freshenUp);
+ ADD_CALLBACK_FUNCTION(Anna, goSalon);
+ ADD_CALLBACK_FUNCTION(Anna, waitAugust);
ADD_CALLBACK_FUNCTION(Anna, function30);
- ADD_CALLBACK_FUNCTION(Anna, function31);
- ADD_CALLBACK_FUNCTION(Anna, function32);
- ADD_CALLBACK_FUNCTION(Anna, function33);
- ADD_CALLBACK_FUNCTION(Anna, function34);
- ADD_CALLBACK_FUNCTION(Anna, function35);
- ADD_CALLBACK_FUNCTION(Anna, function36);
+ ADD_CALLBACK_FUNCTION(Anna, leaveAugust);
+ ADD_CALLBACK_FUNCTION(Anna, returnCompartment);
+ ADD_CALLBACK_FUNCTION(Anna, readyForBed);
+ ADD_CALLBACK_FUNCTION(Anna, asleep);
+ ADD_CALLBACK_FUNCTION(Anna, wakeNight);
+ ADD_CALLBACK_FUNCTION(Anna, goVassili);
ADD_CALLBACK_FUNCTION(Anna, function37);
- ADD_CALLBACK_FUNCTION(Anna, function38);
- ADD_CALLBACK_FUNCTION(Anna, function39);
- ADD_CALLBACK_FUNCTION(Anna, function40);
- ADD_CALLBACK_FUNCTION(Anna, function41);
+ ADD_CALLBACK_FUNCTION(Anna, speakTatiana);
+ ADD_CALLBACK_FUNCTION(Anna, doWalk1019);
+ ADD_CALLBACK_FUNCTION(Anna, leaveTatiana);
+ ADD_CALLBACK_FUNCTION(Anna, goBackToSleep);
ADD_CALLBACK_FUNCTION(Anna, chapter2);
- ADD_CALLBACK_FUNCTION(Anna, chapter2Handler);
+ ADD_CALLBACK_FUNCTION(Anna, inPart2);
ADD_CALLBACK_FUNCTION(Anna, chapter3);
- ADD_CALLBACK_FUNCTION(Anna, function45);
- ADD_CALLBACK_FUNCTION(Anna, chapter3Handler);
- ADD_CALLBACK_FUNCTION(Anna, function47);
- ADD_CALLBACK_FUNCTION(Anna, function48);
+ ADD_CALLBACK_FUNCTION(Anna, exitCompartment);
+ ADD_CALLBACK_FUNCTION(Anna, practicing);
+ ADD_CALLBACK_FUNCTION(Anna, goLunch);
+ ADD_CALLBACK_FUNCTION(Anna, lunch);
ADD_CALLBACK_FUNCTION(Anna, leaveTableWithAugust);
- ADD_CALLBACK_FUNCTION(Anna, function50);
- ADD_CALLBACK_FUNCTION(Anna, function51);
- ADD_CALLBACK_FUNCTION(Anna, function52);
- ADD_CALLBACK_FUNCTION(Anna, function53);
- ADD_CALLBACK_FUNCTION(Anna, function54);
- ADD_CALLBACK_FUNCTION(Anna, function55);
- ADD_CALLBACK_FUNCTION(Anna, function56);
- ADD_CALLBACK_FUNCTION(Anna, function57);
- ADD_CALLBACK_FUNCTION(Anna, function58);
- ADD_CALLBACK_FUNCTION(Anna, function59);
- ADD_CALLBACK_FUNCTION(Anna, function60);
- ADD_CALLBACK_FUNCTION(Anna, function61);
+ ADD_CALLBACK_FUNCTION(Anna, leaveLunch);
+ ADD_CALLBACK_FUNCTION(Anna, afterLunch);
+ ADD_CALLBACK_FUNCTION(Anna, returnCompartment3);
+ ADD_CALLBACK_FUNCTION(Anna, dressing);
+ ADD_CALLBACK_FUNCTION(Anna, giveMaxToConductor2);
+ ADD_CALLBACK_FUNCTION(Anna, goConcert);
+ ADD_CALLBACK_FUNCTION(Anna, concert);
+ ADD_CALLBACK_FUNCTION(Anna, leaveConcert);
+ ADD_CALLBACK_FUNCTION(Anna, leaveConcertCathInCompartment);
+ ADD_CALLBACK_FUNCTION(Anna, afterConcert);
+ ADD_CALLBACK_FUNCTION(Anna, giveMaxBack);
+ ADD_CALLBACK_FUNCTION(Anna, goBaggageCompartment);
ADD_CALLBACK_FUNCTION(Anna, function62);
- ADD_CALLBACK_FUNCTION(Anna, function63);
- ADD_CALLBACK_FUNCTION(Anna, baggage);
- ADD_CALLBACK_FUNCTION(Anna, function65);
+ ADD_CALLBACK_FUNCTION(Anna, deadBaggageCompartment);
+ ADD_CALLBACK_FUNCTION(Anna, baggageFight);
+ ADD_CALLBACK_FUNCTION(Anna, prepareVienna);
ADD_CALLBACK_FUNCTION(Anna, chapter4);
- ADD_CALLBACK_FUNCTION(Anna, chapter4Handler);
- ADD_CALLBACK_FUNCTION(Anna, function68);
- ADD_CALLBACK_FUNCTION(Anna, function69);
- ADD_CALLBACK_FUNCTION(Anna, function70);
- ADD_CALLBACK_FUNCTION(Anna, function71);
- ADD_CALLBACK_FUNCTION(Anna, function72);
- ADD_CALLBACK_FUNCTION(Anna, function73);
+ ADD_CALLBACK_FUNCTION(Anna, reading);
+ ADD_CALLBACK_FUNCTION(Anna, sulking);
+ ADD_CALLBACK_FUNCTION(Anna, goSalon4);
+ ADD_CALLBACK_FUNCTION(Anna, returnCompartment4);
+ ADD_CALLBACK_FUNCTION(Anna, enterCompartmentCathFollowsAnna);
+ ADD_CALLBACK_FUNCTION(Anna, doWalkCathFollowsAnna);
+ ADD_CALLBACK_FUNCTION(Anna, letDownHair);
ADD_CALLBACK_FUNCTION(Anna, chapter5);
- ADD_CALLBACK_FUNCTION(Anna, chapter5Handler);
+ ADD_CALLBACK_FUNCTION(Anna, tiedUp);
ADD_CALLBACK_FUNCTION(Anna, function76);
- ADD_CALLBACK_FUNCTION(Anna, function77);
- ADD_CALLBACK_FUNCTION(Anna, function78);
- ADD_CALLBACK_FUNCTION(Anna, function79);
- ADD_CALLBACK_FUNCTION(Anna, function80);
+ ADD_CALLBACK_FUNCTION(Anna, readyToScore);
+ ADD_CALLBACK_FUNCTION(Anna, kidnapped);
+ ADD_CALLBACK_FUNCTION(Anna, waiting);
ADD_CALLBACK_FUNCTION(Anna, finalSequence);
+ ADD_CALLBACK_FUNCTION(Anna, openFirebird);
}
//////////////////////////////////////////////////////////////////////////
@@ -188,7 +188,7 @@ IMPLEMENT_FUNCTION_I(11, Anna, updateFromTime, uint32)
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION(12, Anna, function12)
+IMPLEMENT_FUNCTION(12, Anna, practiceMusic)
switch (savepoint.action) {
default:
break;
@@ -411,7 +411,7 @@ IMPLEMENT_FUNCTION_I(14, Anna, updateFromTicks, uint32)
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION_IS(15, Anna, function15, TimeValue)
+IMPLEMENT_FUNCTION_IS(15, Anna, compartmentLogic, TimeValue)
switch (savepoint.action) {
default:
break;
@@ -547,7 +547,7 @@ IMPLEMENT_FUNCTION(16, Anna, chapter1)
break;
case kActionNone:
- Entity::timeCheck(kTimeChapter1, params->param1, WRAP_SETUP_FUNCTION(Anna, setup_chapter1Handler));
+ Entity::timeCheck(kTimeChapter1, params->param1, WRAP_SETUP_FUNCTION(Anna, setup_fleeTyler));
break;
case kActionDefault:
@@ -567,7 +567,7 @@ IMPLEMENT_FUNCTION(16, Anna, chapter1)
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION_II(17, Anna, function17, uint32, uint32)
+IMPLEMENT_FUNCTION_II(17, Anna, doWalkP1, uint32, uint32)
switch (savepoint.action) {
default:
break;
@@ -656,7 +656,7 @@ IMPLEMENT_FUNCTION_II(17, Anna, function17, uint32, uint32)
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION_I(18, Anna, function18, TimeValue)
+IMPLEMENT_FUNCTION_I(18, Anna, diningLogic, TimeValue)
switch (savepoint.action) {
default:
break;
@@ -764,7 +764,7 @@ IMPLEMENT_FUNCTION_I(18, Anna, function18, TimeValue)
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION(19, Anna, chapter1Handler)
+IMPLEMENT_FUNCTION(19, Anna, fleeTyler)
switch (savepoint.action) {
default:
break;
@@ -797,7 +797,7 @@ IMPLEMENT_FUNCTION(19, Anna, chapter1Handler)
getData()->entityPosition = kPosition_4070;
getData()->location = kLocationInsideCompartment;
- setup_function20();
+ setup_waitDinner();
break;
}
break;
@@ -805,14 +805,14 @@ IMPLEMENT_FUNCTION(19, Anna, chapter1Handler)
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION(20, Anna, function20)
+IMPLEMENT_FUNCTION(20, Anna, waitDinner)
switch (savepoint.action) {
default:
break;
case kActionDefault:
setCallback(1);
- setup_function15(kTime1093500, "NONE");
+ setup_compartmentLogic(kTime1093500, "NONE");
break;
case kActionCallback:
@@ -828,7 +828,7 @@ IMPLEMENT_FUNCTION(20, Anna, function20)
case 2:
getData()->location = kLocationOutsideCompartment;
getSavePoints()->push(kEntityAnna, kEntityMax, kAction71277948);
- setup_function21();
+ setup_goDinner();
break;
}
break;
@@ -836,14 +836,14 @@ IMPLEMENT_FUNCTION(20, Anna, function20)
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION(21, Anna, function21)
+IMPLEMENT_FUNCTION(21, Anna, goDinner)
switch (savepoint.action) {
default:
break;
case kActionDefault:
setCallback(1);
- setup_function17(kCarRestaurant, kPosition_850);
+ setup_doWalkP1(kCarRestaurant, kPosition_850);
break;
case kActionCallback:
@@ -894,13 +894,13 @@ IMPLEMENT_FUNCTION(22, Anna, function22)
case kAction157370960:
getData()->location = kLocationInsideCompartment;
- setup_function23();
+ setup_waitingDinner();
break;
}
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION(23, Anna, function23)
+IMPLEMENT_FUNCTION(23, Anna, waitingDinner)
switch (savepoint.action) {
default:
break;
@@ -911,7 +911,7 @@ IMPLEMENT_FUNCTION(23, Anna, function23)
getSavePoints()->push(kEntityAnna, kEntityTables0, kAction136455232);
setCallback(1);
- setup_function18(kTimeNone);
+ setup_diningLogic(kTimeNone);
break;
case kActionCallback:
@@ -932,7 +932,7 @@ IMPLEMENT_FUNCTION(23, Anna, function23)
case 3:
getSavePoints()->push(kEntityAnna, kEntityServers0, kAction203859488);
- setup_function24();
+ setup_waitingDinner2();
break;
}
break;
@@ -940,7 +940,7 @@ IMPLEMENT_FUNCTION(23, Anna, function23)
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION(24, Anna, function24)
+IMPLEMENT_FUNCTION(24, Anna, waitingDinner2)
switch (savepoint.action) {
default:
break;
@@ -949,7 +949,7 @@ IMPLEMENT_FUNCTION(24, Anna, function24)
getEntities()->drawSequenceLeft(kEntityAnna, "001G");
setCallback(1);
- setup_function18(kTimeNone);
+ setup_diningLogic(kTimeNone);
break;
case kActionCallback:
@@ -965,7 +965,7 @@ IMPLEMENT_FUNCTION(24, Anna, function24)
case 2:
getSavePoints()->push(kEntityAnna, kEntityServers0, kAction136702400);
- setup_function25();
+ setup_eatingDinner();
break;
}
break;
@@ -973,7 +973,7 @@ IMPLEMENT_FUNCTION(24, Anna, function24)
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION(25, Anna, function25)
+IMPLEMENT_FUNCTION(25, Anna, eatingDinner)
switch (savepoint.action) {
default:
break;
@@ -983,7 +983,7 @@ IMPLEMENT_FUNCTION(25, Anna, function25)
getProgress().field_28 = 1;
setCallback(1);
- setup_function18(kTimeNone);
+ setup_diningLogic(kTimeNone);
break;
case kActionCallback:
@@ -996,7 +996,7 @@ IMPLEMENT_FUNCTION(25, Anna, function25)
break;
case 3:
- setup_function26();
+ setup_leaveDinner();
break;
}
break;
@@ -1008,13 +1008,13 @@ IMPLEMENT_FUNCTION(25, Anna, function25)
case kAction201437056:
getEntities()->drawSequenceLeft(kEntityAnna, "001J");
setCallback(2);
- setup_function18(kTime1138500);
+ setup_diningLogic(kTime1138500);
break;
}
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION(26, Anna, function26)
+IMPLEMENT_FUNCTION(26, Anna, leaveDinner)
switch (savepoint.action) {
default:
break;
@@ -1046,7 +1046,7 @@ IMPLEMENT_FUNCTION(26, Anna, function26)
case 2:
setCallback(3);
- setup_function17(kCarRedSleeping, kPosition_4070);
+ setup_doWalkP1(kCarRedSleeping, kPosition_4070);
break;
case 3:
@@ -1059,7 +1059,7 @@ IMPLEMENT_FUNCTION(26, Anna, function26)
getData()->entityPosition = kPosition_4070;
getData()->location = kLocationInsideCompartment;
- setup_function27();
+ setup_freshenUp();
break;
}
break;
@@ -1067,7 +1067,7 @@ IMPLEMENT_FUNCTION(26, Anna, function26)
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION(27, Anna, function27)
+IMPLEMENT_FUNCTION(27, Anna, freshenUp)
switch (savepoint.action) {
default:
break;
@@ -1075,7 +1075,7 @@ IMPLEMENT_FUNCTION(27, Anna, function27)
case kActionDefault:
getSavePoints()->push(kEntityAnna, kEntityMax, kAction101687594);
setCallback(1);
- setup_function15(kTime1156500, "NONE");
+ setup_compartmentLogic(kTime1156500, "NONE");
break;
case kActionCallback:
@@ -1088,7 +1088,7 @@ IMPLEMENT_FUNCTION(27, Anna, function27)
if (getProgress().field_14 == 29) {
params->param1 = (uint)(getState()->time + 900);
setCallback(2);
- setup_function15((TimeValue)params->param1, "NONE");
+ setup_compartmentLogic((TimeValue)params->param1, "NONE");
} else {
setCallback(3);
setup_enterExitCompartment("618Bf", kObjectCompartmentF);
@@ -1098,7 +1098,7 @@ IMPLEMENT_FUNCTION(27, Anna, function27)
case 3:
getData()->location = kLocationOutsideCompartment;
getSavePoints()->push(kEntityAnna, kEntityMax, kAction71277948);
- setup_function28();
+ setup_goSalon();
break;
}
break;
@@ -1106,14 +1106,14 @@ IMPLEMENT_FUNCTION(27, Anna, function27)
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION(28, Anna, function28)
+IMPLEMENT_FUNCTION(28, Anna, goSalon)
switch (savepoint.action) {
default:
break;
case kActionDefault:
setCallback(1);
- setup_function17(kCarRestaurant, kPosition_850);
+ setup_doWalkP1(kCarRestaurant, kPosition_850);
break;
case kActionCallback:
@@ -1137,7 +1137,7 @@ IMPLEMENT_FUNCTION(28, Anna, function28)
case 3:
getData()->location = kLocationInsideCompartment;
- setup_function29();
+ setup_waitAugust();
break;
}
break;
@@ -1145,7 +1145,7 @@ IMPLEMENT_FUNCTION(28, Anna, function28)
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION(29, Anna, function29)
+IMPLEMENT_FUNCTION(29, Anna, waitAugust)
switch (savepoint.action) {
default:
break;
@@ -1268,7 +1268,7 @@ IMPLEMENT_FUNCTION(30, Anna, function30)
if (getState()->time > kTime1192500) {
params->param4 = kTimeInvalid;
- setup_function30();
+ setup_leaveAugust();
break;
}
@@ -1277,7 +1277,7 @@ IMPLEMENT_FUNCTION(30, Anna, function30)
if (params->param4 < getState()->time) {
params->param4 = kTimeInvalid;
- setup_function30();
+ setup_leaveAugust();
break;
}
}
@@ -1308,7 +1308,7 @@ IMPLEMENT_FUNCTION(30, Anna, function30)
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION(31, Anna, function31)
+IMPLEMENT_FUNCTION(31, Anna, leaveAugust)
switch (savepoint.action) {
default:
break;
@@ -1343,7 +1343,7 @@ IMPLEMENT_FUNCTION(31, Anna, function31)
getInventory()->setLocationAndProcess(kItem3, kObjectLocation1);
getSavePoints()->push(kEntityAnna, kEntityAugust, kAction159332865);
- setup_function32();
+ setup_returnCompartment();
break;
}
break;
@@ -1351,14 +1351,14 @@ IMPLEMENT_FUNCTION(31, Anna, function31)
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION(32, Anna, function32)
+IMPLEMENT_FUNCTION(32, Anna, returnCompartment)
switch (savepoint.action) {
default:
break;
case kActionDefault:
setCallback(1);
- setup_function17(kCarRedSleeping, kPosition_4070);
+ setup_doWalkP1(kCarRedSleeping, kPosition_4070);
break;
case kActionCallback:
@@ -1377,7 +1377,7 @@ IMPLEMENT_FUNCTION(32, Anna, function32)
getData()->entityPosition = kPosition_4070;
getData()->location = kLocationInsideCompartment;
- setup_function33();
+ setup_readyForBed();
break;
}
break;
@@ -1385,7 +1385,7 @@ IMPLEMENT_FUNCTION(32, Anna, function32)
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION(33, Anna, function33)
+IMPLEMENT_FUNCTION(33, Anna, readyForBed)
switch (savepoint.action) {
default:
break;
@@ -1395,20 +1395,20 @@ IMPLEMENT_FUNCTION(33, Anna, function33)
params->param1 = (uint)(getState()->time + 4500);
setCallback(1);
- setup_function15((TimeValue)params->param1, "NONE");
+ setup_compartmentLogic((TimeValue)params->param1, "NONE");
break;
case kActionCallback:
if (getCallback() == 1) {
- getObjects()->updateLocation2(kObjectCompartmentF, kObjectLocation1);
- setup_function34();
+ getObjects()->updateModel(kObjectCompartmentF, kObjectModel1);
+ setup_asleep();
}
break;
}
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION(34, Anna, function34)
+IMPLEMENT_FUNCTION(34, Anna, asleep)
switch (savepoint.action) {
default:
break;
@@ -1423,7 +1423,7 @@ IMPLEMENT_FUNCTION(34, Anna, function34)
}
label_callback_1:
- Entity::timeCheck(kTime1489500, params->param3, WRAP_SETUP_FUNCTION(Anna, setup_function35));
+ Entity::timeCheck(kTime1489500, params->param3, WRAP_SETUP_FUNCTION(Anna, setup_wakeNight));
break;
case kActionKnock:
@@ -1480,7 +1480,7 @@ label_callback_1:
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION(35, Anna, function35)
+IMPLEMENT_FUNCTION(35, Anna, wakeNight)
switch (savepoint.action) {
default:
break;
@@ -1561,11 +1561,11 @@ IMPLEMENT_FUNCTION(35, Anna, function35)
getSavePoints()->push(kEntityAnna, kEntityCoudert, kAction339669520);
getSavePoints()->push(kEntityAnna, kEntityMax, kAction71277948);
- setup_function36();
+ setup_goVassili();
break;
case 2:
- setup_function36();
+ setup_goVassili();
break;
}
break;
@@ -1585,7 +1585,7 @@ IMPLEMENT_FUNCTION(35, Anna, function35)
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION(36, Anna, function36)
+IMPLEMENT_FUNCTION(36, Anna, goVassili)
switch (savepoint.action) {
default:
break;
@@ -1634,13 +1634,13 @@ IMPLEMENT_FUNCTION(37, Anna, function37)
break;
case kAction191477936:
- setup_function38();
+ setup_speakTatiana();
break;
}
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION(38, Anna, function38)
+IMPLEMENT_FUNCTION(38, Anna, speakTatiana)
switch (savepoint.action) {
default:
break;
@@ -1655,14 +1655,14 @@ IMPLEMENT_FUNCTION(38, Anna, function38)
case kActionCallback:
if (getCallback() == 1) {
getSound()->playSound(kEntityPlayer, "MUS043");
- setup_function40();
+ setup_leaveTatiana();
}
break;
}
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION_II(39, Anna, function39, CarIndex, EntityPosition)
+IMPLEMENT_FUNCTION_II(39, Anna, doWalk1019, CarIndex, EntityPosition)
switch (savepoint.action) {
default:
break;
@@ -1708,7 +1708,7 @@ IMPLEMENT_FUNCTION_II(39, Anna, function39, CarIndex, EntityPosition)
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION(40, Anna, function40)
+IMPLEMENT_FUNCTION(40, Anna, leaveTatiana)
switch (savepoint.action) {
default:
break;
@@ -1727,7 +1727,7 @@ IMPLEMENT_FUNCTION(40, Anna, function40)
getData()->location = kLocationOutsideCompartment;
setCallback(2);
- setup_function39(kCarRedSleeping, kPosition_4070);
+ setup_doWalk1019(kCarRedSleeping, kPosition_4070);
break;
case 2:
@@ -1752,7 +1752,7 @@ IMPLEMENT_FUNCTION(40, Anna, function40)
getData()->location = kLocationOutsideCompartment;
setCallback(6);
- setup_function39(kCarRedSleeping, kPosition_7500);
+ setup_doWalk1019(kCarRedSleeping, kPosition_7500);
break;
case 6:
@@ -1777,7 +1777,7 @@ IMPLEMENT_FUNCTION(40, Anna, function40)
getData()->location = kLocationOutsideCompartment;
setCallback(10);
- setup_function39(kCarRedSleeping, kPosition_4070);
+ setup_doWalk1019(kCarRedSleeping, kPosition_4070);
break;
case 10:
@@ -1790,7 +1790,7 @@ IMPLEMENT_FUNCTION(40, Anna, function40)
getData()->location = kLocationInsideCompartment;
getData()->entityPosition = kPosition_4070;
- setup_function41();
+ setup_goBackToSleep();
break;
}
break;
@@ -1798,7 +1798,7 @@ IMPLEMENT_FUNCTION(40, Anna, function40)
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION(41, Anna, function41)
+IMPLEMENT_FUNCTION(41, Anna, goBackToSleep)
switch (savepoint.action) {
default:
break;
@@ -1875,7 +1875,7 @@ IMPLEMENT_FUNCTION(42, Anna, chapter2)
break;
case kActionNone:
- setup_chapter2Handler();
+ setup_inPart2();
break;
case kActionDefault:
@@ -1892,7 +1892,7 @@ IMPLEMENT_FUNCTION(42, Anna, chapter2)
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION(43, Anna, chapter2Handler)
+IMPLEMENT_FUNCTION(43, Anna, inPart2)
switch (savepoint.action) {
default:
break;
@@ -1901,7 +1901,7 @@ IMPLEMENT_FUNCTION(43, Anna, chapter2Handler)
getObjects()->update(kObjectOutsideAnnaCompartment, kEntityPlayer, kObjectLocationNone, kCursorKeepValue, kCursorKeepValue);
setCallback(1);
- setup_function12();
+ setup_practiceMusic();
break;
case kActionCallback:
@@ -1911,27 +1911,27 @@ IMPLEMENT_FUNCTION(43, Anna, chapter2Handler)
case 1:
setCallback(2);
- setup_function15(kTime1786500, "418C");
+ setup_compartmentLogic(kTime1786500, "418C");
break;
case 2:
setCallback(3);
- setup_function12();
+ setup_practiceMusic();
break;
case 3:
setCallback(4);
- setup_function15(kTime1818000, "418C");
+ setup_compartmentLogic(kTime1818000, "418C");
break;
case 4:
setCallback(5);
- setup_function12();
+ setup_practiceMusic();
break;
case 5:
setCallback(6);
- setup_function15(kTimeEnd, "418C");
+ setup_compartmentLogic(kTimeEnd, "418C");
break;
}
break;
@@ -1945,7 +1945,7 @@ IMPLEMENT_FUNCTION(44, Anna, chapter3)
break;
case kActionNone:
- setup_chapter3Handler();
+ setup_practicing();
break;
case kActionDefault:
@@ -1965,7 +1965,7 @@ IMPLEMENT_FUNCTION(44, Anna, chapter3)
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION_I(45, Anna, function45, bool)
+IMPLEMENT_FUNCTION_I(45, Anna, exitCompartment, bool)
switch (savepoint.action) {
default:
break;
@@ -2004,7 +2004,7 @@ IMPLEMENT_FUNCTION_I(45, Anna, function45, bool)
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION(46, Anna, chapter3Handler)
+IMPLEMENT_FUNCTION(46, Anna, practicing)
switch (savepoint.action) {
default:
break;
@@ -2014,16 +2014,16 @@ IMPLEMENT_FUNCTION(46, Anna, chapter3Handler)
getScenes()->loadSceneFromPosition(kCarRedSleeping, 49);
setCallback(1);
- setup_function12();
+ setup_practiceMusic();
break;
case kActionCallback:
if (getCallback() == 1 || getCallback() == 2) {
if (ENTITY_PARAM(0, 1)) {
- setup_function47();
+ setup_goLunch();
} else {
setCallback(2);
- setup_function15((TimeValue)(getState()->time + 4500), "418C");
+ setup_compartmentLogic((TimeValue) (getState()->time + 4500), "418C");
}
}
break;
@@ -2031,7 +2031,7 @@ IMPLEMENT_FUNCTION(46, Anna, chapter3Handler)
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION(47, Anna, function47)
+IMPLEMENT_FUNCTION(47, Anna, goLunch)
switch (savepoint.action) {
default:
break;
@@ -2080,7 +2080,7 @@ IMPLEMENT_FUNCTION(47, Anna, function47)
case 5:
getEntities()->drawSequenceLeft(kEntityAugust, "BLANK");
- setup_function48();
+ setup_lunch();
break;
}
break;
@@ -2088,7 +2088,7 @@ IMPLEMENT_FUNCTION(47, Anna, function47)
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION(48, Anna, function48)
+IMPLEMENT_FUNCTION(48, Anna, lunch)
switch (savepoint.action) {
default:
break;
@@ -2121,7 +2121,7 @@ label_callback_4:
params->param4 = kTimeInvalid;
- setup_function50();
+ setup_leaveLunch();
}
}
break;
@@ -2213,7 +2213,7 @@ IMPLEMENT_FUNCTION(49, Anna, leaveTableWithAugust)
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION(50, Anna, function50)
+IMPLEMENT_FUNCTION(50, Anna, leaveLunch)
switch (savepoint.action) {
default:
break;
@@ -2240,7 +2240,7 @@ IMPLEMENT_FUNCTION(50, Anna, function50)
break;
case 3:
- setup_function51();
+ setup_afterLunch();
break;
}
break;
@@ -2248,7 +2248,7 @@ IMPLEMENT_FUNCTION(50, Anna, function50)
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION(51, Anna, function51)
+IMPLEMENT_FUNCTION(51, Anna, afterLunch)
switch (savepoint.action) {
default:
break;
@@ -2291,7 +2291,7 @@ IMPLEMENT_FUNCTION(51, Anna, function51)
case 2:
getSavePoints()->push(kEntityAnna, kEntityAugust, kAction122288808);
- setup_function52();
+ setup_returnCompartment3();
break;
case 3:
@@ -2348,7 +2348,7 @@ IMPLEMENT_FUNCTION(51, Anna, function51)
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION(52, Anna, function52)
+IMPLEMENT_FUNCTION(52, Anna, returnCompartment3)
switch (savepoint.action) {
default:
break;
@@ -2360,7 +2360,7 @@ IMPLEMENT_FUNCTION(52, Anna, function52)
getEntities()->clearSequences(kEntityAnna);
- setup_function53();
+ setup_dressing();
break;
case kActionDefault:
@@ -2385,7 +2385,7 @@ IMPLEMENT_FUNCTION(52, Anna, function52)
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION(53, Anna, function53)
+IMPLEMENT_FUNCTION(53, Anna, dressing)
switch (savepoint.action) {
default:
break;
@@ -2393,7 +2393,7 @@ IMPLEMENT_FUNCTION(53, Anna, function53)
case kActionNone:
if (getProgress().field_48 && params->param5 != kTimeInvalid) {
if (Entity::updateParameterTime(kTime2065500, !getEntities()->isPlayerInCar(kCarRedSleeping), params->param5, 150)) {
- setup_function54();
+ setup_giveMaxToConductor2();
break;
}
}
@@ -2537,14 +2537,14 @@ IMPLEMENT_FUNCTION(53, Anna, function53)
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION(54, Anna, function54)
+IMPLEMENT_FUNCTION(54, Anna, giveMaxToConductor2)
switch (savepoint.action) {
default:
break;
case kActionNone:
if (params->param3) {
- if (Entity::timeCheck(kTime2079000, params->param5, WRAP_SETUP_FUNCTION(Anna, setup_function55)))
+ if (Entity::timeCheck(kTime2079000, params->param5, WRAP_SETUP_FUNCTION(Anna, setup_goConcert)))
break;
if (Entity::updateParameter(params->param6, getState()->time, 9000)) {
@@ -2702,7 +2702,7 @@ IMPLEMENT_FUNCTION(54, Anna, function54)
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION(55, Anna, function55)
+IMPLEMENT_FUNCTION(55, Anna, goConcert)
switch (savepoint.action) {
default:
break;
@@ -2718,7 +2718,7 @@ IMPLEMENT_FUNCTION(55, Anna, function55)
getInventory()->setLocationAndProcess(kItemKey, kObjectLocation1);
setCallback(1);
- setup_function45(true);
+ setup_exitCompartment(true);
break;
case kActionCallback:
@@ -2733,7 +2733,7 @@ IMPLEMENT_FUNCTION(55, Anna, function55)
break;
case 2:
- setup_function56();
+ setup_concert();
break;
}
break;
@@ -2741,7 +2741,7 @@ IMPLEMENT_FUNCTION(55, Anna, function55)
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION(56, Anna, function56)
+IMPLEMENT_FUNCTION(56, Anna, concert)
switch (savepoint.action) {
default:
break;
@@ -2754,13 +2754,13 @@ IMPLEMENT_FUNCTION(56, Anna, function56)
break;
case kAction191668032:
- setup_function57();
+ setup_leaveConcert();
break;
}
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION(57, Anna, function57)
+IMPLEMENT_FUNCTION(57, Anna, leaveConcert)
switch (savepoint.action) {
default:
break;
@@ -2820,7 +2820,7 @@ IMPLEMENT_FUNCTION(57, Anna, function57)
getEntities()->exitCompartment(kEntityAnna, kObjectCompartmentF, true);
getSavePoints()->push(kEntityAnna, kEntityAugust, kAction122288808);
- setup_function59();
+ setup_afterConcert();
break;
}
break;
@@ -2841,7 +2841,7 @@ IMPLEMENT_FUNCTION(57, Anna, function57)
if (getEntities()->isInsideCompartment(kEntityPlayer, kCarRedSleeping, kPosition_4070)
|| getEntities()->isInsideCompartment(kEntityPlayer, kCarRedSleeping, kPosition_4455)) {
getEntities()->exitCompartment(kEntityAnna, kObjectCompartmentF, true);
- setup_function58();
+ setup_leaveConcertCathInCompartment();
} else {
setCallback(3);
setup_enterExitCompartment("625Ff", kObjectCompartmentF);
@@ -2851,7 +2851,7 @@ IMPLEMENT_FUNCTION(57, Anna, function57)
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION(58, Anna, function58)
+IMPLEMENT_FUNCTION(58, Anna, leaveConcertCathInCompartment)
switch (savepoint.action) {
default:
break;
@@ -2868,14 +2868,14 @@ IMPLEMENT_FUNCTION(58, Anna, function58)
getScenes()->loadSceneFromPosition(kCarRedSleeping, 8);
getSound()->playSound(kEntityAnna, "lib015");
getSavePoints()->push(kEntityAnna, kEntityAugust, kAction122288808);
- setup_function59();
+ setup_afterConcert();
}
break;
}
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION(59, Anna, function59)
+IMPLEMENT_FUNCTION(59, Anna, afterConcert)
switch (savepoint.action) {
default:
break;
@@ -2884,7 +2884,7 @@ IMPLEMENT_FUNCTION(59, Anna, function59)
if (getInventory()->hasItem(kItemKey) && params->param4 != kTimeInvalid && getState()->time > kTime2218500) {
if (getState()->time > kTime2248200) {
params->param4 = kTimeInvalid;
- setup_function61();
+ setup_goBaggageCompartment();
break;
}
@@ -2897,7 +2897,7 @@ IMPLEMENT_FUNCTION(59, Anna, function59)
if (params->param4 < getState()->time) {
params->param4 = kTimeInvalid;
- setup_function61();
+ setup_goBaggageCompartment();
break;
}
}
@@ -2996,7 +2996,7 @@ IMPLEMENT_FUNCTION(59, Anna, function59)
case kAction156622016:
if (params->param3) {
setCallback(8);
- setup_function60();
+ setup_giveMaxBack();
}
break;
@@ -3017,7 +3017,7 @@ IMPLEMENT_FUNCTION(59, Anna, function59)
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION(60, Anna, function60)
+IMPLEMENT_FUNCTION(60, Anna, giveMaxBack)
switch (savepoint.action) {
default:
break;
@@ -3063,7 +3063,7 @@ IMPLEMENT_FUNCTION(60, Anna, function60)
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION(61, Anna, function61)
+IMPLEMENT_FUNCTION(61, Anna, goBaggageCompartment)
switch (savepoint.action) {
default:
break;
@@ -3084,7 +3084,7 @@ IMPLEMENT_FUNCTION(61, Anna, function61)
getObjects()->update(kObject53, kEntityPlayer, kObjectLocation1, kCursorHandKnock, kCursorHand);
setCallback(2);
- setup_function45(false);
+ setup_exitCompartment(false);
break;
case 2:
@@ -3135,7 +3135,7 @@ IMPLEMENT_FUNCTION(62, Anna, function62)
if (getState()->time > kTime2259000 && !params->param2) {
params->param2 = 1;
getSavePoints()->push(kEntityAnna, kEntityVesna, kAction189299008);
- setup_function63();
+ setup_deadBaggageCompartment();
}
break;
@@ -3151,7 +3151,7 @@ IMPLEMENT_FUNCTION(62, Anna, function62)
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION(63, Anna, function63)
+IMPLEMENT_FUNCTION(63, Anna, deadBaggageCompartment)
switch (savepoint.action) {
default:
break;
@@ -3180,7 +3180,7 @@ IMPLEMENT_FUNCTION(63, Anna, function63)
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION(64, Anna, baggage)
+IMPLEMENT_FUNCTION(64, Anna, baggageFight)
switch (savepoint.action) {
default:
break;
@@ -3224,7 +3224,7 @@ IMPLEMENT_FUNCTION(64, Anna, baggage)
getProgress().field_54 = 0;
getState()->time = kTime2266200;
- setup_function65();
+ setup_prepareVienna();
break;
}
break;
@@ -3232,7 +3232,7 @@ IMPLEMENT_FUNCTION(64, Anna, baggage)
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION(65, Anna, function65)
+IMPLEMENT_FUNCTION(65, Anna, prepareVienna)
if (savepoint.action == kActionDefault) {
getData()->entityPosition = kPosition_4070;
getData()->location = kLocationInsideCompartment;
@@ -3243,7 +3243,7 @@ IMPLEMENT_FUNCTION(65, Anna, function65)
getObjects()->update(kObjectOutsideAnnaCompartment, kEntityPlayer, kObjectLocation1, kCursorKeepValue, kCursorKeepValue);
setCallback(1);
- setup_function15(kTimeEnd, "NONE");
+ setup_compartmentLogic(kTimeEnd, "NONE");
}
IMPLEMENT_FUNCTION_END
@@ -3254,7 +3254,7 @@ IMPLEMENT_FUNCTION(66, Anna, chapter4)
break;
case kActionNone:
- setup_chapter4Handler();
+ setup_reading();
break;
case kActionDefault:
@@ -3271,7 +3271,7 @@ IMPLEMENT_FUNCTION(66, Anna, chapter4)
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION(67, Anna, chapter4Handler)
+IMPLEMENT_FUNCTION(67, Anna, reading)
switch (savepoint.action) {
default:
break;
@@ -3344,7 +3344,7 @@ label_next:
getSound()->playSound(kEntityPlayer, "LIB015");
getScenes()->loadSceneFromPosition(kCarRedSleeping, 8);
- setup_function68();
+ setup_sulking();
break;
case 2:
@@ -3369,7 +3369,7 @@ label_next:
getObjects()->update(kObjectCompartmentF, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
getData()->inventoryItem = kItemNone;
- setup_function69();
+ setup_goSalon4();
break;
case kAction219971920:
@@ -3379,7 +3379,7 @@ label_next:
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION(68, Anna, function68)
+IMPLEMENT_FUNCTION(68, Anna, sulking)
switch (savepoint.action) {
default:
break;
@@ -3387,7 +3387,7 @@ IMPLEMENT_FUNCTION(68, Anna, function68)
case kActionNone:
if (!params->param1) {
setCallback(1);
- setup_function15(kTime2511900, "NONE");
+ setup_compartmentLogic(kTime2511900, "NONE");
}
break;
@@ -3402,7 +3402,7 @@ IMPLEMENT_FUNCTION(68, Anna, function68)
case kAction191001984:
getObjects()->update(kObjectCompartmentF, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
- setup_function69();
+ setup_goSalon4();
break;
case kAction201431954:
@@ -3412,7 +3412,7 @@ IMPLEMENT_FUNCTION(68, Anna, function68)
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION(69, Anna, function69)
+IMPLEMENT_FUNCTION(69, Anna, goSalon4)
switch (savepoint.action) {
default:
break;
@@ -3426,7 +3426,7 @@ IMPLEMENT_FUNCTION(69, Anna, function69)
getData()->entityPosition = kPosition_9270;
getData()->location = kLocationOutsideCompartment;
- setup_function70();
+ setup_returnCompartment4();
break;
}
@@ -3448,7 +3448,7 @@ IMPLEMENT_FUNCTION(69, Anna, function69)
getData()->entityPosition = kPosition_8200;
getData()->location = kLocationOutsideCompartment;
- setup_function70();
+ setup_returnCompartment4();
}
break;
@@ -3484,7 +3484,7 @@ IMPLEMENT_FUNCTION(69, Anna, function69)
break;
case 5:
- setup_function70();
+ setup_returnCompartment4();
break;
}
break;
@@ -3506,14 +3506,14 @@ IMPLEMENT_FUNCTION(69, Anna, function69)
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION(70, Anna, function70)
+IMPLEMENT_FUNCTION(70, Anna, returnCompartment4)
switch (savepoint.action) {
default:
break;
case kActionDefault:
setCallback(1);
- setup_function72(kCarRedSleeping, kPosition_4070);
+ setup_doWalkCathFollowsAnna(kCarRedSleeping, kPosition_4070);
break;
case kActionCallback:
@@ -3523,13 +3523,13 @@ IMPLEMENT_FUNCTION(70, Anna, function70)
case 1:
setCallback(2);
- setup_function71();
+ setup_enterCompartmentCathFollowsAnna();
break;
case 2:
getData()->location = kLocationOutsideCompartment;
getEntities()->clearSequences(kEntityAnna);
- setup_function73();
+ setup_letDownHair();
break;
}
break;
@@ -3537,7 +3537,7 @@ IMPLEMENT_FUNCTION(70, Anna, function70)
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION(71, Anna, function71)
+IMPLEMENT_FUNCTION(71, Anna, enterCompartmentCathFollowsAnna)
switch (savepoint.action) {
default:
break;
@@ -3589,7 +3589,7 @@ IMPLEMENT_FUNCTION(71, Anna, function71)
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION_II(72, Anna, function72, CarIndex, EntityPosition)
+IMPLEMENT_FUNCTION_II(72, Anna, doWalkCathFollowsAnna, CarIndex, EntityPosition)
switch (savepoint.action) {
default:
break;
@@ -3631,7 +3631,7 @@ IMPLEMENT_FUNCTION_II(72, Anna, function72, CarIndex, EntityPosition)
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION(73, Anna, function73)
+IMPLEMENT_FUNCTION(73, Anna, letDownHair)
switch (savepoint.action) {
default:
break;
@@ -3712,7 +3712,7 @@ IMPLEMENT_FUNCTION(74, Anna, chapter5)
break;
case kActionNone:
- setup_chapter5Handler();
+ setup_tiedUp();
break;
case kActionDefault:
@@ -3731,7 +3731,7 @@ IMPLEMENT_FUNCTION(74, Anna, chapter5)
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION(75, Anna, chapter5Handler)
+IMPLEMENT_FUNCTION(75, Anna, tiedUp)
switch (savepoint.action) {
default:
break;
@@ -3758,11 +3758,11 @@ IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
IMPLEMENT_FUNCTION(76, Anna, function76)
if (savepoint.action == kAction158480160)
- setup_function77();
+ setup_readyToScore();
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION(77, Anna, function77)
+IMPLEMENT_FUNCTION(77, Anna, readyToScore)
switch (savepoint.action) {
default:
break;
@@ -3818,7 +3818,7 @@ IMPLEMENT_FUNCTION(77, Anna, function77)
break;
case 3:
- setup_function78();
+ setup_kidnapped();
break;
}
break;
@@ -3826,14 +3826,14 @@ IMPLEMENT_FUNCTION(77, Anna, function77)
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION(78, Anna, function78)
+IMPLEMENT_FUNCTION(78, Anna, kidnapped)
switch (savepoint.action) {
default:
break;
case kActionDrawScene:
if ((getEntities()->isInRestaurant(kEntityPlayer) || getEntities()->isInSalon(kEntityPlayer)) && getInventory()->hasItem(kItemFirebird)) {
- setup_function80();
+ setup_finalSequence();
break;
}
@@ -3857,7 +3857,7 @@ IMPLEMENT_FUNCTION(78, Anna, function78)
getAction()->playAnimation(kEventKronosHostageAnna);
getScenes()->loadSceneFromPosition(kCarRestaurant, 61);
getSound()->playSound(kEntityAnna, "Mus024", kFlagDefault);
- setup_function79();
+ setup_waiting();
break;
}
break;
@@ -3865,7 +3865,7 @@ IMPLEMENT_FUNCTION(78, Anna, function78)
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION(79, Anna, function79)
+IMPLEMENT_FUNCTION(79, Anna, waiting)
switch (savepoint.action) {
default:
break;
@@ -3878,7 +3878,7 @@ IMPLEMENT_FUNCTION(79, Anna, function79)
case kActionDrawScene:
if (getEntities()->isInRestaurant(kEntityPlayer) && getInventory()->hasItem(kItemFirebird)) {
- setup_function80();
+ setup_finalSequence();
break;
}
@@ -3918,7 +3918,7 @@ IMPLEMENT_FUNCTION(79, Anna, function79)
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION(80, Anna, function80)
+IMPLEMENT_FUNCTION(80, Anna, finalSequence)
switch (savepoint.action) {
default:
break;
@@ -3973,7 +3973,7 @@ IMPLEMENT_FUNCTION(80, Anna, function80)
getAction()->playAnimation(kEventKronosOpenFirebird);
getScenes()->loadSceneFromPosition(kCarRestaurant, 3);
- setup_finalSequence();
+ setup_openFirebird();
break;
}
break;
@@ -3988,7 +3988,7 @@ IMPLEMENT_FUNCTION(80, Anna, function80)
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION(81, Anna, finalSequence)
+IMPLEMENT_FUNCTION(81, Anna, openFirebird)
switch (savepoint.action) {
default:
break;
diff --git a/engines/lastexpress/entities/anna.h b/engines/lastexpress/entities/anna.h
index 205ff9d42c..de79ccb826 100644
--- a/engines/lastexpress/entities/anna.h
+++ b/engines/lastexpress/entities/anna.h
@@ -113,7 +113,7 @@ public:
*/
DECLARE_FUNCTION_1(updateFromTime, uint32 time)
- DECLARE_FUNCTION(function12)
+ DECLARE_FUNCTION(practiceMusic)
/**
* Draws the entity along with another one
@@ -131,43 +131,43 @@ public:
*/
DECLARE_FUNCTION_1(updateFromTicks, uint32 ticks)
- DECLARE_FUNCTION_2(function15, TimeValue timeValue, const char *sequence)
+ DECLARE_FUNCTION_2(compartmentLogic, TimeValue timeValue, const char *sequence)
/**
* Setup Chapter 1
*/
DECLARE_FUNCTION(chapter1)
- DECLARE_FUNCTION_2(function17, uint32, uint32)
+ DECLARE_FUNCTION_2(doWalkP1, uint32, uint32)
- DECLARE_FUNCTION_1(function18, TimeValue timeValue)
+ DECLARE_FUNCTION_1(diningLogic, TimeValue timeValue)
/**
* Handle Chapter 1 events
*/
- DECLARE_FUNCTION(chapter1Handler)
- DECLARE_FUNCTION(function20)
- DECLARE_FUNCTION(function21)
+ DECLARE_FUNCTION(fleeTyler)
+ DECLARE_FUNCTION(waitDinner)
+ DECLARE_FUNCTION(goDinner)
DECLARE_FUNCTION(function22)
- DECLARE_FUNCTION(function23)
- DECLARE_FUNCTION(function24)
- DECLARE_FUNCTION(function25)
- DECLARE_FUNCTION(function26)
- DECLARE_FUNCTION(function27)
- DECLARE_FUNCTION(function28)
- DECLARE_FUNCTION(function29)
+ DECLARE_FUNCTION(waitingDinner)
+ DECLARE_FUNCTION(waitingDinner2)
+ DECLARE_FUNCTION(eatingDinner)
+ DECLARE_FUNCTION(leaveDinner)
+ DECLARE_FUNCTION(freshenUp)
+ DECLARE_FUNCTION(goSalon)
+ DECLARE_FUNCTION(waitAugust)
DECLARE_FUNCTION(function30)
- DECLARE_FUNCTION(function31)
- DECLARE_FUNCTION(function32)
- DECLARE_FUNCTION(function33)
- DECLARE_FUNCTION(function34)
- DECLARE_FUNCTION(function35)
- DECLARE_FUNCTION(function36)
+ DECLARE_FUNCTION(leaveAugust)
+ DECLARE_FUNCTION(returnCompartment)
+ DECLARE_FUNCTION(readyForBed)
+ DECLARE_FUNCTION(asleep)
+ DECLARE_FUNCTION(wakeNight)
+ DECLARE_FUNCTION(goVassili)
DECLARE_FUNCTION(function37)
- DECLARE_FUNCTION(function38)
- DECLARE_FUNCTION_2(function39, CarIndex car, EntityPosition entityPosition)
- DECLARE_FUNCTION(function40)
- DECLARE_FUNCTION(function41)
+ DECLARE_FUNCTION(speakTatiana)
+ DECLARE_FUNCTION_2(doWalk1019, CarIndex car, EntityPosition entityPosition)
+ DECLARE_FUNCTION(leaveTatiana)
+ DECLARE_FUNCTION(goBackToSleep)
/**
* Setup Chapter 2
@@ -177,37 +177,37 @@ public:
/**
* Handle Chapter 2 events
*/
- DECLARE_FUNCTION(chapter2Handler)
+ DECLARE_FUNCTION(inPart2)
/**
* Setup Chapter 3
*/
DECLARE_FUNCTION(chapter3)
- DECLARE_FUNCTION_1(function45, bool useAction1)
/**
* Handle Chapter 3 events
*/
- DECLARE_FUNCTION(chapter3Handler)
- DECLARE_FUNCTION(function47)
- DECLARE_FUNCTION(function48)
+ DECLARE_FUNCTION_1(exitCompartment, bool useAction1)
+ DECLARE_FUNCTION(practicing)
+ DECLARE_FUNCTION(goLunch)
+ DECLARE_FUNCTION(lunch)
DECLARE_FUNCTION(leaveTableWithAugust)
- DECLARE_FUNCTION(function50)
- DECLARE_FUNCTION(function51)
- DECLARE_FUNCTION(function52)
- DECLARE_FUNCTION(function53)
- DECLARE_FUNCTION(function54)
- DECLARE_FUNCTION(function55)
- DECLARE_FUNCTION(function56)
- DECLARE_FUNCTION(function57)
- DECLARE_FUNCTION(function58)
- DECLARE_FUNCTION(function59)
- DECLARE_FUNCTION(function60)
- DECLARE_FUNCTION(function61)
+ DECLARE_FUNCTION(leaveLunch)
+ DECLARE_FUNCTION(afterLunch)
+ DECLARE_FUNCTION(returnCompartment3)
+ DECLARE_FUNCTION(dressing)
+ DECLARE_FUNCTION(giveMaxToConductor2)
+ DECLARE_FUNCTION(goConcert)
+ DECLARE_FUNCTION(concert)
+ DECLARE_FUNCTION(leaveConcert)
+ DECLARE_FUNCTION(leaveConcertCathInCompartment)
+ DECLARE_FUNCTION(afterConcert)
+ DECLARE_FUNCTION(giveMaxBack)
+ DECLARE_FUNCTION(goBaggageCompartment)
DECLARE_FUNCTION(function62)
- DECLARE_FUNCTION(function63)
- DECLARE_FUNCTION(baggage)
- DECLARE_FUNCTION(function65)
+ DECLARE_FUNCTION(deadBaggageCompartment)
+ DECLARE_FUNCTION(baggageFight)
+ DECLARE_FUNCTION(prepareVienna)
/**
* Setup Chapter 4
@@ -217,14 +217,13 @@ public:
/**
* Handle Chapter 4 events
*/
- DECLARE_FUNCTION(chapter4Handler)
-
- DECLARE_FUNCTION(function68)
- DECLARE_FUNCTION(function69)
- DECLARE_FUNCTION(function70)
- DECLARE_FUNCTION(function71)
- DECLARE_FUNCTION_2(function72, CarIndex car, EntityPosition entityPosition)
- DECLARE_FUNCTION(function73)
+ DECLARE_FUNCTION(reading)
+ DECLARE_FUNCTION(sulking)
+ DECLARE_FUNCTION(goSalon4)
+ DECLARE_FUNCTION(returnCompartment4)
+ DECLARE_FUNCTION(enterCompartmentCathFollowsAnna)
+ DECLARE_FUNCTION_2(doWalkCathFollowsAnna, CarIndex car, EntityPosition entityPosition)
+ DECLARE_FUNCTION(letDownHair)
/**
* Setup Chapter 5
@@ -234,13 +233,13 @@ public:
/**
* Handle Chapter 5 events
*/
- DECLARE_FUNCTION(chapter5Handler)
+ DECLARE_FUNCTION(tiedUp)
DECLARE_FUNCTION(function76)
- DECLARE_FUNCTION(function77)
- DECLARE_FUNCTION(function78)
- DECLARE_FUNCTION(function79)
- DECLARE_FUNCTION(function80)
+ DECLARE_FUNCTION(readyToScore)
+ DECLARE_FUNCTION(kidnapped)
+ DECLARE_FUNCTION(waiting)
DECLARE_FUNCTION(finalSequence)
+ DECLARE_FUNCTION(openFirebird)
};
} // End of namespace LastExpress
diff --git a/engines/lastexpress/entities/august.cpp b/engines/lastexpress/entities/august.cpp
index b0bc0732d4..11f72ecfe8 100644
--- a/engines/lastexpress/entities/august.cpp
+++ b/engines/lastexpress/entities/august.cpp
@@ -640,7 +640,7 @@ label_continue:
break;
case 6:
- getAction()->playAnimation(getObjects()->get(kObjectCompartment3).location2 == kObjectLocation1 ? kEventMeetAugustHisCompartmentBed : kEventMeetAugustHisCompartment);
+ getAction()->playAnimation(getObjects()->get(kObjectCompartment3).model == kObjectModel1 ? kEventMeetAugustHisCompartmentBed : kEventMeetAugustHisCompartment);
getProgress().eventMetAugust = true;
getObjects()->update(kObjectCompartment3, kEntityAugust, kObjectLocation1, kCursorNormal, kCursorNormal);
@@ -840,11 +840,11 @@ label_callback_9:
if (CURRENT_PARAM(1, 1) >= getState()->timeTicks)
break;
- if (getObjects()->get(kObjectCompartment1).location == kObjectLocation1) {
+ if (getObjects()->get(kObjectCompartment1).status == kObjectLocation1) {
if (!Entity::updateParameter(CURRENT_PARAM(1, 2), getState()->timeTicks, 75))
break;
- getObjects()->update(kObjectCompartment1, kEntityAugust, getObjects()->get(kObjectCompartment1).location, kCursorNormal, kCursorNormal);
+ getObjects()->update(kObjectCompartment1, kEntityAugust, getObjects()->get(kObjectCompartment1).status, kCursorNormal, kCursorNormal);
params->param6++;
@@ -866,7 +866,7 @@ label_callback_9:
params->param8++;
if (params->param8 >= 3) {
- getObjects()->update(kObjectCompartment1, kEntityPlayer, getObjects()->get(kObjectCompartment1).location, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObjectCompartment1, kEntityPlayer, getObjects()->get(kObjectCompartment1).status, kCursorHandKnock, kCursorHand);
callbackAction();
break;
}
@@ -874,12 +874,12 @@ label_callback_9:
params->param6 = 0;
}
- getObjects()->update(kObjectCompartment1, kEntityAugust, getObjects()->get(kObjectCompartment1).location, params->param4 ? kCursorNormal : kCursorTalk, kCursorHand);
+ getObjects()->update(kObjectCompartment1, kEntityAugust, getObjects()->get(kObjectCompartment1).status, params->param4 ? kCursorNormal : kCursorTalk, kCursorHand);
CURRENT_PARAM(1, 2) = 0;
} else {
if (getProgress().eventCorpseMovedFromFloor && getProgress().jacket != kJacketBlood) {
- params->param7 = (getObjects()->get(kObjectCompartment1).location2 == kObjectLocation1) ? 8 : 7;
+ params->param7 = (getObjects()->get(kObjectCompartment1).model == kObjectModel1) ? 8 : 7;
getObjects()->update(kObjectOutsideTylerCompartment, kEntityPlayer, kObjectLocationNone, kCursorKeepValue, kCursorKeepValue);
setCallback(4);
@@ -900,7 +900,7 @@ label_callback_9:
setCallback(15);
setup_playSound("LIB012");
} else if (!params->param4) {
- getObjects()->update(kObjectCompartment1, kEntityAugust, getObjects()->get(kObjectCompartment1).location, kCursorNormal, kCursorNormal);
+ getObjects()->update(kObjectCompartment1, kEntityAugust, getObjects()->get(kObjectCompartment1).status, kCursorNormal, kCursorNormal);
setCallback(17);
setup_playSound("AUG1002A");
@@ -912,9 +912,9 @@ label_callback_9:
if (params->param3) {
getData()->location = kLocationInsideCompartment;
- params->param7 = (getObjects()->get(kObjectCompartment1).location2 == kObjectLocation1) ? kEventMeetAugustHisCompartmentBed : kEventMeetAugustHisCompartment;
+ params->param7 = (getObjects()->get(kObjectCompartment1).model == kObjectModel1) ? kEventMeetAugustHisCompartmentBed : kEventMeetAugustHisCompartment;
} else {
- params->param7 = (getObjects()->get(kObjectCompartment1).location2 == kObjectLocation1) ? kEventMeetAugustTylerCompartmentBed : kEventMeetAugustTylerCompartment;
+ params->param7 = (getObjects()->get(kObjectCompartment1).model == kObjectModel1) ? kEventMeetAugustTylerCompartmentBed : kEventMeetAugustTylerCompartment;
}
setCallback(14);
@@ -931,14 +931,14 @@ label_callback_9:
if (getEntities()->isInsideCompartment(kEntityPlayer, kCarGreenSleeping, kPosition_8200)
|| getEntities()->isInsideCompartment(kEntityPlayer, kCarGreenSleeping, kPosition_7850)
|| getEntities()->isOutsideAlexeiWindow()) {
- getObjects()->update(kObjectCompartment1, kEntityAugust, getObjects()->get(kObjectCompartment1).location, kCursorNormal, kCursorNormal);
+ getObjects()->update(kObjectCompartment1, kEntityAugust, getObjects()->get(kObjectCompartment1).status, kCursorNormal, kCursorNormal);
if (getEntities()->isOutsideAlexeiWindow())
getScenes()->loadSceneFromPosition(kCarGreenSleeping, 49);
getSound()->playSound(kEntityPlayer, "LIB012");
- getObjects()->update(kObjectCompartment1, kEntityAugust, getObjects()->get(kObjectCompartment1).location, kCursorTalk, kCursorHand);
+ getObjects()->update(kObjectCompartment1, kEntityAugust, getObjects()->get(kObjectCompartment1).status, kCursorTalk, kCursorHand);
params->param2 = 1;
} else {
@@ -996,7 +996,7 @@ label_callback_9:
case 6:
case 7:
- getObjects()->update(kObjectCompartment1, kEntityAugust, getObjects()->get(kObjectCompartment1).location, params->param4 ? kCursorNormal : kCursorTalk, kCursorHand);
+ getObjects()->update(kObjectCompartment1, kEntityAugust, getObjects()->get(kObjectCompartment1).status, params->param4 ? kCursorNormal : kCursorTalk, kCursorHand);
ENTITY_PARAM(1, 2) = 0;
break;
@@ -1032,7 +1032,7 @@ label_callback_9:
break;
case 13:
- getSound()->playSound(kEntityPlayer, getObjects()->get(kObjectCompartment1).location == kObjectLocation1 ? "LIB032" : "LIB014");
+ getSound()->playSound(kEntityPlayer, getObjects()->get(kObjectCompartment1).status == kObjectLocation1 ? "LIB032" : "LIB014");
getAction()->playAnimation(kEventAugustFindCorpse);
if (getEvent(kEventDinerAugustOriginalJacket))
@@ -1045,7 +1045,7 @@ label_callback_9:
case 14:
if (!params->param2)
- getSound()->playSound(kEntityPlayer, getObjects()->get(kObjectCompartment1).location == kObjectLocation1 ? "LIB032" : "LIB014");
+ getSound()->playSound(kEntityPlayer, getObjects()->get(kObjectCompartment1).status == kObjectLocation1 ? "LIB032" : "LIB014");
getObjects()->update(kObjectCompartment1, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
getObjects()->update(kObjectOutsideTylerCompartment, kEntityPlayer, kObjectLocationNone, kCursorKeepValue, kCursorKeepValue);
@@ -1070,7 +1070,7 @@ label_callback_9:
case 17:
params->param4 = 1;
- getObjects()->update(kObjectCompartment1, kEntityAugust, getObjects()->get(kObjectCompartment1).location, kCursorNormal, kCursorHand);
+ getObjects()->update(kObjectCompartment1, kEntityAugust, getObjects()->get(kObjectCompartment1).status, kCursorNormal, kCursorHand);
break;
}
break;
@@ -3249,7 +3249,7 @@ IMPLEMENT_FUNCTION(63, August, function63)
case kAction1:
if (getEntities()->isInSalon(kEntityAlexei)) {
- RESET_ENTITY_STATE(kEntityAlexei, Alexei, setup_function44);
+ RESET_ENTITY_STATE(kEntityAlexei, Alexei, setup_goToPlatform);
}
getData()->inventoryItem = kItemNone;
diff --git a/engines/lastexpress/entities/chapters.cpp b/engines/lastexpress/entities/chapters.cpp
index d373432710..6c8f7ca41c 100644
--- a/engines/lastexpress/entities/chapters.cpp
+++ b/engines/lastexpress/entities/chapters.cpp
@@ -221,7 +221,7 @@ IMPLEMENT_FUNCTION(6, Chapters, chapter1End)
RESET_ENTITY_STATE(kEntityKronos, Kronos, setup_function10);
RESET_ENTITY_STATE(kEntityKahina, Kahina, setup_function13);
- RESET_ENTITY_STATE(kEntityAnna, Anna, setup_function34);
+ RESET_ENTITY_STATE(kEntityAnna, Anna, setup_asleep);
RESET_ENTITY_STATE(kEntityAugust, August, setup_function34);
RESET_ENTITY_STATE(kEntityTatiana, Tatiana, setup_function24);
RESET_ENTITY_STATE(kEntityVassili, Vassili, setup_function7);
@@ -349,19 +349,19 @@ IMPLEMENT_FUNCTION(7, Chapters, chapter1Init)
getObjects()->update(kObjectOutsideTylerCompartment, kEntityPlayer, kObjectLocationNone, kCursorKeepValue, kCursorKeepValue);
for (uint i = kObjectCompartment1; i <= kObjectCompartment8; i++) {
- getObjects()->updateLocation2((ObjectIndex)i, kObjectLocation2);
+ getObjects()->updateModel((ObjectIndex) i, kObjectModel2);
}
for (uint i = kObjectCompartmentA; i <= kObjectCompartmentH; i++) {
- getObjects()->updateLocation2((ObjectIndex)i, kObjectLocation2);
+ getObjects()->updateModel((ObjectIndex) i, kObjectModel2);
}
params->param1 = 40;
- getObjects()->updateLocation2(kObject25, kObjectLocation1);
- getObjects()->updateLocation2(kObjectTrainTimeTable, kObjectLocation1);
- getObjects()->updateLocation2(kObject98, kObjectLocation1);
- getObjects()->updateLocation2(kObjectRestaurantCar, kObjectLocation1);
+ getObjects()->updateModel(kObject25, kObjectModel1);
+ getObjects()->updateModel(kObjectTrainTimeTable, kObjectModel1);
+ getObjects()->updateModel(kObject98, kObjectModel1);
+ getObjects()->updateModel(kObjectRestaurantCar, kObjectModel1);
getObjects()->update(kObject25, kEntityPlayer, kObjectLocationNone, kCursorNormal, kCursorForward);
getObjects()->update(kObjectTrainTimeTable, kEntityPlayer, kObjectLocationNone, kCursorNormal, kCursorForward);
@@ -792,11 +792,11 @@ IMPLEMENT_FUNCTION(11, Chapters, chapter2Init)
getInventory()->setLocationAndProcess(kItem3, kObjectLocation1);
for (uint i = 1; i < 9; i++) {
- getObjects()->updateLocation2((ObjectIndex)i, kObjectLocation2);
+ getObjects()->updateModel((ObjectIndex) i, kObjectModel2);
}
for (uint i = 33; i < 40; i++) {
- getObjects()->updateLocation2((ObjectIndex)i, kObjectLocation2);
+ getObjects()->updateModel((ObjectIndex) i, kObjectModel2);
}
params->param1 = 40;
@@ -893,7 +893,7 @@ IMPLEMENT_FUNCTION(14, Chapters, chapter3Init)
getObjects()->update(kObjectHandleOutsideRight, kEntityPlayer, kObjectLocation1, kCursorNormal, kCursorHand);
getInventory()->setLocationAndProcess(kItemBriefcase, kObjectLocation1);
getInventory()->setLocationAndProcess(kItem3, kObjectLocation1);
- getObjects()->updateLocation2(kObjectCompartment1, kObjectLocation2);
+ getObjects()->updateModel(kObjectCompartment1, kObjectModel2);
getObjects()->update(kObject107, kEntityPlayer, kObjectLocation3, kCursorKeepValue, kCursorKeepValue);
if (ENTITY_PARAM(0, 2) || ENTITY_PARAM(0, 3)) {
@@ -1204,7 +1204,7 @@ IMPLEMENT_FUNCTION(18, Chapters, chapter4Init)
if (getInventory()->get(kItemBeetle)->location == kObjectLocation3)
getScenes()->loadSceneFromItemPosition(kItemBeetle);
- getObjects()->updateLocation2(kObject25, kObjectLocation2);
+ getObjects()->updateModel(kObject25, kObjectModel2);
getObjects()->update(kObject107, kEntityPlayer, kObjectLocation3, kCursorKeepValue, kCursorKeepValue);
if (ENTITY_PARAM(0, 2) || ENTITY_PARAM(0, 3)) {
@@ -1265,7 +1265,7 @@ label_exitPozsony:
break;
label_enterGalanta:
- if (getObjects()->get(kObjectCompartment1).location2 == kObjectLocation1) {
+ if (getObjects()->get(kObjectCompartment1).model == kObjectModel1) {
if (getState()->time > kTime2403000 && !CURRENT_PARAM(1, 2)) {
CURRENT_PARAM(1, 2) = 1;
getProgress().field_18 = 2;
@@ -1440,7 +1440,7 @@ label_callback_4:
case 10:
getAction()->playAnimation(kEventDefuseBomb);
- RESET_ENTITY_STATE(kEntityAbbot, Abbot, setup_function48);
+ RESET_ENTITY_STATE(kEntityAbbot, Abbot, setup_afterBomb);
getSavePoints()->push(kEntityChapters, kEntityAnna, kAction191001984);
getSavePoints()->push(kEntityChapters, kEntityCoudert, kAction191001984);
getScenes()->loadSceneFromItemPosition(kItem2);
@@ -1514,7 +1514,7 @@ label_callback_4:
if (getInventory()->hasItem(kItemBomb)) {
RESET_ENTITY_STATE(kEntityAlexei, Alexei, setup_function47);
- RESET_ENTITY_STATE(kEntityAnna, Anna, setup_function68);
+ RESET_ENTITY_STATE(kEntityAnna, Anna, setup_sulking);
RESET_ENTITY_STATE(kEntityAugust, August, setup_function65);
RESET_ENTITY_STATE(kEntityMertens, Mertens, setup_function48);
RESET_ENTITY_STATE(kEntityCoudert, Coudert, setup_function53);
@@ -1675,8 +1675,8 @@ IMPLEMENT_FUNCTION(21, Chapters, chapter5Init)
getObjects()->update(kObject94, kEntityPlayer, kObjectLocationNone, kCursorKeepValue, kCursorKeepValue);
getObjects()->update(kObject101, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
- getObjects()->updateLocation2(kObject98, kObjectLocation2);
- getObjects()->updateLocation2(kObjectRestaurantCar, kObjectLocation2);
+ getObjects()->updateModel(kObject98, kObjectModel2);
+ getObjects()->updateModel(kObjectRestaurantCar, kObjectModel2);
if (ENTITY_PARAM(0, 2) || ENTITY_PARAM(0, 3)) {
getSoundQueue()->removeFromQueue(kEntityChapters);
diff --git a/engines/lastexpress/entities/coudert.cpp b/engines/lastexpress/entities/coudert.cpp
index b604277903..ebe2a930a5 100644
--- a/engines/lastexpress/entities/coudert.cpp
+++ b/engines/lastexpress/entities/coudert.cpp
@@ -915,7 +915,7 @@ IMPLEMENT_FUNCTION_II(20, Coudert, function20, ObjectIndex, ObjectIndex)
if (!Entity::updateParameter(CURRENT_PARAM(1, 4), getState()->time, 900))
break;
- getObjects()->updateLocation2((ObjectIndex)params->param1, kObjectLocation1);
+ getObjects()->updateModel((ObjectIndex) params->param1, kObjectModel1);
if (params->param4 != kObjectLocation2)
getObjects()->update((ObjectIndex)params->param1, (EntityIndex)params->param3, (ObjectLocation)params->param4, (CursorStyle)params->param5, (CursorStyle)params->param6);
@@ -938,15 +938,15 @@ IMPLEMENT_FUNCTION_II(20, Coudert, function20, ObjectIndex, ObjectIndex)
case kActionDefault:
params->param3 = getObjects()->get((ObjectIndex)params->param1).entity;
- params->param4 = getObjects()->get((ObjectIndex)params->param1).location;
- params->param5 = getObjects()->get((ObjectIndex)params->param1).cursor;
- params->param6 = getObjects()->get((ObjectIndex)params->param1).cursor2;
+ params->param4 = getObjects()->get((ObjectIndex)params->param1).status;
+ params->param5 = getObjects()->get((ObjectIndex)params->param1).windowCursor;
+ params->param6 = getObjects()->get((ObjectIndex)params->param1).handleCursor;
if (params->param2) {
params->param7 = getObjects()->get((ObjectIndex)params->param2).entity;
- params->param8 = getObjects()->get((ObjectIndex)params->param2).location;
- CURRENT_PARAM(1, 1) = getObjects()->get((ObjectIndex)params->param2).cursor;
- CURRENT_PARAM(1, 2) = getObjects()->get((ObjectIndex)params->param2).cursor2;
+ params->param8 = getObjects()->get((ObjectIndex)params->param2).status;
+ CURRENT_PARAM(1, 1) = getObjects()->get((ObjectIndex)params->param2).windowCursor;
+ CURRENT_PARAM(1, 2) = getObjects()->get((ObjectIndex)params->param2).handleCursor;
getObjects()->update((ObjectIndex)params->param2, kEntityCoudert, kObjectLocation1, kCursorHandKnock, kCursorHand);
}
@@ -1580,7 +1580,7 @@ IMPLEMENT_FUNCTION_I(30, Coudert, function30, ObjectIndex)
case 2:
if (getEntities()->checkFields19(kEntityPlayer, kCarRedSleeping, (EntityPosition)parameters->param3)
|| ((parameters->param1 == kObjectCompartmentE || parameters->param1 == kObjectCompartmentF) && getEntities()->isOutsideAnnaWindow())) {
- getObjects()->update((ObjectIndex)parameters->param1, kEntityPlayer, getObjects()->get((ObjectIndex)parameters->param1).location, kCursorNormal, kCursorNormal);
+ getObjects()->update((ObjectIndex)parameters->param1, kEntityPlayer, getObjects()->get((ObjectIndex)parameters->param1).status, kCursorNormal, kCursorNormal);
parameters->param5 = true;
}
@@ -1598,7 +1598,7 @@ IMPLEMENT_FUNCTION_I(30, Coudert, function30, ObjectIndex)
case 4:
if (parameters->param5)
- getObjects()->update((ObjectIndex)parameters->param1, kEntityPlayer, getObjects()->get((ObjectIndex)parameters->param1).location, kCursorHandKnock, kCursorHand);
+ getObjects()->update((ObjectIndex)parameters->param1, kEntityPlayer, getObjects()->get((ObjectIndex)parameters->param1).status, kCursorHandKnock, kCursorHand);
getEntities()->exitCompartment(kEntityCoudert, (ObjectIndex)parameters->param1, true);
@@ -1991,7 +1991,7 @@ IMPLEMENT_FUNCTION(36, Coudert, chapter1)
getData()->location = kLocationOutsideCompartment;
getData()->car = kCarRedSleeping;
- getObjects()->updateLocation2(kObject111, kObjectLocation1);
+ getObjects()->updateModel(kObject111, kObjectModel1);
break;
case kActionCallback:
@@ -2294,9 +2294,9 @@ label_callback_10:
if (!ENTITY_PARAM(0, 2))
break;
- timeCheckObject(kTime1107000, params->param4, kObject111, kObjectLocation2);
- timeCheckObject(kTime1161000, params->param5, kObject111, kObjectLocation3);
- timeCheckObject(kTime1206000, params->param6, kObject111, kObjectLocation4);
+ timeCheckObject(kTime1107000, params->param4, kObject111, kObjectModel2);
+ timeCheckObject(kTime1161000, params->param5, kObject111, kObjectModel3);
+ timeCheckObject(kTime1206000, params->param6, kObject111, kObjectModel4);
break;
case kAction1:
@@ -2577,7 +2577,7 @@ IMPLEMENT_FUNCTION(42, Coudert, chapter2)
ENTITY_PARAM(2, 4) = 0;
- getObjects()->updateLocation2(kObject111, kObjectLocation5);
+ getObjects()->updateModel(kObject111, kObjectModel5);
break;
case kActionCallback:
@@ -2716,7 +2716,7 @@ IMPLEMENT_FUNCTION(44, Coudert, chapter3)
ENTITY_PARAM(2, 4) = 0;
ENTITY_PARAM(2, 5) = 0;
- getObjects()->updateLocation2(kObject111, kObjectLocation6);
+ getObjects()->updateModel(kObject111, kObjectModel6);
break;
case kActionCallback:
@@ -2850,9 +2850,9 @@ label_callback_18:
label_callback_19:
if (ENTITY_PARAM(0, 2)) {
- timeCheckObject(kTime2025000, params->param7, kObject111, kObjectLocation7);
- timeCheckObject(kTime2133000, params->param8, kObject111, kObjectLocation8);
- timeCheckObject(kTime2173500, CURRENT_PARAM(1, 1), kObject111, kObjectLocation9);
+ timeCheckObject(kTime2025000, params->param7, kObject111, kObjectModel7);
+ timeCheckObject(kTime2133000, params->param8, kObject111, kObjectModel8);
+ timeCheckObject(kTime2173500, CURRENT_PARAM(1, 1), kObject111, kObjectModel9);
}
break;
@@ -3498,7 +3498,7 @@ IMPLEMENT_FUNCTION(52, Coudert, chapter4)
ENTITY_PARAM(2, 3) = 0;
ENTITY_PARAM(2, 4) = 0;
- getObjects()->updateLocation2(kObject111, kObjectLocation10);
+ getObjects()->updateModel(kObject111, kObjectModel10);
break;
case kActionCallback:
@@ -3523,14 +3523,14 @@ IMPLEMENT_FUNCTION(53, Coudert, function53)
params->param1 = 1;
- getObjects()->updateLocation2(kObjectCompartmentA, kObjectLocation1);
- getObjects()->updateLocation2(kObjectCompartmentB, kObjectLocation1);
- getObjects()->updateLocation2(kObjectCompartmentC, kObjectLocation1);
- getObjects()->updateLocation2(kObjectCompartmentD, kObjectLocation1);
- getObjects()->updateLocation2(kObjectCompartmentE, kObjectLocation1);
- getObjects()->updateLocation2(kObjectCompartmentF, kObjectLocation1);
- getObjects()->updateLocation2(kObjectCompartmentG, kObjectLocation1);
- getObjects()->updateLocation2(kObjectCompartmentH, kObjectLocation1);
+ getObjects()->updateModel(kObjectCompartmentA, kObjectModel1);
+ getObjects()->updateModel(kObjectCompartmentB, kObjectModel1);
+ getObjects()->updateModel(kObjectCompartmentC, kObjectModel1);
+ getObjects()->updateModel(kObjectCompartmentD, kObjectModel1);
+ getObjects()->updateModel(kObjectCompartmentE, kObjectModel1);
+ getObjects()->updateModel(kObjectCompartmentF, kObjectModel1);
+ getObjects()->updateModel(kObjectCompartmentG, kObjectModel1);
+ getObjects()->updateModel(kObjectCompartmentH, kObjectModel1);
ENTITY_PARAM(2, 3) = 0;
diff --git a/engines/lastexpress/entities/entity.cpp b/engines/lastexpress/entities/entity.cpp
index dad5e67392..b2fc30829f 100644
--- a/engines/lastexpress/entities/entity.cpp
+++ b/engines/lastexpress/entities/entity.cpp
@@ -943,10 +943,10 @@ void Entity::timeCheckSavepoint(TimeValue timeValue, uint &parameter, EntityInde
}
}
-void Entity::timeCheckObject(TimeValue timeValue, uint &parameter, ObjectIndex object, ObjectLocation location) const {
+void Entity::timeCheckObject(TimeValue timeValue, uint &parameter, ObjectIndex object, ObjectModel model) const {
if (getState()->time > timeValue && !parameter) {
parameter = 1;
- getObjects()->updateLocation2(object, location);
+ getObjects()->updateModel(object, model);
}
}
diff --git a/engines/lastexpress/entities/entity.h b/engines/lastexpress/entities/entity.h
index c67d13db9e..634c854d05 100644
--- a/engines/lastexpress/entities/entity.h
+++ b/engines/lastexpress/entities/entity.h
@@ -330,7 +330,7 @@ public:
};
struct EntityParametersSIII : EntityParameters {
- char seq[12];
+ char seq[13];
uint param4;
uint param5;
uint param6;
@@ -338,7 +338,7 @@ public:
uint param8;
EntityParametersSIII() {
- memset(&seq, 0, 12);
+ memset(&seq, 0, 13);
param4 = 0;
param5 = 0;
param6 = 0;
@@ -374,16 +374,16 @@ public:
};
struct EntityParametersSIIS : EntityParameters {
- char seq1[12];
+ char seq1[13];
uint param4;
uint param5;
- char seq2[12];
+ char seq2[13];
EntityParametersSIIS() {
- memset(&seq1, 0, 12);
+ memset(&seq1, 0, 13);
param4 = 0;
param5 = 0;
- memset(&seq2, 0, 12);
+ memset(&seq2, 0, 13);
}
Common::String toString() {
@@ -410,14 +410,14 @@ public:
struct EntityParametersISSI : EntityParameters {
uint param1;
- char seq1[12];
- char seq2[12];
+ char seq1[13];
+ char seq2[13];
uint param8;
EntityParametersISSI() {
param1 = 0;
- memset(&seq1, 0, 12);
- memset(&seq2, 0, 12);
+ memset(&seq1, 0, 13);
+ memset(&seq2, 0, 13);
param8 = 0;
}
@@ -445,7 +445,7 @@ public:
struct EntityParametersISII : EntityParameters {
uint param1;
- char seq[12];
+ char seq[13];
uint param5;
uint param6;
uint param7;
@@ -453,7 +453,7 @@ public:
EntityParametersISII() {
param1 = 0;
- memset(&seq, 0, 12);
+ memset(&seq, 0, 13);
param5 = 0;
param6 = 0;
param7 = 0;
@@ -488,14 +488,14 @@ public:
};
struct EntityParametersSSII : EntityParameters {
- char seq1[12];
- char seq2[12];
+ char seq1[13];
+ char seq2[13];
uint param7;
uint param8;
EntityParametersSSII() {
- memset(&seq1, 0, 12);
- memset(&seq2, 0, 12);
+ memset(&seq1, 0, 13);
+ memset(&seq2, 0, 13);
param7 = 0;
param8 = 0;
}
@@ -523,14 +523,14 @@ public:
};
struct EntityParametersSSS : EntityParameters {
- char seq1[12];
- char seq2[12];
- char seq3[8];
+ char seq1[13];
+ char seq2[13];
+ char seq3[9];
EntityParametersSSS() {
- memset(&seq1, 0, 12);
- memset(&seq2, 0, 12);
- memset(&seq3, 0, 8);
+ memset(&seq1, 0, 13);
+ memset(&seq2, 0, 13);
+ memset(&seq3, 0, 9);
}
Common::String toString() {
@@ -551,14 +551,14 @@ public:
struct EntityParametersIISS : EntityParameters {
uint param1;
uint param2;
- char seq1[12];
- char seq2[12];
+ char seq1[13];
+ char seq2[13];
EntityParametersIISS() {
param1 = 0;
param2 = 0;
- memset(&seq1, 0, 12);
- memset(&seq2, 0, 12);
+ memset(&seq1, 0, 13);
+ memset(&seq2, 0, 13);
}
Common::String toString() {
@@ -586,7 +586,7 @@ public:
struct EntityParametersIISI : EntityParameters {
uint param1;
uint param2;
- char seq[12];
+ char seq[13];
uint param6;
uint param7;
uint param8;
@@ -594,7 +594,7 @@ public:
EntityParametersIISI() {
param1 = 0;
param2 = 0;
- memset(&seq, 0, 12);
+ memset(&seq, 0, 13);
param6 = 0;
param7 = 0;
param8 = 0;
@@ -631,7 +631,7 @@ public:
uint param1;
uint param2;
uint param3;
- char seq[12];
+ char seq[13];
uint param7;
uint param8;
@@ -639,7 +639,7 @@ public:
param1 = 0;
param2 = 0;
param3 = 0;
- memset(&seq, 0, 12);
+ memset(&seq, 0, 13);
param7 = 0;
param8 = 0;
}
@@ -677,7 +677,7 @@ public:
uint param3;
uint param4;
uint param5;
- char seq[12];
+ char seq[13];
EntityParametersI5S() {
param1 = 0;
@@ -685,7 +685,7 @@ public:
param3 = 0;
param4 = 0;
param5 = 0;
- memset(&seq, 0, 12);
+ memset(&seq, 0, 13);
}
void saveLoadWithSerializer(Common::Serializer &s) {
@@ -818,9 +818,9 @@ public:
/**
* Synchronizes a string.
*
- * @param s The Common::Serializer to use.
- * @param string The string.
- * @param length Length of the string.
+ * @param s The Common::Serializer to use.
+ * @param string The string.
+ * @param length Length of the string.
*/
void syncString(Common::Serializer &s, Common::String &string, uint length) const;
@@ -921,7 +921,7 @@ protected:
/**
* Play sound
*
- * @param savepoint The savepoint
+ * @param savepoint The savepoint
* - Sound filename
* @param resetItem true to reset item.
* @param flag sound flag
@@ -931,9 +931,9 @@ protected:
/**
* Draws the entity
*
- * @param savepoint The savepoint
- * - Sequence
- * - ExcuseMe flag
+ * @param savepoint The savepoint
+ * - Sequence
+ * - ExcuseMe flag
* @param handleExcuseMe true to handle excuseMeCath action
*/
void draw(const SavePoint &savepoint, bool handleExcuseMe = false);
@@ -941,7 +941,7 @@ protected:
/**
* Draws the entity along with another one
*
- * @param savepoint The savepoint.
+ * @param savepoint The savepoint.
* - Sequence 1
* - Sequence 2
* - EntityIndex
@@ -976,23 +976,23 @@ protected:
/**
* Process callback action when the entity direction is not kDirectionRight
*
- * @param savepoint The savepoint.
+ * @param savepoint The savepoint.
*/
void callbackActionOnDirection(const SavePoint &savepoint);
/**
* Process callback action when somebody is standing in the restaurant or salon.
*
- * @param savepoint The savepoint.
+ * @param savepoint The savepoint.
*/
void callbackActionRestaurantOrSalon(const SavePoint &savepoint);
/**
* Updates the entity
*
- * @param savepoint The savepoint.
- * - CarIndex
- * - EntityPosition
+ * @param savepoint The savepoint.
+ * - CarIndex
+ * - EntityPosition
* @param handleExcuseMe true to handle the kActionExcuseMe/kActionExcuseMeCath actions.
*/
void updateEntity(const SavePoint &savepoint, bool handleExcuseMe = false);
@@ -1000,11 +1000,11 @@ protected:
/**
* Call a specific savepoint (or draw sequence in default case)
*
- * @param savepoint The savepoint.
- * - Sequence to draw in default case
- * - EntityIndex
- * - ActionIndex
- * - Sequence for the savepoint
+ * @param savepoint The savepoint.
+ * - Sequence to draw in default case
+ * - EntityIndex
+ * - ActionIndex
+ * - Sequence for the savepoint
* @param handleExcuseMe true to handle excuse me.
*/
void callSavepoint(const SavePoint &savepoint, bool handleExcuseMe = false);
@@ -1012,36 +1012,36 @@ protected:
/**
* Handles entering/exiting a compartment.
*
- * @param savepoint The savepoint.
- * @param position1 The first position.
- * @param position2 The second position.
- * @param car The car.
- * @param compartment The compartment.
- * @param alternate true to use the alternate version of SceneManager::loadSceneFromObject()
+ * @param savepoint The savepoint.
+ * @param position1 The first position.
+ * @param position2 The second position.
+ * @param car The car.
+ * @param compartment The compartment.
+ * @param alternate true to use the alternate version of SceneManager::loadSceneFromObject()
*/
void enterExitCompartment(const SavePoint &savepoint, EntityPosition position1 = kPositionNone, EntityPosition position2 = kPositionNone, CarIndex car = kCarNone, ObjectIndex compartment = kObjectNone, bool alternate = false, bool updateLocation = false);
/**
* Go to compartment.
*
- * @param savepoint The savepoint.
- * @param compartmentFrom The compartment from.
- * @param positionFrom The position from.
- * @param sequenceFrom The sequence from.
- * @param sequenceTo The sequence to.
+ * @param savepoint The savepoint.
+ * @param compartmentFrom The compartment from.
+ * @param positionFrom The position from.
+ * @param sequenceFrom The sequence from.
+ * @param sequenceTo The sequence to.
*/
void goToCompartment(const SavePoint &savepoint, ObjectIndex compartmentFrom, EntityPosition positionFrom, Common::String sequenceFrom, Common::String sequenceTo);
/**
* Go to compartment from compartment.
*
- * @param savepoint The savepoint.
- * @param compartmentFrom The compartment from.
- * @param positionFrom The position from.
- * @param sequenceFrom The sequence from.
- * @param compartmentTo The compartment to.
- * @param positionTo The position to.
- * @param sequenceTo The sequence to.
+ * @param savepoint The savepoint.
+ * @param compartmentFrom The compartment from.
+ * @param positionFrom The position from.
+ * @param sequenceFrom The sequence from.
+ * @param compartmentTo The compartment to.
+ * @param positionTo The position to.
+ * @param sequenceTo The sequence to.
*/
void goToCompartmentFromCompartment(const SavePoint &savepoint, ObjectIndex compartmentFrom, EntityPosition positionFrom, Common::String sequenceFrom, ObjectIndex compartmentTo, EntityPosition positionTo, Common::String sequenceTo);
@@ -1095,7 +1095,7 @@ protected:
bool timeCheckCallbackInventory(TimeValue timeValue, uint &parameter, byte callback, Common::Functor0<void> *function);
bool timeCheckCar(TimeValue timeValue, uint &parameter, byte callback, Common::Functor0<void> *function);
void timeCheckSavepoint(TimeValue timeValue, uint &parameter, EntityIndex entity1, EntityIndex entity2, ActionIndex action) const;
- void timeCheckObject(TimeValue timeValue, uint &parameter, ObjectIndex index, ObjectLocation location) const;
+ void timeCheckObject(TimeValue timeValue, uint &parameter, ObjectIndex index, ObjectModel model) const;
bool timeCheckCallbackAction(TimeValue timeValue, uint &parameter);
bool timeCheckPlaySoundUpdatePosition(TimeValue timeValue, uint &parameter, byte callback, const char* sound, EntityPosition position);
diff --git a/engines/lastexpress/entities/francois.cpp b/engines/lastexpress/entities/francois.cpp
index d2bbc9854c..12ce16a32b 100644
--- a/engines/lastexpress/entities/francois.cpp
+++ b/engines/lastexpress/entities/francois.cpp
@@ -44,22 +44,22 @@ Francois::Francois(LastExpressEngine *engine) : Entity(engine, kEntityFrancois)
ADD_CALLBACK_FUNCTION(Francois, enterExitCompartment2);
ADD_CALLBACK_FUNCTION(Francois, playSound);
ADD_CALLBACK_FUNCTION(Francois, savegame);
- ADD_CALLBACK_FUNCTION(Francois, updateEntity);
- ADD_CALLBACK_FUNCTION(Francois, function9);
- ADD_CALLBACK_FUNCTION(Francois, function10);
- ADD_CALLBACK_FUNCTION(Francois, function11);
- ADD_CALLBACK_FUNCTION(Francois, function12);
- ADD_CALLBACK_FUNCTION(Francois, function13);
- ADD_CALLBACK_FUNCTION(Francois, function14);
- ADD_CALLBACK_FUNCTION(Francois, function15);
- ADD_CALLBACK_FUNCTION(Francois, function16);
+ ADD_CALLBACK_FUNCTION(Francois, doWalk);
+ ADD_CALLBACK_FUNCTION(Francois, exitCompartment);
+ ADD_CALLBACK_FUNCTION(Francois, enterCompartment);
+ ADD_CALLBACK_FUNCTION(Francois, rampage);
+ ADD_CALLBACK_FUNCTION(Francois, takeWalk);
+ ADD_CALLBACK_FUNCTION(Francois, haremVisit);
+ ADD_CALLBACK_FUNCTION(Francois, chaseBeetle);
+ ADD_CALLBACK_FUNCTION(Francois, findCath);
+ ADD_CALLBACK_FUNCTION(Francois, letsGo);
ADD_CALLBACK_FUNCTION(Francois, chapter1);
ADD_CALLBACK_FUNCTION(Francois, chapter1Handler);
- ADD_CALLBACK_FUNCTION(Francois, function19);
+ ADD_CALLBACK_FUNCTION(Francois, inCompartment);
ADD_CALLBACK_FUNCTION(Francois, function20);
ADD_CALLBACK_FUNCTION(Francois, chapter2);
- ADD_CALLBACK_FUNCTION(Francois, chapter2Handler);
- ADD_CALLBACK_FUNCTION(Francois, function23);
+ ADD_CALLBACK_FUNCTION(Francois, atBreakfast);
+ ADD_CALLBACK_FUNCTION(Francois, withMama);
ADD_CALLBACK_FUNCTION(Francois, chapter3);
ADD_CALLBACK_FUNCTION(Francois, chapter3Handler);
ADD_CALLBACK_FUNCTION(Francois, chapter4);
@@ -106,7 +106,7 @@ IMPLEMENT_FUNCTION_II(7, Francois, savegame, SavegameType, uint32)
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION_II(8, Francois, updateEntity, CarIndex, EntityPosition)
+IMPLEMENT_FUNCTION_II(8, Francois, doWalk, CarIndex, EntityPosition)
switch (savepoint.action) {
default:
break;
@@ -196,13 +196,13 @@ IMPLEMENT_FUNCTION_II(8, Francois, updateEntity, CarIndex, EntityPosition)
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION(9, Francois, function9)
+IMPLEMENT_FUNCTION(9, Francois, exitCompartment)
switch (savepoint.action) {
default:
break;
case kActionDefault:
- if (getObjects()->get(kObjectCompartmentD).location == kObjectLocation2) {
+ if (getObjects()->get(kObjectCompartmentD).status == kObjectLocation2) {
getObjects()->update(kObjectCompartmentD, kEntityPlayer, kObjectLocationNone, kCursorKeepValue, kCursorKeepValue);
getSavePoints()->push(kEntityFrancois, kEntityMmeBoutarel, kAction134289824);
setCallback(1);
@@ -232,13 +232,13 @@ IMPLEMENT_FUNCTION(9, Francois, function9)
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION(10, Francois, function10)
+IMPLEMENT_FUNCTION(10, Francois, enterCompartment)
switch (savepoint.action) {
default:
break;
case kActionDefault:
- if (getObjects()->get(kObjectCompartmentD).location == kObjectLocation2) {
+ if (getObjects()->get(kObjectCompartmentD).status == kObjectLocation2) {
getObjects()->update(kObjectCompartmentD, kEntityPlayer, kObjectLocationNone, kCursorKeepValue, kCursorKeepValue);
setCallback(1);
setup_enterExitCompartment2("605Bd", kObjectCompartmentD);
@@ -270,7 +270,7 @@ IMPLEMENT_FUNCTION(10, Francois, function10)
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION_I(11, Francois, function11, TimeValue)
+IMPLEMENT_FUNCTION_I(11, Francois, rampage, TimeValue)
switch (savepoint.action) {
default:
break;
@@ -375,7 +375,7 @@ label_callback:
getSoundQueue()->processEntry(kEntityFrancois);
setCallback(4);
- setup_updateEntity(kCarRedSleeping, kPosition_5790);
+ setup_doWalk(kCarRedSleeping, kPosition_5790);
}
break;
@@ -400,7 +400,7 @@ label_callback:
case kActionDefault:
setCallback(1);
- setup_function9();
+ setup_exitCompartment();
break;
case kActionCallback:
@@ -437,7 +437,7 @@ label_callback:
case 4:
setCallback(5);
- setup_function10();
+ setup_enterCompartment();
break;
case 5:
@@ -477,14 +477,14 @@ label_callback:
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION(12, Francois, function12)
+IMPLEMENT_FUNCTION(12, Francois, takeWalk)
switch (savepoint.action) {
default:
break;
case kActionDefault:
setCallback(1);
- setup_function9();
+ setup_exitCompartment();
break;
case kActionCallback:
@@ -494,7 +494,7 @@ IMPLEMENT_FUNCTION(12, Francois, function12)
case 1:
setCallback(2);
- setup_updateEntity(kCarRedSleeping, kPosition_9460);
+ setup_doWalk(kCarRedSleeping, kPosition_9460);
break;
case 2:
@@ -504,7 +504,7 @@ IMPLEMENT_FUNCTION(12, Francois, function12)
case 3:
setCallback(4);
- setup_updateEntity(kCarRedSleeping, kPosition_540);
+ setup_doWalk(kCarRedSleeping, kPosition_540);
break;
case 4:
@@ -514,12 +514,12 @@ IMPLEMENT_FUNCTION(12, Francois, function12)
case 5:
setCallback(6);
- setup_updateEntity(kCarRedSleeping, kPosition_5790);
+ setup_doWalk(kCarRedSleeping, kPosition_5790);
break;
case 6:
setCallback(7);
- setup_function10();
+ setup_enterCompartment();
break;
case 7:
@@ -531,14 +531,14 @@ IMPLEMENT_FUNCTION(12, Francois, function12)
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION(13, Francois, function13)
+IMPLEMENT_FUNCTION(13, Francois, haremVisit)
switch (savepoint.action) {
default:
break;
case kActionDefault:
setCallback(1);
- setup_function9();
+ setup_exitCompartment();
break;
case kActionCallback:
@@ -548,12 +548,12 @@ IMPLEMENT_FUNCTION(13, Francois, function13)
case 1:
setCallback(2);
- setup_updateEntity(kCarRedSleeping, kPosition_540);
+ setup_doWalk(kCarRedSleeping, kPosition_540);
break;
case 2:
setCallback(3);
- setup_updateEntity(kCarGreenSleeping, kPosition_4070);
+ setup_doWalk(kCarGreenSleeping, kPosition_4070);
break;
case 3:
@@ -577,13 +577,13 @@ IMPLEMENT_FUNCTION(13, Francois, function13)
getData()->location = kLocationOutsideCompartment;
setCallback(7);
- setup_updateEntity(kCarGreenSleeping, kPosition_4840);
+ setup_doWalk(kCarGreenSleeping, kPosition_4840);
break;
case 7:
if (getInventory()->hasItem(kItemWhistle) || getInventory()->get(kItemWhistle)->location == kObjectLocation3) {
setCallback(10);
- setup_updateEntity(kCarGreenSleeping, kPosition_5790);
+ setup_doWalk(kCarGreenSleeping, kPosition_5790);
break;
}
@@ -599,12 +599,12 @@ IMPLEMENT_FUNCTION(13, Francois, function13)
getEntities()->exitCompartment(kEntityFrancois, kObjectCompartmentE, true);
setCallback(10);
- setup_updateEntity(kCarGreenSleeping, kPosition_5790);
+ setup_doWalk(kCarGreenSleeping, kPosition_5790);
break;
case 10:
setCallback(11);
- setup_function10();
+ setup_enterCompartment();
break;
case 11:
@@ -621,7 +621,7 @@ IMPLEMENT_FUNCTION(13, Francois, function13)
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION_IIS(14, Francois, function14, ObjectIndex, EntityPosition)
+IMPLEMENT_FUNCTION_IIS(14, Francois, chaseBeetle, ObjectIndex, EntityPosition)
// Expose parameters as IISS and ignore the default exposed parameters
EntityData::EntityParametersIISS *parameters = (EntityData::EntityParametersIISS*)_data->getCurrentParameters();
@@ -634,7 +634,7 @@ IMPLEMENT_FUNCTION_IIS(14, Francois, function14, ObjectIndex, EntityPosition)
strcat((char *)&parameters->seq2, (char *)&parameters->seq1);
setCallback(1);
- setup_function9();
+ setup_exitCompartment();
break;
case kActionCallback:
@@ -644,7 +644,7 @@ IMPLEMENT_FUNCTION_IIS(14, Francois, function14, ObjectIndex, EntityPosition)
case 1:
setCallback(2);
- setup_updateEntity(kCarRedSleeping, (EntityPosition)parameters->param2);
+ setup_doWalk(kCarRedSleeping, (EntityPosition)parameters->param2);
break;
case 2:
@@ -657,10 +657,10 @@ IMPLEMENT_FUNCTION_IIS(14, Francois, function14, ObjectIndex, EntityPosition)
} else {
if (parameters->param2 >= kPosition_5790) {
setCallback(10);
- setup_updateEntity(kCarRedSleeping, kPosition_9460);
+ setup_doWalk(kCarRedSleeping, kPosition_9460);
} else {
setCallback(9);
- setup_updateEntity(kCarRedSleeping, kPosition_540);
+ setup_doWalk(kCarRedSleeping, kPosition_540);
}
}
break;
@@ -688,7 +688,7 @@ IMPLEMENT_FUNCTION_IIS(14, Francois, function14, ObjectIndex, EntityPosition)
case 9:
setCallback(10);
- setup_updateEntity(kCarRedSleeping, kPosition_9460);
+ setup_doWalk(kCarRedSleeping, kPosition_9460);
break;
case 10:
@@ -698,12 +698,12 @@ IMPLEMENT_FUNCTION_IIS(14, Francois, function14, ObjectIndex, EntityPosition)
case 11:
setCallback(12);
- setup_updateEntity(kCarRedSleeping, kPosition_5790);
+ setup_doWalk(kCarRedSleeping, kPosition_5790);
break;
case 12:
setCallback(13);
- setup_function10();
+ setup_enterCompartment();
break;
case 13:
@@ -715,14 +715,14 @@ IMPLEMENT_FUNCTION_IIS(14, Francois, function14, ObjectIndex, EntityPosition)
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION(15, Francois, function15)
+IMPLEMENT_FUNCTION(15, Francois, findCath)
switch (savepoint.action) {
default:
break;
case kActionDefault:
setCallback(1);
- setup_function9();
+ setup_exitCompartment();
break;
case kActionCallback:
@@ -733,10 +733,10 @@ IMPLEMENT_FUNCTION(15, Francois, function15)
case 1:
if (getData()->entityPosition >= getEntityData(kEntityPlayer)->entityPosition) {
setCallback(3);
- setup_updateEntity(kCarRedSleeping, kPosition_540);
+ setup_doWalk(kCarRedSleeping, kPosition_540);
} else {
setCallback(2);
- setup_updateEntity(kCarRedSleeping, kPosition_9460);
+ setup_doWalk(kCarRedSleeping, kPosition_9460);
}
break;
@@ -748,12 +748,12 @@ IMPLEMENT_FUNCTION(15, Francois, function15)
case 4:
setCallback(5);
- setup_updateEntity(kCarRedSleeping, kPosition_5790);
+ setup_doWalk(kCarRedSleeping, kPosition_5790);
break;
case 5:
setCallback(6);
- setup_function10();
+ setup_enterCompartment();
break;
case 6:
@@ -780,7 +780,7 @@ IMPLEMENT_FUNCTION(15, Francois, function15)
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION(16, Francois, function16)
+IMPLEMENT_FUNCTION(16, Francois, letsGo)
switch (savepoint.action) {
default:
break;
@@ -809,7 +809,7 @@ IMPLEMENT_FUNCTION(16, Francois, function16)
getSavePoints()->push(kEntityFrancois, kEntityMmeBoutarel, kAction101107728);
setCallback(2);
- setup_updateEntity(kCarRestaurant, kPosition_850);
+ setup_doWalk(kCarRestaurant, kPosition_850);
break;
case 2:
@@ -836,7 +836,7 @@ IMPLEMENT_FUNCTION(16, Francois, function16)
case kAction100901266:
setCallback(3);
- setup_updateEntity(kCarRedSleeping, kPosition_5790);
+ setup_doWalk(kCarRedSleeping, kPosition_5790);
break;
}
IMPLEMENT_FUNCTION_END
@@ -871,24 +871,24 @@ IMPLEMENT_FUNCTION(18, Francois, chapter1Handler)
case kActionCallback:
if (getCallback() == 1)
- setup_function19();
+ setup_inCompartment();
break;
}
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION(19, Francois, function19)
+IMPLEMENT_FUNCTION(19, Francois, inCompartment)
switch (savepoint.action) {
default:
break;
case kActionNone:
- Entity::timeCheckCallback(kTime1161000, params->param1, 2, WRAP_SETUP_FUNCTION(Francois, setup_function12));
+ Entity::timeCheckCallback(kTime1161000, params->param1, 2, WRAP_SETUP_FUNCTION(Francois, setup_takeWalk));
break;
case kAction101107728:
setCallback(1);
- setup_function16();
+ setup_letsGo();
break;
}
IMPLEMENT_FUNCTION_END
@@ -911,7 +911,7 @@ IMPLEMENT_FUNCTION(21, Francois, chapter2)
break;
case kActionNone:
- setup_chapter2Handler();
+ setup_atBreakfast();
break;
case kActionDefault:
@@ -927,7 +927,7 @@ IMPLEMENT_FUNCTION(21, Francois, chapter2)
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION(22, Francois, chapter2Handler)
+IMPLEMENT_FUNCTION(22, Francois, atBreakfast)
switch (savepoint.action) {
default:
break;
@@ -948,20 +948,20 @@ IMPLEMENT_FUNCTION(22, Francois, chapter2Handler)
getData()->entityPosition = kPosition_5790;
getData()->location = kLocationInsideCompartment;
getEntities()->clearSequences(kEntityFrancois);
- setup_function23();
+ setup_withMama();
break;
}
break;
case kAction100901266:
setCallback(1);
- setup_updateEntity(kCarRedSleeping, kPosition_5790);
+ setup_doWalk(kCarRedSleeping, kPosition_5790);
break;
}
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION(23, Francois, function23)
+IMPLEMENT_FUNCTION(23, Francois, withMama)
switch (savepoint.action) {
default:
break;
@@ -973,7 +973,7 @@ IMPLEMENT_FUNCTION(23, Francois, function23)
if (ENTITY_PARAM(0, 1) && getEntities()->isPlayerInCar(kCarRedSleeping)) {
setCallback(1);
- setup_function15();
+ setup_findCath();
break;
}
@@ -982,7 +982,7 @@ label_callback_1:
break;
label_callback_2:
- if (Entity::timeCheckCallback(kTime1800000, params->param2, 3, WRAP_SETUP_FUNCTION(Francois, setup_function13)))
+ if (Entity::timeCheckCallback(kTime1800000, params->param2, 3, WRAP_SETUP_FUNCTION(Francois, setup_haremVisit)))
break;
label_callback_3:
@@ -1085,36 +1085,36 @@ IMPLEMENT_FUNCTION(25, Francois, chapter3Handler)
if (ENTITY_PARAM(0, 1) && getEntities()->isPlayerInCar(kCarRedSleeping)) {
setCallback(2);
- setup_function15();
+ setup_findCath();
break;
}
label_callback_2:
- if (Entity::timeCheckCallback(kTime2025000, params->param3, 3, WRAP_SETUP_FUNCTION(Francois, setup_function12)))
+ if (Entity::timeCheckCallback(kTime2025000, params->param3, 3, WRAP_SETUP_FUNCTION(Francois, setup_takeWalk)))
break;
label_callback_3:
- if (Entity::timeCheckCallback(kTime2052000, params->param4, 4, WRAP_SETUP_FUNCTION(Francois, setup_function12)))
+ if (Entity::timeCheckCallback(kTime2052000, params->param4, 4, WRAP_SETUP_FUNCTION(Francois, setup_takeWalk)))
break;
label_callback_4:
- if (Entity::timeCheckCallback(kTime2079000, params->param5, 5, WRAP_SETUP_FUNCTION(Francois, setup_function12)))
+ if (Entity::timeCheckCallback(kTime2079000, params->param5, 5, WRAP_SETUP_FUNCTION(Francois, setup_takeWalk)))
break;
label_callback_5:
- if (Entity::timeCheckCallback(kTime2092500, params->param6, 6, WRAP_SETUP_FUNCTION(Francois, setup_function12)))
+ if (Entity::timeCheckCallback(kTime2092500, params->param6, 6, WRAP_SETUP_FUNCTION(Francois, setup_takeWalk)))
break;
label_callback_6:
- if (Entity::timeCheckCallback(kTime2173500, params->param7, 7, WRAP_SETUP_FUNCTION(Francois, setup_function12)))
+ if (Entity::timeCheckCallback(kTime2173500, params->param7, 7, WRAP_SETUP_FUNCTION(Francois, setup_takeWalk)))
break;
label_callback_7:
- if (Entity::timeCheckCallback(kTime2182500, params->param8, 8, WRAP_SETUP_FUNCTION(Francois, setup_function12)))
+ if (Entity::timeCheckCallback(kTime2182500, params->param8, 8, WRAP_SETUP_FUNCTION(Francois, setup_takeWalk)))
break;
label_callback_8:
- if (Entity::timeCheckCallback(kTime2241000, CURRENT_PARAM(1, 1), 9, WRAP_SETUP_FUNCTION(Francois, setup_function12)))
+ if (Entity::timeCheckCallback(kTime2241000, CURRENT_PARAM(1, 1), 9, WRAP_SETUP_FUNCTION(Francois, setup_takeWalk)))
break;
label_callback_9:
@@ -1208,7 +1208,7 @@ label_callback_14:
case kAction101107728:
setCallback(1);
- setup_function16();
+ setup_letsGo();
break;
case kAction189872836:
@@ -1246,7 +1246,7 @@ IMPLEMENT_FUNCTION_END
IMPLEMENT_FUNCTION(27, Francois, chapter4Handler)
if (savepoint.action == kAction101107728) {
setCallback(1);
- setup_function16();
+ setup_letsGo();
}
IMPLEMENT_FUNCTION_END
@@ -1314,7 +1314,7 @@ bool Francois::timeCheckCallbackCompartment(TimeValue timeValue, uint &parameter
if (getState()->time > timeValue && !parameter) {
parameter = 1;
setCallback(callback);
- setup_function14(compartment, position, sequenceSuffix);
+ setup_chaseBeetle(compartment, position, sequenceSuffix);
return true;
}
@@ -1326,7 +1326,7 @@ bool Francois::timeCheckCallback(TimeValue timeValue, uint &parameter, byte call
if (getState()->time > timeValue && !parameter) {
parameter = 1;
setCallback(callback);
- setup_function11(timeValue2);
+ setup_rampage(timeValue2);
return true;
}
diff --git a/engines/lastexpress/entities/francois.h b/engines/lastexpress/entities/francois.h
index 51270fa4b6..3118faf867 100644
--- a/engines/lastexpress/entities/francois.h
+++ b/engines/lastexpress/entities/francois.h
@@ -85,21 +85,21 @@ public:
DECLARE_FUNCTION_2(savegame, SavegameType savegameType, uint32 param)
/**
- * Updates the entity
+ * Walk
*
* @param car The car
* @param entityPosition The entity position
*/
- DECLARE_FUNCTION_2(updateEntity, CarIndex car, EntityPosition entityPosition)
+ DECLARE_FUNCTION_2(doWalk, CarIndex car, EntityPosition entityPosition)
- DECLARE_FUNCTION(function9)
- DECLARE_FUNCTION(function10)
- DECLARE_FUNCTION_1(function11, TimeValue timeValue)
- DECLARE_FUNCTION(function12)
- DECLARE_FUNCTION(function13)
- DECLARE_FUNCTION_3(function14, ObjectIndex compartment, EntityPosition entityPosition, const char *str)
- DECLARE_FUNCTION(function15)
- DECLARE_FUNCTION(function16)
+ DECLARE_FUNCTION(exitCompartment)
+ DECLARE_FUNCTION(enterCompartment)
+ DECLARE_FUNCTION_1(rampage, TimeValue timeValue)
+ DECLARE_FUNCTION(takeWalk)
+ DECLARE_FUNCTION(haremVisit)
+ DECLARE_FUNCTION_3(chaseBeetle, ObjectIndex compartment, EntityPosition entityPosition, const char *str)
+ DECLARE_FUNCTION(findCath)
+ DECLARE_FUNCTION(letsGo)
/**
* Setup Chapter 1
@@ -110,8 +110,7 @@ public:
* Handle Chapter 1 events
*/
DECLARE_FUNCTION(chapter1Handler)
-
- DECLARE_FUNCTION(function19)
+ DECLARE_FUNCTION(inCompartment)
DECLARE_FUNCTION(function20)
/**
@@ -122,9 +121,8 @@ public:
/**
* Handle Chapter 2 events
*/
- DECLARE_FUNCTION(chapter2Handler)
-
- DECLARE_FUNCTION(function23)
+ DECLARE_FUNCTION(atBreakfast)
+ DECLARE_FUNCTION(withMama)
/**
* Setup Chapter 3
@@ -155,7 +153,6 @@ public:
* Handle Chapter 5 events
*/
DECLARE_FUNCTION(chapter5Handler)
-
DECLARE_FUNCTION(function30)
DECLARE_NULL_FUNCTION()
diff --git a/engines/lastexpress/entities/gendarmes.cpp b/engines/lastexpress/entities/gendarmes.cpp
index a912fa4ecb..2ff34ef4c9 100644
--- a/engines/lastexpress/entities/gendarmes.cpp
+++ b/engines/lastexpress/entities/gendarmes.cpp
@@ -250,7 +250,7 @@ IMPLEMENT_FUNCTION_III(10, Gendarmes, function10, CarIndex, EntityPosition, Obje
if (!params->param5)
params->param5 = getState()->timeTicks + 75;
- if (!getEntities()->isOutsideAlexeiWindow() && getObjects()->get((ObjectIndex)params->param3).location != kObjectLocation1) {
+ if (!getEntities()->isOutsideAlexeiWindow() && getObjects()->get((ObjectIndex)params->param3).status != kObjectLocation1) {
setCallback(2);
setup_savegame(kSavegameTypeEvent, kEventGendarmesArrestation);
break;
@@ -284,7 +284,7 @@ IMPLEMENT_FUNCTION_III(10, Gendarmes, function10, CarIndex, EntityPosition, Obje
break;
case kActionKnock:
- getObjects()->update((ObjectIndex)params->param3, kEntityGendarmes, getObjects()->get((ObjectIndex)params->param3).location, kCursorNormal, kCursorNormal);
+ getObjects()->update((ObjectIndex)params->param3, kEntityGendarmes, getObjects()->get((ObjectIndex)params->param3).status, kCursorNormal, kCursorNormal);
setCallback(5);
setup_arrestPlaysound16("POL1046B");
@@ -296,7 +296,7 @@ IMPLEMENT_FUNCTION_III(10, Gendarmes, function10, CarIndex, EntityPosition, Obje
break;
case kActionDefault:
- getObjects()->update((ObjectIndex)params->param3, kEntityGendarmes, getObjects()->get((ObjectIndex)params->param3).location, kCursorNormal, kCursorNormal);
+ getObjects()->update((ObjectIndex)params->param3, kEntityGendarmes, getObjects()->get((ObjectIndex)params->param3).status, kCursorNormal, kCursorNormal);
setCallback(1);
setup_arrestPlaysound16("POL1046");
@@ -308,7 +308,7 @@ IMPLEMENT_FUNCTION_III(10, Gendarmes, function10, CarIndex, EntityPosition, Obje
break;
case 1:
- getObjects()->update((ObjectIndex)params->param3, kEntityGendarmes, getObjects()->get((ObjectIndex)params->param3).location, kCursorTalk, kCursorNormal);
+ getObjects()->update((ObjectIndex)params->param3, kEntityGendarmes, getObjects()->get((ObjectIndex)params->param3).status, kCursorTalk, kCursorNormal);
break;
case 2:
@@ -334,7 +334,7 @@ IMPLEMENT_FUNCTION_III(10, Gendarmes, function10, CarIndex, EntityPosition, Obje
break;
case 5:
- getObjects()->update((ObjectIndex)params->param3, kEntityGendarmes, getObjects()->get((ObjectIndex)params->param3).location, kCursorNormal, kCursorHand);
+ getObjects()->update((ObjectIndex)params->param3, kEntityGendarmes, getObjects()->get((ObjectIndex)params->param3).status, kCursorNormal, kCursorHand);
break;
case 6:
diff --git a/engines/lastexpress/entities/kahina.cpp b/engines/lastexpress/entities/kahina.cpp
index 467c8d8b3c..29e9a90d41 100644
--- a/engines/lastexpress/entities/kahina.cpp
+++ b/engines/lastexpress/entities/kahina.cpp
@@ -503,16 +503,16 @@ IMPLEMENT_FUNCTION(15, Kahina, function15)
getData()->location = kLocationInsideCompartment;
getEntities()->clearSequences(kEntityKahina);
- getObjects()->update(kObjectCompartmentC, kEntityPlayer, getObjects()->get(kObjectCompartmentC).location, kCursorNormal, kCursorNormal);
- getObjects()->update(kObject50, kEntityPlayer, getObjects()->get(kObject50).location, kCursorNormal, kCursorNormal);
+ getObjects()->update(kObjectCompartmentC, kEntityPlayer, getObjects()->get(kObjectCompartmentC).status, kCursorNormal, kCursorNormal);
+ getObjects()->update(kObject50, kEntityPlayer, getObjects()->get(kObject50).status, kCursorNormal, kCursorNormal);
setCallback(13);
setup_updateFromTime(900);
break;
case 13:
- getObjects()->update(kObjectCompartmentC, kEntityPlayer, getObjects()->get(kObjectCompartmentC).location, kCursorHandKnock, kCursorHand);
- getObjects()->update(kObject50, kEntityPlayer, getObjects()->get(kObject50).location, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObjectCompartmentC, kEntityPlayer, getObjects()->get(kObjectCompartmentC).status, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObject50, kEntityPlayer, getObjects()->get(kObject50).status, kCursorHandKnock, kCursorHand);
setCallback(14);
setup_enterExitCompartment("616Bc", kObjectCompartmentC);
@@ -1088,16 +1088,16 @@ IMPLEMENT_FUNCTION(23, Kahina, function23)
getData()->location = kLocationInsideCompartment;
getEntities()->clearSequences(kEntityKahina);
- getObjects()->update(kObjectCompartmentF, kEntityPlayer, getObjects()->get(kObjectCompartmentF).location, kCursorNormal, kCursorNormal);
- getObjects()->update(kObject53, kEntityPlayer, getObjects()->get(kObject53).location, kCursorNormal, kCursorNormal);
+ getObjects()->update(kObjectCompartmentF, kEntityPlayer, getObjects()->get(kObjectCompartmentF).status, kCursorNormal, kCursorNormal);
+ getObjects()->update(kObject53, kEntityPlayer, getObjects()->get(kObject53).status, kCursorNormal, kCursorNormal);
setCallback(3);
setup_updateFromTime(900);
break;
case 3:
- getObjects()->update(kObjectCompartmentF, kEntityPlayer, getObjects()->get(kObjectCompartmentF).location, kCursorHandKnock, kCursorHand);
- getObjects()->update(kObject53, kEntityPlayer, getObjects()->get(kObject53).location, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObjectCompartmentF, kEntityPlayer, getObjects()->get(kObjectCompartmentF).status, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObject53, kEntityPlayer, getObjects()->get(kObject53).status, kCursorHandKnock, kCursorHand);
setCallback(4);
setup_enterExitCompartment("616Df", kObjectCompartmentF);
@@ -1436,16 +1436,16 @@ IMPLEMENT_FUNCTION(26, Kahina, function26)
getData()->location = kLocationInsideCompartment;
getEntities()->clearSequences(kEntityKahina);
- getObjects()->update(kObjectCompartmentA, kEntityPlayer, getObjects()->get(kObjectCompartmentA).location, kCursorNormal, kCursorNormal);
- getObjects()->update(kObject48, kEntityPlayer, getObjects()->get(kObject48).location, kCursorNormal, kCursorNormal);
+ getObjects()->update(kObjectCompartmentA, kEntityPlayer, getObjects()->get(kObjectCompartmentA).status, kCursorNormal, kCursorNormal);
+ getObjects()->update(kObject48, kEntityPlayer, getObjects()->get(kObject48).status, kCursorNormal, kCursorNormal);
setCallback(7);
setup_updateFromTime(900);
break;
case 7:
- getObjects()->update(kObjectCompartmentA, kEntityPlayer, getObjects()->get(kObjectCompartmentA).location, kCursorHandKnock, kCursorHand);
- getObjects()->update(kObject48, kEntityPlayer, getObjects()->get(kObject48).location, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObjectCompartmentA, kEntityPlayer, getObjects()->get(kObjectCompartmentA).status, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObject48, kEntityPlayer, getObjects()->get(kObject48).status, kCursorHandKnock, kCursorHand);
if (getInventory()->get(kItemFirebird)->location == kObjectLocation1 || getInventory()->get(kItemFirebird)->location == kObjectLocation2) {
getScenes()->loadSceneFromItemPosition(kItemFirebird);
diff --git a/engines/lastexpress/entities/kronos.cpp b/engines/lastexpress/entities/kronos.cpp
index 26ce3ca424..38a685ec19 100644
--- a/engines/lastexpress/entities/kronos.cpp
+++ b/engines/lastexpress/entities/kronos.cpp
@@ -399,7 +399,7 @@ IMPLEMENT_FUNCTION(18, Kronos, function18)
case kActionNone:
if (getState()->time > kTime2079000 && !params->param2) {
- getObjects()->updateLocation2(kObjectCompartmentKronos, kObjectLocation3);
+ getObjects()->updateModel(kObjectCompartmentKronos, kObjectModel3);
getObjects()->update(kObjectCompartmentKronos, kEntityPlayer, kObjectLocation3, kCursorHandKnock, kCursorHand);
params->param1 = 1;
params->param2 = 1;
@@ -462,7 +462,7 @@ IMPLEMENT_FUNCTION(19, Kronos, function19)
RESET_ENTITY_STATE(kEntityRebecca, Rebecca, setup_function39);
RESET_ENTITY_STATE(kEntitySophie, Sophie, setup_chaptersHandler);
RESET_ENTITY_STATE(kEntityAugust, August, setup_function50);
- RESET_ENTITY_STATE(kEntityAnna, Anna, setup_function56);
+ RESET_ENTITY_STATE(kEntityAnna, Anna, setup_concert);
RESET_ENTITY_STATE(kEntityTatiana, Tatiana, setup_function35);
setup_function20();
diff --git a/engines/lastexpress/entities/mertens.cpp b/engines/lastexpress/entities/mertens.cpp
index 97dd293793..f484d00a2c 100644
--- a/engines/lastexpress/entities/mertens.cpp
+++ b/engines/lastexpress/entities/mertens.cpp
@@ -1067,7 +1067,7 @@ IMPLEMENT_FUNCTION_II(21, Mertens, function21, ObjectIndex, ObjectIndex)
break;
// Update objects
- getObjects()->updateLocation2((ObjectIndex)params->param1, kObjectLocation1);
+ getObjects()->updateModel((ObjectIndex)params->param1, kObjectModel1);
if (params->param5 != kObjectLocation2)
getObjects()->update((ObjectIndex)params->param1, (EntityIndex)params->param4, (ObjectLocation)params->param5, (CursorStyle)params->param6, (CursorStyle)params->param7);
@@ -1090,15 +1090,15 @@ IMPLEMENT_FUNCTION_II(21, Mertens, function21, ObjectIndex, ObjectIndex)
case kActionDefault:
params->param3 = 1;
params->param4 = getObjects()->get((ObjectIndex)params->param1).entity;
- params->param5 = getObjects()->get((ObjectIndex)params->param1).location;
- params->param6 = getObjects()->get((ObjectIndex)params->param1).cursor;
- params->param7 = getObjects()->get((ObjectIndex)params->param1).cursor2;
+ params->param5 = getObjects()->get((ObjectIndex)params->param1).status;
+ params->param6 = getObjects()->get((ObjectIndex)params->param1).windowCursor;
+ params->param7 = getObjects()->get((ObjectIndex)params->param1).handleCursor;
if (params->param2) {
- params->param8 = getObjects()->get((ObjectIndex)params->param2).entity;
- CURRENT_PARAM(1, 1) = getObjects()->get((ObjectIndex)params->param2).location;
- CURRENT_PARAM(1, 2) = getObjects()->get((ObjectIndex)params->param2).cursor;
- CURRENT_PARAM(1, 3) = getObjects()->get((ObjectIndex)params->param2).cursor2;
+ params->param8 = getObjects()->get((ObjectIndex)params->param2).entity;
+ CURRENT_PARAM(1, 1) = getObjects()->get((ObjectIndex)params->param2).status;
+ CURRENT_PARAM(1, 2) = getObjects()->get((ObjectIndex)params->param2).windowCursor;
+ CURRENT_PARAM(1, 3) = getObjects()->get((ObjectIndex)params->param2).handleCursor;
getObjects()->update((ObjectIndex)params->param2, kEntityMertens, kObjectLocation1, kCursorHandKnock, kCursorHand);
}
@@ -1506,7 +1506,7 @@ IMPLEMENT_FUNCTION_I(26, Mertens, function26, bool)
getData()->location = kLocationInsideCompartment;
getEntities()->clearSequences(kEntityMertens);
- getObjects()->update(kObjectCompartment1, kEntityPlayer, getObjects()->get(kObjectCompartment1).location, kCursorNormal, kCursorNormal);
+ getObjects()->update(kObjectCompartment1, kEntityPlayer, getObjects()->get(kObjectCompartment1).status, kCursorNormal, kCursorNormal);
setCallback(3);
setup_playSound16("ZNU1001");
@@ -1522,14 +1522,14 @@ IMPLEMENT_FUNCTION_I(26, Mertens, function26, bool)
break;
case 1:
- getObjects()->update(kObjectCompartment1, kEntityPlayer, getObjects()->get(kObjectCompartment1).location, kCursorNormal, kCursorNormal);
+ getObjects()->update(kObjectCompartment1, kEntityPlayer, getObjects()->get(kObjectCompartment1).status, kCursorNormal, kCursorNormal);
setCallback(2);
setup_playSound16("CON1062");
break;
case 2:
- getObjects()->update(kObjectCompartment1, kEntityPlayer, getObjects()->get(kObjectCompartment1).location, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObjectCompartment1, kEntityPlayer, getObjects()->get(kObjectCompartment1).status, kCursorHandKnock, kCursorHand);
callbackAction();
break;
@@ -1617,7 +1617,7 @@ IMPLEMENT_FUNCTION_I(27, Mertens, tylerCompartment, MertensActionType)
}
if (Entity::updateParameter(params->param2, getState()->timeTicks, 150)) {
- getObjects()->update(kObjectCompartment1, kEntityPlayer, getObjects()->get(kObjectCompartment1).location, kCursorNormal, kCursorNormal);
+ getObjects()->update(kObjectCompartment1, kEntityPlayer, getObjects()->get(kObjectCompartment1).status, kCursorNormal, kCursorNormal);
setCallback(10);
setup_playSound16("CON1018A");
@@ -1683,7 +1683,7 @@ label_callback11:
} else {
params->param3 = kTimeInvalid;
- if (getObjects()->get(kObjectCompartment1).location == kObjectLocation1) {
+ if (getObjects()->get(kObjectCompartment1).status == kObjectLocation1) {
getObjects()->update(kObjectCompartment1, kEntityPlayer, kObjectLocation1, kCursorNormal, kCursorNormal);
setCallback(11);
@@ -1742,11 +1742,11 @@ label_callback11:
case kActionKnock:
if (params->param1) {
- getObjects()->update(kObjectCompartment1, kEntityMertens, getObjects()->get(kObjectCompartment1).location, kCursorNormal, kCursorNormal);
+ getObjects()->update(kObjectCompartment1, kEntityMertens, getObjects()->get(kObjectCompartment1).status, kCursorNormal, kCursorNormal);
switch (params->param1) {
default:
- getObjects()->update(kObjectCompartment1, kEntityPlayer, getObjects()->get(kObjectCompartment1).location, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObjectCompartment1, kEntityPlayer, getObjects()->get(kObjectCompartment1).status, kCursorHandKnock, kCursorHand);
callbackAction();
break;
@@ -1774,7 +1774,7 @@ label_callback11:
break;
case kActionOpenDoor:
- getSound()->playSound(kEntityPlayer, getObjects()->get(kObjectCompartment1).location == kObjectLocation1 ? "LIB012" : "LIB014");
+ getSound()->playSound(kEntityPlayer, getObjects()->get(kObjectCompartment1).status == kObjectLocation1 ? "LIB012" : "LIB014");
if (getProgress().eventCorpseMovedFromFloor) {
@@ -1828,7 +1828,7 @@ label_callback11:
if (getEntities()->isInsideCompartment(kEntityPlayer, kCarGreenSleeping, kPosition_8200)
|| getEntities()->isInsideCompartment(kEntityPlayer, kCarGreenSleeping, kPosition_7850)
|| getEntities()->isOutsideAlexeiWindow()) {
- getObjects()->update(kObjectCompartment1, kEntityPlayer, getObjects()->get(kObjectCompartment1).location, kCursorNormal, kCursorNormal);
+ getObjects()->update(kObjectCompartment1, kEntityPlayer, getObjects()->get(kObjectCompartment1).status, kCursorNormal, kCursorNormal);
if (getEntities()->isOutsideAlexeiWindow())
getScenes()->loadSceneFromPosition(kCarGreenSleeping, 49);
@@ -1920,15 +1920,15 @@ label_callback11:
case 8:
case 9:
- getObjects()->update(kObjectCompartment1, kEntityMertens, getObjects()->get(kObjectCompartment1).location, kCursorTalk, kCursorHand);
+ getObjects()->update(kObjectCompartment1, kEntityMertens, getObjects()->get(kObjectCompartment1).status, kCursorTalk, kCursorHand);
break;
case 10:
- getObjects()->update(kObjectCompartment1, kEntityMertens, getObjects()->get(kObjectCompartment1).location, kCursorTalk, kCursorHand);
+ getObjects()->update(kObjectCompartment1, kEntityMertens, getObjects()->get(kObjectCompartment1).status, kCursorTalk, kCursorHand);
goto label_callback10;
case 11:
- getObjects()->update(kObjectCompartment1, kEntityMertens, getObjects()->get(kObjectCompartment1).location, kCursorTalk, kCursorHand);
+ getObjects()->update(kObjectCompartment1, kEntityMertens, getObjects()->get(kObjectCompartment1).status, kCursorTalk, kCursorHand);
goto label_callback11;
case 13:
@@ -1971,20 +1971,20 @@ label_callback11:
case 23:
getProgress().eventMertensAugustWaiting = true;
- getObjects()->update(kObjectCompartment1, kEntityPlayer, getObjects()->get(kObjectCompartment1).location, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObjectCompartment1, kEntityPlayer, getObjects()->get(kObjectCompartment1).status, kCursorHandKnock, kCursorHand);
callbackAction();
break;
case 24:
getProgress().eventMertensKronosInvitation = true;
- getObjects()->update(kObjectCompartment1, kEntityPlayer, getObjects()->get(kObjectCompartment1).location, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObjectCompartment1, kEntityPlayer, getObjects()->get(kObjectCompartment1).status, kCursorHandKnock, kCursorHand);
callbackAction();
break;
case 25:
- getObjects()->update(kObjectCompartment1, kEntityPlayer, getObjects()->get(kObjectCompartment1).location, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObjectCompartment1, kEntityPlayer, getObjects()->get(kObjectCompartment1).status, kCursorHandKnock, kCursorHand);
callbackAction();
break;
@@ -2182,7 +2182,7 @@ IMPLEMENT_FUNCTION_I(30, Mertens, function30, MertensActionType)
case 2:
if (getEntities()->isInsideCompartment(kEntityPlayer, kCarGreenSleeping, kPosition_7500)) {
- getObjects()->update(kObjectCompartment2, kEntityPlayer, getObjects()->get(kObjectCompartment2).location, kCursorNormal, kCursorNormal);
+ getObjects()->update(kObjectCompartment2, kEntityPlayer, getObjects()->get(kObjectCompartment2).status, kCursorNormal, kCursorNormal);
params->param3 = 1;
}
@@ -2192,7 +2192,7 @@ IMPLEMENT_FUNCTION_I(30, Mertens, function30, MertensActionType)
case 3:
if (getEntities()->isInsideCompartment(kEntityPlayer, kCarGreenSleeping, kPosition_6470)) {
- getObjects()->update(kObjectCompartment3, kEntityPlayer, getObjects()->get(kObjectCompartment3).location, kCursorNormal, kCursorNormal);
+ getObjects()->update(kObjectCompartment3, kEntityPlayer, getObjects()->get(kObjectCompartment3).status, kCursorNormal, kCursorNormal);
params->param3 = 1;
}
@@ -2220,7 +2220,7 @@ IMPLEMENT_FUNCTION_I(30, Mertens, function30, MertensActionType)
case 5:
if (params->param3)
- getObjects()->update(kObjectCompartment2, kEntityPlayer, getObjects()->get(kObjectCompartment2).location, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObjectCompartment2, kEntityPlayer, getObjects()->get(kObjectCompartment2).status, kCursorHandKnock, kCursorHand);
getEntities()->exitCompartment(kEntityMertens, kObjectCompartment2);
@@ -2241,7 +2241,7 @@ IMPLEMENT_FUNCTION_I(30, Mertens, function30, MertensActionType)
case 7:
if (params->param3)
- getObjects()->update(kObjectCompartment3, kEntityPlayer, getObjects()->get(kObjectCompartment3).location, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObjectCompartment3, kEntityPlayer, getObjects()->get(kObjectCompartment3).status, kCursorHandKnock, kCursorHand);
getEntities()->exitCompartment(kEntityMertens, kObjectCompartment3);
@@ -3688,9 +3688,9 @@ IMPLEMENT_FUNCTION(48, Mertens, function48)
if (ENTITY_PARAM(2, 3)) {
params->param1 = 1;
- getObjects()->updateLocation2(kObjectCompartment2, kObjectLocation1);
- getObjects()->updateLocation2(kObjectCompartment3, kObjectLocation1);
- getObjects()->updateLocation2(kObjectCompartment4, kObjectLocation1);
+ getObjects()->updateModel(kObjectCompartment2, kObjectModel1);
+ getObjects()->updateModel(kObjectCompartment3, kObjectModel1);
+ getObjects()->updateModel(kObjectCompartment4, kObjectModel1);
ENTITY_PARAM(1, 4) = 0;
ENTITY_PARAM(1, 5) = 0;
diff --git a/engines/lastexpress/entities/milos.cpp b/engines/lastexpress/entities/milos.cpp
index 519a613497..76dc0aa0a0 100644
--- a/engines/lastexpress/entities/milos.cpp
+++ b/engines/lastexpress/entities/milos.cpp
@@ -433,16 +433,16 @@ IMPLEMENT_FUNCTION(14, Milos, function14)
if (CURRENT_PARAM(1, 1) < getState()->timeTicks) {
- if (getObjects()->get(kObjectCompartment1).location == kObjectLocation1) {
+ if (getObjects()->get(kObjectCompartment1).status == kObjectLocation1) {
if (!Entity::updateParameter(CURRENT_PARAM(1, 2), getState()->timeTicks, 75))
break;
- getObjects()->update(kObjectCompartment1, kEntityMilos, getObjects()->get(kObjectCompartment1).location, kCursorNormal, kCursorNormal);
+ getObjects()->update(kObjectCompartment1, kEntityMilos, getObjects()->get(kObjectCompartment1).status, kCursorNormal, kCursorNormal);
++params->param5;
switch (params->param5) {
default:
- getObjects()->update(kObjectCompartment1, kEntityMilos, getObjects()->get(kObjectCompartment1).location, params->param3 < 1 ? kCursorTalk : kCursorNormal, kCursorHand);
+ getObjects()->update(kObjectCompartment1, kEntityMilos, getObjects()->get(kObjectCompartment1).status, params->param3 < 1 ? kCursorTalk : kCursorNormal, kCursorHand);
CURRENT_PARAM(1, 2) = 0;
break;
@@ -466,19 +466,19 @@ IMPLEMENT_FUNCTION(14, Milos, function14)
if (params->param7 < 3) {
params->param5 = 1;
- getObjects()->update(kObjectCompartment1, kEntityMilos, getObjects()->get(kObjectCompartment1).location, params->param3 < 1 ? kCursorTalk : kCursorNormal, kCursorHand);
+ getObjects()->update(kObjectCompartment1, kEntityMilos, getObjects()->get(kObjectCompartment1).status, params->param3 < 1 ? kCursorTalk : kCursorNormal, kCursorHand);
CURRENT_PARAM(1, 2) = 0;
break;
}
- getObjects()->update(kObjectCompartment1, kEntityPlayer, getObjects()->get(kObjectCompartment1).location, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObjectCompartment1, kEntityPlayer, getObjects()->get(kObjectCompartment1).status, kCursorHandKnock, kCursorHand);
callbackAction();
break;
}
} else {
if (getProgress().eventCorpseMovedFromFloor && getProgress().jacket != kJacketBlood) {
- params->param6 = (getObjects()->get(kObjectCompartment1).location2 == kObjectLocation1) ? kEventMilosTylerCompartmentBedVisit : kEventMilosTylerCompartmentVisit;
+ params->param6 = (getObjects()->get(kObjectCompartment1).model == kObjectModel1) ? kEventMilosTylerCompartmentBedVisit : kEventMilosTylerCompartmentVisit;
setCallback(3);
setup_savegame(kSavegameTypeEvent, kEventMilosTylerCompartmentVisit);
@@ -538,7 +538,7 @@ label_callback_12:
setCallback(20);
setup_playSound("LIB012");
} else if (!params->param3) {
- getObjects()->update(kObjectCompartment1, kEntityMilos, getObjects()->get(kObjectCompartment1).location, kCursorNormal, kCursorNormal);
+ getObjects()->update(kObjectCompartment1, kEntityMilos, getObjects()->get(kObjectCompartment1).status, kCursorNormal, kCursorNormal);
setCallback(22);
setup_playSound16("MIL1032");
@@ -549,9 +549,9 @@ label_callback_12:
if (getProgress().eventCorpseMovedFromFloor && getProgress().jacket != kJacketBlood) {
if (params->param2) {
getEntityData(kEntityPlayer)->location = kLocationInsideCompartment;
- params->param6 = (getObjects()->get(kObjectCompartment1).location2 == kObjectLocation1) ? kEventMilosTylerCompartmentBed : kEventMilosTylerCompartment;
+ params->param6 = (getObjects()->get(kObjectCompartment1).model == kObjectModel1) ? kEventMilosTylerCompartmentBed : kEventMilosTylerCompartment;
} else {
- params->param6 = (getObjects()->get(kObjectCompartment1).location2 == kObjectLocation1) ? kEventMilosTylerCompartmentBedVisit : kEventMilosTylerCompartmentVisit;
+ params->param6 = (getObjects()->get(kObjectCompartment1).model == kObjectModel1) ? kEventMilosTylerCompartmentBedVisit : kEventMilosTylerCompartmentVisit;
}
setCallback(17);
@@ -568,14 +568,14 @@ label_callback_12:
if (getEntities()->isInsideCompartment(kEntityPlayer, kCarGreenSleeping, kPosition_8200)
|| getEntities()->isInsideCompartment(kEntityPlayer, kCarGreenSleeping, kPosition_7850)
|| getEntities()->isOutsideAlexeiWindow()) {
- getObjects()->update(kObjectCompartment1, kEntityMilos, getObjects()->get(kObjectCompartment1).location, kCursorNormal, kCursorNormal);
+ getObjects()->update(kObjectCompartment1, kEntityMilos, getObjects()->get(kObjectCompartment1).status, kCursorNormal, kCursorNormal);
if (getEntities()->isOutsideAlexeiWindow())
getScenes()->loadSceneFromPosition(kCarGreenSleeping, 49);
getSound()->playSound(kEntityPlayer, "LIB012");
- getObjects()->update(kObjectCompartment1, kEntityMilos, getObjects()->get(kObjectCompartment1).location, kCursorTalk, kCursorHand);
+ getObjects()->update(kObjectCompartment1, kEntityMilos, getObjects()->get(kObjectCompartment1).status, kCursorTalk, kCursorHand);
params->param1 = 1;
} else {
@@ -644,7 +644,7 @@ label_callback_12:
case 7:
case 9:
case 11:
- getObjects()->update(kObjectCompartment1, kEntityMilos, getObjects()->get(kObjectCompartment1).location, params->param3 < 1 ? kCursorTalk : kCursorNormal, kCursorHand);
+ getObjects()->update(kObjectCompartment1, kEntityMilos, getObjects()->get(kObjectCompartment1).status, params->param3 < 1 ? kCursorTalk : kCursorNormal, kCursorHand);
CURRENT_PARAM(1, 2) = 0;
break;
@@ -682,13 +682,13 @@ label_callback_12:
break;
case 16:
- getSound()->playSound(kEntityPlayer, getObjects()->get(kObjectCompartment1).location == kObjectLocation1 ? "LIB032" : "LIB014");
+ getSound()->playSound(kEntityPlayer, getObjects()->get(kObjectCompartment1).status == kObjectLocation1 ? "LIB032" : "LIB014");
getAction()->playAnimation(kEventMilosCorpseFloor);
getLogic()->gameOver(kSavegameTypeIndex, 1, getProgress().eventCorpseMovedFromFloor ? kSceneGameOverBloodJacket : kSceneGameOverPolice1, true);
break;
case 17:
- getSound()->playSound(kEntityPlayer, getObjects()->get(kObjectCompartment1).location == kObjectLocation1 ? "LIB032" : "LIB014");
+ getSound()->playSound(kEntityPlayer, getObjects()->get(kObjectCompartment1).status == kObjectLocation1 ? "LIB032" : "LIB014");
getObjects()->update(kObjectCompartment1, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
getObjects()->update(kObjectOutsideTylerCompartment, kEntityPlayer, kObjectLocationNone, kCursorKeepValue, kCursorKeepValue);
getAction()->playAnimation((EventIndex)params->param6);
@@ -708,7 +708,7 @@ label_callback_12:
case 22:
params->param3 = 1;
- getObjects()->update(kObjectCompartment1, kEntityMilos, getObjects()->get(kObjectCompartment1).location, kCursorNormal, kCursorHand);
+ getObjects()->update(kObjectCompartment1, kEntityMilos, getObjects()->get(kObjectCompartment1).status, kCursorNormal, kCursorHand);
break;
}
break;
diff --git a/engines/lastexpress/entities/rebecca.cpp b/engines/lastexpress/entities/rebecca.cpp
index 5bcb6aef85..8c779baeba 100644
--- a/engines/lastexpress/entities/rebecca.cpp
+++ b/engines/lastexpress/entities/rebecca.cpp
@@ -665,7 +665,7 @@ IMPLEMENT_FUNCTION(21, Rebecca, chapter1)
getObjects()->update(kObject52, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
getObjects()->update(kObjectOutsideBetweenCompartments, kEntityPlayer, kObjectLocationNone, kCursorKeepValue, kCursorKeepValue);
- getObjects()->updateLocation2(kObject110, kObjectLocation1);
+ getObjects()->updateModel(kObject110, kObjectModel1);
getData()->entityPosition = kPosition_2830;
getData()->location = kLocationInsideCompartment;
@@ -1051,7 +1051,7 @@ IMPLEMENT_FUNCTION(28, Rebecca, chapter2)
getObjects()->update(kObjectCompartmentE, kEntityPlayer, kObjectLocation1, kCursorHandKnock, kCursorHand);
getObjects()->update(kObject52, kEntityPlayer, kObjectLocation1, kCursorHandKnock, kCursorHand);
- getObjects()->updateLocation2(kObject110, kObjectLocation2);
+ getObjects()->updateModel(kObject110, kObjectModel2);
ENTITY_PARAM(0, 2) = 1;
break;
@@ -1574,7 +1574,7 @@ IMPLEMENT_FUNCTION(42, Rebecca, chapter4)
getData()->clothes = kClothesDefault;
getData()->inventoryItem = kItemNone;
- getObjects()->updateLocation2(kObject110, kObjectLocation3);
+ getObjects()->updateModel(kObject110, kObjectModel3);
ENTITY_PARAM(0, 1) = 0;
ENTITY_PARAM(0, 2) = 1;
@@ -1750,7 +1750,7 @@ IMPLEMENT_FUNCTION(46, Rebecca, chapter5)
getData()->car = kCarRestaurant;
getData()->inventoryItem = kItemNone;
- getObjects()->updateLocation2(kObject110, kObjectLocation4);
+ getObjects()->updateModel(kObject110, kObjectModel4);
break;
}
IMPLEMENT_FUNCTION_END
diff --git a/engines/lastexpress/entities/servers0.cpp b/engines/lastexpress/entities/servers0.cpp
index 73e0d34722..6323ef0ca8 100644
--- a/engines/lastexpress/entities/servers0.cpp
+++ b/engines/lastexpress/entities/servers0.cpp
@@ -115,7 +115,7 @@ IMPLEMENT_FUNCTION_NOSETUP(5, Servers0, callbackActionOnDirection)
case kActionExitCompartment:
callbackAction();
- break;
+ break;
case kActionExcuseMeCath:
if (!params->param1) {
@@ -445,7 +445,7 @@ IMPLEMENT_FUNCTION(24, Servers0, chapter2Handler)
HANDLE_TABLE(1, 3, 1, setup_function25);
HANDLE_TABLE(1, 4, 2, setup_function26);
- break;
+ break;
case kActionCallback:
if (getCallback() == 1)
diff --git a/engines/lastexpress/entities/tatiana.cpp b/engines/lastexpress/entities/tatiana.cpp
index 432def6253..d6bf4479e9 100644
--- a/engines/lastexpress/entities/tatiana.cpp
+++ b/engines/lastexpress/entities/tatiana.cpp
@@ -835,7 +835,7 @@ IMPLEMENT_FUNCTION(27, Tatiana, function27)
break;
case 1:
- RESET_ENTITY_STATE(kEntityAlexei, Alexei, setup_function30);
+ RESET_ENTITY_STATE(kEntityAlexei, Alexei, setup_atBreakfast);
getAction()->playAnimation(kEventTatianaBreakfastAlexei);
getInventory()->addItem(kItemParchemin);
getInventory()->setLocationAndProcess(kItem11, kObjectLocation1);
@@ -843,7 +843,7 @@ IMPLEMENT_FUNCTION(27, Tatiana, function27)
break;
case 2:
- RESET_ENTITY_STATE(kEntityAlexei, Alexei, setup_function30);
+ RESET_ENTITY_STATE(kEntityAlexei, Alexei, setup_atBreakfast);
getAction()->playAnimation(kEventTatianaBreakfast);
if (getInventory()->hasItem(kItemParchemin)) {
getAction()->playAnimation(kEventTatianaBreakfastGivePoem);
@@ -1917,7 +1917,7 @@ IMPLEMENT_FUNCTION(47, Tatiana, function47)
case 3:
case 4:
- if (ENTITY_PARAM(0, 1) && getObjects()->get(kObjectCompartment1).location2 == kObjectLocation1) {
+ if (ENTITY_PARAM(0, 1) && getObjects()->get(kObjectCompartment1).model == kObjectModel1) {
setup_function48();
} else {
setCallback(4);
@@ -1940,7 +1940,7 @@ IMPLEMENT_FUNCTION(48, Tatiana, function48)
if (!getEvent(kEventTatianaTylerCompartment) && getEntities()->isInsideCompartment(kEntityPlayer, kCarGreenSleeping, kPosition_8200)) {
params->param1 = 1;
getProgress().field_E4 = 1;
- getObjects()->update(kObjectCompartment1, kEntityTatiana, getObjects()->get(kObjectCompartment1).location, kCursorNormal, kCursorHand);
+ getObjects()->update(kObjectCompartment1, kEntityTatiana, getObjects()->get(kObjectCompartment1).status, kCursorNormal, kCursorHand);
}
if (!params->param1)
@@ -1948,7 +1948,7 @@ IMPLEMENT_FUNCTION(48, Tatiana, function48)
}
if (!getEntities()->checkFields19(kEntityPlayer, kCarGreenSleeping, kPosition_7850)) {
- getObjects()->update(kObjectCompartment1, kEntityPlayer, getObjects()->get(kObjectCompartment1).location, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObjectCompartment1, kEntityPlayer, getObjects()->get(kObjectCompartment1).status, kCursorHandKnock, kCursorHand);
params->param1 = 0;
}
@@ -1964,7 +1964,7 @@ IMPLEMENT_FUNCTION(48, Tatiana, function48)
label_end:
if (getEvent(kEventTatianaTylerCompartment) || getState()->time > kTime2475000) {
if (params->param1)
- getObjects()->update(kObjectCompartment1, kEntityPlayer, getObjects()->get(kObjectCompartment1).location, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObjectCompartment1, kEntityPlayer, getObjects()->get(kObjectCompartment1).status, kCursorHandKnock, kCursorHand);
getProgress().field_E4 = 0;
getEntities()->exitCompartment(kEntityTatiana, kObjectCompartment2, true);
@@ -2040,7 +2040,7 @@ label_end:
case kAction238790488:
params->param1 = 0;
- getObjects()->update(kObjectCompartment1, kEntityPlayer, getObjects()->get(kObjectCompartment1).location, kCursorHandKnock, kCursorHand);
+ getObjects()->update(kObjectCompartment1, kEntityPlayer, getObjects()->get(kObjectCompartment1).status, kCursorHandKnock, kCursorHand);
getEntities()->exitCompartment(kEntityTatiana, kObjectCompartment2, true);
getEntities()->clearSequences(kEntityTatiana);
diff --git a/engines/lastexpress/entities/vassili.cpp b/engines/lastexpress/entities/vassili.cpp
index 4695f8831f..67135c426f 100644
--- a/engines/lastexpress/entities/vassili.cpp
+++ b/engines/lastexpress/entities/vassili.cpp
@@ -112,7 +112,7 @@ IMPLEMENT_FUNCTION(5, Vassili, chapter1Handler)
break;
}
- if (!params->param2 && getObjects()->get(kObjectCompartmentA).location == kObjectLocation1) {
+ if (!params->param2 && getObjects()->get(kObjectCompartmentA).status == kObjectLocation1) {
params->param2 = 1;
getEntities()->drawSequenceLeft(kEntityVassili, "303A");
getObjects()->update(kObjectCompartmentA, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
@@ -289,7 +289,7 @@ IMPLEMENT_FUNCTION(9, Vassili, function9)
case kActionDefault:
case kActionDrawScene:
- if ((getObjects()->get(kObjectCompartmentA).location == kObjectLocation2 && getEntities()->isPlayerPosition(kCarRedSleeping, 17))
+ if ((getObjects()->get(kObjectCompartmentA).status == kObjectLocation2 && getEntities()->isPlayerPosition(kCarRedSleeping, 17))
|| getEntities()->isPlayerPosition(kCarRedSleeping, 18)
|| getEntities()->isPlayerPosition(kCarRedSleeping, 37)
|| getEntities()->isPlayerPosition(kCarRedSleeping, 38)
@@ -388,7 +388,7 @@ IMPLEMENT_FUNCTION(12, Vassili, chapter2)
getData()->inventoryItem = kItemNone;
getObjects()->update(kObjectCompartmentA, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
- getObjects()->updateLocation2(kObjectCompartmentA, kObjectLocation1);
+ getObjects()->updateModel(kObjectCompartmentA, kObjectModel1);
break;
}
IMPLEMENT_FUNCTION_END
@@ -532,7 +532,7 @@ IMPLEMENT_FUNCTION(16, Vassili, chapter4)
getData()->inventoryItem = kItemNone;
getObjects()->update(kObjectCompartmentA, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
- getObjects()->updateLocation2(kObjectCompartmentA, kObjectLocation1);
+ getObjects()->updateModel(kObjectCompartmentA, kObjectModel1);
break;
}
IMPLEMENT_FUNCTION_END
diff --git a/engines/lastexpress/entities/verges.cpp b/engines/lastexpress/entities/verges.cpp
index d9ddb0a4d1..f1e980842e 100644
--- a/engines/lastexpress/entities/verges.cpp
+++ b/engines/lastexpress/entities/verges.cpp
@@ -105,7 +105,7 @@ IMPLEMENT_FUNCTION(3, Verges, callbackActionOnDirection)
case kActionExitCompartment:
callbackAction();
- break;
+ break;
case kActionExcuseMeCath:
if (!params->param1) {
@@ -1816,7 +1816,7 @@ IMPLEMENT_FUNCTION(41, Verges, askPassengersToStayInCompartments)
break;
case kActionDefault:
- getObjects()->updateLocation2(kObjectRestaurantCar, kObjectLocation3);
+ getObjects()->updateModel(kObjectRestaurantCar, kObjectModel3);
getData()->car = kCarRedSleeping;
getData()->entityPosition = kPosition_9460;
getData()->location = kLocationInsideCompartment;
diff --git a/engines/lastexpress/entities/yasmin.cpp b/engines/lastexpress/entities/yasmin.cpp
index 1d280f51e0..67963e50f6 100644
--- a/engines/lastexpress/entities/yasmin.cpp
+++ b/engines/lastexpress/entities/yasmin.cpp
@@ -39,22 +39,22 @@ Yasmin::Yasmin(LastExpressEngine *engine) : Entity(engine, kEntityYasmin) {
ADD_CALLBACK_FUNCTION(Yasmin, playSound);
ADD_CALLBACK_FUNCTION(Yasmin, updateFromTime);
ADD_CALLBACK_FUNCTION(Yasmin, updateEntity);
- ADD_CALLBACK_FUNCTION(Yasmin, function6);
- ADD_CALLBACK_FUNCTION(Yasmin, function7);
+ ADD_CALLBACK_FUNCTION(Yasmin, goEtoG);
+ ADD_CALLBACK_FUNCTION(Yasmin, goGtoE);
ADD_CALLBACK_FUNCTION(Yasmin, chapter1);
- ADD_CALLBACK_FUNCTION(Yasmin, chapter1Handler);
+ ADD_CALLBACK_FUNCTION(Yasmin, part1);
ADD_CALLBACK_FUNCTION(Yasmin, function10);
ADD_CALLBACK_FUNCTION(Yasmin, chapter2);
- ADD_CALLBACK_FUNCTION(Yasmin, chapter2Handler);
+ ADD_CALLBACK_FUNCTION(Yasmin, part2);
ADD_CALLBACK_FUNCTION(Yasmin, chapter3);
- ADD_CALLBACK_FUNCTION(Yasmin, chapter3Handler);
+ ADD_CALLBACK_FUNCTION(Yasmin, part3);
ADD_CALLBACK_FUNCTION(Yasmin, chapter4);
- ADD_CALLBACK_FUNCTION(Yasmin, chapter4Handler);
+ ADD_CALLBACK_FUNCTION(Yasmin, part4);
ADD_CALLBACK_FUNCTION(Yasmin, function17);
ADD_CALLBACK_FUNCTION(Yasmin, chapter5);
- ADD_CALLBACK_FUNCTION(Yasmin, chapter5Handler);
+ ADD_CALLBACK_FUNCTION(Yasmin, part5);
ADD_CALLBACK_FUNCTION(Yasmin, function20);
- ADD_CALLBACK_FUNCTION(Yasmin, function21);
+ ADD_CALLBACK_FUNCTION(Yasmin, hiding);
ADD_NULL_FUNCTION();
}
@@ -98,7 +98,7 @@ IMPLEMENT_FUNCTION_II(5, Yasmin, updateEntity, CarIndex, EntityPosition)
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION(6, Yasmin, function6)
+IMPLEMENT_FUNCTION(6, Yasmin, goEtoG)
switch (savepoint.action) {
default:
break;
@@ -138,7 +138,7 @@ IMPLEMENT_FUNCTION(6, Yasmin, function6)
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION(7, Yasmin, function7)
+IMPLEMENT_FUNCTION(7, Yasmin, goGtoE)
switch (savepoint.action) {
default:
break;
@@ -184,7 +184,7 @@ IMPLEMENT_FUNCTION(8, Yasmin, chapter1)
break;
case kActionNone:
- Entity::timeCheck(kTimeChapter1, params->param1, WRAP_SETUP_FUNCTION(Yasmin, setup_chapter1Handler));
+ Entity::timeCheck(kTimeChapter1, params->param1, WRAP_SETUP_FUNCTION(Yasmin, setup_part1));
break;
case kActionDefault:
@@ -196,16 +196,16 @@ IMPLEMENT_FUNCTION(8, Yasmin, chapter1)
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION(9, Yasmin, chapter1Handler)
+IMPLEMENT_FUNCTION(9, Yasmin, part1)
switch (savepoint.action) {
default:
break;
case kActionNone:
- if (Entity::timeCheckCallback(kTime1093500, params->param1, 1, WRAP_SETUP_FUNCTION(Yasmin, setup_function6)))
+ if (Entity::timeCheckCallback(kTime1093500, params->param1, 1, WRAP_SETUP_FUNCTION(Yasmin, setup_goEtoG)))
break;
- if (Entity::timeCheckCallback(kTime1161000, params->param2, 3, WRAP_SETUP_FUNCTION(Yasmin, setup_function7)))
+ if (Entity::timeCheckCallback(kTime1161000, params->param2, 3, WRAP_SETUP_FUNCTION(Yasmin, setup_goGtoE)))
break;
if (Entity::timeCheckPlaySoundUpdatePosition(kTime1162800, params->param3, 4, "Har1102", kPosition_4070))
@@ -217,7 +217,7 @@ IMPLEMENT_FUNCTION(9, Yasmin, chapter1Handler)
if (Entity::timeCheckCallback(kTime1174500, params->param5, 6, "Har1106", WRAP_SETUP_FUNCTION_S(Yasmin, setup_playSound)))
break;
- Entity::timeCheckCallback(kTime1183500, params->param6, 7, WRAP_SETUP_FUNCTION(Yasmin, setup_function6));
+ Entity::timeCheckCallback(kTime1183500, params->param6, 7, WRAP_SETUP_FUNCTION(Yasmin, setup_goEtoG));
break;
case kActionCallback:
@@ -232,7 +232,7 @@ IMPLEMENT_FUNCTION(9, Yasmin, chapter1Handler)
break;
case 2:
- if (Entity::timeCheckCallback(kTime1161000, params->param2, 3, WRAP_SETUP_FUNCTION(Yasmin, setup_function7)))
+ if (Entity::timeCheckCallback(kTime1161000, params->param2, 3, WRAP_SETUP_FUNCTION(Yasmin, setup_goGtoE)))
break;
// Fallback to case 3
@@ -252,7 +252,7 @@ IMPLEMENT_FUNCTION(9, Yasmin, chapter1Handler)
// Fallback to case 6
case 6:
- Entity::timeCheckCallback(kTime1183500, params->param6, 7, WRAP_SETUP_FUNCTION(Yasmin, setup_function6));
+ Entity::timeCheckCallback(kTime1183500, params->param6, 7, WRAP_SETUP_FUNCTION(Yasmin, setup_goEtoG));
break;
}
break;
@@ -282,18 +282,18 @@ IMPLEMENT_FUNCTION(11, Yasmin, chapter2)
getData()->clothes = kClothesDefault;
getData()->inventoryItem = kItemNone;
- setup_chapter2Handler();
+ setup_part2();
}
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION(12, Yasmin, chapter2Handler)
+IMPLEMENT_FUNCTION(12, Yasmin, part2)
switch (savepoint.action) {
default:
break;
case kActionNone:
- if (Entity::timeCheckCallback(kTime1759500, params->param1, 1, WRAP_SETUP_FUNCTION(Yasmin, setup_function7)))
+ if (Entity::timeCheckCallback(kTime1759500, params->param1, 1, WRAP_SETUP_FUNCTION(Yasmin, setup_goGtoE)))
break;
if (getState()->time > kTime1800000 && !params->param2) {
@@ -327,7 +327,7 @@ IMPLEMENT_FUNCTION(13, Yasmin, chapter3)
break;
case kActionNone:
- setup_chapter3Handler();
+ setup_part3();
break;
case kActionDefault:
@@ -341,19 +341,19 @@ IMPLEMENT_FUNCTION(13, Yasmin, chapter3)
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION(14, Yasmin, chapter3Handler)
+IMPLEMENT_FUNCTION(14, Yasmin, part3)
switch (savepoint.action) {
default:
break;
case kActionNone:
- if (Entity::timeCheckCallback(kTime2062800, params->param1, 1, WRAP_SETUP_FUNCTION(Yasmin, setup_function6)))
+ if (Entity::timeCheckCallback(kTime2062800, params->param1, 1, WRAP_SETUP_FUNCTION(Yasmin, setup_goEtoG)))
break;
- if (Entity::timeCheckCallback(kTime2106000, params->param2, 2, WRAP_SETUP_FUNCTION(Yasmin, setup_function7)))
+ if (Entity::timeCheckCallback(kTime2106000, params->param2, 2, WRAP_SETUP_FUNCTION(Yasmin, setup_goGtoE)))
break;
- Entity::timeCheckCallback(kTime2160000, params->param3, 3, WRAP_SETUP_FUNCTION(Yasmin, setup_function6));
+ Entity::timeCheckCallback(kTime2160000, params->param3, 3, WRAP_SETUP_FUNCTION(Yasmin, setup_goEtoG));
break;
case kActionCallback:
@@ -362,12 +362,12 @@ IMPLEMENT_FUNCTION(14, Yasmin, chapter3Handler)
break;
case 1:
- if (Entity::timeCheckCallback(kTime2106000, params->param2, 2, WRAP_SETUP_FUNCTION(Yasmin, setup_function7)))
+ if (Entity::timeCheckCallback(kTime2106000, params->param2, 2, WRAP_SETUP_FUNCTION(Yasmin, setup_goGtoE)))
break;
// Fallback to case 2
case 2:
- Entity::timeCheckCallback(kTime2160000, params->param3, 3, WRAP_SETUP_FUNCTION(Yasmin, setup_function6));
+ Entity::timeCheckCallback(kTime2160000, params->param3, 3, WRAP_SETUP_FUNCTION(Yasmin, setup_goEtoG));
break;
}
break;
@@ -381,7 +381,7 @@ IMPLEMENT_FUNCTION(15, Yasmin, chapter4)
break;
case kActionNone:
- setup_chapter4Handler();
+ setup_part4();
break;
case kActionDefault:
@@ -393,16 +393,16 @@ IMPLEMENT_FUNCTION(15, Yasmin, chapter4)
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION(16, Yasmin, chapter4Handler)
+IMPLEMENT_FUNCTION(16, Yasmin, part4)
switch (savepoint.action) {
default:
break;
case kActionNone:
- if (Entity::timeCheckCallback(kTime2457000, params->param1, 1, WRAP_SETUP_FUNCTION(Yasmin, setup_function7)))
+ if (Entity::timeCheckCallback(kTime2457000, params->param1, 1, WRAP_SETUP_FUNCTION(Yasmin, setup_goGtoE)))
break;
- Entity::timeCheckCallback(kTime2479500, params->param2, 3, WRAP_SETUP_FUNCTION(Yasmin, setup_function6));
+ Entity::timeCheckCallback(kTime2479500, params->param2, 3, WRAP_SETUP_FUNCTION(Yasmin, setup_goEtoG));
break;
case kActionCallback:
@@ -417,7 +417,7 @@ IMPLEMENT_FUNCTION(16, Yasmin, chapter4Handler)
break;
case 2:
- Entity::timeCheckCallback(kTime2479500, params->param2, 3, WRAP_SETUP_FUNCTION(Yasmin, setup_function6));
+ Entity::timeCheckCallback(kTime2479500, params->param2, 3, WRAP_SETUP_FUNCTION(Yasmin, setup_goEtoG));
break;
}
break;
@@ -437,7 +437,7 @@ IMPLEMENT_FUNCTION(18, Yasmin, chapter5)
break;
case kActionNone:
- setup_chapter5Handler();
+ setup_part5();
break;
case kActionDefault:
@@ -453,7 +453,7 @@ IMPLEMENT_FUNCTION(18, Yasmin, chapter5)
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION(19, Yasmin, chapter5Handler)
+IMPLEMENT_FUNCTION(19, Yasmin, part5)
if (savepoint.action == kActionProceedChapter5)
setup_function20();
IMPLEMENT_FUNCTION_END
@@ -468,7 +468,7 @@ IMPLEMENT_FUNCTION(20, Yasmin, function20)
if (!Entity::updateParameter(params->param1, getState()->time, 2700))
break;
- setup_function21();
+ setup_hiding();
break;
case kActionDefault:
@@ -479,14 +479,14 @@ IMPLEMENT_FUNCTION(20, Yasmin, function20)
case kActionDrawScene:
if (getEntities()->isInsideTrainCar(kEntityPlayer, kCarGreenSleeping)) {
- setup_function21();
+ setup_hiding();
}
break;
}
IMPLEMENT_FUNCTION_END
//////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION(21, Yasmin, function21)
+IMPLEMENT_FUNCTION(21, Yasmin, hiding)
switch (savepoint.action) {
default:
break;
diff --git a/engines/lastexpress/entities/yasmin.h b/engines/lastexpress/entities/yasmin.h
index b1413f5c2f..8fa8c10bb1 100644
--- a/engines/lastexpress/entities/yasmin.h
+++ b/engines/lastexpress/entities/yasmin.h
@@ -70,8 +70,8 @@ public:
*/
DECLARE_FUNCTION_2(updateEntity, CarIndex car, EntityPosition entityPosition)
- DECLARE_FUNCTION(function6)
- DECLARE_FUNCTION(function7)
+ DECLARE_FUNCTION(goEtoG)
+ DECLARE_FUNCTION(goGtoE)
/**
* Setup Chapter 1
@@ -81,7 +81,7 @@ public:
/**
* Handle Chapter 1 events
*/
- DECLARE_FUNCTION(chapter1Handler)
+ DECLARE_FUNCTION(part1)
DECLARE_FUNCTION(function10)
@@ -93,7 +93,7 @@ public:
/**
* Handle Chapter 2 events
*/
- DECLARE_FUNCTION(chapter2Handler)
+ DECLARE_FUNCTION(part2)
/**
* Setup Chapter 3
@@ -103,7 +103,7 @@ public:
/**
* Handle Chapter 3 events
*/
- DECLARE_FUNCTION(chapter3Handler)
+ DECLARE_FUNCTION(part3)
/**
* Setup Chapter 4
@@ -113,7 +113,7 @@ public:
/**
* Handle Chapter 4 events
*/
- DECLARE_FUNCTION(chapter4Handler)
+ DECLARE_FUNCTION(part4)
DECLARE_FUNCTION(function17)
@@ -125,10 +125,10 @@ public:
/**
* Handle Chapter 5 events
*/
- DECLARE_FUNCTION(chapter5Handler)
+ DECLARE_FUNCTION(part5)
DECLARE_FUNCTION(function20)
- DECLARE_FUNCTION(function21)
+ DECLARE_FUNCTION(hiding)
DECLARE_NULL_FUNCTION()
};
diff --git a/engines/lastexpress/fight/fight.cpp b/engines/lastexpress/fight/fight.cpp
index 49a9b85657..944b1cb4ac 100644
--- a/engines/lastexpress/fight/fight.cpp
+++ b/engines/lastexpress/fight/fight.cpp
@@ -222,7 +222,7 @@ Fight::FightEndType Fight::setup(FightType type) {
break;
case kFightMilos:
- sceneIndex = (getObjects()->get(kObjectCompartment1).location2 < kObjectLocation3) ? kSceneFightMilos : kSceneFightMilosBedOpened;
+ sceneIndex = (getObjects()->get(kObjectCompartment1).model < kObjectModel3) ? kSceneFightMilos : kSceneFightMilosBedOpened;
break;
case kFightAnna:
diff --git a/engines/lastexpress/game/action.cpp b/engines/lastexpress/game/action.cpp
index 796abf2ce7..c6ea6f6c8a 100644
--- a/engines/lastexpress/game/action.cpp
+++ b/engines/lastexpress/game/action.cpp
@@ -351,42 +351,42 @@ Action::Action(LastExpressEngine *engine) : _engine(engine) {
ADD_ACTION(savePoint);
ADD_ACTION(playSound);
ADD_ACTION(playMusic);
- ADD_ACTION(knock);
+ ADD_ACTION(knock); // 5
ADD_ACTION(compartment);
ADD_ACTION(playSounds);
ADD_ACTION(playAnimation);
ADD_ACTION(openCloseObject);
- ADD_ACTION(updateObjetLocation2);
- ADD_ACTION(setItemLocation);
- ADD_ACTION(knockNoSound);
+ ADD_ACTION(setModel); // 10
+ ADD_ACTION(setItem);
+ ADD_ACTION(knockInside);
ADD_ACTION(pickItem);
ADD_ACTION(dropItem);
- ADD_ACTION(dummy);
+ ADD_ACTION(dummy); // 15
ADD_ACTION(enterCompartment);
ADD_ACTION(dummy);
- ADD_ACTION(getOutsideTrain);
- ADD_ACTION(slip);
- ADD_ACTION(getInsideTrain);
- ADD_ACTION(climbUpTrain);
+ ADD_ACTION(leanOutWindow);
+ ADD_ACTION(almostFall);
+ ADD_ACTION(climbInWindow); // 20
+ ADD_ACTION(climbLadder);
ADD_ACTION(climbDownTrain);
- ADD_ACTION(jumpUpDownTrain);
- ADD_ACTION(unbound);
- ADD_ACTION(25);
- ADD_ACTION(26);
+ ADD_ACTION(kronosSanctum);
+ ADD_ACTION(escapeBaggage);
+ ADD_ACTION(enterBaggage); // 25
+ ADD_ACTION(bombPuzzle);
ADD_ACTION(27);
- ADD_ACTION(concertSitCough);
+ ADD_ACTION(kronosConcert);
ADD_ACTION(29);
- ADD_ACTION(catchBeetle);
+ ADD_ACTION(catchBeetle); // 30
ADD_ACTION(exitCompartment);
- ADD_ACTION(32);
- ADD_ACTION(useWhistle);
+ ADD_ACTION(outsideTrain);
+ ADD_ACTION(firebirdPuzzle);
ADD_ACTION(openMatchBox);
- ADD_ACTION(openBed);
+ ADD_ACTION(openBed); // 35
ADD_ACTION(dummy);
ADD_ACTION(dialog);
ADD_ACTION(eggBox);
ADD_ACTION(39);
- ADD_ACTION(bed);
+ ADD_ACTION(bed); // 40
ADD_ACTION(playMusicChapter);
ADD_ACTION(playMusicChapterSetupTrain);
ADD_ACTION(switchChapter);
@@ -521,7 +521,7 @@ IMPLEMENT_ACTION(compartment)
return kSceneNone;
}
- ObjectLocation location = getObjects()->get(compartment).location;
+ ObjectLocation location = getObjects()->get(compartment).status;
if (location == kObjectLocation1 || location == kObjectLocation3 || getEntities()->checkFields2(compartment)) {
if (location != kObjectLocation1 || getEntities()->checkFields2(compartment)
@@ -625,14 +625,14 @@ IMPLEMENT_ACTION(openCloseObject)
//////////////////////////////////////////////////////////////////////////
// Action 10
-IMPLEMENT_ACTION(updateObjetLocation2)
+IMPLEMENT_ACTION(setModel)
ObjectIndex object = (ObjectIndex)hotspot.param1;
- ObjectLocation location = (ObjectLocation)hotspot.param2;
+ ObjectModel model = (ObjectModel)hotspot.param2;
if (object >= kObjectMax)
return kSceneInvalid;
- getObjects()->updateLocation2(object, location);
+ getObjects()->updateModel(object, model);
if (object != kObject112 || getSoundQueue()->isBuffered("LIB096")) {
if (object == 1)
@@ -646,13 +646,13 @@ IMPLEMENT_ACTION(updateObjetLocation2)
//////////////////////////////////////////////////////////////////////////
// Action 11
-IMPLEMENT_ACTION(setItemLocation)
+IMPLEMENT_ACTION(setItem)
InventoryItem item = (InventoryItem)hotspot.param1;
if (item >= kPortraitOriginal)
return kSceneInvalid;
Inventory::InventoryEntry *entry = getInventory()->get(item);
- if (entry->isPresent)
+ if (entry->inPocket)
return kSceneInvalid;
entry->location = (ObjectLocation)hotspot.param2;
@@ -667,7 +667,7 @@ IMPLEMENT_ACTION(setItemLocation)
//////////////////////////////////////////////////////////////////////////
// Action 12
-IMPLEMENT_ACTION(knockNoSound)
+IMPLEMENT_ACTION(knockInside)
ObjectIndex object = (ObjectIndex)hotspot.param1;
if (object >= kObjectMax)
return kSceneInvalid;
@@ -726,7 +726,7 @@ IMPLEMENT_ACTION(pickItem)
break;
case kItemBomb:
- RESET_ENTITY_STATE(kEntityAbbot, Abbot, setup_pickBomb);
+ RESET_ENTITY_STATE(kEntityAbbot, Abbot, setup_catchCath);
break;
case kItemBriefcase:
@@ -808,7 +808,7 @@ IMPLEMENT_ACTION(dropItem)
//////////////////////////////////////////////////////////////////////////
// Action 16
IMPLEMENT_ACTION(enterCompartment)
- if (getObjects()->get(kObjectCompartment1).location == kObjectLocation1 || getObjects()->get(kObjectCompartment1).location == kObjectLocation3 || getInventory()->getSelectedItem() == kItemKey)
+ if (getObjects()->get(kObjectCompartment1).status == kObjectLocation1 || getObjects()->get(kObjectCompartment1).status == kObjectLocation3 || getInventory()->getSelectedItem() == kItemKey)
return action_compartment(hotspot);
if (getProgress().eventCorpseFound) {
@@ -842,12 +842,12 @@ IMPLEMENT_ACTION(enterCompartment)
//////////////////////////////////////////////////////////////////////////
// Action 18
-IMPLEMENT_ACTION(getOutsideTrain)
+IMPLEMENT_ACTION(leanOutWindow)
ObjectIndex object = (ObjectIndex)hotspot.param1;
- if ((getEvent(kEventCathLookOutsideWindowDay) || getEvent(kEventCathLookOutsideWindowNight) || getObjects()->get(kObjectCompartment1).location2 == kObjectLocation1)
+ if ((getEvent(kEventCathLookOutsideWindowDay) || getEvent(kEventCathLookOutsideWindowNight) || getObjects()->get(kObjectCompartment1).model == kObjectModel1)
&& getProgress().isTrainRunning
- && (object != kObjectOutsideAnnaCompartment || (!getEntities()->isInsideCompartment(kEntityRebecca, kCarRedSleeping, kPosition_4840) && getObjects()->get(kObjectOutsideBetweenCompartments).location == kObjectLocation2))
+ && (object != kObjectOutsideAnnaCompartment || (!getEntities()->isInsideCompartment(kEntityRebecca, kCarRedSleeping, kPosition_4840) && getObjects()->get(kObjectOutsideBetweenCompartments).status == kObjectLocation2))
&& getInventory()->getSelectedItem() != kItemFirebird
&& getInventory()->getSelectedItem() != kItemBriefcase) {
@@ -887,7 +887,7 @@ IMPLEMENT_ACTION(getOutsideTrain)
//////////////////////////////////////////////////////////////////////////
// Action 19
-IMPLEMENT_ACTION(slip)
+IMPLEMENT_ACTION(almostFall)
switch((ObjectIndex)hotspot.param1) {
default:
return kSceneInvalid;
@@ -911,7 +911,7 @@ IMPLEMENT_ACTION(slip)
//////////////////////////////////////////////////////////////////////////
// Action 20
-IMPLEMENT_ACTION(getInsideTrain)
+IMPLEMENT_ACTION(climbInWindow)
switch ((ObjectIndex)hotspot.param1) {
default:
return kSceneInvalid;
@@ -937,7 +937,7 @@ IMPLEMENT_ACTION(getInsideTrain)
//////////////////////////////////////////////////////////////////////////
// Action 21
-IMPLEMENT_ACTION(climbUpTrain)
+IMPLEMENT_ACTION(climbLadder)
byte action = hotspot.param1;
if (action != 1 && action != 2)
@@ -999,7 +999,7 @@ IMPLEMENT_ACTION(climbDownTrain)
//////////////////////////////////////////////////////////////////////////
// Action 23
-IMPLEMENT_ACTION(jumpUpDownTrain)
+IMPLEMENT_ACTION(kronosSanctum)
switch (hotspot.param1) {
default:
break;
@@ -1038,7 +1038,7 @@ IMPLEMENT_ACTION(jumpUpDownTrain)
//////////////////////////////////////////////////////////////////////////
// Action 24
-IMPLEMENT_ACTION(unbound)
+IMPLEMENT_ACTION(escapeBaggage)
byte action = hotspot.param1;
switch (action) {
@@ -1086,7 +1086,7 @@ IMPLEMENT_ACTION(unbound)
//////////////////////////////////////////////////////////////////////////
// Action 25
-IMPLEMENT_ACTION(25)
+IMPLEMENT_ACTION(enterBaggage)
switch(hotspot.param1) {
default:
break;
@@ -1103,7 +1103,7 @@ IMPLEMENT_ACTION(25)
case 3:
getSound()->playSoundEvent(kEntityPlayer, 43);
if (!getInventory()->hasItem(kItemKey) && !getEvent(kEventAnnaBaggageArgument)) {
- RESET_ENTITY_STATE(kEntityAnna, Anna, setup_baggage);
+ RESET_ENTITY_STATE(kEntityAnna, Anna, setup_baggageFight);
return kSceneNone;
}
break;
@@ -1114,7 +1114,7 @@ IMPLEMENT_ACTION(25)
//////////////////////////////////////////////////////////////////////////
// Action 26
-IMPLEMENT_ACTION(26)
+IMPLEMENT_ACTION(bombPuzzle)
switch(hotspot.param1) {
default:
return kSceneInvalid;
@@ -1168,7 +1168,7 @@ IMPLEMENT_ACTION(27)
//////////////////////////////////////////////////////////////////////////
// Action 28
-IMPLEMENT_ACTION(concertSitCough)
+IMPLEMENT_ACTION(kronosConcert)
switch(hotspot.param1) {
default:
return kSceneInvalid;
@@ -1224,7 +1224,7 @@ IMPLEMENT_ACTION(exitCompartment)
getProgress().field_30 = 1;
}
- getObjects()->updateLocation2(kObjectCompartment1, (ObjectLocation)hotspot.param2);
+ getObjects()->updateModel(kObjectCompartment1, (ObjectModel)hotspot.param2);
// fall to case enterCompartment action
return action_enterCompartment(hotspot);
@@ -1232,7 +1232,7 @@ IMPLEMENT_ACTION(exitCompartment)
//////////////////////////////////////////////////////////////////////////
// Action 32
-IMPLEMENT_ACTION(32)
+IMPLEMENT_ACTION(outsideTrain)
switch(hotspot.param1) {
default:
break;
@@ -1273,7 +1273,7 @@ IMPLEMENT_ACTION(32)
//////////////////////////////////////////////////////////////////////////
// Action 33
-IMPLEMENT_ACTION(useWhistle)
+IMPLEMENT_ACTION(firebirdPuzzle)
EventIndex evt = kEventNone;
SceneIndex sceneIndex = kSceneInvalid;
@@ -1335,7 +1335,7 @@ IMPLEMENT_ACTION(useWhistle)
IMPLEMENT_ACTION(openMatchBox)
// If the match is already in the inventory, do nothing
if (!getInventory()->get(kItemMatch)->location
- || getInventory()->get(kItemMatch)->isPresent)
+ || getInventory()->get(kItemMatch)->inPocket)
return kSceneInvalid;
getInventory()->addItem(kItemMatch);
@@ -1392,7 +1392,7 @@ IMPLEMENT_ACTION(39)
IMPLEMENT_ACTION(bed)
getSound()->playSoundEvent(kEntityPlayer, 85);
// falls to case knockNoSound
- return action_knockNoSound(hotspot);
+ return action_knockInside(hotspot);
}
//////////////////////////////////////////////////////////////////////////
@@ -1724,7 +1724,7 @@ bool Action::handleOtherCompartment(ObjectIndex object, bool doPlaySound, bool d
}
void Action::playCompartmentSoundEvents(ObjectIndex object) const {
- if (getObjects()->get(object).location == kObjectLocation1 || getObjects()->get(object).location == kObjectLocation3 || getEntities()->checkFields2(object)) {
+ if (getObjects()->get(object).status == kObjectLocation1 || getObjects()->get(object).status == kObjectLocation3 || getEntities()->checkFields2(object)) {
getSound()->playSoundEvent(kEntityPlayer, 13);
} else {
getSound()->playSoundEvent(kEntityPlayer, 14);
@@ -1757,7 +1757,7 @@ CursorStyle Action::getCursor(const SceneHotspot &hotspot) const {
if (object >= kObjectMax)
return kCursorNormal;
else
- return (CursorStyle)getObjects()->get(object).cursor;
+ return (CursorStyle)getObjects()->get(object).windowCursor;
case SceneHotspot::kAction12:
debugC(2, kLastExpressDebugScenes, "================================= OBJECT %03d =================================", object);
@@ -1765,7 +1765,7 @@ CursorStyle Action::getCursor(const SceneHotspot &hotspot) const {
return kCursorNormal;
if (getObjects()->get(object).entity)
- return (CursorStyle)getObjects()->get(object).cursor;
+ return (CursorStyle)getObjects()->get(object).windowCursor;
else
return kCursorNormal;
@@ -1774,7 +1774,7 @@ CursorStyle Action::getCursor(const SceneHotspot &hotspot) const {
if (object >= kObjectCompartmentA)
return kCursorNormal;
- if ((!getInventory()->getSelectedItem() || getInventory()->getSelectedEntry()->manualSelect)
+ if ((!getInventory()->getSelectedItem() || getInventory()->getSelectedEntry()->floating)
&& (object != kObject21 || getProgress().eventCorpseMovedFromFloor))
return kCursorHand;
else
@@ -1806,8 +1806,8 @@ CursorStyle Action::getCursor(const SceneHotspot &hotspot) const {
return kCursorNormal;
case SceneHotspot::kActionEnterCompartment:
- if ((getInventory()->getSelectedItem() != kItemKey || getObjects()->get(kObjectCompartment1).location)
- && (getObjects()->get(kObjectCompartment1).location != 1 || !getInventory()->hasItem(kItemKey)
+ if ((getInventory()->getSelectedItem() != kItemKey || getObjects()->get(kObjectCompartment1).status)
+ && (getObjects()->get(kObjectCompartment1).status != 1 || !getInventory()->hasItem(kItemKey)
|| (getInventory()->getSelectedItem() != kItemFirebird && getInventory()->getSelectedItem() != kItemBriefcase)))
goto LABEL_KEY;
@@ -1817,13 +1817,13 @@ CursorStyle Action::getCursor(const SceneHotspot &hotspot) const {
if (getProgress().jacket != kJacketGreen)
return kCursorNormal;
- if ((getEvent(kEventCathLookOutsideWindowDay) || getEvent(kEventCathLookOutsideWindowNight) || getObjects()->get(kObjectCompartment1).location2 == kObjectLocation1)
+ if ((getEvent(kEventCathLookOutsideWindowDay) || getEvent(kEventCathLookOutsideWindowNight) || getObjects()->get(kObjectCompartment1).model == kObjectModel1)
&& getProgress().isTrainRunning
- && (object != kObjectOutsideAnnaCompartment || (getEntities()->isInsideCompartment(kEntityRebecca, kCarRedSleeping, kPosition_4840) && getObjects()->get(kObjectOutsideBetweenCompartments).location == 2))
+ && (object != kObjectOutsideAnnaCompartment || (getEntities()->isInsideCompartment(kEntityRebecca, kCarRedSleeping, kPosition_4840) && getObjects()->get(kObjectOutsideBetweenCompartments).status == 2))
&& getInventory()->getSelectedItem() != kItemBriefcase && getInventory()->getSelectedItem() != kItemFirebird)
return kCursorForward;
- return (getObjects()->get(kObjectCompartment1).location2 < kObjectLocation2) ? kCursorNormal : kCursorMagnifier;
+ return (getObjects()->get(kObjectCompartment1).model < kObjectModel2) ? kCursorNormal : kCursorMagnifier;
case SceneHotspot::kActionSlip:
return (getProgress().field_C8 < 1) ? kCursorNormal : kCursorLeft;
@@ -1841,7 +1841,7 @@ CursorStyle Action::getCursor(const SceneHotspot &hotspot) const {
if (object != kObjectCompartment1)
return kCursorNormal;
- return (getObjects()->get(kObjectCeiling).location < kObjectLocation1) ? kCursorHand : kCursorNormal;
+ return (getObjects()->get(kObjectCeiling).status < kObjectLocation1) ? kCursorHand : kCursorNormal;
case SceneHotspot::kActionUnbound:
if (hotspot.param2 != 2)
@@ -1904,11 +1904,11 @@ LABEL_KEY:
if (getInventory()->getSelectedItem() != kItemKey
|| getObjects()->get(object).entity
- || getObjects()->get(object).location != 1
- || !getObjects()->get(object).cursor2
+ || getObjects()->get(object).status != 1
+ || !getObjects()->get(object).handleCursor
|| getEntities()->isInsideCompartments(kEntityPlayer)
|| getEntities()->checkFields2(object))
- return (CursorStyle)getObjects()->get(object).cursor2;
+ return (CursorStyle)getObjects()->get(object).handleCursor;
else
return (CursorStyle)getInventory()->get(kItemKey)->cursor;
}
diff --git a/engines/lastexpress/game/action.h b/engines/lastexpress/game/action.h
index e1a4a53224..3dad51d0d3 100644
--- a/engines/lastexpress/game/action.h
+++ b/engines/lastexpress/game/action.h
@@ -82,28 +82,28 @@ private:
DECLARE_ACTION(playSounds);
DECLARE_ACTION(playAnimation);
DECLARE_ACTION(openCloseObject);
- DECLARE_ACTION(updateObjetLocation2);
- DECLARE_ACTION(setItemLocation);
- DECLARE_ACTION(knockNoSound);
+ DECLARE_ACTION(setModel);
+ DECLARE_ACTION(setItem);
+ DECLARE_ACTION(knockInside);
DECLARE_ACTION(pickItem);
DECLARE_ACTION(dropItem);
DECLARE_ACTION(enterCompartment);
- DECLARE_ACTION(getOutsideTrain);
- DECLARE_ACTION(slip);
- DECLARE_ACTION(getInsideTrain);
- DECLARE_ACTION(climbUpTrain);
+ DECLARE_ACTION(leanOutWindow);
+ DECLARE_ACTION(almostFall);
+ DECLARE_ACTION(climbInWindow);
+ DECLARE_ACTION(climbLadder);
DECLARE_ACTION(climbDownTrain);
- DECLARE_ACTION(jumpUpDownTrain);
- DECLARE_ACTION(unbound);
- DECLARE_ACTION(25);
- DECLARE_ACTION(26);
+ DECLARE_ACTION(kronosSanctum);
+ DECLARE_ACTION(escapeBaggage);
+ DECLARE_ACTION(enterBaggage);
+ DECLARE_ACTION(bombPuzzle);
DECLARE_ACTION(27);
- DECLARE_ACTION(concertSitCough);
+ DECLARE_ACTION(kronosConcert);
DECLARE_ACTION(29);
DECLARE_ACTION(catchBeetle);
DECLARE_ACTION(exitCompartment);
- DECLARE_ACTION(32);
- DECLARE_ACTION(useWhistle);
+ DECLARE_ACTION(outsideTrain);
+ DECLARE_ACTION(firebirdPuzzle);
DECLARE_ACTION(openMatchBox);
DECLARE_ACTION(openBed);
DECLARE_ACTION(dialog);
diff --git a/engines/lastexpress/game/entities.h b/engines/lastexpress/game/entities.h
index 81aed627aa..cacbc408c9 100644
--- a/engines/lastexpress/game/entities.h
+++ b/engines/lastexpress/game/entities.h
@@ -110,7 +110,7 @@ public:
* Query if 'entity' is inside a compartment
*
* @param entity The entity.
- * @param car The car.
+ * @param car The car.
* @param position The position.
*
* @return true if inside the compartment, false if not.
@@ -247,7 +247,7 @@ public:
/**
* Query if nobody is in a compartment at that position.
*
- * @param car The car.
+ * @param car The car.
* @param position The position.
*
* @return true if nobody is in a compartment, false if not.
@@ -334,8 +334,8 @@ private:
static const int _compartmentsCount = 16;
static const int _positionsCount = 100 * 10; // 100 positions per train car
- LastExpressEngine *_engine;
- EntityData *_header;
+ LastExpressEngine *_engine;
+ EntityData *_header;
Common::Array<Entity *> _entities;
// Compartments & positions
diff --git a/engines/lastexpress/game/inventory.cpp b/engines/lastexpress/game/inventory.cpp
index 11e7369ee1..11a76a77f0 100644
--- a/engines/lastexpress/game/inventory.cpp
+++ b/engines/lastexpress/game/inventory.cpp
@@ -52,6 +52,8 @@ Inventory::Inventory(LastExpressEngine *engine) : _engine(engine), _selectedItem
_selectedItemRect = Common::Rect(44, 0, 76, 32);
init();
+
+ debug(9, "_showingHourGlass: %d", _showingHourGlass);
}
Inventory::~Inventory() {
@@ -95,19 +97,19 @@ void Inventory::init() {
_entries[kItemPassengerList].isSelectable = true;
// Auto selection
- _entries[kItem2].manualSelect = false;
- _entries[kItem3].manualSelect = false;
- _entries[kItem5].manualSelect = false;
- _entries[kItem7].manualSelect = false;
- _entries[kItem9].manualSelect = false;
- _entries[kItem11].manualSelect = false;
- _entries[kItemBeetle].manualSelect = false;
- _entries[kItem17].manualSelect = false;
- _entries[kItemFirebird].manualSelect = false;
- _entries[kItemBriefcase].manualSelect = false;
- _entries[kItemCorpse].manualSelect = false;
- _entries[kItemGreenJacket].manualSelect = false;
- _entries[kItem22].manualSelect = false;
+ _entries[kItem2].floating = false;
+ _entries[kItem3].floating = false;
+ _entries[kItem5].floating = false;
+ _entries[kItem7].floating = false;
+ _entries[kItem9].floating = false;
+ _entries[kItem11].floating = false;
+ _entries[kItemBeetle].floating = false;
+ _entries[kItem17].floating = false;
+ _entries[kItemFirebird].floating = false;
+ _entries[kItemBriefcase].floating = false;
+ _entries[kItemCorpse].floating = false;
+ _entries[kItemGreenJacket].floating = false;
+ _entries[kItem22].floating = false;
// Scene
_entries[kItemMatchBox].scene = kSceneMatchbox;
@@ -121,8 +123,8 @@ void Inventory::init() {
_entries[kItemBriefcase].scene = kSceneBriefcase;
// Has item
- _entries[kItemTelegram].isPresent = true;
- _entries[kItemArticle].isPresent = true;
+ _entries[kItemTelegram].inPocket = true;
+ _entries[kItemArticle].inPocket = true;
_selectedItem = kItemNone;
}
@@ -296,7 +298,7 @@ void Inventory::handleMouseEvent(const Common::Event &ev) {
getScenes()->loadScene(entry.scene);
}
- if (entry.field_2)
+ if (entry.usable)
selectItem((InventoryItem)index);
else
drawSelectedItem();
@@ -344,7 +346,7 @@ void Inventory::handleMouseEvent(const Common::Event &ev) {
if (!getProgress().field_84
&& getEntityData(kEntityPlayer)->location != kLocationOutsideTrain
&& getProgress().field_18 != 4
- && (_selectedItem == kItemNone || get(_selectedItem)->manualSelect || getState()->sceneUseBackup)) {
+ && (_selectedItem == kItemNone || get(_selectedItem)->floating || getState()->sceneUseBackup)) {
// Draw inventory contents when clicking on portrait
if (ev.type == Common::EVENT_LBUTTONDOWN) {
@@ -361,7 +363,7 @@ void Inventory::handleMouseEvent(const Common::Event &ev) {
close();
// Select item
- if (_selectedItem == kItemNone || get(_selectedItem)->manualSelect) {
+ if (_selectedItem == kItemNone || get(_selectedItem)->floating) {
_selectedItem = getFirstExaminableItem();
if (_selectedItem != kItemNone)
@@ -445,11 +447,11 @@ void Inventory::addItem(InventoryItem item) {
if (item >= kPortraitOriginal)
return;
- get(item)->isPresent = true;
+ get(item)->inPocket = true;
get(item)->location = kObjectLocationNone;
// Auto-select item if necessary
- if (get(item)->cursor && !get(item)->manualSelect) {
+ if (get(item)->cursor && !get(item)->floating) {
_selectedItem = item;
drawItem(get(_selectedItem)->cursor, 44, 0);
askForRedraw();
@@ -460,7 +462,7 @@ void Inventory::removeItem(InventoryItem item, ObjectLocation newLocation) {
if (item >= kPortraitOriginal)
return;
- get(item)->isPresent = false;
+ get(item)->inPocket = false;
get(item)->location = newLocation;
if (get(item)->cursor == get(_selectedItem)->cursor) {
@@ -471,7 +473,7 @@ void Inventory::removeItem(InventoryItem item, ObjectLocation newLocation) {
}
bool Inventory::hasItem(InventoryItem item) {
- if (get(item)->isPresent && item < kPortraitOriginal)
+ if (get(item)->inPocket && item < kPortraitOriginal)
return true;
return false;
@@ -535,7 +537,7 @@ InventoryItem Inventory::getFirstExaminableItem() const {
int index = 0;
InventoryEntry entry = _entries[index];
- while (!entry.isPresent || !entry.cursor || entry.manualSelect) {
+ while (!entry.inPocket || !entry.cursor || entry.floating) {
index++;
entry = _entries[index];
@@ -674,7 +676,7 @@ void Inventory::drawItem(CursorStyle id, uint16 x, uint16 y, int16 brightnessInd
void Inventory::drawSelectedItem() {
// Draw the selected item if any
- if (!_selectedItem || get(_selectedItem)->manualSelect) {
+ if (!_selectedItem || get(_selectedItem)->floating) {
_selectedItem = getFirstExaminableItem();
if (_selectedItem) {
@@ -701,10 +703,10 @@ void Inventory::open() {
// Draw at most 11 items in the inventory
_itemsShown = 0;
for (int i = 1; i < ARRAYSIZE(_entries); i++) {
- if (!_entries[i].isPresent)
+ if (!_entries[i].inPocket)
continue;
- if (!_entries[i].manualSelect)
+ if (!_entries[i].floating)
continue;
if (_itemsShown < 11) {
@@ -745,10 +747,10 @@ uint32 Inventory::getItemIndex(uint32 currentIndex) const {
uint32 count = 0;
for (uint32 i = 1; i < ARRAYSIZE(_entries); i++) {
- if (!_entries[i].isPresent)
+ if (!_entries[i].inPocket)
continue;
- if (!_entries[i].manualSelect)
+ if (!_entries[i].floating)
continue;
if (count < 11) {
diff --git a/engines/lastexpress/game/inventory.h b/engines/lastexpress/game/inventory.h
index b1019a43c6..242dfc30cc 100644
--- a/engines/lastexpress/game/inventory.h
+++ b/engines/lastexpress/game/inventory.h
@@ -56,33 +56,33 @@ public:
struct InventoryEntry : Common::Serializable {
CursorStyle cursor;
SceneIndex scene;
- byte field_2;
+ byte usable;
bool isSelectable;
- bool isPresent;
- bool manualSelect;
+ bool inPocket;
+ bool floating;
ObjectLocation location;
InventoryEntry() {
cursor = kCursorNormal;
scene = kSceneNone;
- field_2 = 0;
+ usable = 0;
isSelectable = false;
- isPresent = false;
- manualSelect = true;
+ inPocket = false;
+ floating = true;
location = kObjectLocationNone;
}
Common::String toString() {
- return Common::String::format("{ %d - %d - %d - %d - %d - %d - %d }", cursor, scene, field_2, isSelectable, isPresent, manualSelect, location);
+ return Common::String::format("{ %d - %d - %d - %d - %d - %d - %d }", cursor, scene, usable, isSelectable, inPocket, floating, location);
}
void saveLoadWithSerializer(Common::Serializer &s) {
s.syncAsByte(cursor);
s.syncAsByte(scene);
- s.syncAsByte(field_2);
+ s.syncAsByte(usable);
s.syncAsByte(isSelectable);
- s.syncAsByte(isPresent);
- s.syncAsByte(manualSelect);
+ s.syncAsByte(inPocket);
+ s.syncAsByte(floating);
s.syncAsByte(location);
}
};
diff --git a/engines/lastexpress/game/logic.cpp b/engines/lastexpress/game/logic.cpp
index 09104d1bf9..1a9c6b4123 100644
--- a/engines/lastexpress/game/logic.cpp
+++ b/engines/lastexpress/game/logic.cpp
@@ -413,8 +413,8 @@ void Logic::resetState() {
/**
* Handle game over
*
- * @param type The savegame type.
- * @param value The value (event, time, index, ...)
+ * @param type The savegame type.
+ * @param value The value (event, time, index, ...)
* @param sceneIndex Index of the scene to show.
* @param showScene true to show a scene, false to return to menu directly
*/
@@ -468,7 +468,7 @@ void Logic::switchChapter() const {
case kChapter3:
getInventory()->get(kItemFirebird)->location = kObjectLocation4;
- getInventory()->get(kItemFirebird)->isPresent = false;
+ getInventory()->get(kItemFirebird)->inPocket = false;
getInventory()->get(kItem11)->location = kObjectLocation1;
getInventory()->addItem(kItemWhistle);
getInventory()->addItem(kItemKey);
diff --git a/engines/lastexpress/game/logic.h b/engines/lastexpress/game/logic.h
index efb8f1e1a3..b2d08cb06f 100644
--- a/engines/lastexpress/game/logic.h
+++ b/engines/lastexpress/game/logic.h
@@ -54,7 +54,7 @@ public:
void playFinalSequence() const;
void updateCursor(bool redraw = true) const;
- Action *getGameAction() { return _action; }
+ Action *getGameAction() { return _action; }
Beetle *getGameBeetle() { return _beetle; }
Entities *getGameEntities() { return _entities; }
Fight *getGameFight() { return _fight; }
diff --git a/engines/lastexpress/game/object.cpp b/engines/lastexpress/game/object.cpp
index 48df91ea6d..ad13a65199 100644
--- a/engines/lastexpress/game/object.cpp
+++ b/engines/lastexpress/game/object.cpp
@@ -32,7 +32,7 @@
namespace LastExpress {
Common::String Objects::Object::toString() {
- return Common::String::format("{ %s - %d - %d - %d - %d }", ENTITY_NAME(entity), location, cursor, cursor2, location2);
+ return Common::String::format("{ %s - %d - %d - %d - %d }", ENTITY_NAME(entity), status, windowCursor, handleCursor, model);
}
Objects::Objects(LastExpressEngine *engine) : _engine(engine) {}
@@ -44,24 +44,24 @@ const Objects::Object Objects::get(ObjectIndex index) const {
return _objects[index];
}
-void Objects::update(ObjectIndex index, EntityIndex entity, ObjectLocation location, CursorStyle cursor, CursorStyle cursor2) {
+void Objects::update(ObjectIndex index, EntityIndex entity, ObjectLocation status, CursorStyle windowCursor, CursorStyle handleCursor) {
if (index >= kObjectMax)
return;
Object *object = &_objects[index];
// Store original location
- ObjectLocation original_location = object->location;
+ ObjectLocation original_status = object->status;
// Update entity
object->entity = entity;
- object->location = location;
+ object->status = status;
- if (cursor != kCursorKeepValue || cursor2 != kCursorKeepValue) {
- if (cursor != kCursorKeepValue)
- object->cursor = cursor;
- if (cursor2 != kCursorKeepValue)
- object->cursor2 = cursor2;
+ if (windowCursor != kCursorKeepValue || handleCursor != kCursorKeepValue) {
+ if (windowCursor != kCursorKeepValue)
+ object->windowCursor = windowCursor;
+ if (handleCursor != kCursorKeepValue)
+ object->handleCursor = handleCursor;
getLogic()->updateCursor();
}
@@ -69,18 +69,19 @@ void Objects::update(ObjectIndex index, EntityIndex entity, ObjectLocation locat
getFlags()->flag_3 = true;
// Compartments
- if (original_location != location && (original_location == kObjectLocation2 || location == kObjectLocation2))
+ if (original_status != status && (original_status == kObjectLocation2 || status == kObjectLocation2)) {
if ((index >= kObjectCompartment1 && index <= kObjectCompartment8)
- || (index >= kObjectCompartmentA && index <= kObjectCompartmentF)) {
- getScenes()->updateDoorsAndClock();
+ || (index >= kObjectCompartmentA && index <= kObjectCompartmentF)) {
+ getScenes()->updateDoorsAndClock();
}
+ }
}
-void Objects::updateLocation2(ObjectIndex index, ObjectLocation location2) {
+void Objects::updateModel(ObjectIndex index, ObjectModel model) {
if (index >= kObjectMax)
return;
- _objects[index].location2 = location2;
+ _objects[index].model = model;
}
//////////////////////////////////////////////////////////////////////////
diff --git a/engines/lastexpress/game/object.h b/engines/lastexpress/game/object.h
index 87c9d7d407..be9d63d6c5 100644
--- a/engines/lastexpress/game/object.h
+++ b/engines/lastexpress/game/object.h
@@ -37,17 +37,17 @@ public:
struct Object : Common::Serializable { // All fields should be saved as bytes
EntityIndex entity;
- ObjectLocation location;
- CursorStyle cursor;
- CursorStyle cursor2;
- ObjectLocation location2;
+ ObjectLocation status;
+ CursorStyle windowCursor;
+ CursorStyle handleCursor;
+ ObjectModel model;
Object() {
entity = kEntityPlayer;
- location = kObjectLocationNone;
- cursor = kCursorHandKnock;
- cursor2 = kCursorHandKnock;
- location2 = kObjectLocationNone;
+ status = kObjectLocationNone;
+ windowCursor = kCursorHandKnock;
+ handleCursor = kCursorHandKnock;
+ model = kObjectModelNone;
}
Common::String toString();
@@ -55,18 +55,18 @@ public:
// Serializable
void saveLoadWithSerializer(Common::Serializer &s) {
s.syncAsByte(entity);
- s.syncAsByte(location);
- s.syncAsByte(cursor);
- s.syncAsByte(cursor2);
- s.syncAsByte(location2);
+ s.syncAsByte(status);
+ s.syncAsByte(windowCursor);
+ s.syncAsByte(handleCursor);
+ s.syncAsByte(model);
}
};
Objects(LastExpressEngine *engine);
const Object get(ObjectIndex index) const;
- void update(ObjectIndex index, EntityIndex entity, ObjectLocation location, CursorStyle cursor, CursorStyle cursor2);
- void updateLocation2(ObjectIndex index, ObjectLocation location2);
+ void update(ObjectIndex index, EntityIndex entity, ObjectLocation status, CursorStyle cursor, CursorStyle cursor2);
+ void updateModel(ObjectIndex index, ObjectModel model);
// Serializable
void saveLoadWithSerializer(Common::Serializer &s);
diff --git a/engines/lastexpress/game/savegame.h b/engines/lastexpress/game/savegame.h
index 361957227e..7e8095fde1 100644
--- a/engines/lastexpress/game/savegame.h
+++ b/engines/lastexpress/game/savegame.h
@@ -40,32 +40,32 @@
Game data Format
-----------------
- uint32 {4} - entity
- uint32 {4} - current time
- uint32 {4} - time delta (how much a tick is in "real" time)
- uint32 {4} - time ticks
- uint32 {4} - scene Index max: 2500
- byte {1} - use backup scene
- uint32 {4} - backup Scene Index 1 max: 2500
- uint32 {4} - backup Scene Index 2 max: 2500
- uint32 {4} - selected inventory item max: 32
- uint32 {4*100*10} - positions (by car)
- uint32 {4*16} - compartments
- uint32 {4*16} - compartments ??
- uint32 {4*128} - game progress
- byte {512} - game events
- byte {7*32} - inventory
- byte {5*128} - objects
- byte {1262*40} - entities (characters and train entities)
-
- uint32 {4} - sound queue state
- uint32 {4} - ??
- uint32 {4} - number of sound entries
- byte {count*68} - sound entries
-
- byte {16*128} - save point data
- uint32 {4} - number of save points (max: 128)
- byte {count*16} - save points
+ uint32 {4} - entity
+ uint32 {4} - current time
+ uint32 {4} - time delta (how much a tick is in "real" time)
+ uint32 {4} - time ticks
+ uint32 {4} - scene Index max: 2500
+ byte {1} - use backup scene
+ uint32 {4} - backup Scene Index 1 max: 2500
+ uint32 {4} - backup Scene Index 2 max: 2500
+ uint32 {4} - selected inventory item max: 32
+ uint32 {4*100*10} - positions by car(BlockedView)
+ uint32 {4*16} - compartments (BlockedX)
+ uint32 {4*16} - compartments? (SoftBlockedX)
+ uint32 {4*128} - game progress
+ byte {512} - game events
+ byte {7*32} - inventory
+ byte {5*128} - objects
+ byte {1262*40} - entities (characters and train entities)
+
+ uint32 {4} - sound queue state
+ uint32 {4} - ??
+ uint32 {4} - number of sound entries
+ byte {count*68} - sound entries
+
+ byte {16*128} - save point data
+ uint32 {4} - number of save points (max: 128)
+ byte {count*16} - save points
... more unknown stuff
@@ -167,7 +167,7 @@ public:
bool isGameFinished(uint32 menuIndex, uint32 savegameIndex);
// Accessors
- uint32 getTime(uint32 index) { return getEntry(index)->time; }
+ uint32 getTime(uint32 index) { return getEntry(index)->time; }
ChapterIndex getChapter(uint32 index) { return getEntry(index)->chapter; }
uint32 getValue(uint32 index) { return getEntry(index)->value; }
uint32 getLastSavegameTicks() const { return _gameTicksLastSavegame; }
diff --git a/engines/lastexpress/game/scenes.cpp b/engines/lastexpress/game/scenes.cpp
index 82688fff2e..0d8f51af6e 100644
--- a/engines/lastexpress/game/scenes.cpp
+++ b/engines/lastexpress/game/scenes.cpp
@@ -579,7 +579,7 @@ void SceneManager::updateDoorsAndClock() {
for (ObjectIndex index = firstIndex; index < (ObjectIndex)(firstIndex + 8); index = (ObjectIndex)(index + 1)) {
// Doors is not open, nothing to do
- if (getObjects()->get(index).location != kObjectLocation2)
+ if (getObjects()->get(index).status != kObjectLocation2)
continue;
// Load door sequence
@@ -842,11 +842,11 @@ void SceneManager::preProcessScene(SceneIndex *index) {
if (object >= kObjectMax)
break;
- if (getObjects()->get(object).location == kObjectLocationNone)
+ if (getObjects()->get(object).status == kObjectLocationNone)
break;
for (Common::Array<SceneHotspot *>::iterator it = scene->getHotspots()->begin(); it != scene->getHotspots()->end(); ++it) {
- if (getObjects()->get(object).location != (*it)->location)
+ if (getObjects()->get(object).status != (*it)->location)
continue;
PROCESS_HOTSPOT_SCENE(*it, index);
@@ -920,7 +920,7 @@ void SceneManager::preProcessScene(SceneIndex *index) {
int location = kObjectLocationNone;
- if (getObjects()->get(object).location == kObjectLocation2)
+ if (getObjects()->get(object).status == kObjectLocation2)
location = kObjectLocation1;
if (getInventory()->get(item)->location != kObjectLocationNone)
@@ -933,7 +933,7 @@ void SceneManager::preProcessScene(SceneIndex *index) {
if (location != (*it)->location)
continue;
- if (getObjects()->get(object).location != (*it)->param1)
+ if (getObjects()->get(object).status != (*it)->param1)
continue;
if (getInventory()->get(item)->location != (*it)->param2)
@@ -994,7 +994,7 @@ void SceneManager::preProcessScene(SceneIndex *index) {
bool found = false;
for (Common::Array<SceneHotspot *>::iterator it = scene->getHotspots()->begin(); it != scene->getHotspots()->end(); ++it) {
- if (getObjects()->get(object).location2 != (*it)->location)
+ if (getObjects()->get(object).model != (*it)->location)
continue;
PROCESS_HOTSPOT_SCENE(*it, index);
diff --git a/engines/lastexpress/game/state.h b/engines/lastexpress/game/state.h
index 944f6d47b1..83d528d346 100644
--- a/engines/lastexpress/game/state.h
+++ b/engines/lastexpress/game/state.h
@@ -657,12 +657,12 @@ private:
// Timer
int _timer;
- Flags *_flags; ///< Flags
- Inventory *_inventory; ///< Inventory
- Objects *_objects; ///< Objects
- SavePoints *_savepoints; ///< SavePoints
- GameState *_state; ///< State
- Common::Point _coords; ///< Current coordinates
+ Flags *_flags; ///< Flags
+ Inventory *_inventory; ///< Inventory
+ Objects *_objects; ///< Objects
+ SavePoints *_savepoints; ///< SavePoints
+ GameState *_state; ///< State
+ Common::Point _coords; ///< Current coordinates
};
} // End of namespace LastExpress
diff --git a/engines/lastexpress/shared.h b/engines/lastexpress/shared.h
index 56cf730e24..dae7928043 100644
--- a/engines/lastexpress/shared.h
+++ b/engines/lastexpress/shared.h
@@ -755,7 +755,7 @@ enum ClothesIndex {
};
//////////////////////////////////////////////////////////////////////////
-// Location of objects
+// Objects (doors)
//////////////////////////////////////////////////////////////////////////
enum ObjectLocation {
kObjectLocationNone = 0,
@@ -763,13 +763,27 @@ enum ObjectLocation {
kObjectLocation2 = 2, // Bed ?
kObjectLocation3 = 3,
kObjectLocation4 = 4, // Window ?
- kObjectLocation5 = 5,
- kObjectLocation6 = 6,
- kObjectLocation7 = 7,
- kObjectLocation8 = 8,
- kObjectLocation9 = 9,
- kObjectLocation10 = 10,
- kObjectLocation18 = 18
+ kObjectLocation5 = 5,
+ kObjectLocation6 = 6,
+ kObjectLocation7 = 7,
+ kObjectLocation8 = 8,
+ kObjectLocation9 = 9,
+ kObjectLocation10 = 10,
+ kObjectLocation18 = 18
+};
+
+enum ObjectModel {
+ kObjectModelNone = 0,
+ kObjectModel1 = 1,
+ kObjectModel2 = 2,
+ kObjectModel3 = 3,
+ kObjectModel4 = 4,
+ kObjectModel5 = 5,
+ kObjectModel6 = 6,
+ kObjectModel7 = 7,
+ kObjectModel8 = 8,
+ kObjectModel9 = 9,
+ kObjectModel10 = 10
};
//////////////////////////////////////////////////////////////////////////
diff --git a/engines/lastexpress/sound/sound.cpp b/engines/lastexpress/sound/sound.cpp
index 319f7cd4f4..ad61c2e0d9 100644
--- a/engines/lastexpress/sound/sound.cpp
+++ b/engines/lastexpress/sound/sound.cpp
@@ -1323,7 +1323,7 @@ void SoundManager::playLoopingSound(int param) {
break;
if (getEntities()->isInsideCompartment(kEntityPlayer, getEntityData(kEntityPlayer)->car, positions[pos])) {
numLoops[0] = 1;
- partNumber = (getObjects()->get((ObjectIndex)objNum).location - 2) < 1 ? 6 : 1;
+ partNumber = (getObjects()->get((ObjectIndex)objNum).status - 2) < 1 ? 6 : 1;
}
objNum++;
}
diff --git a/engines/lure/configure.engine b/engines/lure/configure.engine
new file mode 100644
index 0000000000..e9f92893e3
--- /dev/null
+++ b/engines/lure/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 lure "Lure of the Temptress" yes
diff --git a/engines/made/configure.engine b/engines/made/configure.engine
new file mode 100644
index 0000000000..2266712338
--- /dev/null
+++ b/engines/made/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 made "MADE" yes
diff --git a/engines/made/detection.cpp b/engines/made/detection.cpp
index e8b755cb40..c2c866ff34 100644
--- a/engines/made/detection.cpp
+++ b/engines/made/detection.cpp
@@ -211,77 +211,77 @@ static const MadeGameDescription gameDescriptions[] = {
3,
},
- {
- // Return to Zork - Italian CD version 1.2 3/31/95 (installed)
+ {
+ // Return to Zork - Italian CD version 1.2 3/31/95 (installed)
// Patch #2685032 submitted by goodoldgeorg
- {
- "rtz",
- "V1.2, 3/31/95, installed, CD",
- AD_ENTRY1s("rtzcd.dat", "5b86035aed0277f96e3d173542b5364a", 523776),
- Common::IT_ITA,
- Common::kPlatformDOS,
+ {
+ "rtz",
+ "V1.2, 3/31/95, installed, CD",
+ AD_ENTRY1s("rtzcd.dat", "5b86035aed0277f96e3d173542b5364a", 523776),
+ Common::IT_ITA,
+ Common::kPlatformDOS,
ADGF_CD,
GUIO0()
- },
- GID_RTZ,
- 0,
- GF_CD,
- 3,
- },
+ },
+ GID_RTZ,
+ 0,
+ GF_CD,
+ 3,
+ },
{
- // Return to Zork - Italian CD version 1.2 3/31/95
+ // Return to Zork - Italian CD version 1.2 3/31/95
// Patch #2685032 submitted by goodoldgeorg
- {
- "rtz",
- "V1.2, 3/31/95, CD",
- AD_ENTRY1s("rtzcd.red", "946997d8b0aa6cb4e848bad02a1fc3d2", 354971),
- Common::IT_ITA,
- Common::kPlatformDOS,
+ {
+ "rtz",
+ "V1.2, 3/31/95, CD",
+ AD_ENTRY1s("rtzcd.red", "946997d8b0aa6cb4e848bad02a1fc3d2", 354971),
+ Common::IT_ITA,
+ Common::kPlatformDOS,
ADGF_CD,
GUIO0()
- },
- GID_RTZ,
- 0,
- GF_CD_COMPRESSED,
- 3,
- },
-
- {
- // Return to Zork - French CD version 1.2 5/13/95 (installed)
+ },
+ GID_RTZ,
+ 0,
+ GF_CD_COMPRESSED,
+ 3,
+ },
+
+ {
+ // Return to Zork - French CD version 1.2 5/13/95 (installed)
// Patch #2685032 submitted by goodoldgeorg
- {
- "rtz",
- "V1.2, 5/13/95, installed, CD",
- AD_ENTRY1s("rtzcd.dat", "bde8251a8e34e87c54e3f93147d56c9e", 523776),
- Common::FR_FRA,
- Common::kPlatformDOS,
+ {
+ "rtz",
+ "V1.2, 5/13/95, installed, CD",
+ AD_ENTRY1s("rtzcd.dat", "bde8251a8e34e87c54e3f93147d56c9e", 523776),
+ Common::FR_FRA,
+ Common::kPlatformDOS,
ADGF_CD,
GUIO0()
- },
- GID_RTZ,
- 0,
- GF_CD,
- 3,
- },
-
- {
- // Return to Zork - French CD version 1.2 5/13/95
+ },
+ GID_RTZ,
+ 0,
+ GF_CD,
+ 3,
+ },
+
+ {
+ // Return to Zork - French CD version 1.2 5/13/95
// Patch #2685032 submitted by goodoldgeorg
- {
- "rtz",
- "V1.2, 3/31/95, CD",
- AD_ENTRY1s("rtzcd.red", "946997d8b0aa6cb4e848bad02a1fc3d2", 354614),
- Common::FR_FRA,
- Common::kPlatformDOS,
+ {
+ "rtz",
+ "V1.2, 3/31/95, CD",
+ AD_ENTRY1s("rtzcd.red", "946997d8b0aa6cb4e848bad02a1fc3d2", 354614),
+ Common::FR_FRA,
+ Common::kPlatformDOS,
ADGF_CD,
GUIO0()
- },
- GID_RTZ,
- 0,
- GF_CD_COMPRESSED,
- 3,
- },
+ },
+ GID_RTZ,
+ 0,
+ GF_CD_COMPRESSED,
+ 3,
+ },
{
// Return to Zork - English floppy version
diff --git a/engines/made/made.cpp b/engines/made/made.cpp
index 3843040961..3e192cb04c 100644
--- a/engines/made/made.cpp
+++ b/engines/made/made.cpp
@@ -85,7 +85,7 @@ MadeEngine::MadeEngine(OSystem *syst, const MadeGameDescription *gameDesc) : Eng
_script = new ScriptInterpreter(this);
- _music = new MusicPlayer();
+ _music = nullptr;
// Set default sound frequency
switch (getGameID()) {
@@ -102,8 +102,6 @@ MadeEngine::MadeEngine(OSystem *syst, const MadeGameDescription *gameDesc) : Eng
// Return to Zork sets it itself via a script funtion
break;
}
-
- syncSoundSettings();
}
MadeEngine::~MadeEngine() {
@@ -277,6 +275,8 @@ void MadeEngine::handleEvents() {
}
Common::Error MadeEngine::run() {
+ _music = new MusicPlayer();
+ syncSoundSettings();
// Initialize backend
initGraphics(320, 200, false);
diff --git a/engines/made/screenfx.cpp b/engines/made/screenfx.cpp
index d069308a4b..b89b3af802 100644
--- a/engines/made/screenfx.cpp
+++ b/engines/made/screenfx.cpp
@@ -165,7 +165,7 @@ void ScreenEffects::flash(int flashCount, byte *palette, int colorCount) {
_screen->setRGBPalette(_fxPalette, 0, colorCount);
_screen->updateScreenAndWait(20);
_screen->setRGBPalette(palette, 0, colorCount);
- _screen->updateScreenAndWait(20);
+ _screen->updateScreenAndWait(20);
}
}
diff --git a/engines/made/sound.cpp b/engines/made/sound.cpp
index f73c580560..176f8688bd 100644
--- a/engines/made/sound.cpp
+++ b/engines/made/sound.cpp
@@ -228,7 +228,7 @@ void decompressSound(byte *source, byte *dest, uint16 chunkSize, uint16 chunkCou
break;
default:
- return;
+ return;
}
diff --git a/engines/mohawk/configure.engine b/engines/mohawk/configure.engine
new file mode 100644
index 0000000000..fa9d15cffc
--- /dev/null
+++ b/engines/mohawk/configure.engine
@@ -0,0 +1,6 @@
+# This file is included from the main "configure" script
+# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps]
+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"
diff --git a/engines/mohawk/cstime.cpp b/engines/mohawk/cstime.cpp
index 3f9827581b..0f69d50a22 100644
--- a/engines/mohawk/cstime.cpp
+++ b/engines/mohawk/cstime.cpp
@@ -51,6 +51,15 @@ MohawkEngine_CSTime::MohawkEngine_CSTime(OSystem *syst, const MohawkGameDescript
_state = kCSTStateStartup;
reset();
+
+ _console = 0;
+ _gfx = 0;
+ _cursor = 0;
+ _interface = 0;
+ _view = 0;
+ _needsUpdate = false;
+ _case = 0;
+ _nextSceneId = 1;
}
MohawkEngine_CSTime::~MohawkEngine_CSTime() {
diff --git a/engines/mohawk/cstime_game.cpp b/engines/mohawk/cstime_game.cpp
index 2e21111025..91d2f895c0 100644
--- a/engines/mohawk/cstime_game.cpp
+++ b/engines/mohawk/cstime_game.cpp
@@ -1094,7 +1094,7 @@ void CSTimeScene::idleAmbientAnims() {
bool CSTimeScene::eventIsActive() {
return _vm->NISIsRunning() /* TODO || _vm->soundIsPlaying()*/ || _vm->getCurrentEventType() == kCSTimeEventWaitForClick
- || _activeChar->_flappingState != 0xffff || _vm->getInterface()->getState() == 4;
+ || _activeChar->_flappingState != 0xffff || _vm->getInterface()->getState() == kCSTimeInterfaceDroppedInventory;
}
void CSTimeScene::cursorOverHotspot(uint id) {
diff --git a/engines/mohawk/cstime_ui.cpp b/engines/mohawk/cstime_ui.cpp
index de7d5bde80..6d5e5dd3ef 100644
--- a/engines/mohawk/cstime_ui.cpp
+++ b/engines/mohawk/cstime_ui.cpp
@@ -854,7 +854,7 @@ void CSTimeInterface::dropItemInInventory(uint16 id) {
clearDialogArea();
_inventoryDisplay->show();
_inventoryDisplay->draw();
- _inventoryDisplay->setState(4);
+ _inventoryDisplay->setState(kCSTimeInterfaceDroppedInventory);
}
CSTimeHelp::CSTimeHelp(MohawkEngine_CSTime *vm) : _vm(vm) {
diff --git a/engines/mohawk/cstime_ui.h b/engines/mohawk/cstime_ui.h
index 27df7cac3e..3154d4b2ef 100644
--- a/engines/mohawk/cstime_ui.h
+++ b/engines/mohawk/cstime_ui.h
@@ -167,7 +167,8 @@ protected:
enum CSTimeInterfaceState {
kCSTimeInterfaceStateNormal = 1,
kCSTimeInterfaceStateDragStart = 2,
- kCSTimeInterfaceStateDragging = 3
+ kCSTimeInterfaceStateDragging = 3,
+ kCSTimeInterfaceDroppedInventory = 4
};
class CSTimeInterface {
diff --git a/engines/mortevielle/actions.cpp b/engines/mortevielle/actions.cpp
index b68dd48b0f..c5d55066ba 100644
--- a/engines/mortevielle/actions.cpp
+++ b/engines/mortevielle/actions.cpp
@@ -40,7 +40,7 @@ namespace Mortevielle {
* @remarks Originally called 'taller'
*/
void MortevielleEngine::fctMove() {
- int oldMenu = (_menu._moveMenu[6]._menuId << 8) | _menu._moveMenu[6]._actionId;
+ int oldMenu = (_menu->_moveMenu[6]._menuId << 8) | _menu->_moveMenu[6]._actionId;
if ((_coreVar._currPlace == ROOM26) && (_currAction == oldMenu)) {
_coreVar._currPlace = LANDING;
_caff = _coreVar._currPlace;
@@ -65,10 +65,10 @@ void MortevielleEngine::fctMove() {
if (_num == 1) {
_coreVar._currPlace = OWN_ROOM;
- _menu.setDestinationText(OWN_ROOM);
+ _menu->setDestinationText(OWN_ROOM);
} else if (_num == 7) {
_coreVar._currPlace = ATTIC;
- _menu.setDestinationText(ATTIC);
+ _menu->setDestinationText(ATTIC);
} else if (_num != 6)
_coreVar._currPlace = ROOM26;
@@ -85,10 +85,10 @@ void MortevielleEngine::fctMove() {
}
exitRoom();
int menuChoice = 1;
- oldMenu = (_menu._moveMenu[menuChoice]._menuId << 8) | _menu._moveMenu[menuChoice]._actionId;
+ oldMenu = (_menu->_moveMenu[menuChoice]._menuId << 8) | _menu->_moveMenu[menuChoice]._actionId;
while (oldMenu != _currAction) {
++menuChoice;
- oldMenu = (_menu._moveMenu[menuChoice]._menuId << 8) | _menu._moveMenu[menuChoice]._actionId;
+ oldMenu = (_menu->_moveMenu[menuChoice]._menuId << 8) | _menu->_moveMenu[menuChoice]._actionId;
}
switch (_coreVar._currPlace) {
@@ -97,14 +97,14 @@ void MortevielleEngine::fctMove() {
gotoManorFront();
else if (menuChoice == 2)
checkManorDistance();
- _menu.setDestinationText(_coreVar._currPlace);
+ _menu->setDestinationText(_coreVar._currPlace);
return;
case INSIDE_WELL:
if (menuChoice == 1)
floodedInWell();
else if (menuChoice == 2)
gotoManorBack();
- _menu.setDestinationText(_coreVar._currPlace);
+ _menu->setDestinationText(_coreVar._currPlace);
return;
case BUREAU:
if (menuChoice == 1)
@@ -193,7 +193,7 @@ void MortevielleEngine::fctMove() {
if ((menuChoice < 5) || (menuChoice == 13) || (menuChoice == 14))
prepareDisplayText();
resetRoomVariables(_coreVar._currPlace);
- _menu.setDestinationText(_coreVar._currPlace);
+ _menu->setDestinationText(_coreVar._currPlace);
}
/**
@@ -208,23 +208,32 @@ void MortevielleEngine::fctTake() {
if (_currBitIndex > 0)
_coreVar._faithScore += 3;
if (_obpart) {
- if (_coreVar._currPlace == PURPLE_ROOM)
+ switch (_coreVar._currPlace) {
+ case PURPLE_ROOM:
_coreVar._purpleRoomObjectId = 0;
- if (_coreVar._currPlace == ATTIC) {
+ break;
+ case ATTIC:
if (_coreVar._atticBallHoleObjectId == _caff)
_coreVar._atticBallHoleObjectId = 0;
if (_coreVar._atticRodHoleObjectId == _caff)
_coreVar._atticRodHoleObjectId = 0;
- }
- if (_coreVar._currPlace == CELLAR)
+ break;
+ case CELLAR:
_coreVar._cellarObjectId = 0;
- if (_coreVar._currPlace == CRYPT)
+ break;
+ case CRYPT:
_coreVar._cryptObjectId = 0;
- if (_coreVar._currPlace == SECRET_PASSAGE)
+ break;
+ case SECRET_PASSAGE:
_coreVar._secretPassageObjectId = 0;
- if (_coreVar._currPlace == WELL)
+ break;
+ case WELL:
_coreVar._wellObjectId = 0;
- _menu.unsetSearchMenu();
+ break;
+ default:
+ break;
+ }
+ _menu->unsetSearchMenu();
_obpart = false;
prepareDisplayText();
} else {
@@ -258,38 +267,54 @@ void MortevielleEngine::fctTake() {
if (_currBitIndex > 0)
_coreVar._faithScore += 3;
_crep = 997;
- if ((_coreVar._currPlace == PURPLE_ROOM) && (_coreVar._purpleRoomObjectId != 0))
- putInHand(_coreVar._purpleRoomObjectId);
- if ((_coreVar._currPlace == ATTIC) && (_num == 1) && (_coreVar._atticBallHoleObjectId != 0)) {
- putInHand(_coreVar._atticBallHoleObjectId);
- if ((_crep != 997) && (_crep != 139))
- displayAnimFrame(2, 7);
- }
- if ((_coreVar._currPlace == ATTIC) && (_num == 2) && (_coreVar._atticRodHoleObjectId != 0)) {
- putInHand(_coreVar._atticRodHoleObjectId);
- if ((_crep != 997) && (_crep != 139))
- displayAnimFrame(2, 6);
- }
- if ((_coreVar._currPlace == CELLAR) && (_coreVar._cellarObjectId != 0)) {
- putInHand(_coreVar._cellarObjectId);
- if ((_crep != 997) && (_crep != 139))
- displayAnimFrame(2, 2);
- }
- if ((_coreVar._currPlace == CRYPT) && (_coreVar._cryptObjectId != 0))
- putInHand(_coreVar._cryptObjectId);
-
- if ((_coreVar._currPlace == SECRET_PASSAGE) && (_coreVar._secretPassageObjectId != 0)) {
- putInHand(_coreVar._secretPassageObjectId);
- if ((_crep != 997) && (_crep != 139)) {
- _crep = 182;
- displayAnimFrame(2, 1);
+
+ switch (_coreVar._currPlace) {
+ case PURPLE_ROOM:
+ if (_coreVar._purpleRoomObjectId != 0)
+ putInHand(_coreVar._purpleRoomObjectId);
+ break;
+ case ATTIC:
+ if ((_num == 1) && (_coreVar._atticBallHoleObjectId != 0)) {
+ putInHand(_coreVar._atticBallHoleObjectId);
+ if ((_crep != 997) && (_crep != 139))
+ displayAnimFrame(2, 7);
+ } else if ((_num == 2) && (_coreVar._atticRodHoleObjectId != 0)) {
+ putInHand(_coreVar._atticRodHoleObjectId);
+ if ((_crep != 997) && (_crep != 139))
+ displayAnimFrame(2, 6);
}
+ break;
+ case CELLAR:
+ if (_coreVar._cellarObjectId != 0) {
+ putInHand(_coreVar._cellarObjectId);
+ if ((_crep != 997) && (_crep != 139))
+ displayAnimFrame(2, 2);
+ }
+ break;
+ case CRYPT:
+ if (_coreVar._cryptObjectId != 0)
+ putInHand(_coreVar._cryptObjectId);
+ break;
+ case SECRET_PASSAGE:
+ if (_coreVar._secretPassageObjectId != 0) {
+ putInHand(_coreVar._secretPassageObjectId);
+ if ((_crep != 997) && (_crep != 139)) {
+ _crep = 182;
+ displayAnimFrame(2, 1);
+ }
+ }
+ break;
+ case WELL:
+ if (_coreVar._wellObjectId != 0) {
+ putInHand(_coreVar._wellObjectId);
+ if ((_crep != 997) && (_crep != 139))
+ displayAnimFrame(2, 1);
+ }
+ break;
+ default:
+ break;
}
- if ((_coreVar._currPlace == WELL) && (_coreVar._wellObjectId != 0)) {
- putInHand(_coreVar._wellObjectId);
- if ((_crep != 997) && (_crep != 139))
- displayAnimFrame(2, 1);
- }
+
if ((_crep != 997) && (_crep != 182) && (_crep != 139))
_crep = 999;
}
@@ -325,7 +350,7 @@ void MortevielleEngine::fctInventoryTake() {
int oldMenu = 0;
do {
++inventIndex;
- oldMenu = (_menu._inventoryMenu[inventIndex]._menuId << 8) | _menu._inventoryMenu[inventIndex]._actionId;
+ oldMenu = (_menu->_inventoryMenu[inventIndex]._menuId << 8) | _menu->_inventoryMenu[inventIndex]._actionId;
} while (oldMenu != _currAction);
int cz = 0;
int cy = 0;
@@ -336,7 +361,7 @@ void MortevielleEngine::fctInventoryTake() {
} while (cz != inventIndex);
cz = _coreVar._inventory[cy];
_coreVar._inventory[cy] = 0;
- _menu.setInventoryText();
+ _menu->setInventoryText();
putInHand(cz);
_crep = 998;
clearDescriptionBar();
@@ -536,7 +561,7 @@ void MortevielleEngine::fctSearch() {
if (_curSearchObjId != 0) {
_searchCount = 0;
_heroSearching = true;
- _menu.setSearchMenu();
+ _menu->setSearchMenu();
prepareNextObject();
} else
_crep = 997;
@@ -607,7 +632,7 @@ void MortevielleEngine::fctOpen() {
if (_caff == ROOM26) {
if (_roomDoorId != OWN_ROOM) {
- _currAction = _menu._opcodeEnter;
+ _currAction = _menu->_opcodeEnter;
_syn = true;
} else
_crep = 997;
@@ -663,11 +688,11 @@ void MortevielleEngine::fctOpen() {
|| (_coreVar._currPlace == PURPLE_ROOM)
|| (_coreVar._currPlace == BLUE_ROOM)) {
if (getRandomNumber(1, 4) == 3)
- _soundManager.startSpeech(7, 9, 1);
+ _soundManager->startSpeech(7, 9, 1);
}
_openObjects[i] = _num;
displayAnimFrame(1, _num);
- _soundManager.waitSpeech();
+ _soundManager->waitSpeech();
}
int tmpPlace = _coreVar._currPlace;
if (_coreVar._currPlace == CRYPT)
@@ -731,21 +756,21 @@ void MortevielleEngine::fctPlace() {
displayAnimFrame(1, 1);
handleDescriptionText(2, 165);
displayEmptyHand();
- _soundManager.startSpeech(6, -9, 1);
+ _soundManager->startSpeech(6, -9, 1);
// Do you want to enter the hidden passage?
- int answer = _dialogManager.show(getEngineString(S_YES_NO));
+ int answer = _dialogManager->show(getEngineString(S_YES_NO));
if (answer == 1) {
Common::String alertTxt = getString(582);
- _dialogManager.show(alertTxt);
+ _dialogManager->show(alertTxt);
- bool enterPassageFl = _dialogManager.showKnowledgeCheck();
- _mouse.hideMouse();
+ bool enterPassageFl = _dialogManager->showKnowledgeCheck();
+ _mouse->hideMouse();
clearScreen();
drawRightFrame();
clearDescriptionBar();
clearVerbBar();
- _mouse.showMouse();
+ _mouse->showMouse();
prepareRoom();
drawClock();
if (_currBitIndex != 0)
@@ -753,18 +778,18 @@ void MortevielleEngine::fctPlace() {
else
displayAloneText();
- _menu.displayMenu();
+ _menu->displayMenu();
if (enterPassageFl) {
_coreVar._currPlace = SECRET_PASSAGE;
- _menu.setDestinationText(SECRET_PASSAGE);
+ _menu->setDestinationText(SECRET_PASSAGE);
} else {
- _menu.setDestinationText(_coreVar._currPlace);
+ _menu->setDestinationText(_coreVar._currPlace);
setPal(14);
drawPicture();
displayAnimFrame(1, 2);
displayAnimFrame(1, 1);
alertTxt = getString(577);
- _dialogManager.show(alertTxt);
+ _dialogManager->show(alertTxt);
displayAnimFrame(2, 1);
_crep = 166;
}
@@ -832,8 +857,8 @@ void MortevielleEngine::fctTurn() {
_crep = 997;
if ((_coreVar._currPlace == ATTIC) && (_coreVar._atticRodHoleObjectId == 159) && (_coreVar._atticBallHoleObjectId == 141)) {
handleDescriptionText(2, 167);
- _soundManager.startSpeech(7, 9, 1);
- int answer = _dialogManager.show(getEngineString(S_YES_NO));
+ _soundManager->startSpeech(7, 9, 1);
+ int answer = _dialogManager->show(getEngineString(S_YES_NO));
if (answer == 1)
_endGame = true;
else
@@ -842,8 +867,8 @@ void MortevielleEngine::fctTurn() {
if ((_coreVar._currPlace == SECRET_PASSAGE) && (_coreVar._secretPassageObjectId == 143)) {
handleDescriptionText(2, 175);
clearVerbBar();
- _soundManager.startSpeech(6, -9, 1);
- int answer = _dialogManager.show(getEngineString(S_YES_NO));
+ _soundManager->startSpeech(6, -9, 1);
+ int answer = _dialogManager->show(getEngineString(S_YES_NO));
if (answer == 1) {
_coreVar._currPlace = CRYPT;
prepareDisplayText();
@@ -949,7 +974,7 @@ void MortevielleEngine::fctKnock() {
displayTextInVerbBar(getEngineString(S_HIT));
if (_coreVar._currPlace == LANDING) {
- _dialogManager.show(getEngineString(S_BEFORE_USE_DEP_MENU));
+ _dialogManager->show(getEngineString(S_BEFORE_USE_DEP_MENU));
return;
}
@@ -967,7 +992,7 @@ void MortevielleEngine::fctKnock() {
if (_coreVar._currPlace == ROOM26) {
int rand = (getRandomNumber(0, 8)) - 4;
- _soundManager.startSpeech(11, rand, 1);
+ _soundManager->startSpeech(11, rand, 1);
int pres = getPresenceStats(rand, _coreVar._faithScore, _roomDoorId);
if (_roomDoorId != OWN_ROOM) {
if (pres != -500) {
@@ -1132,7 +1157,7 @@ void MortevielleEngine::fctEat() {
_coreVar._currPlace = DINING_ROOM;
_caff = DINING_ROOM;
resetRoomVariables(_coreVar._currPlace);
- _menu.setDestinationText(_coreVar._currPlace);
+ _menu->setDestinationText(_coreVar._currPlace);
int day, hour, minute;
updateHour(day, hour, minute);
@@ -1168,7 +1193,7 @@ void MortevielleEngine::fctEat() {
void MortevielleEngine::fctEnter() {
if ((_coreVar._currPlace == MANOR_FRONT) || (_coreVar._currPlace == MANOR_BACK)) {
gotoDiningRoom();
- _menu.setDestinationText(_coreVar._currPlace);
+ _menu->setDestinationText(_coreVar._currPlace);
} else if (_coreVar._currPlace == LANDING)
showMoveMenuAlert();
else if (_roomDoorId == OWN_ROOM)
@@ -1178,22 +1203,22 @@ void MortevielleEngine::fctEnter() {
_coreVar._availableQuestion[8] = '*';
} else {
int pres = 0;
- if (!_blo)
+ if (!_outsideOnlyFl)
pres = getPresence(_roomDoorId);
if (pres != 0) {
if ((_roomDoorId == TOILETS) || (_roomDoorId == BATHROOM))
_crep = 179;
else {
int randVal = (getRandomNumber(0, 10)) - 5;
- _soundManager.startSpeech(7, randVal, 1);
+ _soundManager->startSpeech(7, randVal, 1);
displayAnimFrame(1, 1);
- _soundManager.waitSpeech();
+ _soundManager->waitSpeech();
int charIndex = convertBitIndexToCharacterIndex(pres);
++_coreVar._faithScore;
_coreVar._currPlace = LANDING;
_currMenu = MENU_DISCUSS;
- _currAction = (_menu._discussMenu[charIndex]._menuId << 8) | _menu._discussMenu[charIndex]._actionId;
+ _currAction = (_menu->_discussMenu[charIndex]._menuId << 8) | _menu->_discussMenu[charIndex]._actionId;
_syn = true;
if (_roomDoorId == JULIA_ROOM) {
_col = true;
@@ -1207,14 +1232,14 @@ void MortevielleEngine::fctEnter() {
}
} else {
int randVal = (getRandomNumber(0, 10)) - 5;
- _soundManager.startSpeech(7, randVal, 1);
+ _soundManager->startSpeech(7, randVal, 1);
displayAnimFrame(1, 1);
- _soundManager.waitSpeech();
+ _soundManager->waitSpeech();
_coreVar._currPlace = _roomDoorId;
prepareDisplayText();
resetRoomVariables(_coreVar._currPlace);
- _menu.setDestinationText(_coreVar._currPlace);
+ _menu->setDestinationText(_coreVar._currPlace);
_roomDoorId = OWN_ROOM;
_savedBitIndex = 0;
_currBitIndex = 0;
@@ -1237,7 +1262,7 @@ void MortevielleEngine::fctSleep() {
prepareDisplayText();
drawPictureWithText();
resetRoomVariables(_coreVar._currPlace);
- _menu.setDestinationText(_coreVar._currPlace);
+ _menu->setDestinationText(_coreVar._currPlace);
}
clearVerbBar();
clearDescriptionBar();
@@ -1261,7 +1286,7 @@ void MortevielleEngine::fctSleep() {
if (hour > 23)
hour = 0;
prepareRoom();
- answer = _dialogManager.show(getEngineString(S_YES_NO));
+ answer = _dialogManager->show(getEngineString(S_YES_NO));
_anyone = false;
} while (answer != 1);
_crep = 998;
@@ -1321,7 +1346,7 @@ void MortevielleEngine::fctLeave() {
if (_crep == 0)
_crep = nextPlace;
resetRoomVariables(nextPlace);
- _menu.setDestinationText(nextPlace);
+ _menu->setDestinationText(nextPlace);
}
}
@@ -1337,7 +1362,7 @@ void MortevielleEngine::fctWait() {
do {
++_currentHourCount;
prepareRoom();
- if (!_blo)
+ if (!_outsideOnlyFl)
getPresence(_coreVar._currPlace);
if ((_currBitIndex != 0) && (_savedBitIndex == 0)) {
_crep = 998;
@@ -1351,7 +1376,7 @@ void MortevielleEngine::fctWait() {
return;
}
handleDescriptionText(2, 102);
- answer = _dialogManager.show(getEngineString(S_YES_NO));
+ answer = _dialogManager->show(getEngineString(S_YES_NO));
} while (answer != 2);
_crep = 998;
if (!_anyone)
@@ -1394,7 +1419,7 @@ void MortevielleEngine::fctDiscuss() {
int oldMenu;
do {
++cx;
- oldMenu = (_menu._discussMenu[cx]._menuId << 8) | _menu._discussMenu[cx]._actionId;
+ oldMenu = (_menu->_discussMenu[cx]._menuId << 8) | _menu->_discussMenu[cx]._actionId;
} while (oldMenu != _currAction);
_caff = 69 + cx;
drawPictureWithText();
@@ -1403,7 +1428,7 @@ void MortevielleEngine::fctDiscuss() {
}
testKey(false);
menuUp();
- _mouse.hideMouse();
+ _mouse->hideMouse();
clearScreen();
drawDiscussionBox();
startDialog(displId);
@@ -1417,13 +1442,13 @@ void MortevielleEngine::fctDiscuss() {
}
lib[46] = lib[45];
lib[45] = ' ';
- _mouse.showMouse();
+ _mouse->showMouse();
do {
choice = 0;
int posX = 0;
int posY = 0;
for (int icm = 1; icm < 43; icm++) {
- _screenSurface.putxy(posX, posY);
+ _screenSurface->putxy(posX, posY);
if (_coreVar._availableQuestion[icm] == '*') {
// If question already asked, write it in reverse video
if (questionAsked[icm])
@@ -1438,17 +1463,17 @@ void MortevielleEngine::fctDiscuss() {
} else
posY += 8;
}
- _screenSurface.putxy(320, 176);
+ _screenSurface->putxy(320, 176);
displayQuestionText(lib[46], 0);
char retKey = '\0';
bool click;
do {
bool dummyFl;
- _mouse.moveMouse(dummyFl, retKey);
+ _mouse->moveMouse(dummyFl, retKey);
if (shouldQuit())
return;
- _mouse.getMousePosition(x, y, click);
+ _mouse->getMousePosition(x, y, click);
x *= (3 - kResolutionScaler);
if (x > 319)
cx = 41;
@@ -1462,7 +1487,7 @@ void MortevielleEngine::fctDiscuss() {
posX = 320;
else
posX = 0;
- _screenSurface.putxy(posX, posY);
+ _screenSurface->putxy(posX, posY);
if (questionAsked[choice])
displayQuestionText(lib[choice], 0);
else
@@ -1481,7 +1506,7 @@ void MortevielleEngine::fctDiscuss() {
posX = 320;
else
posX = 0;
- _screenSurface.putxy(posX, posY);
+ _screenSurface->putxy(posX, posY);
if (questionAsked[choice])
displayQuestionText(lib[choice], 0);
else
@@ -1494,7 +1519,7 @@ void MortevielleEngine::fctDiscuss() {
posX = 320;
else
posX = 0;
- _screenSurface.putxy(posX, posY);
+ _screenSurface->putxy(posX, posY);
if (questionAsked[ix])
displayQuestionText(lib[ix], 0);
else
@@ -1533,11 +1558,11 @@ void MortevielleEngine::fctDiscuss() {
_coreVar._faithScore += 3;
displId = 139;
}
- _mouse.hideMouse();
+ _mouse->hideMouse();
clearScreen();
drawDiscussionBox();
startDialog(displId);
- _mouse.showMouse();
+ _mouse->showMouse();
if ((displId == 84) || (displId == 86)) {
_coreVar._pctHintFound[5] = '*';
_coreVar._availableQuestion[7] = '*';
@@ -1551,32 +1576,32 @@ void MortevielleEngine::fctDiscuss() {
_coreVar._pctHintFound[8] = '*';
_coreVar._availableQuestion[32] = '*';
}
- _mouse.hideMouse();
+ _mouse->hideMouse();
clearScreen();
- _mouse.showMouse();
+ _mouse->showMouse();
}
} while ((choice != 46) && (displId != 138));
if (_col) {
_coreVar._faithScore += (3 * (_coreVar._faithScore / 10));
- _mouse.hideMouse();
+ _mouse->hideMouse();
clearScreen();
drawDiscussionBox();
startDialog(138);
- _mouse.showMouse();
+ _mouse->showMouse();
_col = false;
_coreVar._currPlace = LANDING;
}
_controlMenu = 0;
- _mouse.hideMouse();
+ _mouse->hideMouse();
clearScreen();
drawRightFrame();
- _mouse.showMouse();
+ _mouse->showMouse();
showPeoplePresent(_currBitIndex);
prepareRoom();
drawClock();
prepareDisplayText();
/* chech;*/
- _menu.setDestinationText(_coreVar._currPlace);
+ _menu->setDestinationText(_coreVar._currPlace);
clearVerbBar();
}
@@ -1625,13 +1650,13 @@ void MortevielleEngine::endGame() {
clearVerbBar();
handleDescriptionText(9, 1509);
testKey(false);
- _mouse.hideMouse();
+ _mouse->hideMouse();
_caff = 70;
- _text.taffich();
+ _text->taffich();
clearScreen();
drawDiscussionBox();
startDialog(141);
- _mouse.showMouse();
+ _mouse->showMouse();
clearUpperLeftPart();
handleDescriptionText(9, 1509);
handleDescriptionText(2, 142);
@@ -1667,7 +1692,7 @@ void MortevielleEngine::askRestart() {
_day = 0;
handleDescriptionText(2, 180);
- int answer = _dialogManager.show(getEngineString(S_YES_NO));
+ int answer = _dialogManager->show(getEngineString(S_YES_NO));
_quitGame = (answer != 1);
}
diff --git a/engines/mortevielle/configure.engine b/engines/mortevielle/configure.engine
new file mode 100644
index 0000000000..a7fb2ccda6
--- /dev/null
+++ b/engines/mortevielle/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 mortevielle "Mortevielle" yes
diff --git a/engines/mortevielle/debugger.cpp b/engines/mortevielle/debugger.cpp
index 4ef5151c81..4b39462cde 100644
--- a/engines/mortevielle/debugger.cpp
+++ b/engines/mortevielle/debugger.cpp
@@ -25,7 +25,8 @@
namespace Mortevielle {
-Debugger::Debugger() : GUI::Debugger() {
+Debugger::Debugger(MortevielleEngine *vm) : GUI::Debugger() {
+ _vm = vm;
DCmd_Register("continue", WRAP_METHOD(Debugger, Cmd_Exit));
DCmd_Register("show_questions", WRAP_METHOD(Debugger, Cmd_showAllQuestions));
DCmd_Register("reset_parano", WRAP_METHOD(Debugger, Cmd_resetParano));
@@ -52,8 +53,4 @@ bool Debugger::Cmd_resetParano(int argc, const char **argv) {
return true;
}
-void Debugger::setParent(MortevielleEngine *vm) {
- _vm = vm;
-}
-
} // End of namespace Mortevielle
diff --git a/engines/mortevielle/debugger.h b/engines/mortevielle/debugger.h
index 9041d90110..6e1006681c 100644
--- a/engines/mortevielle/debugger.h
+++ b/engines/mortevielle/debugger.h
@@ -39,9 +39,8 @@ protected:
bool Cmd_resetParano(int argc, const char **argv);
public:
- Debugger();
+ Debugger(MortevielleEngine *vm);
virtual ~Debugger() {}
- void setParent(MortevielleEngine *vm);
};
} // End of namespace Mortevielle
diff --git a/engines/mortevielle/dialogs.cpp b/engines/mortevielle/dialogs.cpp
index 9a2ade60ab..09a4227cc0 100644
--- a/engines/mortevielle/dialogs.cpp
+++ b/engines/mortevielle/dialogs.cpp
@@ -35,15 +35,19 @@
namespace Mortevielle {
+DialogManager::DialogManager(MortevielleEngine *vm) {
+ _vm = vm;
+}
+
/**
* Alert function - Show
* @remarks Originally called 'do_alert'
*/
int DialogManager::show(const Common::String &msg) {
// Make a copy of the current screen surface for later restore
- _vm->_backgroundSurface.copyFrom(_vm->_screenSurface);
+ _vm->_backgroundSurface.copyFrom(*_vm->_screenSurface);
- _vm->_mouse.hideMouse();
+ _vm->_mouse->hideMouse();
while (_vm->keyPressed())
_vm->getChar();
@@ -63,7 +67,7 @@ int DialogManager::show(const Common::String &msg) {
} else {
drawAlertBox(8, 7, colNumb);
int i = 0;
- _vm->_screenSurface._textPos.y = 70;
+ _vm->_screenSurface->_textPos.y = 70;
do {
curPos.x = 320;
Common::String displayStr = "";
@@ -72,9 +76,9 @@ int DialogManager::show(const Common::String &msg) {
displayStr += alertStr[i];
curPos.x -= 3;
}
- _vm->_screenSurface.putxy(curPos.x, _vm->_screenSurface._textPos.y);
- _vm->_screenSurface._textPos.y += 6;
- _vm->_screenSurface.drawString(displayStr, 4);
+ _vm->_screenSurface->putxy(curPos.x, _vm->_screenSurface->_textPos.y);
+ _vm->_screenSurface->_textPos.y += 6;
+ _vm->_screenSurface->drawString(displayStr, 4);
++i;
} while (alertStr[i] != ']');
}
@@ -99,17 +103,17 @@ int DialogManager::show(const Common::String &msg) {
limit[2][1] = ((uint)(320 + ((uint)esp >> 1)) / 2) * kResolutionScaler;
limit[2][2] = (limit[2][1]) + 40;
}
- _vm->_mouse.showMouse();
+ _vm->_mouse->showMouse();
int id = 0;
bool dummyFl = false;
bool test3;
do {
char dummyKey = '\377';
- _vm->_mouse.moveMouse(dummyFl, dummyKey);
+ _vm->_mouse->moveMouse(dummyFl, dummyKey);
if (_vm->shouldQuit())
return 0;
- curPos = _vm->_mouse._pos;
+ curPos = _vm->_mouse->_pos;
bool newaff = false;
if ((curPos.y > 95) && (curPos.y < 105)) {
bool test1 = (curPos.x > limit[1][1]) && (curPos.x < limit[1][2]);
@@ -125,56 +129,56 @@ int DialogManager::show(const Common::String &msg) {
else
ix = 2;
if (ix != id) {
- _vm->_mouse.hideMouse();
+ _vm->_mouse->hideMouse();
if (id != 0) {
setPosition(id, coldep, esp);
Common::String tmpStr(" ");
tmpStr += buttonStr[id];
tmpStr += " ";
- _vm->_screenSurface.drawString(tmpStr, 0);
+ _vm->_screenSurface->drawString(tmpStr, 0);
}
setPosition(ix, coldep, esp);
Common::String tmp2 = " ";
tmp2 += buttonStr[ix];
tmp2 += " ";
- _vm->_screenSurface.drawString(tmp2, 1);
+ _vm->_screenSurface->drawString(tmp2, 1);
id = ix;
- _vm->_mouse.showMouse();
+ _vm->_mouse->showMouse();
}
}
}
if ((id != 0) && !newaff) {
- _vm->_mouse.hideMouse();
+ _vm->_mouse->hideMouse();
setPosition(id, coldep, esp);
Common::String tmp3(" ");
tmp3 += buttonStr[id];
tmp3 += " ";
- _vm->_screenSurface.drawString(tmp3, 0);
+ _vm->_screenSurface->drawString(tmp3, 0);
id = 0;
- _vm->_mouse.showMouse();
+ _vm->_mouse->showMouse();
}
test3 = (curPos.y > 95) && (curPos.y < 105) && (((curPos.x > limit[1][1]) && (curPos.x < limit[1][2]))
|| ((curPos.x > limit[2][1]) && (curPos.x < limit[2][2])));
} while (!_vm->getMouseClick());
_vm->setMouseClick(false);
- _vm->_mouse.hideMouse();
+ _vm->_mouse->hideMouse();
if (!test3) {
id = 1;
setPosition(1, coldep, esp);
Common::String tmp4(" ");
tmp4 += buttonStr[1];
tmp4 += " ";
- _vm->_screenSurface.drawString(tmp4, 1);
+ _vm->_screenSurface->drawString(tmp4, 1);
}
- _vm->_mouse.showMouse();
+ _vm->_mouse->showMouse();
/* Restore the background area */
- _vm->_screenSurface.copyFrom(_vm->_backgroundSurface, 0, 0);
+ _vm->_screenSurface->copyFrom(_vm->_backgroundSurface, 0, 0);
return id;
}
@@ -221,7 +225,7 @@ void DialogManager::decodeAlertDetails(Common::String inputStr, int &choiceNumb,
}
void DialogManager::setPosition(int ji, int coldep, int esp) {
- _vm->_screenSurface.putxy(coldep + (40 + esp) * (ji - 1), 98);
+ _vm->_screenSurface->putxy(coldep + (40 + esp) * (ji - 1), 98);
}
/**
@@ -235,9 +239,9 @@ void DialogManager::drawAlertBox(int firstLine, int lineNum, int width) {
int y = (firstLine - 1) * 8;
int xx = x + width;
int yy = y + (lineNum * 8);
- _vm->_screenSurface.fillRect(15, Common::Rect(x, y, xx, yy));
- _vm->_screenSurface.fillRect(0, Common::Rect(x, y + 2, xx, y + 4));
- _vm->_screenSurface.fillRect(0, Common::Rect(x, yy - 4, xx, yy - 2));
+ _vm->_screenSurface->fillRect(15, Common::Rect(x, y, xx, yy));
+ _vm->_screenSurface->fillRect(0, Common::Rect(x, y + 2, xx, y + 4));
+ _vm->_screenSurface->fillRect(0, Common::Rect(x, yy - 4, xx, yy - 2));
}
/**
@@ -259,13 +263,13 @@ void DialogManager::setButtonText(Common::String c, int coldep, int nbcase, Comm
while (str[l].size() < 3)
str[l] += ' ';
- _vm->_screenSurface.putxy(x, 98);
+ _vm->_screenSurface->putxy(x, 98);
Common::String tmp(" ");
tmp += str[l];
tmp += " ";
- _vm->_screenSurface.drawString(tmp, 0);
+ _vm->_screenSurface->drawString(tmp, 0);
x += esp + 40;
}
}
@@ -292,13 +296,13 @@ bool DialogManager::showKnowledgeCheck() {
int correctCount = 0;
for (int indx = 0; indx < 10; ++indx) {
- _vm->_mouse.hideMouse();
+ _vm->_mouse->hideMouse();
_vm->clearScreen();
- _vm->_mouse.showMouse();
+ _vm->_mouse->showMouse();
int dialogHeight = 23;
- _vm->_screenSurface.fillRect(15, Common::Rect(0, 14, 630, dialogHeight));
+ _vm->_screenSurface->fillRect(15, Common::Rect(0, 14, 630, dialogHeight));
Common::String tmpStr = _vm->getString(textIndexArr[indx]);
- _vm->_text.displayStr(tmpStr, 20, 15, 100, 2, 0);
+ _vm->_text->displayStr(tmpStr, 20, 15, 100, 2, 0);
int firstOption;
int lastOption;
@@ -318,7 +322,7 @@ bool DialogManager::showKnowledgeCheck() {
tmpStr = _vm->getString(j);
if ((int) tmpStr.size() > maxLength)
maxLength = tmpStr.size();
- _vm->_text.displayStr(tmpStr, 100, optionPosY, 100, 1, 0);
+ _vm->_text->displayStr(tmpStr, 100, optionPosY, 100, 1, 0);
choiceArray[prevChoice] = tmpStr;
optionPosY += 8;
}
@@ -333,7 +337,7 @@ bool DialogManager::showKnowledgeCheck() {
}
coor[lastOption - firstOption + 2]._enabled = false;
int rep = 6;
- _vm->_screenSurface.drawBox(80, 33, 40 + (maxLength * rep), (lastOption - firstOption) * 8 + 16, 15);
+ _vm->_screenSurface->drawBox(80, 33, 40 + (maxLength * rep), (lastOption - firstOption) * 8 + 16, 15);
rep = 0;
prevChoice = 0;
@@ -342,26 +346,26 @@ bool DialogManager::showKnowledgeCheck() {
_vm->setMouseClick(false);
bool flag;
char key;
- _vm->_mouse.moveMouse(flag, key);
+ _vm->_mouse->moveMouse(flag, key);
if (_vm->shouldQuit())
return false;
currChoice = 1;
- while (coor[currChoice]._enabled && !_vm->_mouse.isMouseIn(coor[currChoice]._rect))
+ while (coor[currChoice]._enabled && !_vm->_mouse->isMouseIn(coor[currChoice]._rect))
++currChoice;
if (coor[currChoice]._enabled) {
if ((prevChoice != 0) && (prevChoice != currChoice)) {
tmpStr = choiceArray[prevChoice] + '$';
- _vm->_text.displayStr(tmpStr, 100, 27 + (prevChoice * 8), 100, 1, 0);
+ _vm->_text->displayStr(tmpStr, 100, 27 + (prevChoice * 8), 100, 1, 0);
}
if (prevChoice != currChoice) {
tmpStr = choiceArray[currChoice] + '$';
- _vm->_text.displayStr(tmpStr, 100, 27 + (currChoice * 8), 100, 1, 1);
+ _vm->_text->displayStr(tmpStr, 100, 27 + (currChoice * 8), 100, 1, 1);
prevChoice = currChoice;
}
} else if (prevChoice != 0) {
tmpStr = choiceArray[prevChoice] + '$';
- _vm->_text.displayStr(tmpStr, 100, 27 + (prevChoice * 8), 100, 1, 0);
+ _vm->_text->displayStr(tmpStr, 100, 27 + (prevChoice * 8), 100, 1, 0);
prevChoice = 0;
}
} while (!((prevChoice != 0) && _vm->getMouseClick()));
@@ -391,17 +395,17 @@ void DialogManager::drawF3F8() {
Common::String f8 = _vm->getEngineString(S_F8);
// Write the F3 and F8 text strings
- _vm->_screenSurface.putxy(3, 44);
- _vm->_screenSurface.drawString(f3, 5);
- _vm->_screenSurface._textPos.y = 51;
- _vm->_screenSurface.drawString(f8, 5);
+ _vm->_screenSurface->putxy(3, 44);
+ _vm->_screenSurface->drawString(f3, 5);
+ _vm->_screenSurface->_textPos.y = 51;
+ _vm->_screenSurface->drawString(f8, 5);
// Get the width of the written text strings
- int f3Width = _vm->_screenSurface.getStringWidth(f3);
- int f8Width = _vm->_screenSurface.getStringWidth(f8);
+ int f3Width = _vm->_screenSurface->getStringWidth(f3);
+ 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) + 6, 18, 7);
}
/**
@@ -412,7 +416,7 @@ void DialogManager::drawF3F8() {
void DialogManager::checkForF8(int SpeechNum, bool drawFrame2Fl) {
_vm->testKeyboard();
do {
- _vm->_soundManager.startSpeech(SpeechNum, 0, 0);
+ _vm->_soundManager->startSpeech(SpeechNum, 0, 0);
_vm->_key = waitForF3F8();
if (_vm->shouldQuit())
return;
@@ -442,7 +446,7 @@ int DialogManager::waitForF3F8() {
void DialogManager::displayIntroScreen(bool drawFrame2Fl) {
_vm->_caff = 50;
_vm->_maff = 0;
- _vm->_text.taffich();
+ _vm->_text->taffich();
_vm->draw(63, 12);
if (drawFrame2Fl)
displayIntroFrame2();
@@ -466,7 +470,4 @@ void DialogManager::displayIntroFrame2() {
_vm->handleDescriptionText(2, kDialogStringIndex + 143);
}
-void DialogManager::setParent(MortevielleEngine *vm) {
- _vm = vm;
-}
} // End of namespace Mortevielle
diff --git a/engines/mortevielle/dialogs.h b/engines/mortevielle/dialogs.h
index 3f30851960..03dfc78023 100644
--- a/engines/mortevielle/dialogs.h
+++ b/engines/mortevielle/dialogs.h
@@ -51,7 +51,8 @@ private:
void drawAlertBox(int firstLine, int lineNum, int width);
void setButtonText(Common::String c, int coldep, int nbcase, Common::String *str, int esp);
public:
- void setParent(MortevielleEngine *vm);
+ DialogManager(MortevielleEngine *vm);
+
int show(const Common::String &msg);
void drawF3F8();
void checkForF8(int SpeechNum, bool drawFrame2Fl);
diff --git a/engines/mortevielle/graphics.cpp b/engines/mortevielle/graphics.cpp
index daf7926438..18b0e7f1c1 100644
--- a/engines/mortevielle/graphics.cpp
+++ b/engines/mortevielle/graphics.cpp
@@ -881,6 +881,10 @@ GfxSurface::~GfxSurface() {
* Screen surface
*-------------------------------------------------------------------------*/
+ScreenSurface::ScreenSurface(MortevielleEngine *vm) {
+ _vm = vm;
+}
+
/**
* Called to populate the font data from the passed file
*/
@@ -1070,7 +1074,7 @@ void ScreenSurface::drawString(const Common::String &l, int command) {
if (l == "")
return;
- _vm->_mouse.hideMouse();
+ _vm->_mouse->hideMouse();
Common::Point pt = _textPos;
int charWidth = 6;
@@ -1082,11 +1086,11 @@ void ScreenSurface::drawString(const Common::String &l, int command) {
case 0:
case 2:
color = 15;
- _vm->_screenSurface.fillRect(0, Common::Rect(pt.x, pt.y, x, pt.y + 7));
+ _vm->_screenSurface->fillRect(0, Common::Rect(pt.x, pt.y, x, pt.y + 7));
break;
case 1:
case 3:
- _vm->_screenSurface.fillRect(15, Common::Rect(pt.x, pt.y, x, pt.y + 7));
+ _vm->_screenSurface->fillRect(15, Common::Rect(pt.x, pt.y, x, pt.y + 7));
break;
case 5:
color = 15;
@@ -1099,10 +1103,10 @@ void ScreenSurface::drawString(const Common::String &l, int command) {
pt.x += 1;
pt.y += 1;
for (x = 1; (x <= (int)l.size()) && (l[x - 1] != 0); ++x) {
- _vm->_screenSurface.writeCharacter(Common::Point(pt.x, pt.y), l[x - 1], color);
+ _vm->_screenSurface->writeCharacter(Common::Point(pt.x, pt.y), l[x - 1], color);
pt.x += charWidth;
}
- _vm->_mouse.showMouse();
+ _vm->_mouse->showMouse();
}
/**
@@ -1133,7 +1137,7 @@ void ScreenSurface::drawLine(int x, int y, int xx, int yy, int coul) {
else
step = 1;
do {
- _vm->_screenSurface.setPixel(Common::Point(abs((int)(a * i + b)), i), coul);
+ _vm->_screenSurface->setPixel(Common::Point(abs((int)(a * i + b)), i), coul);
i += step;
} while (i != yy);
} else {
@@ -1145,7 +1149,7 @@ void ScreenSurface::drawLine(int x, int y, int xx, int yy, int coul) {
else
step = 1;
do {
- _vm->_screenSurface.setPixel(Common::Point(i, abs((int)(a * i + b))), coul);
+ _vm->_screenSurface->setPixel(Common::Point(i, abs((int)(a * i + b))), coul);
i = i + step;
} while (i != xx);
}
@@ -1156,12 +1160,7 @@ void ScreenSurface::drawLine(int x, int y, int xx, int yy, int coul) {
* @remarks Originally called 'paint_rect'
*/
void ScreenSurface::drawRectangle(int x, int y, int dx, int dy) {
- _vm->_screenSurface.fillRect(11, Common::Rect(x, y, x + dx, y + dy));
+ _vm->_screenSurface->fillRect(11, Common::Rect(x, y, x + dx, y + dy));
}
-void ScreenSurface::setParent(MortevielleEngine *vm) {
- _vm = vm;
-}
-
-
} // End of namespace Mortevielle
diff --git a/engines/mortevielle/graphics.h b/engines/mortevielle/graphics.h
index e31f5da29a..7f0d4823cb 100644
--- a/engines/mortevielle/graphics.h
+++ b/engines/mortevielle/graphics.h
@@ -91,6 +91,8 @@ private:
byte _fontData[FONT_NUM_CHARS * FONT_HEIGHT];
public:
+ ScreenSurface(MortevielleEngine *vm);
+
Common::Point _textPos; // Original called xwhere/ywhere
void readFontData(Common::File &f, int dataSize);
Graphics::Surface lockArea(const Common::Rect &bounds);
@@ -106,7 +108,6 @@ public:
int getStringWidth(const Common::String &s);
void drawLine(int x, int y, int xx, int yy, int coul);
void drawRectangle(int x, int y, int dx, int dy);
- void setParent(MortevielleEngine *vm);
// TODO: Refactor code to remove this method, for increased performance
void setPixel(const Common::Point &pt, int palIndex);
diff --git a/engines/mortevielle/menu.cpp b/engines/mortevielle/menu.cpp
index 641a527c98..7979e3ce7f 100644
--- a/engines/mortevielle/menu.cpp
+++ b/engines/mortevielle/menu.cpp
@@ -48,14 +48,34 @@ const byte menuConstants[8][4] = {
{62, 46, 13, 10}
};
-Menu::Menu() {
+Menu::Menu(MortevielleEngine *vm) {
+ _vm = vm;
_opcodeAttach = _opcodeWait = _opcodeForce = _opcodeSleep = OPCODE_NONE;
_opcodeListen = _opcodeEnter = _opcodeClose = _opcodeSearch = OPCODE_NONE;
_opcodeKnock = _opcodeScratch = _opcodeRead = _opcodeEat = OPCODE_NONE;
_opcodePlace = _opcodeOpen = _opcodeTake = _opcodeLook = OPCODE_NONE;
_opcodeSmell = _opcodeSound = _opcodeLeave = _opcodeLift = OPCODE_NONE;
_opcodeTurn = _opcodeSHide = _opcodeSSearch = _opcodeSRead = OPCODE_NONE;
- _opcodeSPut = _opcodeSLook = OPCODE_NONE;
+ _opcodeSPut = _opcodeSLook = _msg3 = _msg4 = OPCODE_NONE;
+
+ _menuActive = false;
+ _menuSelected = false;
+ _multiTitle = false;
+ _menuDisplayed = false;
+ for (int i = 0; i < 9; i++) {
+ _discussMenu[i]._menuId = MENU_NONE;
+ _discussMenu[i]._actionId = 0;
+ _inventoryMenu[i]._menuId = MENU_NONE;
+ _inventoryMenu[i]._actionId = 0;
+ }
+ for (int i = 0; i < 8; i++) {
+ _moveMenu[i]._menuId = MENU_NONE;
+ _moveMenu[i]._actionId = 0;
+ }
+ for (int i = 0; i < 12; i++) {
+ _actionMenu[i]._menuId = MENU_NONE;
+ _actionMenu[i]._actionId = 0;
+ }
}
void Menu::readVerbNums(Common::File &f, int dataSize) {
@@ -295,8 +315,8 @@ void Menu::enableMenuItem(MenuItem item) {
}
void Menu::displayMenu() {
- _vm->_mouse.hideMouse();
- _vm->_screenSurface.fillRect(7, Common::Rect(0, 0, 639, 10));
+ _vm->_mouse->hideMouse();
+ _vm->_screenSurface->fillRect(7, Common::Rect(0, 0, 639, 10));
int col = 28 * kResolutionScaler;
for (int charNum = 0; charNum < 6; charNum++) {
@@ -310,9 +330,9 @@ void Menu::displayMenu() {
uint msk = 0x80;
for (int pt = 0; pt <= 7; ++pt) {
if ((_charArr[charNum][idx] & msk) != 0) {
- _vm->_screenSurface.setPixel(Common::Point(x + 1, y + 1), 0);
- _vm->_screenSurface.setPixel(Common::Point(x, y + 1), 0);
- _vm->_screenSurface.setPixel(Common::Point(x, y), 9);
+ _vm->_screenSurface->setPixel(Common::Point(x + 1, y + 1), 0);
+ _vm->_screenSurface->setPixel(Common::Point(x, y + 1), 0);
+ _vm->_screenSurface->setPixel(Common::Point(x, y), 9);
}
msk >>= 1;
++x;
@@ -322,7 +342,7 @@ void Menu::displayMenu() {
}
col += 48 * kResolutionScaler;
}
- _vm->_mouse.showMouse();
+ _vm->_mouse->showMouse();
}
/**
@@ -348,7 +368,7 @@ void Menu::invert(int indx) {
int menuIndex = _msg4 & 0xFF;
- _vm->_screenSurface.putxy(menuConstants[_msg3 - 1][0] << 3, (menuIndex + 1) << 3);
+ _vm->_screenSurface->putxy(menuConstants[_msg3 - 1][0] << 3, (menuIndex + 1) << 3);
Common::String str;
switch (_msg3) {
@@ -388,7 +408,7 @@ void Menu::invert(int indx) {
break;
}
if ((str[0] != '*') && (str[0] != '<'))
- _vm->_screenSurface.drawString(str, indx);
+ _vm->_screenSurface->drawString(str, indx);
else
_msg4 = OPCODE_NONE;
}
@@ -419,71 +439,71 @@ void Menu::util(Common::Point pos) {
*/
void Menu::menuDown(int ii) {
// Make a copy of the current screen surface for later restore
- _vm->_backgroundSurface.copyFrom(_vm->_screenSurface);
+ _vm->_backgroundSurface.copyFrom(*_vm->_screenSurface);
// Draw the menu
int minX = menuConstants[ii - 1][0] << 3;
int lineNum = menuConstants[ii - 1][3];
- _vm->_mouse.hideMouse();
+ _vm->_mouse->hideMouse();
int deltaX = 6;
int maxX = minX + (menuConstants[ii - 1][2] * deltaX) + 6;
if ((ii == 4) && (_vm->getLanguage() == Common::EN_ANY))
// Extra width needed for Self menu in English version
maxX = 435;
- _vm->_screenSurface.fillRect(15, Common::Rect(minX, 12, maxX, 10 + (menuConstants[ii - 1][1] << 1)));
- _vm->_screenSurface.fillRect(0, Common::Rect(maxX, 12, maxX + 4, 10 + (menuConstants[ii - 1][1] << 1)));
- _vm->_screenSurface.fillRect(0, Common::Rect(minX, 8 + (menuConstants[ii - 1][1] << 1), maxX + 4, 12 + (menuConstants[ii - 1][1] << 1)));
- _vm->_screenSurface.putxy(minX, 16);
+ _vm->_screenSurface->fillRect(15, Common::Rect(minX, 12, maxX, 10 + (menuConstants[ii - 1][1] << 1)));
+ _vm->_screenSurface->fillRect(0, Common::Rect(maxX, 12, maxX + 4, 10 + (menuConstants[ii - 1][1] << 1)));
+ _vm->_screenSurface->fillRect(0, Common::Rect(minX, 8 + (menuConstants[ii - 1][1] << 1), maxX + 4, 12 + (menuConstants[ii - 1][1] << 1)));
+ _vm->_screenSurface->putxy(minX, 16);
for (int i = 1; i <= lineNum; i++) {
switch (ii) {
case 1:
if (_inventoryStringArray[i][0] != '*')
- _vm->_screenSurface.drawString(_inventoryStringArray[i], 4);
+ _vm->_screenSurface->drawString(_inventoryStringArray[i], 4);
break;
case 2:
if (_moveStringArray[i][0] != '*')
- _vm->_screenSurface.drawString(_moveStringArray[i], 4);
+ _vm->_screenSurface->drawString(_moveStringArray[i], 4);
break;
case 3:
if (_actionStringArray[i][0] != '*')
- _vm->_screenSurface.drawString(_actionStringArray[i], 4);
+ _vm->_screenSurface->drawString(_actionStringArray[i], 4);
break;
case 4:
if (_selfStringArray[i][0] != '*')
- _vm->_screenSurface.drawString(_selfStringArray[i], 4);
+ _vm->_screenSurface->drawString(_selfStringArray[i], 4);
break;
case 5:
if (_discussStringArray[i][0] != '*')
- _vm->_screenSurface.drawString(_discussStringArray[i], 4);
+ _vm->_screenSurface->drawString(_discussStringArray[i], 4);
break;
case 6:
- _vm->_screenSurface.drawString(_vm->getEngineString(S_SAVE_LOAD + i), 4);
+ _vm->_screenSurface->drawString(_vm->getEngineString(S_SAVE_LOAD + i), 4);
break;
case 7: {
Common::String s = _vm->getEngineString(S_SAVE_LOAD + 1);
s += ' ';
s += (char)(48 + i);
- _vm->_screenSurface.drawString(s, 4);
+ _vm->_screenSurface->drawString(s, 4);
}
break;
case 8:
if (i == 1)
- _vm->_screenSurface.drawString(_vm->getEngineString(S_RESTART), 4);
+ _vm->_screenSurface->drawString(_vm->getEngineString(S_RESTART), 4);
else {
Common::String s = _vm->getEngineString(S_SAVE_LOAD + 2);
s += ' ';
s += (char)(47 + i);
- _vm->_screenSurface.drawString(s, 4);
+ _vm->_screenSurface->drawString(s, 4);
}
break;
default:
break;
}
- _vm->_screenSurface.putxy(minX, _vm->_screenSurface._textPos.y + 8);
+ _vm->_screenSurface->putxy(minX, _vm->_screenSurface->_textPos.y + 8);
}
_multiTitle = true;
- _vm->_mouse.showMouse();
+ _vm->_mouse->showMouse();
}
/**
@@ -492,11 +512,11 @@ void Menu::menuDown(int ii) {
void Menu::menuUp(int msgId) {
if (_multiTitle) {
/* Restore the background area */
- assert(_vm->_screenSurface.pitch == _vm->_backgroundSurface.pitch);
+ assert(_vm->_screenSurface->pitch == _vm->_backgroundSurface.pitch);
// Get a pointer to the source and destination of the area to restore
const byte *pSrc = (const byte *)_vm->_backgroundSurface.getBasePtr(0, 10);
- Graphics::Surface destArea = _vm->_screenSurface.lockArea(Common::Rect(0, 10, SCREEN_WIDTH, SCREEN_HEIGHT));
+ Graphics::Surface destArea = _vm->_screenSurface->lockArea(Common::Rect(0, 10, SCREEN_WIDTH, SCREEN_HEIGHT));
byte *pDest = (byte *)destArea.getPixels();
// Copy the data
@@ -523,7 +543,7 @@ void Menu::updateMenu() {
if (!_menuActive)
return;
- Common::Point curPos = _vm->_mouse._pos;
+ Common::Point curPos = _vm->_mouse->_pos;
if (!_vm->getMouseClick()) {
if (curPos == _vm->_prevPos)
return;
@@ -590,10 +610,6 @@ void Menu::updateMenu() {
}
}
-void Menu::setParent(MortevielleEngine *vm) {
- _vm = vm;
-}
-
void Menu::initMenu() {
Common::File f;
diff --git a/engines/mortevielle/menu.h b/engines/mortevielle/menu.h
index debf5b09b6..d8a3b4d0d6 100644
--- a/engines/mortevielle/menu.h
+++ b/engines/mortevielle/menu.h
@@ -60,7 +60,7 @@ private:
void menuDown(int ii);
public:
- Menu();
+ Menu(MortevielleEngine *vm);
bool _menuActive;
bool _menuSelected;
@@ -103,7 +103,6 @@ public:
int _opcodeSLook;
MenuItem _actionMenu[12];
- void setParent(MortevielleEngine *vm);
void readVerbNums(Common::File &f, int dataSize);
void setText(MenuItem item, Common::String name);
void setDestinationText(int roomId);
diff --git a/engines/mortevielle/mortevielle.cpp b/engines/mortevielle/mortevielle.cpp
index d434150977..49876f1bf2 100644
--- a/engines/mortevielle/mortevielle.cpp
+++ b/engines/mortevielle/mortevielle.cpp
@@ -47,17 +47,16 @@ namespace Mortevielle {
MortevielleEngine *g_vm;
MortevielleEngine::MortevielleEngine(OSystem *system, const MortevielleGameDescription *gameDesc):
- Engine(system), _gameDescription(gameDesc), _randomSource("mortevielle"),
- _soundManager(_mixer) {
+ Engine(system), _gameDescription(gameDesc), _randomSource("mortevielle") {
g_vm = this;
- _debugger.setParent(this);
- _dialogManager.setParent(this);
- _screenSurface.setParent(this);
- _mouse.setParent(this);
- _text.setParent(this);
- _soundManager.setParent(this);
- _savegameManager.setParent(this);
- _menu.setParent(this);
+ _debugger = new Debugger(this);
+ _dialogManager = new DialogManager(this);
+ _screenSurface = new ScreenSurface(this);
+ _mouse = new MouseHandler(this);
+ _text = new TextHandler(this);
+ _soundManager = new SoundManager(this, _mixer);
+ _savegameManager = new SavegameManager(this);
+ _menu = new Menu(this);
_lastGameFrame = 0;
_mouseClick = false;
@@ -84,7 +83,7 @@ MortevielleEngine::MortevielleEngine(OSystem *system, const MortevielleGameDescr
_keyPressedEsc = false;
_reloadCFIEC = false;
- _blo = false;
+ _outsideOnlyFl = true;
_col = false;
_syn = false;
_obpart = false;
@@ -102,9 +101,62 @@ MortevielleEngine::MortevielleEngine(OSystem *system, const MortevielleGameDescr
_curPict = nullptr;
_curAnim = nullptr;
_rightFramePict = nullptr;
+
+ resetCoreVar();
+
+ _maff = 0;
+ _crep = 0;
+
+ _minute = 0;
+ _curSearchObjId = 0;
+ _controlMenu = 0;
+ _startTime = 0;
+ _endTime = 0;
+ _roomDoorId = OWN_ROOM;
+ _openObjCount = 0;
+ _takeObjCount = 0;
+ _num = 0;
+ _searchCount = 0;
+ _introSpeechPlayed = false;
+ _inGameHourDuration = 0;
+ _x = 0;
+ _y = 0;
+ _currentHourCount = 0;
+ _currentTime = 0;
+ _cfiecBuffer = nullptr;
+ _cfiecBufferSize = 0;
+ for (int i = 0; i < 601; i++) {
+ _dialogHintArray[i]._hintId = 0;
+ _dialogHintArray[i]._point = 0;
+ }
+ _currMenu = OPCODE_NONE;
+ _currAction = OPCODE_NONE;
+ _menuOpcode = OPCODE_NONE;
+ _addFix = 0;
+ _currBitIndex = 0;
+ _currDay = 0;
+ _currHour = 10;
+ _currHalfHour = 0;
+ _hour = 10;
+ _key = 0;
+ _manorDistance = 0;
+ _numpal = 0;
+ _savedBitIndex = 0;
+ _endGame = false;
+ _loseGame = false;
+ _txxFileFl = false;
}
MortevielleEngine::~MortevielleEngine() {
+ delete _menu;
+ delete _savegameManager;
+ delete _soundManager;
+ delete _text;
+ delete _mouse;
+ delete _screenSurface;
+ delete _dialogManager;
+ delete _debugger;
+
free(_curPict);
free(_curAnim);
free(_rightFramePict);
@@ -140,7 +192,7 @@ bool MortevielleEngine::canSaveGameStateCurrently() {
* Load in a savegame at the specified slot number
*/
Common::Error MortevielleEngine::loadGameState(int slot) {
- return _savegameManager.loadGame(slot);
+ return _savegameManager->loadGame(slot);
}
/**
@@ -150,7 +202,7 @@ Common::Error MortevielleEngine::saveGameState(int slot, const Common::String &d
if (slot == 0)
return Common::kWritingFailed;
- return _savegameManager.saveGame(slot, desc);
+ return _savegameManager->saveGame(slot, desc);
}
/**
@@ -196,7 +248,7 @@ Common::ErrorCode MortevielleEngine::initialize() {
DebugMan.addDebugChannel(kMortevielleGraphics, "graphics", "Graphics debugging");
// Set up an intermediate screen surface
- _screenSurface.create(SCREEN_WIDTH, SCREEN_HEIGHT, Graphics::PixelFormat::createFormatCLUT8());
+ _screenSurface->create(SCREEN_WIDTH, SCREEN_HEIGHT, Graphics::PixelFormat::createFormatCLUT8());
_txxFileFl = false;
// Load texts from TXX files
@@ -205,7 +257,7 @@ Common::ErrorCode MortevielleEngine::initialize() {
// Load the mort.dat resource
Common::ErrorCode result = loadMortDat();
if (result != Common::kNoError) {
- _screenSurface.free();
+ _screenSurface->free();
return result;
}
@@ -235,8 +287,8 @@ Common::ErrorCode MortevielleEngine::initialize() {
testKeyboard();
clearScreen();
- _soundManager.loadNoise();
- _soundManager.loadAmbiantSounds();
+ _soundManager->loadNoise();
+ _soundManager->loadAmbiantSounds();
return Common::kNoError;
}
@@ -278,13 +330,13 @@ Common::ErrorCode MortevielleEngine::loadMortDat() {
if (!strncmp(dataType, "FONT", 4)) {
// Font resource
- _screenSurface.readFontData(f, dataSize);
+ _screenSurface->readFontData(f, dataSize);
} else if (!strncmp(dataType, "SSTR", 4)) {
readStaticStrings(f, dataSize, kStaticStrings);
} else if ((!strncmp(dataType, "GSTR", 4)) && (!_txxFileFl)) {
readStaticStrings(f, dataSize, kGameStrings);
} else if (!strncmp(dataType, "VERB", 4)) {
- _menu.readVerbNums(f, dataSize);
+ _menu->readVerbNums(f, dataSize);
} else {
// Unknown section
f.skip(dataSize);
@@ -369,21 +421,21 @@ Common::Error MortevielleEngine::run() {
showIntroduction();
else {
_caff = 51;
- _text.taffich();
+ _text->taffich();
}
// Either load the initial game state savegame, or the specified savegame number
adzon();
resetVariables();
if (loadSlot != 0)
- _savegameManager.loadSavegame(generateSaveFilename(loadSlot));
+ _savegameManager->loadSavegame(generateSaveFilename(loadSlot));
// Run the main game loop
mainGame();
// Cleanup (allocated in initialize())
- _screenSurface.free();
- free(_soundManager._cfiphBuffer);
+ _screenSurface->free();
+ free(_soundManager->_cfiphBuffer);
free(_cfiecBuffer);
return Common::kNoError;
@@ -393,13 +445,13 @@ Common::Error MortevielleEngine::run() {
* Show the game introduction
*/
void MortevielleEngine::showIntroduction() {
- _dialogManager.displayIntroScreen(false);
- _dialogManager.checkForF8(142, false);
+ _dialogManager->displayIntroScreen(false);
+ _dialogManager->checkForF8(142, false);
if (shouldQuit())
return;
- _dialogManager.displayIntroFrame2();
- _dialogManager.checkForF8(143, true);
+ _dialogManager->displayIntroFrame2();
+ _dialogManager->checkForF8(143, true);
if (shouldQuit())
return;
@@ -419,13 +471,13 @@ void MortevielleEngine::mainGame() {
for (_crep = 1; _crep <= _x26KeyCount; ++_crep)
decodeNumber(&_cfiecBuffer[161 * 16], (_cfiecBufferSize - (161 * 16)) / 64);
- _menu.initMenu();
+ _menu->initMenu();
charToHour();
initGame();
clearScreen();
drawRightFrame();
- _mouse.showMouse();
+ _mouse->showMouse();
// Loop to play the game
do {
diff --git a/engines/mortevielle/mortevielle.h b/engines/mortevielle/mortevielle.h
index 5ae94987a0..7a673f42f9 100644
--- a/engines/mortevielle/mortevielle.h
+++ b/engines/mortevielle/mortevielle.h
@@ -122,7 +122,6 @@ const int kMaxPatt = 20;
const int kResolutionScaler = 2;
/*
-9 "A glance at the forbidden$",
18 "It's already open$",
26 "A photograph$"
*/
@@ -135,11 +134,6 @@ enum Places {
DOOR = 25, ROOM26 = 26, COAT_ARMS = 27
};
-struct Pattern {
- byte _tay, _tax;
- byte _des[kMaxPatt + 1][kMaxPatt + 1];
-};
-
struct SaveStruct {
int _faithScore;
byte _pctHintFound[11];
@@ -391,6 +385,7 @@ private:
void prepareNextObject();
void putObject();
void resetObjectPlace();
+ void resetCoreVar();
void drawDiscussionBox();
void displayNarrativePicture(int af, int ob);
void menuUp();
@@ -407,7 +402,7 @@ public:
int _charAnswerMax[9];
byte _tabdon[4001];
bool _soundOff;
- bool _blo;
+ bool _outsideOnlyFl;
bool _destinationOk;
bool _largestClearScreen;
float _addFix;
@@ -427,17 +422,18 @@ public:
byte *_curAnim;
byte *_rightFramePict;
- Debugger _debugger;
- ScreenSurface _screenSurface;
PaletteManager _paletteManager;
GfxSurface _backgroundSurface;
Common::RandomSource _randomSource;
- SoundManager _soundManager;
- SavegameManager _savegameManager;
- Menu _menu;
- MouseHandler _mouse;
- TextHandler _text;
- DialogManager _dialogManager;
+
+ Debugger *_debugger;
+ ScreenSurface *_screenSurface;
+ SoundManager *_soundManager;
+ SavegameManager *_savegameManager;
+ Menu *_menu;
+ MouseHandler *_mouse;
+ TextHandler *_text;
+ DialogManager *_dialogManager;
MortevielleEngine(OSystem *system, const MortevielleGameDescription *gameDesc);
~MortevielleEngine();
@@ -448,7 +444,7 @@ public:
virtual Common::Error saveGameState(int slot, const Common::String &desc);
virtual Common::Error run();
virtual void pauseEngineIntern(bool pause);
- virtual GUI::Debugger *getDebugger() {return &_debugger;}
+ virtual GUI::Debugger *getDebugger() {return _debugger;}
uint32 getGameFlags() const;
Common::Language getLanguage() const;
Common::Language getOriginalLanguage() const;
diff --git a/engines/mortevielle/mouse.cpp b/engines/mortevielle/mouse.cpp
index 9eb4e129c0..2077a4cdc5 100644
--- a/engines/mortevielle/mouse.cpp
+++ b/engines/mortevielle/mouse.cpp
@@ -33,14 +33,16 @@
namespace Mortevielle {
+MouseHandler::MouseHandler(MortevielleEngine *vm) {
+ _vm = vm;
+}
+
/**
* Initialize the mouse
* @remarks Originally called 'init_mouse'
*/
void MouseHandler::initMouse() {
- _counter = 0;
_pos = Common::Point(0, 0);
-
_vm->setMouseClick(false);
}
@@ -266,8 +268,4 @@ bool MouseHandler::isMouseIn(Common::Rect r) {
return false;
}
-void MouseHandler::setParent(MortevielleEngine *vm) {
- _vm = vm;
-}
-
} // End of namespace Mortevielle
diff --git a/engines/mortevielle/mouse.h b/engines/mortevielle/mouse.h
index 1b9856e2c4..81c02dc8bd 100644
--- a/engines/mortevielle/mouse.h
+++ b/engines/mortevielle/mouse.h
@@ -36,13 +36,10 @@ class MortevielleEngine;
class MouseHandler {
private:
MortevielleEngine *_vm;
-
- int s_s[12][6];
- int _counter;
public:
Common::Point _pos;
+ MouseHandler(MortevielleEngine *vm);
- void setParent(MortevielleEngine *vm);
void initMouse();
void hideMouse();
void showMouse();
diff --git a/engines/mortevielle/outtext.cpp b/engines/mortevielle/outtext.cpp
index d50f4005de..b359860a82 100644
--- a/engines/mortevielle/outtext.cpp
+++ b/engines/mortevielle/outtext.cpp
@@ -35,6 +35,10 @@
namespace Mortevielle {
+TextHandler::TextHandler(MortevielleEngine *vm) {
+ _vm = vm;
+}
+
/**
* Next word
* @remarks Originally called 'l_motsuiv'
@@ -59,7 +63,7 @@ void TextHandler::displayStr(Common::String inputStr, int x, int y, int dx, int
// Safeguard: add $ just in case
inputStr += '$';
- _vm->_screenSurface.putxy(x, y);
+ _vm->_screenSurface->putxy(x, y);
int tab = 6;
dx *= 6;
dy *= 6;
@@ -73,19 +77,19 @@ void TextHandler::displayStr(Common::String inputStr, int x, int y, int dx, int
while (!stringParsed) {
switch (inputStr[p]) {
case '@':
- _vm->_screenSurface.drawString(s, typ);
+ _vm->_screenSurface->drawString(s, typ);
s = "";
++p;
xc = x;
yc += 6;
- _vm->_screenSurface.putxy(xc, yc);
+ _vm->_screenSurface->putxy(xc, yc);
break;
case ' ':
s += ' ';
xc += tab;
++p;
if (nextWord(p, inputStr.c_str(), tab) + xc > xf) {
- _vm->_screenSurface.drawString(s, typ);
+ _vm->_screenSurface->drawString(s, typ);
s = "";
xc = x;
yc += 6;
@@ -96,20 +100,20 @@ void TextHandler::displayStr(Common::String inputStr, int x, int y, int dx, int
do {
j = x;
do {
- _vm->_screenSurface.putxy(j, i);
- _vm->_screenSurface.drawString(" ", 0);
+ _vm->_screenSurface->putxy(j, i);
+ _vm->_screenSurface->drawString(" ", 0);
j += 6;
} while (j <= xf);
i += 6;
} while (i <= yf);
yc = y;
}
- _vm->_screenSurface.putxy(xc, yc);
+ _vm->_screenSurface->putxy(xc, yc);
}
break;
case '$':
stringParsed = true;
- _vm->_screenSurface.drawString(s, typ);
+ _vm->_screenSurface->drawString(s, typ);
break;
default:
s += inputStr[p];
@@ -218,7 +222,7 @@ void TextHandler::taffich() {
}
_vm->_destinationOk = true;
- _vm->_mouse.hideMouse();
+ _vm->_mouse->hideMouse();
drawingStartPos = 0;
Common::String filename, altFilename;
@@ -291,18 +295,14 @@ void TextHandler::taffich() {
}
loadAniFile(filename, drawingStartPos, drawingSize);
}
- _vm->_mouse.showMouse();
- if ((a < COAT_ARMS) && ((_vm->_maff < COAT_ARMS) || (_vm->_coreVar._currPlace == LANDING)) && (_vm->_currAction != _vm->_menu._opcodeEnter)) {
+ _vm->_mouse->showMouse();
+ if ((a < COAT_ARMS) && ((_vm->_maff < COAT_ARMS) || (_vm->_coreVar._currPlace == LANDING)) && (_vm->_currAction != _vm->_menu->_opcodeEnter)) {
if ((a == ATTIC) || (a == CELLAR))
_vm->displayAloneText();
- else if (!_vm->_blo)
+ else if (!_vm->_outsideOnlyFl)
_vm->getPresence(_vm->_coreVar._currPlace);
_vm->_savedBitIndex = 0;
}
}
-void TextHandler::setParent(MortevielleEngine *vm) {
- _vm = vm;
-}
-
} // End of namespace Mortevielle
diff --git a/engines/mortevielle/outtext.h b/engines/mortevielle/outtext.h
index 44868036d5..397ca850dd 100644
--- a/engines/mortevielle/outtext.h
+++ b/engines/mortevielle/outtext.h
@@ -38,7 +38,8 @@ private:
MortevielleEngine *_vm;
int nextWord(int p, const char *ch, int &tab);
public:
- void setParent(MortevielleEngine *vm);
+ TextHandler (MortevielleEngine *vm);
+
void displayStr(Common::String inputStr, int x, int y, int dx, int dy, int typ);
void loadPictureFile(Common::String filename, Common::String altFilename, int32 skipSize, int length);
void loadAniFile(Common::String filename, int32 skipSize, int length);
diff --git a/engines/mortevielle/saveload.cpp b/engines/mortevielle/saveload.cpp
index c14a03cd60..77a9a6371e 100644
--- a/engines/mortevielle/saveload.cpp
+++ b/engines/mortevielle/saveload.cpp
@@ -37,7 +37,7 @@ namespace Mortevielle {
static const char SAVEGAME_ID[4] = { 'M', 'O', 'R', 'T' };
-void SavegameManager::setParent(MortevielleEngine *vm) {
+SavegameManager::SavegameManager(MortevielleEngine *vm) {
_vm = vm;
}
@@ -116,14 +116,14 @@ bool SavegameManager::loadSavegame(const Common::String &filename) {
* Load a saved game
*/
Common::Error SavegameManager::loadGame(const Common::String &filename) {
- g_vm->_mouse.hideMouse();
+ g_vm->_mouse->hideMouse();
g_vm->displayEmptyHand();
if (loadSavegame(filename)) {
/* Initialization */
g_vm->charToHour();
g_vm->initGame();
g_vm->gameLoaded();
- g_vm->_mouse.showMouse();
+ g_vm->_mouse->showMouse();
return Common::kNoError;
} else
return Common::kUnknownError;
@@ -136,7 +136,7 @@ Common::Error SavegameManager::saveGame(int n, const Common::String &saveName) {
Common::OutSaveFile *f;
int i;
- g_vm->_mouse.hideMouse();
+ g_vm->_mouse->hideMouse();
g_vm->hourToChar();
for (i = 0; i <= 389; ++i)
@@ -165,7 +165,7 @@ Common::Error SavegameManager::saveGame(int n, const Common::String &saveName) {
// Skipped: dialog asking to swap floppy
- g_vm->_mouse.showMouse();
+ g_vm->_mouse->showMouse();
return Common::kNoError;
}
@@ -191,7 +191,7 @@ void SavegameManager::writeSavegameHeader(Common::OutSaveFile *out, const Common
// Create a thumbnail and save it
Graphics::Surface *thumb = new Graphics::Surface();
- Graphics::Surface s = g_vm->_screenSurface.lockArea(Common::Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT));
+ Graphics::Surface s = g_vm->_screenSurface->lockArea(Common::Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT));
::createThumbnail(thumb, (const byte *)s.getPixels(), SCREEN_WIDTH, SCREEN_HEIGHT, thumbPalette);
Graphics::saveThumbnail(*out, *thumb);
diff --git a/engines/mortevielle/saveload.h b/engines/mortevielle/saveload.h
index 79747e6889..9c21b0c294 100644
--- a/engines/mortevielle/saveload.h
+++ b/engines/mortevielle/saveload.h
@@ -56,7 +56,8 @@ private:
void sync_save(Common::Serializer &sz);
public:
- void setParent(MortevielleEngine *vm);
+ SavegameManager(MortevielleEngine *vm);
+
bool loadSavegame(const Common::String &filename);
Common::Error loadGame(const Common::String &filename);
Common::Error saveGame(int n, const Common::String &saveName);
diff --git a/engines/mortevielle/sound.cpp b/engines/mortevielle/sound.cpp
index b670246726..db1f7578f1 100644
--- a/engines/mortevielle/sound.cpp
+++ b/engines/mortevielle/sound.cpp
@@ -55,7 +55,8 @@ namespace Mortevielle {
const byte _tabdph[16] = {0, 10, 2, 0, 2, 10, 3, 0, 3, 7, 5, 0, 6, 7, 7, 10};
const byte _tabdbc[18] = {7, 23, 7, 14, 13, 9, 14, 9, 5, 12, 6, 12, 13, 4, 0, 4, 5, 9};
-SoundManager::SoundManager(Audio::Mixer *mixer) {
+SoundManager::SoundManager(MortevielleEngine *vm, Audio::Mixer *mixer) {
+ _vm = vm;
_mixer = mixer;
_audioStream = nullptr;
_ambiantNoiseBuf = nullptr;
@@ -72,6 +73,8 @@ SoundManager::SoundManager(Audio::Mixer *mixer) {
_queue[i]._rep = 0;
}
_buildingSentence = false;
+ _ptr_oct = 0;
+ _cfiphBuffer = nullptr;
}
SoundManager::~SoundManager() {
@@ -281,10 +284,6 @@ void SoundManager::playSong(const byte* buf, uint size, uint loops) {
_mixer->stopHandle(songHandle);
}
-void SoundManager::setParent(MortevielleEngine *vm) {
- _vm = vm;
-}
-
void SoundManager::spfrac(int wor) {
_queue[2]._rep = (uint)wor >> 12;
if ((_soundType == 0) && (_queue[2]._code != 9)) {
diff --git a/engines/mortevielle/sound.h b/engines/mortevielle/sound.h
index cc0567fd98..5321c8946c 100644
--- a/engines/mortevielle/sound.h
+++ b/engines/mortevielle/sound.h
@@ -84,15 +84,13 @@ private:
void litph(tablint &t, int typ, int tempo);
public:
- SoundManager(Audio::Mixer *mixer);
+ SoundManager(MortevielleEngine *vm, Audio::Mixer *mixer);
~SoundManager();
Audio::Mixer *_mixer;
Audio::SoundHandle _soundHandle;
uint16 *_cfiphBuffer;
- void setParent(MortevielleEngine *vm);
-
int decodeMusic(const byte *PSrc, byte *PDest, int size);
void playSong(const byte *buf, uint usize, uint loops);
void loadAmbiantSounds();
diff --git a/engines/mortevielle/utils.cpp b/engines/mortevielle/utils.cpp
index 7809143176..29c9be2e0c 100644
--- a/engines/mortevielle/utils.cpp
+++ b/engines/mortevielle/utils.cpp
@@ -50,9 +50,9 @@ bool MortevielleEngine::keyPressed() {
if (g_system->getMillis() > (_lastGameFrame + GAME_FRAME_DELAY)) {
_lastGameFrame = g_system->getMillis();
- _screenSurface.updateScreen();
+ _screenSurface->updateScreen();
- _debugger.onFrame();
+ _debugger->onFrame();
}
// Delay briefly to keep CPU usage down
@@ -92,8 +92,8 @@ bool MortevielleEngine::handleEvents() {
case Common::EVENT_LBUTTONUP:
case Common::EVENT_MOUSEMOVE:
_mousePos = Common::Point(event.mouse.x, event.mouse.y / 2);
- _mouse._pos.x = event.mouse.x;
- _mouse._pos.y = event.mouse.y / 2;
+ _mouse->_pos.x = event.mouse.x;
+ _mouse->_pos.y = event.mouse.y / 2;
if (event.type == Common::EVENT_LBUTTONDOWN)
_mouseClick = true;
@@ -121,8 +121,8 @@ void MortevielleEngine::addKeypress(Common::Event &evt) {
// Check for debugger
if ((evt.kbd.keycode == Common::KEYCODE_d) && (evt.kbd.flags & Common::KBD_CTRL)) {
// Attach to the debugger
- _debugger.attach();
- _debugger.onFrame();
+ _debugger->attach();
+ _debugger->onFrame();
} else if ((evt.kbd.keycode >= Common::KEYCODE_a) && (evt.kbd.keycode <= Common::KEYCODE_z)) {
// Handle alphabetic keys
if (evt.kbd.hasFlags(Common::KBD_CTRL))
@@ -208,7 +208,7 @@ void MortevielleEngine::initMouse() {
CursorMan.replaceCursor(CURSOR_ARROW_DATA, 16, 16, 0, 0, 0xff);
CursorMan.showMouse(true);
- _mouse.initMouse();
+ _mouse->initMouse();
}
/**
@@ -237,9 +237,9 @@ void MortevielleEngine::delay(int amount) {
while (g_system->getMillis() < endTime) {
if (g_system->getMillis() > (_lastGameFrame + GAME_FRAME_DELAY)) {
_lastGameFrame = g_system->getMillis();
- _screenSurface.updateScreen();
+ _screenSurface->updateScreen();
- _debugger.onFrame();
+ _debugger->onFrame();
}
g_system->delayMillis(10);
@@ -261,8 +261,8 @@ void MortevielleEngine::handleAction() {
bool handledOpcodeFl = false;
_controlMenu = 0;
if (!_keyPressedEsc) {
- _menu.drawMenu();
- _menu._menuDisplayed = true;
+ _menu->drawMenu();
+ _menu->_menuDisplayed = true;
temps = 0;
_key = 0;
funct = false;
@@ -270,28 +270,28 @@ void MortevielleEngine::handleAction() {
_inMainGameLoop = true;
do {
- _menu.updateMenu();
+ _menu->updateMenu();
prepareRoom();
- _mouse.moveMouse(funct, inkey);
+ _mouse->moveMouse(funct, inkey);
if (shouldQuit())
return;
++temps;
if (keyPressed() || _mouseClick) {
- _soundManager._mixer->stopHandle(_soundManager._soundHandle);
+ _soundManager->_mixer->stopHandle(_soundManager->_soundHandle);
}
- } while (!((_menu._menuSelected) || (temps > lim) || (funct) || (_anyone)));
+ } while (!((_menu->_menuSelected) || (temps > lim) || (funct) || (_anyone)));
_inMainGameLoop = false;
- _menu.eraseMenu();
- _menu._menuDisplayed = false;
- if (_menu._menuSelected && (_currMenu == MENU_SAVE)) {
+ _menu->eraseMenu();
+ _menu->_menuDisplayed = false;
+ if (_menu->_menuSelected && (_currMenu == MENU_SAVE)) {
Common::String saveName = Common::String::format("Savegame #%d", _currAction & 15);
- _savegameManager.saveGame(_currAction & 15, saveName);
+ _savegameManager->saveGame(_currAction & 15, saveName);
}
- if (_menu._menuSelected && (_currMenu == MENU_LOAD))
- _savegameManager.loadGame((_currAction & 15) - 1);
+ if (_menu->_menuSelected && (_currMenu == MENU_LOAD))
+ _savegameManager->loadGame((_currAction & 15) - 1);
if (inkey == '\103') { /* F9 */
- temps = _dialogManager.show(_hintPctMessage);
+ temps = _dialogManager->show(_hintPctMessage);
return;
} else if (inkey == '\77') {
if ((_menuOpcode != OPCODE_NONE) && ((_currMenu == MENU_ACTION) || (_currMenu == MENU_SELF))) {
@@ -321,12 +321,12 @@ void MortevielleEngine::handleAction() {
_menuOpcode = _currAction;
if (!_anyone) {
if ((_heroSearching) || (_obpart)) {
- if (_mouse._pos.y < 12)
+ if (_mouse->_pos.y < 12)
return;
- if ((_currAction == _menu._opcodeSound) || (_currAction == _menu._opcodeLift)) {
+ if ((_currAction == _menu->_opcodeSound) || (_currAction == _menu->_opcodeLift)) {
handledOpcodeFl = true;
- if ((_currAction == _menu._opcodeLift) || (_obpart)) {
+ if ((_currAction == _menu->_opcodeLift) || (_obpart)) {
endSearch();
_caff = _coreVar._currPlace;
_crep = 998;
@@ -341,7 +341,7 @@ void MortevielleEngine::handleAction() {
handleOpcode();
if ((_controlMenu == 0) && (! _loseGame) && (! _endGame)) {
- _text.taffich();
+ _text->taffich();
if (_destinationOk) {
_destinationOk = false;
drawPicture();
@@ -389,7 +389,7 @@ void MortevielleEngine::setTextColor(int col) {
*/
void MortevielleEngine::prepareScreenType1() {
// Large drawing
- _screenSurface.drawBox(0, 11, 512, 164, 15);
+ _screenSurface->drawBox(0, 11, 512, 164, 15);
}
/**
@@ -466,7 +466,7 @@ int MortevielleEngine::convertBitIndexToCharacterIndex(int bitIndex) {
*/
void MortevielleEngine::resetPresenceInRooms(int roomId) {
if (roomId == DINING_ROOM)
- _blo = false;
+ _outsideOnlyFl = false;
if (roomId != GREEN_ROOM) {
_roomPresenceLuc = false;
@@ -500,51 +500,51 @@ void MortevielleEngine::resetPresenceInRooms(int roomId) {
* @remarks Originally called 'affper'
*/
void MortevielleEngine::showPeoplePresent(int bitIndex) {
- int xp = 580 - (_screenSurface.getStringWidth("LEO") / 2);
+ int xp = 580 - (_screenSurface->getStringWidth("LEO") / 2);
for (int i = 1; i <= 8; ++i)
- _menu.disableMenuItem(_menu._discussMenu[i]);
+ _menu->disableMenuItem(_menu->_discussMenu[i]);
clearUpperRightPart();
if ((bitIndex & 128) == 128) {
- _screenSurface.putxy(xp, 24);
- _screenSurface.drawString("LEO", 4);
- _menu.enableMenuItem(_menu._discussMenu[1]);
+ _screenSurface->putxy(xp, 24);
+ _screenSurface->drawString("LEO", 4);
+ _menu->enableMenuItem(_menu->_discussMenu[1]);
}
if ((bitIndex & 64) == 64) {
- _screenSurface.putxy(xp, 32);
- _screenSurface.drawString("PAT", 4);
- _menu.enableMenuItem(_menu._discussMenu[2]);
+ _screenSurface->putxy(xp, 32);
+ _screenSurface->drawString("PAT", 4);
+ _menu->enableMenuItem(_menu->_discussMenu[2]);
}
if ((bitIndex & 32) == 32) {
- _screenSurface.putxy(xp, 40);
- _screenSurface.drawString("GUY", 4);
- _menu.enableMenuItem(_menu._discussMenu[3]);
+ _screenSurface->putxy(xp, 40);
+ _screenSurface->drawString("GUY", 4);
+ _menu->enableMenuItem(_menu->_discussMenu[3]);
}
if ((bitIndex & 16) == 16) {
- _screenSurface.putxy(xp, 48);
- _screenSurface.drawString("EVA", 4);
- _menu.enableMenuItem(_menu._discussMenu[4]);
+ _screenSurface->putxy(xp, 48);
+ _screenSurface->drawString("EVA", 4);
+ _menu->enableMenuItem(_menu->_discussMenu[4]);
}
if ((bitIndex & 8) == 8) {
- _screenSurface.putxy(xp, 56);
- _screenSurface.drawString("BOB", 4);
- _menu.enableMenuItem(_menu._discussMenu[5]);
+ _screenSurface->putxy(xp, 56);
+ _screenSurface->drawString("BOB", 4);
+ _menu->enableMenuItem(_menu->_discussMenu[5]);
}
if ((bitIndex & 4) == 4) {
- _screenSurface.putxy(xp, 64);
- _screenSurface.drawString("LUC", 4);
- _menu.enableMenuItem(_menu._discussMenu[6]);
+ _screenSurface->putxy(xp, 64);
+ _screenSurface->drawString("LUC", 4);
+ _menu->enableMenuItem(_menu->_discussMenu[6]);
}
if ((bitIndex & 2) == 2) {
- _screenSurface.putxy(xp, 72);
- _screenSurface.drawString("IDA", 4);
- _menu.enableMenuItem(_menu._discussMenu[7]);
+ _screenSurface->putxy(xp, 72);
+ _screenSurface->drawString("IDA", 4);
+ _menu->enableMenuItem(_menu->_discussMenu[7]);
}
if ((bitIndex & 1) == 1) {
- _screenSurface.putxy(xp, 80);
- _screenSurface.drawString("MAX", 4);
- _menu.enableMenuItem(_menu._discussMenu[8]);
+ _screenSurface->putxy(xp, 80);
+ _screenSurface->drawString("MAX", 4);
+ _menu->enableMenuItem(_menu->_discussMenu[8]);
}
_currBitIndex = bitIndex;
}
@@ -605,7 +605,7 @@ int MortevielleEngine::getPresenceStatsGreenRoom() {
else if ((hour >= 0) && (hour < 8))
retVal = 70;
- _menu.updateMenu();
+ _menu->updateMenu();
return retVal;
}
@@ -698,19 +698,19 @@ int MortevielleEngine::getPresenceStatsRedRoom() {
*/
void MortevielleEngine::displayAloneText() {
for (int i = 1; i <= 8; ++i)
- _menu.disableMenuItem(_menu._discussMenu[i]);
+ _menu->disableMenuItem(_menu->_discussMenu[i]);
Common::String sYou = getEngineString(S_YOU);
Common::String sAre = getEngineString(S_ARE);
Common::String sAlone = getEngineString(S_ALONE);
clearUpperRightPart();
- _screenSurface.putxy(580 - (_screenSurface.getStringWidth(sYou) / 2), 30);
- _screenSurface.drawString(sYou, 4);
- _screenSurface.putxy(580 - (_screenSurface.getStringWidth(sAre) / 2), 50);
- _screenSurface.drawString(sAre, 4);
- _screenSurface.putxy(580 - (_screenSurface.getStringWidth(sAlone) / 2), 70);
- _screenSurface.drawString(sAlone, 4);
+ _screenSurface->putxy(580 - (_screenSurface->getStringWidth(sYou) / 2), 30);
+ _screenSurface->drawString(sYou, 4);
+ _screenSurface->putxy(580 - (_screenSurface->getStringWidth(sAre) / 2), 50);
+ _screenSurface->drawString(sAre, 4);
+ _screenSurface->putxy(580 - (_screenSurface->getStringWidth(sAlone) / 2), 70);
+ _screenSurface->drawString(sAlone, 4);
_currBitIndex = 0;
}
@@ -1080,7 +1080,7 @@ void MortevielleEngine::initGame() {
_place = MANOR_FRONT;
_currentHourCount = 0;
if (!_coreVar._alreadyEnteredManor)
- _blo = true;
+ _outsideOnlyFl = true;
_inGameHourDuration = kTime1;
_currentTime = readclock();
}
@@ -1255,24 +1255,24 @@ void MortevielleEngine::startMusicOrSpeech(int so) {
;
} else if ((!_introSpeechPlayed) && (!_coreVar._alreadyEnteredManor)) {
// Type 1: Speech
- _soundManager.startSpeech(10, 1, 1);
+ _soundManager->startSpeech(10, 1, 1);
_introSpeechPlayed = true;
} else {
if (((_coreVar._currPlace == MOUNTAIN) || (_coreVar._currPlace == MANOR_FRONT) || (_coreVar._currPlace == MANOR_BACK)) && (getRandomNumber(1, 3) == 2))
// Type 1: Speech
- _soundManager.startSpeech(9, getRandomNumber(2, 4), 1);
+ _soundManager->startSpeech(9, getRandomNumber(2, 4), 1);
else if ((_coreVar._currPlace == CHAPEL) && (getRandomNumber(1, 2) == 1))
// Type 1: Speech
- _soundManager.startSpeech(8, 1, 1);
+ _soundManager->startSpeech(8, 1, 1);
else if ((_coreVar._currPlace == WELL) && (getRandomNumber(1, 2) == 2))
// Type 1: Speech
- _soundManager.startSpeech(12, 1, 1);
+ _soundManager->startSpeech(12, 1, 1);
else if (_coreVar._currPlace == INSIDE_WELL)
// Type 1: Speech
- _soundManager.startSpeech(13, 1, 1);
+ _soundManager->startSpeech(13, 1, 1);
else
// Type 2 : music
- _soundManager.startSpeech(getRandomNumber(1, 17), 1, 2);
+ _soundManager->startSpeech(getRandomNumber(1, 17), 1, 2);
}
}
@@ -1284,13 +1284,13 @@ void MortevielleEngine::loseGame() {
resetOpenObjects();
_roomDoorId = OWN_ROOM;
_curSearchObjId = 0;
- _menu.unsetSearchMenu();
- if (!_blo)
+ _menu->unsetSearchMenu();
+ if (!_outsideOnlyFl)
getPresence(MANOR_FRONT);
_loseGame = true;
clearUpperLeftPart();
- _screenSurface.drawBox(60, 35, 400, 50, 15);
+ _screenSurface->drawBox(60, 35, 400, 50, 15);
handleDescriptionText(9, _crep);
clearDescriptionBar();
clearVerbBar();
@@ -1333,20 +1333,20 @@ void MortevielleEngine::startDialog(int16 rep) {
assert(rep >= 0);
- _mouse.hideMouse();
+ _mouse->hideMouse();
Common::String dialogStr = getString(rep + kDialogStringIndex);
- _text.displayStr(dialogStr, 230, 4, 65, 26, 5);
- _dialogManager.drawF3F8();
+ _text->displayStr(dialogStr, 230, 4, 65, 26, 5);
+ _dialogManager->drawF3F8();
key = 0;
do {
- _soundManager.startSpeech(rep, haut[_caff - 69], 0);
- key = _dialogManager.waitForF3F8();
+ _soundManager->startSpeech(rep, haut[_caff - 69], 0);
+ key = _dialogManager->waitForF3F8();
if (shouldQuit())
return;
} while (key != 66);
clearScreen();
- _mouse.showMouse();
+ _mouse->showMouse();
}
/**
@@ -1357,7 +1357,7 @@ void MortevielleEngine::endSearch() {
_heroSearching = false;
_obpart = false;
_searchCount = 0;
- _menu.unsetSearchMenu();
+ _menu->unsetSearchMenu();
}
/**
@@ -1379,21 +1379,21 @@ void MortevielleEngine::gotoDiningRoom() {
showPeoplePresent(_currBitIndex);
_caff = 77;
drawPictureWithText();
- _screenSurface.drawBox(223, 47, 155, 92, 15);
+ _screenSurface->drawBox(223, 47, 155, 92, 15);
handleDescriptionText(2, 33);
testKey(false);
menuUp();
- _mouse.hideMouse();
+ _mouse->hideMouse();
clearScreen();
drawDiscussionBox();
startDialog(140);
drawRightFrame();
drawClock();
- _mouse.showMouse();
+ _mouse->showMouse();
_coreVar._currPlace = OWN_ROOM;
prepareDisplayText();
resetPresenceInRooms(DINING_ROOM);
- if (!_blo)
+ if (!_outsideOnlyFl)
getPresence(OWN_ROOM);
_currBitIndex = 0;
_savedBitIndex = 0;
@@ -1451,8 +1451,8 @@ void MortevielleEngine::floodedInWell() {
* @remarks Originally called 'antegame'
*/
void MortevielleEngine::gameLoaded() {
- _mouse.hideMouse();
- _menu._menuDisplayed = false;
+ _mouse->hideMouse();
+ _menu->_menuDisplayed = false;
_loseGame = true;
_anyone = false;
_destinationOk = true;
@@ -1490,11 +1490,11 @@ void MortevielleEngine::gameLoaded() {
handleDescriptionText(2, _crep);
clearVerbBar();
_endGame = false;
- _menu.setDestinationText(_coreVar._currPlace);
- _menu.setInventoryText();
+ _menu->setDestinationText(_coreVar._currPlace);
+ _menu->setInventoryText();
if (_coreVar._selectedObjectId != 0)
displayItemInHand(_coreVar._selectedObjectId + 400);
- _mouse.showMouse();
+ _mouse->showMouse();
}
/**
@@ -1508,7 +1508,7 @@ void MortevielleEngine::handleOpcode() {
_keyPressedEsc = false;
if (!_anyone) {
if (_uptodatePresence) {
- if ((_currMenu == MENU_MOVE) || (_currAction == _menu._opcodeLeave) || (_currAction == _menu._opcodeSleep) || (_currAction == _menu._opcodeEat)) {
+ if ((_currMenu == MENU_MOVE) || (_currAction == _menu->_opcodeLeave) || (_currAction == _menu->_opcodeSleep) || (_currAction == _menu->_opcodeEat)) {
_controlMenu = 4;
menuUp();
return;
@@ -1521,60 +1521,60 @@ void MortevielleEngine::handleOpcode() {
fctDiscuss();
else if (_currMenu == MENU_INVENTORY)
fctInventoryTake();
- else if (_currAction == _menu._opcodeAttach)
+ else if (_currAction == _menu->_opcodeAttach)
fctAttach();
- else if (_currAction == _menu._opcodeWait)
+ else if (_currAction == _menu->_opcodeWait)
fctWait();
- else if (_currAction == _menu._opcodeForce)
+ else if (_currAction == _menu->_opcodeForce)
fctForce();
- else if (_currAction == _menu._opcodeSleep)
+ else if (_currAction == _menu->_opcodeSleep)
fctSleep();
- else if (_currAction == _menu._opcodeListen)
+ else if (_currAction == _menu->_opcodeListen)
fctListen();
- else if (_currAction == _menu._opcodeEnter)
+ else if (_currAction == _menu->_opcodeEnter)
fctEnter();
- else if (_currAction == _menu._opcodeClose)
+ else if (_currAction == _menu->_opcodeClose)
fctClose();
- else if (_currAction == _menu._opcodeSearch)
+ else if (_currAction == _menu->_opcodeSearch)
fctSearch();
- else if (_currAction == _menu._opcodeKnock)
+ else if (_currAction == _menu->_opcodeKnock)
fctKnock();
- else if (_currAction == _menu._opcodeScratch)
+ else if (_currAction == _menu->_opcodeScratch)
fctScratch();
- else if (_currAction == _menu._opcodeRead)
+ else if (_currAction == _menu->_opcodeRead)
fctRead();
- else if (_currAction == _menu._opcodeEat)
+ else if (_currAction == _menu->_opcodeEat)
fctEat();
- else if (_currAction == _menu._opcodePlace)
+ else if (_currAction == _menu->_opcodePlace)
fctPlace();
- else if (_currAction == _menu._opcodeOpen)
+ else if (_currAction == _menu->_opcodeOpen)
fctOpen();
- else if (_currAction == _menu._opcodeTake)
+ else if (_currAction == _menu->_opcodeTake)
fctTake();
- else if (_currAction == _menu._opcodeLook)
+ else if (_currAction == _menu->_opcodeLook)
fctLook();
- else if (_currAction == _menu._opcodeSmell)
+ else if (_currAction == _menu->_opcodeSmell)
fctSmell();
- else if (_currAction == _menu._opcodeSound)
+ else if (_currAction == _menu->_opcodeSound)
fctSound();
- else if (_currAction == _menu._opcodeLeave)
+ else if (_currAction == _menu->_opcodeLeave)
fctLeave();
- else if (_currAction == _menu._opcodeLift)
+ else if (_currAction == _menu->_opcodeLift)
fctLift();
- else if (_currAction == _menu._opcodeTurn)
+ else if (_currAction == _menu->_opcodeTurn)
fctTurn();
- else if (_currAction == _menu._opcodeSSearch)
+ else if (_currAction == _menu->_opcodeSSearch)
fctSelfSearch();
- else if (_currAction == _menu._opcodeSRead)
+ else if (_currAction == _menu->_opcodeSRead)
fctSelfRead();
- else if (_currAction == _menu._opcodeSPut)
+ else if (_currAction == _menu->_opcodeSPut)
fctSelfPut();
- else if (_currAction == _menu._opcodeSLook)
+ else if (_currAction == _menu->_opcodeSLook)
fctSelftLook();
_hiddenHero = false;
- if (_currAction == _menu._opcodeSHide)
+ if (_currAction == _menu->_opcodeSHide)
fctSelfHide();
} else if (_anyone) {
interactNPC();
@@ -1640,9 +1640,9 @@ void MortevielleEngine::charToHour() {
* @remarks Originally called 'clsf1'
*/
void MortevielleEngine::clearUpperLeftPart() {
- _mouse.hideMouse();
- _screenSurface.fillRect(0, Common::Rect(0, 11, 514, 175));
- _mouse.showMouse();
+ _mouse->hideMouse();
+ _screenSurface->fillRect(0, Common::Rect(0, 11, 514, 175));
+ _mouse->showMouse();
}
/**
@@ -1650,16 +1650,16 @@ void MortevielleEngine::clearUpperLeftPart() {
* @remarks Originally called 'clsf2'
*/
void MortevielleEngine::clearDescriptionBar() {
- _mouse.hideMouse();
+ _mouse->hideMouse();
if (_largestClearScreen) {
- _screenSurface.fillRect(0, Common::Rect(1, 176, 633, 199));
- _screenSurface.drawBox(0, 176, 634, 23, 15);
+ _screenSurface->fillRect(0, Common::Rect(1, 176, 633, 199));
+ _screenSurface->drawBox(0, 176, 634, 23, 15);
_largestClearScreen = false;
} else {
- _screenSurface.fillRect(0, Common::Rect(1, 176, 633, 190));
- _screenSurface.drawBox(0, 176, 634, 14, 15);
+ _screenSurface->fillRect(0, Common::Rect(1, 176, 633, 190));
+ _screenSurface->drawBox(0, 176, 634, 14, 15);
}
- _mouse.showMouse();
+ _mouse->showMouse();
}
/**
@@ -1667,10 +1667,10 @@ void MortevielleEngine::clearDescriptionBar() {
* @remarks Originally called 'clsf3'
*/
void MortevielleEngine::clearVerbBar() {
- _mouse.hideMouse();
- _screenSurface.fillRect(0, Common::Rect(1, 192, 633, 199));
- _screenSurface.drawBox(0, 191, 634, 8, 15);
- _mouse.showMouse();
+ _mouse->hideMouse();
+ _screenSurface->fillRect(0, Common::Rect(1, 192, 633, 199));
+ _screenSurface->drawBox(0, 191, 634, 8, 15);
+ _mouse->showMouse();
}
/**
@@ -1680,10 +1680,10 @@ void MortevielleEngine::clearVerbBar() {
void MortevielleEngine::clearUpperRightPart() {
Common::String st;
- _mouse.hideMouse();
+ _mouse->hideMouse();
// Clear ambiance description
- _screenSurface.fillRect(15, Common::Rect(544, 93, 600, 98));
+ _screenSurface->fillRect(15, Common::Rect(544, 93, 600, 98));
if (_coreVar._faithScore < 33)
st = getEngineString(S_COOL);
else if (_coreVar._faithScore < 66)
@@ -1691,13 +1691,13 @@ void MortevielleEngine::clearUpperRightPart() {
else if (_coreVar._faithScore > 65)
st = getEngineString(S_MALSAINE);
- int x1 = 580 - (_screenSurface.getStringWidth(st) / 2);
- _screenSurface.putxy(x1, 92);
- _screenSurface.drawString(st, 4);
+ int x1 = 580 - (_screenSurface->getStringWidth(st) / 2);
+ _screenSurface->putxy(x1, 92);
+ _screenSurface->drawString(st, 4);
// Clear person list
- _screenSurface.fillRect(15, Common::Rect(560, 24, 610, 86));
- _mouse.showMouse();
+ _screenSurface->fillRect(15, Common::Rect(560, 24, 610, 86));
+ _mouse->showMouse();
}
/**
@@ -1713,7 +1713,7 @@ int MortevielleEngine::getRandomNumber(int minval, int maxval) {
* @remarks Originally called 'aldepl'
*/
void MortevielleEngine::showMoveMenuAlert() {
- _dialogManager.show(getEngineString(S_USE_DEP_MENU));
+ _dialogManager->show(getEngineString(S_USE_DEP_MENU));
}
/**
@@ -1888,24 +1888,18 @@ void MortevielleEngine::resetObjectPlace() {
_tabdon[i] = _tabdon[i + 390];
}
-/**
- * Engine function - When restarting the game, reset the main variables used by the engine
- * @remarks Originally called 'inzon'
- */
-void MortevielleEngine::resetVariables() {
- resetObjectPlace();
-
- _coreVar._alreadyEnteredManor = false;
- _coreVar._selectedObjectId = 0;
- _coreVar._cellarObjectId = 0;
- _coreVar._atticBallHoleObjectId = 0;
- _coreVar._atticRodHoleObjectId = 0;
- _coreVar._wellObjectId = 0;
- _coreVar._secretPassageObjectId = 0;
- _coreVar._purpleRoomObjectId = 136;
- _coreVar._cryptObjectId = 141;
- _coreVar._faithScore = getRandomNumber(4, 10);
- _coreVar._currPlace = MANOR_FRONT;
+void MortevielleEngine::resetCoreVar() {
+ _saveStruct._alreadyEnteredManor = _coreVar._alreadyEnteredManor = false;
+ _saveStruct._selectedObjectId = _coreVar._selectedObjectId = 0;
+ _saveStruct._cellarObjectId = _coreVar._cellarObjectId = 0;
+ _saveStruct._atticBallHoleObjectId = _coreVar._atticBallHoleObjectId = 0;
+ _saveStruct._atticRodHoleObjectId = _coreVar._atticRodHoleObjectId = 0;
+ _saveStruct._wellObjectId = _coreVar._wellObjectId = 0;
+ _saveStruct._secretPassageObjectId = _coreVar._secretPassageObjectId = 0;
+ _saveStruct._purpleRoomObjectId = _coreVar._purpleRoomObjectId = 136;
+ _saveStruct._cryptObjectId = _coreVar._cryptObjectId = 141;
+ _saveStruct._faithScore = _coreVar._faithScore = getRandomNumber(4, 10);
+ _saveStruct._currPlace = _coreVar._currPlace = MANOR_FRONT;
for (int i = 2; i <= 6; ++i)
_coreVar._inventory[i] = 0;
@@ -1913,7 +1907,7 @@ void MortevielleEngine::resetVariables() {
// Only object in inventory: a gun
_coreVar._inventory[1] = 113;
- _coreVar._fullHour = (unsigned char)20;
+ _saveStruct._fullHour = _coreVar._fullHour = (unsigned char)20;
for (int i = 1; i <= 10; ++i)
_coreVar._pctHintFound[i] = ' ';
@@ -1931,6 +1925,14 @@ void MortevielleEngine::resetVariables() {
_coreVar._availableQuestion[i] = ' ';
_coreVar._availableQuestion[33] = '*';
+}
+/**
+ * Engine function - When restarting the game, reset the main variables used by the engine
+ * @remarks Originally called 'inzon'
+ */
+void MortevielleEngine::resetVariables() {
+ resetObjectPlace();
+ resetCoreVar();
for (int i = 1; i <= 8; ++i)
_charAnswerCount[i] = 0;
@@ -2074,10 +2076,10 @@ void MortevielleEngine::loadCFIPH() {
error("Missing file - *cfiph.mor");
}
- _soundManager._cfiphBuffer = (uint16 *)malloc(sizeof(uint16) * (f.size() / 2));
+ _soundManager->_cfiphBuffer = (uint16 *)malloc(sizeof(uint16) * (f.size() / 2));
for (int i = 0; i < (f.size() / 2); ++i)
- _soundManager._cfiphBuffer[i] = f.readUint16BE();
+ _soundManager->_cfiphBuffer[i] = f.readUint16BE();
f.close();
}
@@ -2102,10 +2104,10 @@ void MortevielleEngine::music() {
f.read(compMusicBuf, size);
f.close();
- int musicSize = _soundManager.decodeMusic(compMusicBuf, musicBuf, size);
+ int musicSize = _soundManager->decodeMusic(compMusicBuf, musicBuf, size);
free(compMusicBuf);
- _soundManager.playSong(musicBuf, musicSize, 5);
+ _soundManager->playSong(musicBuf, musicSize, 5);
while (keyPressed())
getChar();
@@ -2120,14 +2122,14 @@ void MortevielleEngine::showTitleScreen() {
clearScreen();
handleDescriptionText(7, 2035);
_caff = 51;
- _text.taffich();
+ _text->taffich();
testKeyboard();
clearScreen();
draw(0, 0);
Common::String cpr = "COPYRIGHT 1989 : LANKHOR";
- _screenSurface.putxy(104 + 72 * kResolutionScaler, 185);
- _screenSurface.drawString(cpr, 0);
+ _screenSurface->putxy(104 + 72 * kResolutionScaler, 185);
+ _screenSurface->drawString(cpr, 0);
}
/**
@@ -2135,10 +2137,10 @@ void MortevielleEngine::showTitleScreen() {
* @remarks Originally called 'dessine'
*/
void MortevielleEngine::draw(int x, int y) {
- _mouse.hideMouse();
+ _mouse->hideMouse();
setPal(_numpal);
displayPicture(_curPict, x, y);
- _mouse.showMouse();
+ _mouse->showMouse();
}
/**
@@ -2147,9 +2149,9 @@ void MortevielleEngine::draw(int x, int y) {
*/
void MortevielleEngine::drawRightFrame() {
setPal(89);
- _mouse.hideMouse();
+ _mouse->hideMouse();
displayPicture(_rightFramePict, 0, 0);
- _mouse.showMouse();
+ _mouse->showMouse();
}
/**
@@ -2205,10 +2207,10 @@ void MortevielleEngine::prepareRoom() {
_minute = 30;
drawClock();
}
- if (_mouse._pos.y < 12)
+ if (_mouse->_pos.y < 12)
return;
- if (!_blo) {
+ if (!_outsideOnlyFl) {
if ((hour == 12) || ((hour > 18) && (hour < 21)) || ((hour >= 0) && (hour < 7)))
_inGameHourDuration = kTime2;
else
@@ -2221,8 +2223,8 @@ void MortevielleEngine::prepareRoom() {
int newTime = readclock();
if ((newTime - _currentTime) > _inGameHourDuration) {
- bool activeMenu = _menu._menuActive;
- _menu.eraseMenu();
+ bool activeMenu = _menu->_menuActive;
+ _menu->eraseMenu();
_currentHourCount += ((newTime - _currentTime) / _inGameHourDuration);
_currentTime = newTime;
switch (_place) {
@@ -2280,8 +2282,8 @@ void MortevielleEngine::prepareRoom() {
prepareScreenType2();
displayTextInVerbBar(getEngineString(S_HEAR_NOISE));
int rand = (getRandomNumber(0, 4)) - 2;
- _soundManager.startSpeech(1, rand, 1);
- _soundManager.waitSpeech();
+ _soundManager->startSpeech(1, rand, 1);
+ _soundManager->waitSpeech();
clearVerbBar();
}
}
@@ -2289,7 +2291,7 @@ void MortevielleEngine::prepareRoom() {
}
if (activeMenu)
- _menu.drawMenu();
+ _menu->drawMenu();
}
}
_endTime = readclock();
@@ -2315,15 +2317,15 @@ void MortevielleEngine::drawClock() {
const int y = 123;
const int rg = 9;
- _mouse.hideMouse();
+ _mouse->hideMouse();
- _screenSurface.drawRectangle(570, 118, 20, 10);
- _screenSurface.drawRectangle(578, 114, 6, 18);
+ _screenSurface->drawRectangle(570, 118, 20, 10);
+ _screenSurface->drawRectangle(578, 114, 6, 18);
if (_minute == 0)
- _screenSurface.drawLine(((uint)x >> 1) * kResolutionScaler, y, ((uint)x >> 1) * kResolutionScaler, (y - rg), 1);
+ _screenSurface->drawLine(((uint)x >> 1) * kResolutionScaler, y, ((uint)x >> 1) * kResolutionScaler, (y - rg), 1);
else
- _screenSurface.drawLine(((uint)x >> 1) * kResolutionScaler, y, ((uint)x >> 1) * kResolutionScaler, (y + rg), 1);
+ _screenSurface->drawLine(((uint)x >> 1) * kResolutionScaler, y, ((uint)x >> 1) * kResolutionScaler, (y + rg), 1);
int hour12 = _hour;
if (hour12 > 12)
@@ -2331,20 +2333,20 @@ void MortevielleEngine::drawClock() {
if (hour12 == 0)
hour12 = 12;
- _screenSurface.drawLine(((uint)x >> 1) * kResolutionScaler, y, ((uint)(x + cv[0][hour12 - 1]) >> 1) * kResolutionScaler, y + cv[1][hour12 - 1], 1);
- _mouse.showMouse();
- _screenSurface.putxy(568, 154);
+ _screenSurface->drawLine(((uint)x >> 1) * kResolutionScaler, y, ((uint)(x + cv[0][hour12 - 1]) >> 1) * kResolutionScaler, y + cv[1][hour12 - 1], 1);
+ _mouse->showMouse();
+ _screenSurface->putxy(568, 154);
if (_hour > 11)
- _screenSurface.drawString("PM ", 1);
+ _screenSurface->drawString("PM ", 1);
else
- _screenSurface.drawString("AM ", 1);
+ _screenSurface->drawString("AM ", 1);
- _screenSurface.putxy(550, 160);
+ _screenSurface->putxy(550, 160);
if ((_day >= 0) && (_day <= 8)) {
Common::String tmp = getEngineString(S_DAY);
tmp.insertChar((char)(_day + 49), 0);
- _screenSurface.drawString(tmp, 1);
+ _screenSurface->drawString(tmp, 1);
}
}
@@ -2364,8 +2366,7 @@ Common::String MortevielleEngine::copy(const Common::String &s, int idx, size_t
// Copy the substring into a temporary buffer
char *tmp = new char[size + 1];
- strncpy(tmp, s.c_str() + idx - 1, size);
- tmp[size] = '\0';
+ Common::strlcpy(tmp, s.c_str() + idx - 1, size + 1);
Common::String result(tmp);
delete[] tmp;
@@ -2377,7 +2378,7 @@ Common::String MortevielleEngine::copy(const Common::String &s, int idx, size_t
* @remarks Originally called 'hirs'
*/
void MortevielleEngine::clearScreen() {
- _screenSurface.clearScreen();
+ _screenSurface->clearScreen();
}
/**
@@ -2392,8 +2393,8 @@ void MortevielleEngine::initCaveOrCellar() {
prepareScreenType2();
displayTextInVerbBar(getEngineString(S_SOMEONE_ENTERS));
int rand = (getRandomNumber(0, 4)) - 2;
- _soundManager.startSpeech(2, rand, 1);
- _soundManager.waitSpeech();
+ _soundManager->startSpeech(2, rand, 1);
+ _soundManager->waitSpeech();
// The original was doing here a useless loop.
// It has been removed
@@ -2417,7 +2418,7 @@ void MortevielleEngine::displayControlMenu() {
void MortevielleEngine::displayPicture(const byte *pic, int x, int y) {
GfxSurface surface;
surface.decode(pic);
- _screenSurface.drawPicture(surface, x, y);
+ _screenSurface->drawPicture(surface, x, y);
}
void MortevielleEngine::adzon() {
@@ -2466,7 +2467,7 @@ void MortevielleEngine::displayTextInDescriptionBar(int x, int y, int nb, int me
Common::String tmpStr = getString(mesgId);
if ((y == 182) && ((int) tmpStr.size() > nb))
y = 176;
- _text.displayStr(tmpStr, x, y, nb, 20, _textColor);
+ _text->displayStr(tmpStr, x, y, nb, 20, _textColor);
}
/**
@@ -2483,7 +2484,7 @@ void MortevielleEngine::handleDescriptionText(int f, int mesgId) {
_largestClearScreen = false;
clearDescriptionBar();
- _text.displayStr(tmpStr, 8, 176, 85, 3, 5);
+ _text->displayStr(tmpStr, 8, 176, 85, 3, 5);
} else {
mapMessageId(mesgId);
switch (f) {
@@ -2512,7 +2513,7 @@ void MortevielleEngine::handleDescriptionText(int f, int mesgId) {
i = 5;
Common::String tmpStr = getString(mesgId);
- _text.displayStr(tmpStr, 80, 40, 60, 25, i);
+ _text->displayStr(tmpStr, 80, 40, 60, 25, i);
if (mesgId == 180)
_coreVar._pctHintFound[6] = '*';
@@ -2585,32 +2586,32 @@ void MortevielleEngine::resetOpenObjects() {
*/
void MortevielleEngine::displayTextBlock(Common::String text) {
// Some dead code was present in the original: removed
- _screenSurface.putxy(8, 177);
+ _screenSurface->putxy(8, 177);
int tlig = 59 + (kResolutionScaler - 1) * 36;
if ((int)text.size() < tlig)
- _screenSurface.drawString(text, 5);
+ _screenSurface->drawString(text, 5);
else if ((int)text.size() < (tlig << 1)) {
- _screenSurface.putxy(8, 176);
- _screenSurface.drawString(copy(text, 1, (tlig - 1)), 5);
- _screenSurface.putxy(8, 182);
- _screenSurface.drawString(copy(text, tlig, tlig << 1), 5);
+ _screenSurface->putxy(8, 176);
+ _screenSurface->drawString(copy(text, 1, (tlig - 1)), 5);
+ _screenSurface->putxy(8, 182);
+ _screenSurface->drawString(copy(text, tlig, tlig << 1), 5);
} else {
_largestClearScreen = true;
clearDescriptionBar();
- _screenSurface.putxy(8, 176);
- _screenSurface.drawString(copy(text, 1, (tlig - 1)), 5);
- _screenSurface.putxy(8, 182);
- _screenSurface.drawString(copy(text, tlig, ((tlig << 1) - 1)), 5);
- _screenSurface.putxy(8, 190);
- _screenSurface.drawString(copy(text, tlig << 1, tlig * 3), 5);
+ _screenSurface->putxy(8, 176);
+ _screenSurface->drawString(copy(text, 1, (tlig - 1)), 5);
+ _screenSurface->putxy(8, 182);
+ _screenSurface->drawString(copy(text, tlig, ((tlig << 1) - 1)), 5);
+ _screenSurface->putxy(8, 190);
+ _screenSurface->drawString(copy(text, tlig << 1, tlig * 3), 5);
}
}
void MortevielleEngine::displayTextInVerbBar(Common::String text) {
clearVerbBar();
- _screenSurface.putxy(8, 192);
- _screenSurface.drawString(text, 5);
+ _screenSurface->putxy(8, 192);
+ _screenSurface->drawString(text, 5);
}
/**
@@ -2623,8 +2624,8 @@ void MortevielleEngine::displayItemInHand(int objId) {
if (objId != 500)
strp = getString(objId - 501 + kInventoryStringIndex);
- _menu.setText(_menu._inventoryMenu[8], strp);
- _menu.disableMenuItem(_menu._inventoryMenu[8]);
+ _menu->setText(_menu->_inventoryMenu[8], strp);
+ _menu->disableMenuItem(_menu->_inventoryMenu[8]);
}
/**
@@ -2832,7 +2833,7 @@ int MortevielleEngine::getPresence(int roomId) {
* @remarks Originally called 'writetp'
*/
void MortevielleEngine::displayQuestionText(Common::String s, int cmd) {
- _screenSurface.drawString(s, cmd);
+ _screenSurface->drawString(s, cmd);
}
/**
@@ -2856,7 +2857,7 @@ void MortevielleEngine::displayAnimFrame(int frameNum, int animId) {
GfxSurface surface;
surface.decode(&_curAnim[offset]);
- _screenSurface.drawPicture(surface, 0, 12);
+ _screenSurface->drawPicture(surface, 0, 12);
prepareScreenType1();
}
@@ -2869,10 +2870,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, 122, 15); // Medium box
} else if (_caff > 69) {
draw(112, 48); // Heads
- _screenSurface.drawBox(222, 47, 155, 92, 15);
+ _screenSurface->drawBox(222, 47, 155, 92, 15);
} else {
draw(0, 12);
prepareScreenType1();
@@ -2911,7 +2912,7 @@ void MortevielleEngine::drawPicture() {
}
void MortevielleEngine::drawPictureWithText() {
- _text.taffich();
+ _text->taffich();
drawPicture();
_destinationOk = false;
}
@@ -2925,7 +2926,7 @@ void MortevielleEngine::testKey(bool d) {
int x, y;
bool click;
- _mouse.hideMouse();
+ _mouse->hideMouse();
displayStatusInDescriptionBar('K');
// Wait for release from any key or mouse button
@@ -2933,8 +2934,10 @@ void MortevielleEngine::testKey(bool d) {
_key = gettKeyPressed();
do {
- _mouse.getMousePosition(x, y, click);
- keyPressed();
+ _mouse->getMousePosition(x, y, click);
+ quest = keyPressed();
+ if (quest && shouldQuit())
+ return;
} while (click);
// Event loop
@@ -2942,14 +2945,14 @@ void MortevielleEngine::testKey(bool d) {
if (d)
prepareRoom();
quest = keyPressed();
- _mouse.getMousePosition(x, y, click);
+ _mouse->getMousePosition(x, y, click);
if (shouldQuit())
return;
} while (!(quest || (click) || (d && _anyone)));
if (quest)
gettKeyPressed();
setMouseClick(false);
- _mouse.showMouse();
+ _mouse->showMouse();
}
/**
@@ -3060,7 +3063,7 @@ void MortevielleEngine::getSearchDescription(int objId) {
* @remarks Originally called 'mennor'
*/
void MortevielleEngine::menuUp() {
- _menu.menuUp(_currMenu);
+ _menu->menuUp(_currMenu);
}
/**
@@ -3069,7 +3072,7 @@ void MortevielleEngine::menuUp() {
*/
void MortevielleEngine::drawDiscussionBox() {
draw(10, 80);
- _screenSurface.drawBox(18, 79, 155, 92, 15);
+ _screenSurface->drawBox(18, 79, 155, 92, 15);
}
/**
@@ -3100,7 +3103,7 @@ void MortevielleEngine::addObjectToInventory(int objectId) {
if (_coreVar._inventory[i] == 0) {
_coreVar._inventory[i] = objectId;
- _menu.setInventoryText();
+ _menu->setInventoryText();
} else
// Inventory is full
_crep = 139;
@@ -3111,8 +3114,8 @@ void MortevielleEngine::addObjectToInventory(int objectId) {
* @remarks Originally called 'quelquun'
*/
void MortevielleEngine::interactNPC() {
- if (_menu._menuDisplayed)
- _menu.eraseMenu();
+ if (_menu->_menuDisplayed)
+ _menu->eraseMenu();
endSearch();
_crep = 997;
@@ -3122,9 +3125,9 @@ L1:
_crep = 138;
handleDescriptionText(2, _crep);
if (_crep == 138)
- _soundManager.startSpeech(5, 2, 1);
+ _soundManager->startSpeech(5, 2, 1);
else
- _soundManager.startSpeech(4, 4, 1);
+ _soundManager->startSpeech(4, 4, 1);
if (_openObjCount == 0)
_coreVar._faithScore += 2;
@@ -3133,12 +3136,12 @@ L1:
else
_coreVar._faithScore += 3 * (_coreVar._faithScore / 10);
exitRoom();
- _menu.setDestinationText(LANDING);
+ _menu->setDestinationText(LANDING);
int charIdx = convertBitIndexToCharacterIndex(_currBitIndex);
_caff = 69 + charIdx;
_crep = _caff;
_currMenu = MENU_DISCUSS;
- _currAction = (_menu._discussMenu[charIdx]._menuId << 8) | _menu._discussMenu[charIdx]._actionId;
+ _currAction = (_menu->_discussMenu[charIdx]._menuId << 8) | _menu->_discussMenu[charIdx]._actionId;
_syn = true;
_col = true;
} else {
@@ -3149,15 +3152,15 @@ L1:
} else {
handleDescriptionText(2, 136);
int rand = (getRandomNumber(0, 4)) - 2;
- _soundManager.startSpeech(3, rand, 1);
+ _soundManager->startSpeech(3, rand, 1);
clearDescriptionBar();
displayAloneText();
resetRoomVariables(MANOR_FRONT);
prepareDisplayText();
}
}
- if (_menu._menuDisplayed)
- _menu.drawMenu();
+ if (_menu->_menuDisplayed)
+ _menu->drawMenu();
}
/**
@@ -3205,25 +3208,25 @@ void MortevielleEngine::displayStatusArrow() {
touch = '\0';
do {
- _mouse.moveMouse(qust, touch);
+ _mouse->moveMouse(qust, touch);
if (shouldQuit())
return;
if (getMouseClick())
- inRect = (_mouse._pos.x < 256 * kResolutionScaler) && (_mouse._pos.y < 176) && (_mouse._pos.y > 12);
+ inRect = (_mouse->_pos.x < 256 * kResolutionScaler) && (_mouse->_pos.y < 176) && (_mouse->_pos.y > 12);
prepareRoom();
} while (!(qust || inRect || _anyone));
if (qust && (touch == '\103'))
- _dialogManager.show(_hintPctMessage);
+ _dialogManager->show(_hintPctMessage);
} while (!((touch == '\73') || ((touch == '\104') && (_x != 0) && (_y != 0)) || (_anyone) || (inRect)));
if (touch == '\73')
_keyPressedEsc = true;
if (inRect) {
- _x = _mouse._pos.x;
- _y = _mouse._pos.y;
+ _x = _mouse->_pos.x;
+ _y = _mouse->_pos.y;
}
}
@@ -3291,7 +3294,7 @@ void MortevielleEngine::displayLookScreen(int objId) {
int mdes = _caff;
_caff = objId;
- if (((_caff > 29) && (_caff < 33)) || (_caff == 144) || (_caff == 147) || (_caff == 149) || (_currAction == _menu._opcodeSLook)) {
+ if (((_caff > 29) && (_caff < 33)) || (_caff == 144) || (_caff == 147) || (_caff == 149) || (_currAction == _menu->_opcodeSLook)) {
drawPictureWithText();
if ((_caff > 29) && (_caff < 33))
handleDescriptionText(2, _caff);
@@ -3304,7 +3307,7 @@ void MortevielleEngine::displayLookScreen(int objId) {
} else {
_obpart = true;
_crep = _caff + 400;
- _menu.setSearchMenu();
+ _menu->setSearchMenu();
}
}
@@ -3356,10 +3359,10 @@ int MortevielleEngine::checkLeaveSecretPassage() {
* @remarks Originally called 'fenat'
*/
void MortevielleEngine::displayStatusInDescriptionBar(char stat) {
- _mouse.hideMouse();
- _screenSurface.writeCharacter(Common::Point(306, 193), stat, 12);
- _screenSurface.drawBox(300, 191, 16, 8, 15);
- _mouse.showMouse();
+ _mouse->hideMouse();
+ _screenSurface->writeCharacter(Common::Point(306, 193), stat, 12);
+ _screenSurface->drawBox(300, 191, 16, 8, 15);
+ _mouse->showMouse();
}
/**
diff --git a/engines/neverhood/configure.engine b/engines/neverhood/configure.engine
new file mode 100644
index 0000000000..46910e293e
--- /dev/null
+++ b/engines/neverhood/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 neverhood "Neverhood" yes
diff --git a/engines/neverhood/console.cpp b/engines/neverhood/console.cpp
index 708c68746c..34438d821f 100644
--- a/engines/neverhood/console.cpp
+++ b/engines/neverhood/console.cpp
@@ -29,6 +29,7 @@
#include "neverhood/smackerscene.h"
#include "neverhood/sound.h"
#include "neverhood/modules/module1600.h"
+#include "neverhood/modules/module3000_sprites.h"
namespace Neverhood {
diff --git a/engines/neverhood/detection.cpp b/engines/neverhood/detection.cpp
index 96c87ab3ae..feba193609 100644
--- a/engines/neverhood/detection.cpp
+++ b/engines/neverhood/detection.cpp
@@ -130,6 +130,9 @@ static const NeverhoodGameDescription gameDescriptions[] = {
0,
},
+// FIXME: Disabled for now, as it has broken resources that corrupt the heap
+// (e.g. the menu header).
+#if 0
{
// Neverhood Russian version. Fargus
{
@@ -146,19 +149,35 @@ static const NeverhoodGameDescription gameDescriptions[] = {
0,
0,
},
+#endif
{ AD_TABLE_END_MARKER, 0, 0, 0, 0 }
};
} // End of namespace Neverhood
-static const ExtraGuiOption neverhoodExtraGuiOption = {
+static const ExtraGuiOption neverhoodExtraGuiOption1 = {
_s("Use original save/load screens"),
_s("Use the original save/load screens, instead of the ScummVM ones"),
"originalsaveload",
false
};
+static const ExtraGuiOption neverhoodExtraGuiOption2 = {
+ _s("Skip the Hall of Records storyboard scenes"),
+ _s("Allows the player to skip past the Hall of Records storyboard scenes"),
+ "skiphallofrecordsscenes",
+ false
+};
+
+static const ExtraGuiOption neverhoodExtraGuiOption3 = {
+ _s("Scale the making of videos to full screen"),
+ _s("Scale the making of videos, so that they use the whole screen"),
+ "scalemakingofvideos",
+ false
+};
+
+
class NeverhoodMetaEngine : public AdvancedMetaEngine {
public:
NeverhoodMetaEngine() : AdvancedMetaEngine(Neverhood::gameDescriptions, sizeof(Neverhood::NeverhoodGameDescription), neverhoodGames) {
@@ -189,7 +208,7 @@ bool NeverhoodMetaEngine::hasFeature(MetaEngineFeature f) const {
(f == kSupportsListSaves) ||
(f == kSupportsLoadingDuringStartup) ||
(f == kSupportsDeleteSave) ||
- (f == kSavesSupportMetaInfo) ||
+ (f == kSavesSupportMetaInfo) ||
(f == kSavesSupportThumbnail) ||
(f == kSavesSupportCreationDate) ||
(f == kSavesSupportPlayTime);
@@ -212,7 +231,9 @@ bool NeverhoodMetaEngine::createInstance(OSystem *syst, Engine **engine, const A
const ExtraGuiOptions NeverhoodMetaEngine::getExtraGuiOptions(const Common::String &target) const {
ExtraGuiOptions options;
- options.push_back(neverhoodExtraGuiOption);
+ options.push_back(neverhoodExtraGuiOption1);
+ options.push_back(neverhoodExtraGuiOption2);
+ options.push_back(neverhoodExtraGuiOption3);
return options;
}
diff --git a/engines/neverhood/diskplayerscene.cpp b/engines/neverhood/diskplayerscene.cpp
index ef2b856b2f..7513034bf3 100644
--- a/engines/neverhood/diskplayerscene.cpp
+++ b/engines/neverhood/diskplayerscene.cpp
@@ -169,7 +169,7 @@ AsDiskplayerSceneKey::AsDiskplayerSceneKey(NeverhoodEngine *vm)
uint32 AsDiskplayerSceneKey::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x3002:
+ case NM_ANIMATION_STOP:
gotoNextState();
break;
}
@@ -442,7 +442,7 @@ uint32 DiskplayerScene::handleMessage(int messageNum, const MessageParam &param,
Scene::handleMessage(messageNum, param, sender);
if (!_inputDisabled) {
switch (messageNum) {
- case 0x0001:
+ case NM_MOUSE_CLICK:
if (param.asPoint().x <= 20 || param.asPoint().x >= 620) {
sendMessage(_parentModule, 0x1009, 0);
} else if (!_dropKey &&
@@ -460,7 +460,7 @@ uint32 DiskplayerScene::handleMessage(int messageNum, const MessageParam &param,
}
}
break;
- case 0x2000:
+ case NM_ANIMATION_UPDATE:
tuneIn();
break;
case 0x2001:
diff --git a/engines/neverhood/gamemodule.cpp b/engines/neverhood/gamemodule.cpp
index 50c7c503d3..5e9981caa6 100644
--- a/engines/neverhood/gamemodule.cpp
+++ b/engines/neverhood/gamemodule.cpp
@@ -79,7 +79,7 @@ GameModule::GameModule(NeverhoodEngine *vm)
_mainMenuRequested(false) {
// Other initializations moved to actual engine class
- _vm->_soundMan->playSoundThree(0x002D0031, 0x8861079);
+ _vm->_soundMan->playSoundThree(0x002D0031, 0x08861079);
SetMessageHandler(&GameModule::handleMessage);
}
@@ -95,7 +95,7 @@ void GameModule::handleMouseMove(int16 x, int16 y) {
mousePos.x = x;
mousePos.y = y;
debug(2, "GameModule::handleMouseMove(%d, %d)", x, y);
- sendPointMessage(_childObject, 0, mousePos);
+ sendPointMessage(_childObject, NM_MOUSE_MOVE, mousePos);
}
}
@@ -105,7 +105,7 @@ void GameModule::handleMouseDown(int16 x, int16 y) {
mousePos.x = x;
mousePos.y = y;
debug(2, "GameModule::handleMouseDown(%d, %d)", x, y);
- sendPointMessage(_childObject, 0x0001, mousePos);
+ sendPointMessage(_childObject, NM_MOUSE_CLICK, mousePos);
}
}
@@ -115,14 +115,26 @@ void GameModule::handleMouseUp(int16 x, int16 y) {
mousePos.x = x;
mousePos.y = y;
debug(2, "GameModule::handleMouseUp(%d, %d)", x, y);
- sendPointMessage(_childObject, 0x0002, mousePos);
+ sendPointMessage(_childObject, NM_MOUSE_RELEASE, mousePos);
+ }
+}
+
+void GameModule::handleWheelUp() {
+ if (_childObject) {
+ sendMessage(_childObject, NM_MOUSE_WHEELUP, 0);
+ }
+}
+
+void GameModule::handleWheelDown() {
+ if (_childObject) {
+ sendMessage(_childObject, NM_MOUSE_WHEELDOWN, 0);
}
}
void GameModule::handleSpaceKey() {
if (_childObject) {
debug(2, "GameModule::handleSpaceKey()");
- sendMessage(_childObject, 0x0009, 0);
+ sendMessage(_childObject, NM_KEYPRESS_SPACE, 0);
}
}
@@ -150,7 +162,7 @@ void GameModule::handleEscapeKey() {
else if (!_prevChildObject && _canRequestMainMenu)
_mainMenuRequested = true;
else if (_childObject)
- sendMessage(_childObject, 0x000C, 0);
+ sendMessage(_childObject, NM_KEYPRESS_ESC, 0);
}
void GameModule::initKeySlotsPuzzle() {
@@ -216,7 +228,7 @@ void GameModule::initRadioPuzzle() {
setGlobalVar(V_RADIO_ROOM_LEFT_DOOR, 1);
setGlobalVar(V_RADIO_ROOM_RIGHT_DOOR, 0);
setSubVar(VA_IS_PUZZLE_INIT, 0x08C80800, 1);
- }
+ }
}
void GameModule::initTestTubes1Puzzle() {
@@ -415,6 +427,8 @@ void GameModule::checkRequests() {
_vm->_audioResourceMan->stopAllSounds();
_vm->_soundMan->stopAllMusic();
_vm->_soundMan->stopAllSounds();
+ // Reinsert turning sound because SoundMan::stopAllSounds() removes it
+ _vm->_soundMan->playSoundThree(0x002D0031, 0x08861079);
delete _childObject;
delete _prevChildObject;
_childObject = NULL;
@@ -781,7 +795,7 @@ void GameModule::updateModule() {
void GameModule::openMainMenu() {
if (_childObject) {
- sendMessage(_childObject, 0x101D, 0);
+ sendMessage(_childObject, NM_MOUSE_HIDE, 0);
_childObject->draw();
} else {
// If there's no module, create one so there's something to return to
@@ -807,7 +821,7 @@ void GameModule::updateMenuModule() {
if (!updateChild()) {
_vm->_screen->restoreParams();
_childObject = _prevChildObject;
- sendMessage(_childObject, 0x101E, 0);
+ sendMessage(_childObject, NM_MOUSE_SHOW, 0);
_prevChildObject = NULL;
_moduleNum = _prevModuleNum;
SetUpdateHandler(&GameModule::updateModule);
diff --git a/engines/neverhood/gamemodule.h b/engines/neverhood/gamemodule.h
index 2f2fecf463..198f8f6715 100644
--- a/engines/neverhood/gamemodule.h
+++ b/engines/neverhood/gamemodule.h
@@ -40,6 +40,8 @@ public:
void handleMouseMove(int16 x, int16 y);
void handleMouseDown(int16 x, int16 y);
void handleMouseUp(int16 x, int16 y);
+ void handleWheelUp();
+ void handleWheelDown();
void handleSpaceKey();
void handleAsciiKey(char key);
void handleKeyDown(Common::KeyCode keyCode);
diff --git a/engines/neverhood/graphics.cpp b/engines/neverhood/graphics.cpp
index 490959020f..e976844c16 100644
--- a/engines/neverhood/graphics.cpp
+++ b/engines/neverhood/graphics.cpp
@@ -299,11 +299,11 @@ void unpackSpriteRle(const byte *source, int width, int height, byte *dest, int
}
source += copy;
}
- dest += destPitch;
if (replaceColors)
for (int xc = 0; xc < width; xc++)
if (dest[xc] == oldColor)
dest[xc] = newColor;
+ dest += destPitch;
}
}
rows = READ_LE_UINT16(source);
diff --git a/engines/neverhood/klaymen.cpp b/engines/neverhood/klaymen.cpp
index 8ed27c825a..a813440f62 100644
--- a/engines/neverhood/klaymen.cpp
+++ b/engines/neverhood/klaymen.cpp
@@ -47,17 +47,6 @@ static const KlaymenIdleTableItem klaymenIdleTable3[] = {
{1, kIdleTeleporterHands2}
};
-static const KlaymenIdleTableItem klaymenIdleTable4[] = {
- {1, kIdleSpinHead},
- {1, kIdleChest},
- {1, kIdleHeadOff},
-};
-
-static const KlaymenIdleTableItem klaymenIdleTable1002[] = {
- {1, kIdlePickEar},
- {2, kIdleWonderAbout}
-};
-
// Klaymen
Klaymen::Klaymen(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y, NRectArray *clipRects)
@@ -65,7 +54,7 @@ Klaymen::Klaymen(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y, NRec
_isWalkingOpenDoorNotified(false), _spitOutCountdown(0), _tapesToInsert(0), _keysToInsert(0), _busyStatus(0), _acceptInput(true),
_attachedSprite(NULL), _isWalking(false), _actionStatus(1), _parentScene(parentScene), _isSneaking(false), _isLargeStep(false),
_doYHitIncr(false), _isLeverDown(false), _isSittingInTeleporter(false), _actionStatusChanged(false), _ladderStatus(0), _pathPoints(NULL), _soundFlag(false),
- _idleTableNum(0), _otherSprite(NULL), _moveObjectCountdown(0), _readyToSpit(false), _walkResumeFrameIncr(0) {
+ _idleTableNum(0), _otherSprite(NULL), _moveObjectCountdown(0), _walkResumeFrameIncr(0) {
createSurface(1000, 320, 200);
_x = x;
@@ -88,7 +77,7 @@ uint32 Klaymen::xHandleMessage(int messageNum, const MessageParam &param) {
case 0x4800:
startWalkToX(param.asPoint().x, false);
break;
- case 0x4004:
+ case NM_KLAYMEN_STAND_IDLE:
GotoState(&Klaymen::stTryStandIdle);
break;
case 0x4818:
@@ -137,7 +126,7 @@ void Klaymen::stIdlePickEar() {
uint32 Klaymen::hmIdlePickEar(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = hmLowLevelAnimation(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0x04DBC02C) {
playSound(0, 0x44528AA1);
}
@@ -163,7 +152,7 @@ void Klaymen::stIdleSpinHead() {
uint32 Klaymen::hmIdleSpinHead(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = hmLowLevelAnimation(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0x808A0008) {
playSound(0, 0xD948A340);
}
@@ -190,7 +179,7 @@ void Klaymen::evIdleArmsDone() {
uint32 Klaymen::hmIdleArms(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = hmLowLevelAnimation(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0x5A0F0104) {
playSound(0, 0x7970A100);
} else if (param.asInteger() == 0x9A9A0109) {
@@ -216,7 +205,7 @@ void Klaymen::stIdleChest() {
uint32 Klaymen::hmIdleChest(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = hmLowLevelAnimation(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0x0D2A0288) {
playSound(0, 0xD192A368);
}
@@ -238,7 +227,7 @@ void Klaymen::stIdleHeadOff() {
uint32 Klaymen::hmIdleHeadOff(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = hmLowLevelAnimation(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0xC006000C) {
playSound(0, 0x9D406340);
} else if (param.asInteger() == 0x2E4A2940) {
@@ -311,7 +300,7 @@ void Klaymen::stSitIdleTeleporterBlink() {
void Klaymen::stSitIdleTeleporterBlinkSecond() {
_busyStatus = 0;
_acceptInput = true;
- startAnimation(0x5C24C018, 0, -1);
+ startAnimation(0x582EC138, 0, -1);
SetUpdateHandler(&Klaymen::upSitIdleTeleporter);
SetMessageHandler(&Klaymen::hmLowLevel);
SetSpriteUpdate(NULL);
@@ -344,9 +333,9 @@ void Klaymen::stPickUpTube() {
uint32 Klaymen::hmPickUpTube(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = hmLowLevelAnimation(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0xC1380080) {
- sendMessage(_attachedSprite, 0x4806, 0);
+ sendMessage(_attachedSprite, NM_KLAYMEN_USE_OBJECT, 0);
playSound(0, 0xC8004340);
} else if (param.asInteger() == 0x02B20220) {
playSound(0, 0xC5408620);
@@ -405,7 +394,7 @@ void Klaymen::stSitInTeleporter() {
uint32 Klaymen::hmSitInTeleporter(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = hmLowLevelAnimation(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0x001A2832) {
playSound(0, 0xC0E4884C);
}
@@ -529,7 +518,7 @@ uint32 Klaymen::hmLowLevel(int messageNum, const MessageParam &param, Entity *se
case 0x1014:
_attachedSprite = (Sprite*)(param.asEntity());
break;
- case 0x1019:
+ case NM_SCENE_LEAVE:
gotoNextStateExt();
break;
case 0x101C:
@@ -567,7 +556,7 @@ void Klaymen::stIdleBlink() {
uint32 Klaymen::hmLowLevelAnimation(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = hmLowLevel(messageNum, param, sender);
switch (messageNum) {
- case 0x3002:
+ case NM_ANIMATION_STOP:
gotoNextStateExt();
break;
}
@@ -586,7 +575,7 @@ void Klaymen::stStandAround() {
uint32 Klaymen::hmStartAction(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = hmLowLevelAnimation(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0x271AA210) {
playSound(0, 0x4924AAC4);
} else if (param.asInteger() == 0x2B22AA81) {
@@ -628,36 +617,6 @@ void Klaymen::startWalkToX(int16 x, bool walkExt) {
}
}
-void Klaymen::stWakeUp() {
- _busyStatus = 1;
- _acceptInput = false;
- startAnimation(0x527AC970, 0, -1);
- SetUpdateHandler(&Klaymen::update);
- SetMessageHandler(&Klaymen::hmLowLevelAnimation);
- SetSpriteUpdate(NULL);
-}
-
-void Klaymen::stSleeping() {
- _busyStatus = 0;
- _acceptInput = true;
- startAnimation(0x5A38C110, 0, -1);
- SetUpdateHandler(&Klaymen::update);
- SetMessageHandler(&Klaymen::hmSleeping);
- SetSpriteUpdate(NULL);
-}
-
-uint32 Klaymen::hmSleeping(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = hmLowLevel(messageNum, param, sender);
- switch (messageNum) {
- case 0x100D:
- if (param.asInteger() == 0x03060012) {
- playSound(0, 0xC0238244);
- }
- break;
- }
- return messageResult;
-}
-
bool Klaymen::stStartAction(AnimationCb callback3) {
if (_busyStatus == 1) {
_busyStatus = 2;
@@ -771,7 +730,7 @@ void Klaymen::evSneakingDone() {
uint32 Klaymen::hmSneaking(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = hmLowLevel(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0x32180101) {
playSound(0, 0x4924AAC4);
} else if (param.asInteger() == 0x0A2A9098) {
@@ -782,7 +741,7 @@ uint32 Klaymen::hmSneaking(int messageNum, const MessageParam &param, Entity *se
playSound(0, _soundFlag ? 0x50399F64 : 0x0460E2FA);
}
break;
- case 0x3002:
+ case NM_ANIMATION_STOP:
_x = _destX;
gotoNextStateExt();
break;
@@ -812,7 +771,7 @@ void Klaymen::evStartWalkingDone() {
uint32 Klaymen::hmStartWalking(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = hmLowLevelAnimation(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0x32180101) {
playSound(0, _soundFlag ? 0x48498E46 : 0x405002D8);
} else if (param.asInteger() == 0x0A2A9098) {
@@ -843,7 +802,7 @@ void Klaymen::suWalkingFirst() {
uint32 Klaymen::hmWalking(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = hmLowLevel(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0x32180101) {
playSound(0, _soundFlag ? 0x48498E46 : 0x405002D8);
} else if (param.asInteger() == 0x0A2A9098) {
@@ -902,7 +861,7 @@ void Klaymen::suWalkingTestExit() {
(_actionStatus != 2 && _actionStatus != 3 && xdiff <= 10 && (_currFrameIndex >= 12 || _currFrameIndex <= 4)) ||
(_actionStatus == 3 && xdiff < 30) ||
(_actionStatus == 3 && xdiff < 150 && _currFrameIndex >= 6)) {
- sendMessage(this, 0x1019, 0);
+ sendMessage(this, NM_SCENE_LEAVE, 0);
} else {
HitRect *hitRectPrev = _parentScene->findHitRectAtPos(_x, _y);
_x += xdelta;
@@ -934,11 +893,11 @@ void Klaymen::suWalkingTestExit() {
uint32 Klaymen::hmLever(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = hmLowLevelAnimation(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0x4AB28209) {
- sendMessage(_attachedSprite, 0x482A, 0);
+ sendMessage(_attachedSprite, NM_MOVE_TO_BACK, 0);
} else if (param.asInteger() == 0x88001184) {
- sendMessage(_attachedSprite, 0x482B, 0);
+ sendMessage(_attachedSprite, NM_MOVE_TO_FRONT, 0);
}
break;
}
@@ -960,9 +919,9 @@ void Klaymen::stPickUpGeneric() {
uint32 Klaymen::hmPickUpObject(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = hmLowLevelAnimation(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0xC1380080) {
- sendMessage(_attachedSprite, 0x4806, 0);
+ sendMessage(_attachedSprite, NM_KLAYMEN_USE_OBJECT, 0);
playSound(0, 0x40208200);
} else if (param.asInteger() == 0x02B20220) {
playSound(0, 0xC5408620);
@@ -995,7 +954,7 @@ void Klaymen::stPressButton() {
uint32 Klaymen::hmPressButton(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = hmLowLevelAnimation(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0x0D01B294) {
sendMessage(_attachedSprite, 0x480B, 0);
} else if (param.asInteger() == 0x32180101) {
@@ -1089,7 +1048,7 @@ void Klaymen::stStartWalkingSmall() {
uint32 Klaymen::hmWalkingSmall(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = hmLowLevel(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0x32180101)
playSound(0, 0x4924AAC4);
else if (param.asInteger() == 0x0A2A9098)
@@ -1146,11 +1105,11 @@ void Klaymen::stWalkToFrontNoStepSmall() {
uint32 Klaymen::hmWalkFrontBackSmall(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = hmLowLevelAnimation(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0x80C110B5)
- sendMessage(_parentScene, 0x482A, 0);
+ sendMessage(_parentScene, NM_MOVE_TO_BACK, 0);
else if (param.asInteger() == 0x110010D1)
- sendMessage(_parentScene, 0x482B, 0);
+ sendMessage(_parentScene, NM_MOVE_TO_FRONT, 0);
else if (param.asInteger() == 0x32180101)
playSound(0, 0x4924AAC4);
else if (param.asInteger() == 0x0A2A9098)
@@ -1228,12 +1187,12 @@ void Klaymen::stReleaseCord() {
uint32 Klaymen::hmPullReleaseCord(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = hmLowLevelAnimation(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0x4AB28209) {
- sendMessage(_attachedSprite, 0x482A, 0);
- sendMessage(_attachedSprite, 0x480F, 0);
+ sendMessage(_attachedSprite, NM_MOVE_TO_BACK, 0);
+ sendMessage(_attachedSprite, NM_KLAYMEN_LOWER_LEVER, 0);
} else if (param.asInteger() == 0x88001184) {
- sendMessage(_attachedSprite, 0x482B, 0);
+ sendMessage(_attachedSprite, NM_MOVE_TO_FRONT, 0);
}
break;
}
@@ -1254,7 +1213,7 @@ void Klaymen::stUseTube() {
uint32 Klaymen::hmUseTube(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = hmLowLevelAnimation(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0x02B20220)
playSound(0, 0xC5408620);
else if (param.asInteger() == 0x0A720138)
@@ -1410,14 +1369,14 @@ void Klaymen::suLargeStep() {
uint32 Klaymen::hmLargeStep(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = hmLowLevel(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0x32180101) {
playSound(0, 0x4924AAC4);
} else if (param.asInteger() == 0x0A2A9098) {
playSound(0, 0x0A2AA8E0);
}
break;
- case 0x3002:
+ case NM_ANIMATION_STOP:
_x = _destX;
gotoNextStateExt();
break;
@@ -1455,7 +1414,7 @@ void Klaymen::stTurnToUseHalf() {
uint32 Klaymen::hmTurnToUse(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = hmLowLevelAnimation(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0x32180101) {
playSound(0, 0x4924AAC4);
} else if (param.asInteger() == 0x0A2A9098) {
@@ -1501,7 +1460,7 @@ uint32 Klaymen::hmPeekWall(int messageNum, const MessageParam &param, Entity *se
if (_currFrameIndex < speedUpFrameIndex)
startAnimation(0xAC20C012, speedUpFrameIndex, -1);
return 0;
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0x32180101) {
playSound(0, 0x405002D8);
} else if (param.asInteger() == 0x0A2A9098) {
@@ -1512,116 +1471,15 @@ uint32 Klaymen::hmPeekWall(int messageNum, const MessageParam &param, Entity *se
return hmLowLevelAnimation(messageNum, param, sender);
}
-void Klaymen::stJumpToRing1() {
- if (!stStartAction(AnimationCallback(&Klaymen::stJumpToRing1))) {
- _busyStatus = 0;
- startAnimation(0xD82890BA, 0, -1);
- setupJumpToRing();
- }
-}
-
-void Klaymen::setupJumpToRing() {
- _acceptInput = false;
- SetUpdateHandler(&Klaymen::update);
- SetMessageHandler(&Klaymen::hmJumpToRing);
- SetSpriteUpdate(&Klaymen::suUpdateDestX);
- NextState(&Klaymen::stHangOnRing);
- sendMessage(_attachedSprite, 0x482B, 0);
-}
-
-uint32 Klaymen::hmJumpToRing(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = hmLowLevelAnimation(messageNum, param, sender);
- switch (messageNum) {
- case 0x100D:
- if (param.asInteger() == 0x168050A0) {
- sendMessage(_attachedSprite, 0x4806, 0);
- _acceptInput = true;
- } else if (param.asInteger() == 0x320AC306) {
- playSound(0, 0x5860C640);
- } else if (param.asInteger() == 0x4AB28209) {
- sendMessage(_attachedSprite, 0x482A, 0);
- } else if (param.asInteger() == 0x88001184) {
- sendMessage(_attachedSprite, 0x482B, 0);
- }
- break;
- }
- return messageResult;
-}
-
void Klaymen::suUpdateDestX() {
AnimatedSprite::updateDeltaXY();
_destX = _x;
}
-void Klaymen::stHangOnRing() {
- _busyStatus = 0;
- _acceptInput = true;
- startAnimation(0x4829E0B8, 0, -1);
- SetUpdateHandler(&Klaymen::update);
- SetMessageHandler(&Klaymen::hmLowLevel);
- SetSpriteUpdate(NULL);
-}
-
-void Klaymen::stJumpToRing2() {
- if (!stStartAction(AnimationCallback(&Klaymen::stJumpToRing2))) {
- _busyStatus = 0;
- startAnimation(0x900980B2, 0, -1);
- setupJumpToRing();
- }
-}
-
-void Klaymen::stJumpToRing3() {
- if (!stStartAction(AnimationCallback(&Klaymen::stJumpToRing3))) {
- _busyStatus = 0;
- _acceptInput = false;
- startAnimation(0xBA1910B2, 0, -1);
- SetUpdateHandler(&Klaymen::update);
- SetSpriteUpdate(&Klaymen::suUpdateDestX);
- SetMessageHandler(&Klaymen::hmJumpToRing3);
- NextState(&Klaymen::stHoldRing3);
- sendMessage(_attachedSprite, 0x482B, 0);
- }
-}
-
-uint32 Klaymen::hmJumpToRing3(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = hmLowLevelAnimation(messageNum, param, sender);
- switch (messageNum) {
- case 0x100D:
- if (param.asInteger() == 0x168050A0) {
- sendMessage(_attachedSprite, 0x4806, 0);
- } else if (param.asInteger() == 0x320AC306) {
- playSound(0, 0x5860C640);
- } else if (param.asInteger() == 0x4AB28209) {
- sendMessage(_attachedSprite, 0x482A, 0);
- } else if (param.asInteger() == 0x88001184) {
- sendMessage(_attachedSprite, 0x482B, 0);
- }
- break;
- }
- return messageResult;
-}
-
-void Klaymen::stHoldRing3() {
- _busyStatus = 0;
- _acceptInput = true;
- startAnimation(0x4A293FB0, 0, -1);
- SetUpdateHandler(&Klaymen::update);
- SetMessageHandler(&Klaymen::hmHoldRing3);
- SetSpriteUpdate(NULL);
-}
-
-uint32 Klaymen::hmHoldRing3(int messageNum, const MessageParam &param, Entity *sender) {
- if (messageNum == 0x1008) {
- stReleaseRing();
- return 0;
- }
- return hmLowLevel(messageNum, param, sender);
-}
-
void Klaymen::stReleaseRing() {
_busyStatus = 1;
_acceptInput = false;
- sendMessage(_attachedSprite, 0x4807, 0);
+ sendMessage(_attachedSprite, NM_KLAYMEN_RAISE_LEVER, 0);
_attachedSprite = NULL;
startAnimation(0xB869A4B9, 0, -1);
SetUpdateHandler(&Klaymen::update);
@@ -1629,14 +1487,6 @@ void Klaymen::stReleaseRing() {
SetSpriteUpdate(NULL);
}
-void Klaymen::stJumpToRing4() {
- if (!stStartAction(AnimationCallback(&Klaymen::stJumpToRing4))) {
- _busyStatus = 0;
- startAnimation(0xB8699832, 0, -1);
- setupJumpToRing();
- }
-}
-
void Klaymen::startWalkToAttachedSpriteXDistance(int16 distance) {
startWalkToXDistance(_attachedSprite->getX(), distance);
}
@@ -1709,7 +1559,7 @@ void Klaymen::stClimbLadderHalf() {
uint32 Klaymen::hmClimbLadderHalf(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = hmLowLevelAnimation(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0x489B025C) {
playSound(0, 0x52C4C2D7);
} else if (param.asInteger() == 0x400A0E64) {
@@ -1727,7 +1577,7 @@ uint32 Klaymen::hmClimbLadderHalf(int messageNum, const MessageParam &param, Ent
uint32 Klaymen::hmClimbLadderUpDown(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = hmLowLevel(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0x01084280) {
_acceptInput = true;
} else if (param.asInteger() == 0x489B025C) {
@@ -1738,11 +1588,11 @@ uint32 Klaymen::hmClimbLadderUpDown(int messageNum, const MessageParam &param, E
if (_ladderStatus == 1) {
startAnimationByHash(0x3A292504, 0x01084280, 0);
if (_destY >= _y - 30)
- sendMessage(this, 0x1019, 0);
+ sendMessage(this, NM_SCENE_LEAVE, 0);
} else {
startAnimationByHash(0x122D1505, 0x01084280, 0);
if (_destY <= _y)
- sendMessage(this, 0x1019, 0);
+ sendMessage(this, NM_SCENE_LEAVE, 0);
}
}
break;
@@ -1789,11 +1639,11 @@ void Klaymen::stWalkToFrontNoStep() {
uint32 Klaymen::hmWalkToFront(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = hmLowLevelAnimation(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0x80C110B5) {
- sendMessage(_parentScene, 0x482A, 0);
+ sendMessage(_parentScene, NM_MOVE_TO_BACK, 0);
} else if (param.asInteger() == 0x110010D1) {
- sendMessage(_parentScene, 0x482B, 0);
+ sendMessage(_parentScene, NM_MOVE_TO_FRONT, 0);
} else if (param.asInteger() == 0x32180101) {
playSound(0, _soundFlag ? 0x48498E46 : 0x405002D8);
} else if (param.asInteger() == 0x0A2A9098) {
@@ -1849,7 +1699,7 @@ void Klaymen::stLandOnFeet() {
uint32 Klaymen::hmLandOnFeet(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = hmLowLevelAnimation(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0x320AC306) {
playSound(0, 0x5860C640);
}
@@ -1872,7 +1722,7 @@ void Klaymen::stTurnToBackToUse() {
uint32 Klaymen::hmTurnToBackToUse(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = hmLowLevelAnimation(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0xC61A0119) {
playSound(0, 0x402338C2);
} else if (param.asInteger() == 0x32180101) {
@@ -1885,29 +1735,6 @@ uint32 Klaymen::hmTurnToBackToUse(int messageNum, const MessageParam &param, Ent
return messageResult;
}
-void Klaymen::stClayDoorOpen() {
- if (!stStartAction(AnimationCallback(&Klaymen::stClayDoorOpen))) {
- _busyStatus = 2;
- _acceptInput = false;
- startAnimation(0x5CCCB330, 0, -1);
- SetUpdateHandler(&Klaymen::update);
- SetMessageHandler(&Klaymen::hmClayDoorOpen);
- SetSpriteUpdate(&Klaymen::suUpdateDestX);
- }
-}
-
-uint32 Klaymen::hmClayDoorOpen(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = hmLowLevelAnimation(messageNum, param, sender);
- switch (messageNum) {
- case 0x100D:
- if (param.asInteger() == 0x040D4186) {
- sendMessage(_attachedSprite, 0x4808, 0);
- }
- break;
- }
- return messageResult;
-}
-
void Klaymen::stTurnToUse() {
if (!stStartAction(AnimationCallback(&Klaymen::stTurnToUse))) {
_busyStatus = 2;
@@ -1956,12 +1783,12 @@ void Klaymen::stMoveObjectSkipTurnFaceObject() {
}
void Klaymen::evMoveObjectTurnDone() {
- sendMessage(_attachedSprite, 0x4807, 0);
+ sendMessage(_attachedSprite, NM_KLAYMEN_RAISE_LEVER, 0);
}
uint32 Klaymen::hmMoveObjectTurn(int messageNum, const MessageParam &param, Entity *sender) {
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0x01084280) {
sendMessage(_attachedSprite, 0x480B, _doDeltaX ? 1 : 0);
} else if (param.asInteger() == 0x02421405) {
@@ -1977,7 +1804,7 @@ uint32 Klaymen::hmMoveObjectTurn(int messageNum, const MessageParam &param, Enti
playSound(0, 0x0460E2FA);
}
break;
- case 0x480A:
+ case NM_KLAYMEN_MOVE_OBJECT:
_isMoveObjectRequested = true;
return 0;
}
@@ -2012,7 +1839,7 @@ void Klaymen::stUseLever() {
if (_isLeverDown) {
stUseLeverRelease();
} else {
- sendMessage(_attachedSprite, 0x482B, 0);
+ sendMessage(_attachedSprite, NM_MOVE_TO_FRONT, 0);
startAnimation(0x0C303040, 0, -1);
SetSpriteUpdate(&Klaymen::suUpdateDestX);
SetMessageHandler(&Klaymen::hmLever);
@@ -2026,7 +1853,7 @@ void Klaymen::stUseLever() {
// Exactly the same code as sub420DA0 which was removed
void Klaymen::stPullLeverDown() {
startAnimation(0x0D318140, 0, -1);
- sendMessage(_attachedSprite, 0x480F, 0);
+ sendMessage(_attachedSprite, NM_KLAYMEN_LOWER_LEVER, 0);
NextState(&Klaymen::stHoldLeverDown);
}
@@ -2044,7 +1871,7 @@ void Klaymen::stUseLeverRelease() {
SetUpdateHandler(&Klaymen::update);
SetMessageHandler(&Klaymen::hmLever);
SetSpriteUpdate(&Klaymen::suUpdateDestX);
- sendMessage(_attachedSprite, 0x4807, 0);
+ sendMessage(_attachedSprite, NM_KLAYMEN_RAISE_LEVER, 0);
NextState(&Klaymen::stPullLeverDown);
_acceptInput = false;
}
@@ -2056,7 +1883,7 @@ void Klaymen::stReleaseLever() {
SetUpdateHandler(&Klaymen::update);
SetMessageHandler(&Klaymen::hmLever);
SetSpriteUpdate(&Klaymen::suUpdateDestX);
- sendMessage(_attachedSprite, 0x4807, 0);
+ sendMessage(_attachedSprite, NM_KLAYMEN_RAISE_LEVER, 0);
NextState(&Klaymen::stLetGoOfLever);
_acceptInput = false;
_isLeverDown = false;
@@ -2071,7 +1898,7 @@ void Klaymen::stLetGoOfLever() {
}
void Klaymen::evLeverReleasedEvent() {
- sendMessage(_attachedSprite, 0x482A, 0);
+ sendMessage(_attachedSprite, NM_MOVE_TO_BACK, 0);
}
void Klaymen::stInsertDisk() {
@@ -2102,7 +1929,7 @@ void Klaymen::stInsertDisk() {
uint32 Klaymen::hmInsertDisk(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = Klaymen::hmLowLevelAnimation(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (_tapesToInsert == 0 && param.asInteger() == 0x06040580) {
nextAnimationByHash(0xD8C8D100, calcHash("GoToStartLoop/Finish"), 0);
} else if (_tapesToInsert != 0 && param.asInteger() == calcHash("GoToStartLoop/Finish")) {
@@ -2206,15 +2033,15 @@ void Klaymen::suJumpToGrab() {
uint32 Klaymen::hmJumpToGrab(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = hmLowLevel(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0x168050A0)
- sendMessage(_attachedSprite, 0x4806, 0);
+ sendMessage(_attachedSprite, NM_KLAYMEN_USE_OBJECT, 0);
else if (param.asInteger() == 0x320AC306)
startAnimationByHash(0x00AB8C10, 0x01084280, 0);
else if (param.asInteger() == 0x4AB28209)
- sendMessage(_attachedSprite, 0x482A, 0);
+ sendMessage(_attachedSprite, NM_MOVE_TO_BACK, 0);
else if (param.asInteger() == 0x88001184)
- sendMessage(_attachedSprite, 0x482B, 0);
+ sendMessage(_attachedSprite, NM_MOVE_TO_FRONT, 0);
break;
}
return messageResult;
@@ -2232,7 +2059,7 @@ void Klaymen::stFinishGrow() {
uint32 Klaymen::hmFinishGrow(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = hmLowLevelAnimation(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0x040C4C01)
playSound(0, 0x01E11140);
break;
@@ -2259,7 +2086,7 @@ void Klaymen::stJumpToGrabFall() {
SetUpdateHandler(&Klaymen::update);
SetMessageHandler(&Klaymen::hmJumpToGrab);
SetSpriteUpdate(&Klaymen::suJumpToGrab);
- sendMessage(_attachedSprite, 0x482B, 0);
+ sendMessage(_attachedSprite, NM_MOVE_TO_FRONT, 0);
}
}
@@ -2276,7 +2103,7 @@ void Klaymen::stJumpToGrabRelease() {
uint32 Klaymen::hmJumpToGrabRelease(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = hmLowLevelAnimation(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0x320AC306)
playSound(0, 0x5860C640);
break;
@@ -2325,7 +2152,7 @@ void Klaymen::teleporterDisappear(uint32 fileHash) {
uint32 Klaymen::hmTeleporterAppearDisappear(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = hmLowLevelAnimation(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0x4E0A2C24) {
playSound(0, 0x85B10BB8);
} else if (param.asInteger() == 0x4E6A0CA0) {
@@ -2336,29 +2163,6 @@ uint32 Klaymen::hmTeleporterAppearDisappear(int messageNum, const MessageParam &
return messageResult;
}
-uint32 Klaymen::hmShrink(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = hmLowLevelAnimation(messageNum, param, sender);
- switch (messageNum) {
- case 0x100D:
- if (param.asInteger() == 0x80C110B5)
- sendMessage(_parentScene, 0x482A, 0);
- else if (param.asInteger() == 0x33288344)
- playSound(2, 0x10688664);
- break;
- }
- return messageResult;
-}
-
-void Klaymen::stShrink() {
- _busyStatus = 0;
- _acceptInput = false;
- playSound(0, 0x4C69EA53);
- startAnimation(0x1AE88904, 0, -1);
- SetUpdateHandler(&Klaymen::update);
- SetMessageHandler(&Klaymen::hmShrink);
- SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
-}
-
void Klaymen::stStandWonderAbout() {
if (_x > 260)
setDoDeltaX(1);
@@ -2381,7 +2185,7 @@ uint32 Klaymen::hmDrinkPotion(int messageNum, const MessageParam &param, Entity
} else
_potionFlag2 = true;
break;
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0x0002418E)
sendMessage(_parentScene, 0x2000, 0);
else if (param.asInteger() == 0x924090C2) {
@@ -2426,7 +2230,7 @@ uint32 Klaymen::hmDrinkPotion(int messageNum, const MessageParam &param, Entity
uint32 Klaymen::hmGrow(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = hmLowLevelAnimation(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0x32180101)
playSound(0, 0x405002D8);
else if (param.asInteger() == 0x0A2A9098)
@@ -2479,7 +2283,7 @@ void Klaymen::stDrinkPotion() {
uint32 Klaymen::hmInsertKey(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = Klaymen::hmLowLevelAnimation(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (_keysToInsert == 0 && param.asInteger() == 0x06040580) {
nextAnimationByHash(0xDC409440, 0x46431401, 0);
} else if (_keysToInsert != 0 && param.asInteger() == 0x46431401) {
@@ -2537,65 +2341,10 @@ void Klaymen::stInsertKey() {
}
}
-uint32 Klaymen::hmReadNote(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = hmLowLevelAnimation(messageNum, param, sender);
- switch (messageNum) {
- case 0x100D:
- if (param.asInteger() == 0x04684052) {
- _acceptInput = true;
- sendMessage(_parentScene, 0x2002, 0);
- }
- break;
- }
- return messageResult;
-}
-
-void Klaymen::stReadNote() {
- _busyStatus = 2;
- _acceptInput = false;
- startAnimation(0x123E9C9F, 0, -1);
- SetUpdateHandler(&Klaymen::update);
- SetMessageHandler(&Klaymen::hmReadNote);
- SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
-}
-
-uint32 Klaymen::hmHitByDoor(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = hmLowLevelAnimation(messageNum, param, sender);
- int16 speedUpFrameIndex;
- switch (messageNum) {
- case 0x1008:
- speedUpFrameIndex = getFrameIndex(kKlaymenSpeedUpHash);
- if (_currFrameIndex < speedUpFrameIndex) {
- startAnimation(0x35AA8059, speedUpFrameIndex, -1);
- _y = 438;
- }
- messageResult = 0;
- break;
- case 0x100D:
- if (param.asInteger() == 0x1A1A0785) {
- playSound(0, 0x40F0A342);
- } else if (param.asInteger() == 0x60428026) {
- playSound(0, 0x40608A59);
- }
- break;
- }
- return messageResult;
-}
-
-void Klaymen::stHitByDoor() {
- _busyStatus = 1;
- _acceptInput = false;
- startAnimation(0x35AA8059, 0, -1);
- SetUpdateHandler(&Klaymen::update);
- SetMessageHandler(&Klaymen::hmHitByDoor);
- SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
- playSound(0, 0x402E82D4);
-}
-
uint32 Klaymen::hmPeekWallReturn(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = hmLowLevelAnimation(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == calcHash("PopBalloon")) {
sendMessage(_parentScene, 0x2000, 0);
} else if (param.asInteger() == 0x02B20220) {
@@ -2657,65 +2406,6 @@ void Klaymen::stPeekWallReturn() {
SetSpriteUpdate(NULL);
}
-void Klaymen::stPullHammerLever() {
- if (!stStartAction(AnimationCallback(&Klaymen::stPullHammerLever))) {
- _busyStatus = 2;
- _acceptInput = false;
- startAnimation(0x00648953, 0, -1);
- SetUpdateHandler(&Klaymen::update);
- SetMessageHandler(&Klaymen::hmPullHammerLever);
- SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
- }
-}
-
-uint32 Klaymen::hmPullHammerLever(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Klaymen::hmLever(messageNum, param, sender);
- switch (messageNum) {
- case 0x100D:
- if (param.asInteger() == 0x4AB28209)
- sendMessage(_attachedSprite, 0x480F, 0);
- break;
- }
- return messageResult;
-}
-
-void Klaymen::suRidePlatformDown() {
- _platformDeltaY++;
- _y += _platformDeltaY;
- if (_y > 600)
- sendMessage(this, 0x1019, 0);
-}
-
-void Klaymen::stRidePlatformDown() {
- if (!stStartActionFromIdle(AnimationCallback(&Klaymen::stRidePlatformDown))) {
- _busyStatus = 1;
- sendMessage(_parentScene, 0x4803, 0);
- _acceptInput = false;
- _platformDeltaY = 0;
- startAnimation(0x5420E254, 0, -1);
- SetUpdateHandler(&Klaymen::update);
- SetMessageHandler(&Klaymen::hmLowLevel);
- SetSpriteUpdate(&Klaymen::suRidePlatformDown);
- _vm->_soundMan->playSoundLooping(0xD3B02847);
- }
-}
-
-void Klaymen::stCrashDown() {
- playSound(0, 0x41648271);
- _busyStatus = 1;
- _acceptInput = false;
- startAnimationByHash(0x000BAB02, 0x88003000, 0);
- SetUpdateHandler(&Klaymen::update);
- SetSpriteUpdate(NULL);
- SetMessageHandler(&Klaymen::hmLowLevelAnimation);
- NextState(&Klaymen::stCrashDownFinished);
-}
-
-void Klaymen::stCrashDownFinished() {
- setDoDeltaX(2);
- stTryStandIdle();
-}
-
void Klaymen::upSpitOutFall() {
Klaymen::update();
if (_spitOutCountdown != 0 && (--_spitOutCountdown == 0)) {
@@ -2724,24 +2414,6 @@ void Klaymen::upSpitOutFall() {
}
}
-uint32 Klaymen::hmJumpToRingVenusFlyTrap(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = hmLowLevelAnimation(messageNum, param, sender);
- switch (messageNum) {
- case 0x100D:
- if (param.asInteger() == 0x168050A0) {
- sendMessage(_attachedSprite, 0x480F, 0);
- } else if (param.asInteger() == 0x586B0300) {
- sendMessage(_otherSprite, 0x480E, 1);
- } else if (param.asInteger() == 0x4AB28209) {
- sendMessage(_attachedSprite, 0x482A, 0);
- } else if (param.asInteger() == 0x88001184) {
- sendMessage(_attachedSprite, 0x482B, 0);
- }
- break;
- }
- return messageResult;
-}
-
uint32 Klaymen::hmStandIdleSpecial(int messageNum, const MessageParam &param, Entity *sender) {
switch (messageNum) {
case 0x4811:
@@ -2766,130 +2438,17 @@ uint32 Klaymen::hmStandIdleSpecial(int messageNum, const MessageParam &param, En
return 0;
}
-uint32 Klaymen::hmPressDoorButton(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = hmLowLevelAnimation(messageNum, param, sender);
- switch (messageNum) {
- case 0x100D:
- if (param.asInteger() == 0x942D2081) {
- _acceptInput = false;
- sendMessage(_attachedSprite, 0x2003, 0);
- } else if (param.asInteger() == 0xDA600012) {
- stHitByBoxingGlove();
- } else if (param.asInteger() == 0x0D01B294) {
- _acceptInput = false;
- sendMessage(_attachedSprite, 0x480B, 0);
- }
- break;
- }
- return messageResult;
-}
-
-uint32 Klaymen::hmMoveVenusFlyTrap(int messageNum, const MessageParam &param, Entity *sender) {
- switch (messageNum) {
- case 0x100D:
- if (param.asInteger() == 0x01084280) {
- sendMessage(_attachedSprite, 0x480B, (uint32)_doDeltaX);
- } else if (param.asInteger() == 0x02421405) {
- if (_isMoveObjectRequested) {
- if (sendMessage(_attachedSprite, 0x480C, (uint32)_doDeltaX) != 0)
- stContinueMovingVenusFlyTrap();
- } else {
- SetMessageHandler(&Klaymen::hmFirstMoveVenusFlyTrap);
- }
- } else if (param.asInteger() == 0x4AB28209) {
- sendMessage(_attachedSprite, 0x482A, 0);
- } else if (param.asInteger() == 0x88001184) {
- sendMessage(_attachedSprite, 0x482B, 0);
- } else if (param.asInteger() == 0x32180101) {
- playSound(0, 0x405002D8);
- } else if (param.asInteger() == 0x0A2A9098) {
- playSound(0, 0x0460E2FA);
- }
- break;
- case 0x480A:
- _isMoveObjectRequested = true;
- return 0;
- }
- return hmLowLevelAnimation(messageNum, param, sender);
-}
-
-uint32 Klaymen::hmFirstMoveVenusFlyTrap(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = hmLowLevelAnimation(messageNum, param, sender);
- switch (messageNum) {
- case 0x100D:
- if (param.asInteger() == 0x4AB28209) {
- sendMessage(_attachedSprite, 0x482A, 0);
- } else if (param.asInteger() == 0x88001184) {
- sendMessage(_attachedSprite, 0x482B, 0);
- } else if (param.asInteger() == 0x32180101) {
- playSound(0, 0x405002D8);
- } else if (param.asInteger() == 0x0A2A9098) {
- playSound(0, 0x0460E2FA);
- }
- break;
- }
- return messageResult;
-}
-
-uint32 Klaymen::hmHitByBoxingGlove(int messageNum, const MessageParam &param, Entity *sender) {
- int16 speedUpFrameIndex;
- uint32 messageResult = hmLowLevelAnimation(messageNum, param, sender);
- switch (messageNum) {
- case 0x1008:
- speedUpFrameIndex = getFrameIndex(kKlaymenSpeedUpHash);
- if (_currFrameIndex < speedUpFrameIndex) {
- startAnimation(0x35AA8059, speedUpFrameIndex, -1);
- _y = 435;
- }
- messageResult = 0;
- break;
- case 0x100D:
- if (param.asInteger() == 0x1A1A0785) {
- playSound(0, 0x40F0A342);
- } else if (param.asInteger() == 0x60428026) {
- playSound(0, 0x40608A59);
- }
- break;
- }
- return messageResult;
-}
-
-uint32 Klaymen::hmJumpAndFall(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = hmLowLevel(messageNum, param, sender);
- switch (messageNum) {
- case 0x100D:
- if (param.asInteger() == 0x1307050A) {
- playSound(0, 0x40428A09);
- }
- break;
- }
- return messageResult;
-}
-
void Klaymen::suFallDown() {
AnimatedSprite::updateDeltaXY();
HitRect *hitRect = _parentScene->findHitRectAtPos(_x, _y + 10);
if (hitRect->type == 0x5001) {
_y = hitRect->rect.y1;
updateBounds();
- sendMessage(this, 0x1019, 0);
+ sendMessage(this, NM_SCENE_LEAVE, 0);
}
_parentScene->checkCollision(this, 0xFFFF, 0x4810, 0);
}
-void Klaymen::stJumpToRingVenusFlyTrap() {
- if (!stStartAction(AnimationCallback(&Klaymen::stJumpToRingVenusFlyTrap))) {
- _busyStatus = 2;
- _acceptInput = false;
- startAnimation(0x584984B4, 0, -1);
- SetUpdateHandler(&Klaymen::update);
- SetMessageHandler(&Klaymen::hmJumpToRingVenusFlyTrap);
- SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
- NextState(&Klaymen::stLandOnFeet);
- sendMessage(_attachedSprite, 0x482B, 0);
- }
-}
-
void Klaymen::stStandIdleSpecial() {
playSound(0, 0x56548280);
_busyStatus = 0;
@@ -2936,7 +2495,7 @@ void Klaymen::stFalling() {
SetSpriteUpdate(NULL);
SetMessageHandler(&Klaymen::hmLowLevelAnimation);
NextState(&Klaymen::stFallTouchdown);
- sendMessage(_parentScene, 0x2002, 0);
+ sendMessage(_parentScene, NM_POSITION_CHANGE, 0);
_attachedSprite = NULL;
sendMessage(_parentScene, 0x8001, 0);
}
@@ -2946,93 +2505,13 @@ void Klaymen::stFallTouchdown() {
stTryStandIdle();
}
-void Klaymen::stJumpAndFall() {
- if (!stStartAction(AnimationCallback(&Klaymen::stJumpAndFall))) {
- sendMessage(_parentScene, 0x1024, 3);
- _busyStatus = 2;
- _acceptInput = false;
- startAnimation(0xB93AB151, 0, -1);
- SetUpdateHandler(&Klaymen::update);
- SetMessageHandler(&Klaymen::hmJumpAndFall);
- SetSpriteUpdate(&Klaymen::suFallDown);
- NextState(&Klaymen::stLandOnFeet);
- }
-}
-
-void Klaymen::stDropFromRing() {
- if (_attachedSprite) {
- _x = _attachedSprite->getX();
- sendMessage(_attachedSprite, 0x4807, 0);
- _attachedSprite = NULL;
- }
- _busyStatus = 2;
- _acceptInput = false;
- startAnimation(0x586984B1, 0, -1);
- SetUpdateHandler(&Klaymen::update);
- SetMessageHandler(&Klaymen::hmLowLevel);
- SetSpriteUpdate(&Klaymen::suFallDown);
- NextState(&Klaymen::stLandOnFeet);
-}
-
-void Klaymen::stPressDoorButton() {
- _busyStatus = 2;
- _acceptInput = true;
- setDoDeltaX(0);
- startAnimation(0x1CD89029, 0, -1);
- SetUpdateHandler(&Klaymen::update);
- SetMessageHandler(&Klaymen::hmPressDoorButton);
- SetSpriteUpdate(&Klaymen::suAction);
-}
-
-void Klaymen::stHitByBoxingGlove() {
- _busyStatus = 1;
- _acceptInput = false;
- startAnimation(0x35AA8059, 0, -1);
- SetUpdateHandler(&Klaymen::update);
- SetMessageHandler(&Klaymen::hmHitByBoxingGlove);
- SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
- FinalizeState(&Klaymen::evHitByBoxingGloveDone);
-}
-
-void Klaymen::evHitByBoxingGloveDone() {
- sendMessage(_parentScene, 0x1024, 1);
-}
-
-void Klaymen::stMoveVenusFlyTrap() {
- if (!stStartAction(AnimationCallback(&Klaymen::stMoveVenusFlyTrap))) {
- _busyStatus = 2;
- _isMoveObjectRequested = false;
- _acceptInput = true;
- setDoDeltaX(_attachedSprite->getX() < _x ? 1 : 0);
- startAnimation(0x5C01A870, 0, -1);
- SetUpdateHandler(&Klaymen::update);
- SetMessageHandler(&Klaymen::hmMoveVenusFlyTrap);
- SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
- FinalizeState(&Klaymen::evMoveVenusFlyTrapDone);
- }
-}
-
-void Klaymen::stContinueMovingVenusFlyTrap() {
- _isMoveObjectRequested = false;
- _acceptInput = true;
- startAnimationByHash(0x5C01A870, 0x01084280, 0);
- SetUpdateHandler(&Klaymen::update);
- SetMessageHandler(&Klaymen::hmMoveVenusFlyTrap);
- SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
- FinalizeState(&Klaymen::evMoveVenusFlyTrapDone);
-}
-
-void Klaymen::evMoveVenusFlyTrapDone() {
- sendMessage(_attachedSprite, 0x482A, 0);
-}
-
void Klaymen::suFallSkipJump() {
updateDeltaXY();
HitRect *hitRect = _parentScene->findHitRectAtPos(_x, _y + 10);
if (hitRect->type == 0x5001) {
_y = hitRect->rect.y1;
updateBounds();
- sendMessage(this, 0x1019, 0);
+ sendMessage(this, NM_SCENE_LEAVE, 0);
}
}
@@ -3052,52 +2531,9 @@ void Klaymen::upMoveObject() {
Klaymen::update();
}
-uint32 Klaymen::hmMatch(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Klaymen::hmLowLevelAnimation(messageNum, param, sender);
- switch (messageNum) {
- case 0x100D:
- if (param.asInteger() == 0x51281850) {
- setGlobalVar(V_TNT_DUMMY_FUSE_LIT, 1);
- } else if (param.asInteger() == 0x43000538) {
- playSound(0, 0x21043059);
- } else if (param.asInteger() == 0x02B20220) {
- playSound(0, 0xC5408620);
- } else if (param.asInteger() == 0x0A720138) {
- playSound(0, 0xD4C08010);
- } else if (param.asInteger() == 0xB613A180) {
- playSound(0, 0x44051000);
- }
- break;
- }
- return messageResult;
-}
-
-void Klaymen::stFetchMatch() {
- if (!stStartAction(AnimationCallback(&Klaymen::stFetchMatch))) {
- _busyStatus = 0;
- _acceptInput = false;
- setDoDeltaX(_attachedSprite->getX() < _x ? 1 : 0);
- startAnimation(0x9CAA0218, 0, -1);
- SetUpdateHandler(&Klaymen::update);
- SetMessageHandler(&Klaymen::hmMatch);
- SetSpriteUpdate(NULL);
- NextState(&Klaymen::stLightMatch);
- }
-}
-
-void Klaymen::stLightMatch() {
- _busyStatus = 1;
- _acceptInput = false;
- setDoDeltaX(_attachedSprite->getX() < _x ? 1 : 0);
- startAnimation(0x1222A513, 0, -1);
- SetUpdateHandler(&Klaymen::update);
- SetMessageHandler(&Klaymen::hmMatch);
- SetSpriteUpdate(NULL);
-}
-
uint32 Klaymen::hmMoveObject(int messageNum, const MessageParam &param, Entity *sender) {
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0x01084280) {
playSound(0, 0x405002D8);
sendMessage(_attachedSprite, 0x480B, 0);
@@ -3114,18 +2550,6 @@ uint32 Klaymen::hmMoveObject(int messageNum, const MessageParam &param, Entity *
return Klaymen::hmLowLevelAnimation(messageNum, param, sender);
}
-uint32 Klaymen::hmTumbleHeadless(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Klaymen::hmLowLevelAnimation(messageNum, param, sender);
- switch (messageNum) {
- case 0x100D:
- if (param.asInteger() == 0x000F0082) {
- playSound(0, 0x74E2810F);
- }
- break;
- }
- return messageResult;
-}
-
void Klaymen::stMoveObject() {
if (!stStartAction(AnimationCallback(&Klaymen::stMoveObject))) {
_busyStatus = 2;
@@ -3147,93 +2571,6 @@ void Klaymen::stContinueMoveObject() {
SetMessageHandler(&Klaymen::hmMoveObject);
}
-void Klaymen::stTumbleHeadless() {
- if (!stStartActionFromIdle(AnimationCallback(&Klaymen::stTumbleHeadless))) {
- _busyStatus = 1;
- _acceptInput = false;
- setDoDeltaX(0);
- startAnimation(0x2821C590, 0, -1);
- SetUpdateHandler(&Klaymen::update);
- SetMessageHandler(&Klaymen::hmTumbleHeadless);
- SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
- NextState(&Klaymen::stTryStandIdle);
- sendMessage(_parentScene, 0x8000, 0);
- playSound(0, 0x62E0A356);
- }
-}
-
-void Klaymen::stCloseEyes() {
- if (!stStartActionFromIdle(AnimationCallback(&Klaymen::stCloseEyes))) {
- _busyStatus = 1;
- _acceptInput = false;
- startAnimation(0x5420E254, 0, -1);
- SetUpdateHandler(&Klaymen::update);
- SetMessageHandler(&Klaymen::hmLowLevel);
- SetSpriteUpdate(NULL);
- }
-}
-
-uint32 Klaymen::hmSpit(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Klaymen::hmLowLevelAnimation(messageNum, param, sender);
- switch (messageNum) {
- case 0x100D:
- if (param.asInteger() == 0x16401CA6) {
- _canSpitPipe = true;
- if (_contSpitPipe)
- spitIntoPipe();
- } else if (param.asInteger() == 0xC11C0008) {
- _canSpitPipe = false;
- _acceptInput = false;
- _readyToSpit = false;
- } else if (param.asInteger() == 0x018A0001) {
- sendMessage(_parentScene, 0x2001, _spitDestPipeIndex);
- }
- break;
- }
- return messageResult;
-}
-
-void Klaymen::stTrySpitIntoPipe() {
- if (_readyToSpit) {
- _contSpitPipe = true;
- _spitContDestPipeIndex = _spitPipeIndex;
- if (_canSpitPipe)
- spitIntoPipe();
- } else if (!stStartAction(AnimationCallback(&Klaymen::stTrySpitIntoPipe))) {
- _busyStatus = 2;
- _acceptInput = true;
- _spitDestPipeIndex = _spitPipeIndex;
- _readyToSpit = true;
- _canSpitPipe = false;
- _contSpitPipe = false;
- startAnimation(0x1808B150, 0, -1);
- SetUpdateHandler(&Klaymen::update);
- SetMessageHandler(&Klaymen::hmSpit);
- SetSpriteUpdate(NULL);
- }
-}
-
-void Klaymen::spitIntoPipe() {
- _contSpitPipe = false;
- _spitDestPipeIndex = _spitContDestPipeIndex;
- _canSpitPipe = false;
- _acceptInput = false;
- startAnimation(0x1B08B553, 0, -1);
- SetUpdateHandler(&Klaymen::update);
- SetMessageHandler(&Klaymen::hmSpit);
- SetSpriteUpdate(NULL);
- NextState(&Klaymen::stContSpitIntoPipe);
-}
-
-void Klaymen::stContSpitIntoPipe() {
- _canSpitPipe = true;
- _acceptInput = true;
- startAnimationByHash(0x1808B150, 0x16401CA6, 0);
- SetUpdateHandler(&Klaymen::update);
- SetMessageHandler(&Klaymen::hmSpit);
- SetSpriteUpdate(NULL);
-}
-
void Klaymen::suRidePlatform() {
_x = _attachedSprite->getX() - 20;
_y = _attachedSprite->getY() + 46;
@@ -3270,7 +2607,7 @@ void Klaymen::stInteractLever() {
void Klaymen::stPullLever() {
startAnimation(0x0D318140, 0, -1);
NextState(&Klaymen::stLookLeverDown);
- sendMessage(_attachedSprite, 0x480F, 0);
+ sendMessage(_attachedSprite, NM_KLAYMEN_LOWER_LEVER, 0);
}
void Klaymen::stLookLeverDown() {
@@ -3344,2798 +2681,4 @@ void Klaymen::stPeekInsideBlink() {
_blinkCounterMax = _vm->_rnd->getRandomNumber(64 - 1) + 24;
}
-// KmScene1001
-
-KmScene1001::KmScene1001(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
- : Klaymen(vm, parentScene, x, y) {
-}
-
-uint32 KmScene1001::xHandleMessage(int messageNum, const MessageParam &param) {
- switch (messageNum) {
- case 0x4001:
- case 0x4800:
- startWalkToX(param.asPoint().x, false);
- break;
- case 0x4004:
- GotoState(&Klaymen::stTryStandIdle);
- break;
- case 0x4804:
- if (param.asInteger() == 2)
- GotoState(&Klaymen::stSleeping);
- break;
- case 0x480D:
- GotoState(&Klaymen::stPullHammerLever);
- break;
- case 0x4812:
- GotoState(&Klaymen::stPickUpGeneric);
- break;
- case 0x4816:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stPressButton);
- else if (param.asInteger() == 2)
- GotoState(&Klaymen::stPressFloorButton);
- else
- GotoState(&Klaymen::stPressButtonSide);
- break;
- case 0x4817:
- setDoDeltaX(param.asInteger());
- gotoNextStateExt();
- break;
- case 0x481B:
- if (param.asPoint().y != 0)
- startWalkToXDistance(param.asPoint().y, param.asPoint().x);
- else
- startWalkToAttachedSpriteXDistance(param.asPoint().x);
- break;
- case 0x481F:
- if (param.asInteger() == 0)
- GotoState(&Klaymen::stWonderAboutHalf);
- else if (param.asInteger() == 1)
- GotoState(&Klaymen::stWonderAboutAfter);
- else if (param.asInteger() == 3)
- GotoState(&Klaymen::stTurnToUseHalf);
- else if (param.asInteger() == 4)
- GotoState(&Klaymen::stTurnAwayFromUse);
- else
- GotoState(&Klaymen::stWonderAbout);
- break;
- case 0x482D:
- setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
- gotoNextStateExt();
- break;
- case 0x4836:
- if (param.asInteger() == 1) {
- sendMessage(_parentScene, 0x2002, 0);
- GotoState(&Klaymen::stWakeUp);
- }
- break;
- case 0x483F:
- startSpecialWalkRight(param.asInteger());
- break;
- case 0x4840:
- startSpecialWalkLeft(param.asInteger());
- break;
- }
- return 0;
-}
-
-// KmScene1002
-
-KmScene1002::KmScene1002(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
- : Klaymen(vm, parentScene, x, y) {
-
- setKlaymenIdleTable1();
-}
-
-void KmScene1002::xUpdate() {
- if (_x >= 250 && _x <= 435 && _y >= 420) {
- if (_idleTableNum == 0) {
- setKlaymenIdleTable(klaymenIdleTable1002, ARRAYSIZE(klaymenIdleTable1002));
- _idleTableNum = 1;
- }
- } else if (_idleTableNum == 1) {
- setKlaymenIdleTable1();
- _idleTableNum = 0;
- }
-}
-
-uint32 KmScene1002::xHandleMessage(int messageNum, const MessageParam &param) {
- switch (messageNum) {
- case 0x2001:
- GotoState(&Klaymen::stStandIdleSpecial);
- break;
- case 0x2007:
- _otherSprite = (Sprite*)param.asEntity();
- break;
- case 0x4001:
- case 0x4800:
- startWalkToX(param.asPoint().x, false);
- break;
- case 0x4004:
- GotoState(&Klaymen::stTryStandIdle);
- break;
- case 0x4803:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stJumpAndFall);
- else if (param.asInteger() == 2)
- GotoState(&Klaymen::stDropFromRing);
- break;
- case 0x4804:
- GotoState(&Klaymen::stPeekWall);
- break;
- case 0x4805:
- switch (param.asInteger()) {
- case 1:
- GotoState(&Klaymen::stJumpToRing1);
- break;
- case 2:
- GotoState(&Klaymen::stJumpToRing2);
- break;
- case 3:
- GotoState(&Klaymen::stJumpToRing3);
- break;
- case 4:
- GotoState(&Klaymen::stJumpToRing4);
- break;
- }
- break;
- case 0x480A:
- GotoState(&Klaymen::stMoveVenusFlyTrap);
- break;
- case 0x480D:
- GotoState(&Klaymen::stJumpToRingVenusFlyTrap);
- break;
- case 0x4816:
- if (param.asInteger() == 0)
- GotoState(&Klaymen::stPressDoorButton);
- break;
- case 0x4817:
- setDoDeltaX(param.asInteger());
- gotoNextStateExt();
- break;
- case 0x481B:
- startWalkToAttachedSpriteXDistance(param.asInteger());
- break;
- case 0x4820:
- sendMessage(_parentScene, 0x2005, 0);
- GotoState(&Klaymen::stContinueClimbLadderUp);
- break;
- case 0x4821:
- sendMessage(_parentScene, 0x2005, 0);
- _destY = param.asInteger();
- GotoState(&Klaymen::stStartClimbLadderDown);
- break;
- case 0x4822:
- sendMessage(_parentScene, 0x2005, 0);
- _destY = param.asInteger();
- GotoState(&Klaymen::stStartClimbLadderUp);
- break;
- case 0x4823:
- sendMessage(_parentScene, 0x2006, 0);
- GotoState(&Klaymen::stClimbLadderHalf);
- break;
- case 0x482E:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stWalkToFrontNoStep);
- else
- GotoState(&Klaymen::stWalkToFront);
- break;
- case 0x482F:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stTurnToFront);
- else
- GotoState(&Klaymen::stTurnToBack);
- break;
- case 0x483F:
- startSpecialWalkRight(param.asInteger());
- break;
- case 0x4840:
- startSpecialWalkLeft(param.asInteger());
- break;
- }
- return 0;
-}
-
-// KmScene1004
-
-KmScene1004::KmScene1004(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
- : Klaymen(vm, parentScene, x, y) {
-
- _dataResource.load(0x01900A04);
-}
-
-uint32 KmScene1004::xHandleMessage(int messageNum, const MessageParam &param) {
- switch (messageNum) {
- case 0x4001:
- case 0x4800:
- startWalkToX(param.asPoint().x, false);
- break;
- case 0x4004:
- GotoState(&Klaymen::stTryStandIdle);
- break;
- case 0x4817:
- setDoDeltaX(param.asInteger());
- gotoNextStateExt();
- break;
- case 0x4818:
- startWalkToX(_dataResource.getPoint(param.asInteger()).x, false);
- break;
- case 0x481E:
- GotoState(&Klaymen::stReadNote);
- break;
- case 0x4820:
- sendMessage(_parentScene, 0x2000, 0);
- GotoState(&Klaymen::stContinueClimbLadderUp);
- break;
- case 0x4821:
- sendMessage(_parentScene, 0x2000, 0);
- _destY = param.asInteger();
- GotoState(&Klaymen::stStartClimbLadderDown);
- break;
- case 0x4822:
- sendMessage(_parentScene, 0x2000, 0);
- _destY = param.asInteger();
- GotoState(&Klaymen::stStartClimbLadderUp);
- break;
- case 0x4823:
- sendMessage(_parentScene, 0x2001, 0);
- GotoState(&Klaymen::stClimbLadderHalf);
- break;
- case 0x4824:
- sendMessage(_parentScene, 0x2000, 0);
- _destY = _dataResource.getPoint(param.asInteger()).y;
- GotoState(&Klaymen::stStartClimbLadderDown);
- break;
- case 0x4825:
- sendMessage(_parentScene, 0x2000, 0);
- _destY = _dataResource.getPoint(param.asInteger()).y;
- GotoState(&Klaymen::stStartClimbLadderUp);
- break;
- case 0x4828:
- GotoState(&Klaymen::stTurnToBackToUse);
- break;
- case 0x483F:
- startSpecialWalkRight(param.asInteger());
- break;
- case 0x4840:
- startSpecialWalkLeft(param.asInteger());
- break;
- }
- return 0;
-}
-
-KmScene1109::KmScene1109(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
- : Klaymen(vm, parentScene, x, y) {
-
- // Empty
-}
-
-uint32 KmScene1109::xHandleMessage(int messageNum, const MessageParam &param) {
- uint32 messageResult = 0;
- switch (messageNum) {
- case 0x2000:
- _isSittingInTeleporter = param.asInteger() != 0;
- messageResult = 1;
- break;
- case 0x4001:
- case 0x4800:
- startWalkToX(param.asPoint().x, false);
- break;
- case 0x4004:
- if (_isSittingInTeleporter)
- GotoState(&Klaymen::stSitIdleTeleporter);
- else
- GotoState(&Klaymen::stTryStandIdle);
- break;
- case 0x4804:
- if (param.asInteger() != 0) {
- _destX = param.asInteger();
- GotoState(&Klaymen::stWalkingFirst);
- } else
- GotoState(&Klaymen::stPeekWall);
- break;
- case 0x4817:
- setDoDeltaX(param.asInteger());
- gotoNextStateExt();
- break;
- case 0x481D:
- if (_isSittingInTeleporter)
- GotoState(&Klaymen::stTurnToUseInTeleporter);
- break;
- case 0x481E:
- if (_isSittingInTeleporter)
- GotoState(&Klaymen::stReturnFromUseInTeleporter);
- break;
- case 0x4834:
- GotoState(&Klaymen::stStepOver);
- break;
- case 0x4835:
- sendMessage(_parentScene, 0x2000, 1);
- _isSittingInTeleporter = true;
- GotoState(&Klaymen::stSitInTeleporter);
- break;
- case 0x4836:
- sendMessage(_parentScene, 0x2000, 0);
- _isSittingInTeleporter = false;
- GotoState(&Klaymen::stGetUpFromTeleporter);
- break;
- case 0x483D:
- teleporterAppear(0x2C2A4A1C);
- break;
- case 0x483E:
- teleporterDisappear(0x3C2E4245);
- break;
- }
- return messageResult;
-}
-
-// KmScene1201
-
-KmScene1201::KmScene1201(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
- : Klaymen(vm, parentScene, x, y) {
-
- setKlaymenIdleTable(klaymenIdleTable4, ARRAYSIZE(klaymenIdleTable4));
- _doYHitIncr = true;
-}
-
-uint32 KmScene1201::xHandleMessage(int messageNum, const MessageParam &param) {
- switch (messageNum) {
- case 0x4001:
- case 0x4800:
- startWalkToX(param.asPoint().x, false);
- break;
- case 0x4004:
- GotoState(&Klaymen::stTryStandIdle);
- break;
- case 0x480A:
- GotoState(&Klaymen::stMoveObject);
- break;
- case 0x4812:
- GotoState(&Klaymen::stPickUpGeneric);
- break;
- case 0x4813:
- GotoState(&Klaymen::stFetchMatch);
- break;
- case 0x4814:
- GotoState(&Klaymen::stTumbleHeadless);
- break;
- case 0x4815:
- GotoState(&Klaymen::stCloseEyes);
- break;
- case 0x4816:
- if (param.asInteger() == 0)
- GotoState(&Klaymen::stPressButtonSide);
- break;
- case 0x4817:
- setDoDeltaX(param.asInteger());
- gotoNextStateExt();
- break;
- case 0x481B:
- if (param.asPoint().y != 0)
- startWalkToXDistance(param.asPoint().y, param.asPoint().x);
- else
- startWalkToAttachedSpriteXDistance(param.asPoint().x);
- break;
- case 0x481D:
- GotoState(&Klaymen::stTurnToUse);
- break;
- case 0x481E:
- GotoState(&Klaymen::stReturnFromUse);
- break;
- case 0x481F:
- GotoState(&Klaymen::stWonderAbout);
- break;
- case 0x482D:
- setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
- gotoNextStateExt();
- break;
- case 0x483F:
- startSpecialWalkRight(param.asInteger());
- break;
- case 0x4840:
- startSpecialWalkLeft(param.asInteger());
- break;
- }
- return 0;
-}
-
-KmScene1303::KmScene1303(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
- : Klaymen(vm, parentScene, x, y) {
-
- // Empty
-}
-
-uint32 KmScene1303::xHandleMessage(int messageNum, const MessageParam &param) {
- switch (messageNum) {
- case 0x4804:
- GotoState(&Klaymen::stPeekWall1);
- break;
- case 0x483B:
- GotoState(&Klaymen::stPeekWallReturn);
- break;
- case 0x483C:
- GotoState(&Klaymen::stPeekWall2);
- break;
- }
- return 0;
-}
-
-KmScene1304::KmScene1304(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
- : Klaymen(vm, parentScene, x, y) {
-
- // Empty
-}
-
-uint32 KmScene1304::xHandleMessage(int messageNum, const MessageParam &param) {
- switch (messageNum) {
- case 0x4001:
- case 0x4800:
- startWalkToX(param.asPoint().x, false);
- break;
- case 0x4004:
- GotoState(&Klaymen::stTryStandIdle);
- break;
- case 0x4812:
- if (param.asInteger() == 2)
- GotoState(&Klaymen::stPickUpNeedle);
- else if (param.asInteger() == 1)
- GotoState(&Klaymen::stPickUpTube);
- else
- GotoState(&Klaymen::stPickUpGeneric);
- break;
- case 0x4817:
- setDoDeltaX(param.asInteger());
- gotoNextStateExt();
- break;
- case 0x481B:
- if (param.asPoint().y != 0)
- startWalkToXDistance(param.asPoint().y, param.asPoint().x);
- else
- startWalkToAttachedSpriteXDistance(param.asPoint().x);
- break;
- case 0x481F:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stTurnAwayFromUse);
- else if (param.asInteger() == 0)
- GotoState(&Klaymen::stTurnToUseHalf);
- else
- GotoState(&Klaymen::stWonderAbout);
- break;
- case 0x483F:
- startSpecialWalkRight(param.asInteger());
- break;
- case 0x4840:
- startSpecialWalkLeft(param.asInteger());
- break;
- }
- return 0;
-}
-
-KmScene1305::KmScene1305(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
- : Klaymen(vm, parentScene, x, y) {
-
- // Empty
-}
-
-uint32 KmScene1305::xHandleMessage(int messageNum, const MessageParam &param) {
- switch (messageNum) {
- case 0x4001:
- case 0x4800:
- startWalkToX(param.asPoint().x, false);
- break;
- case 0x4004:
- GotoState(&Klaymen::stTryStandIdle);
- break;
- case 0x4804:
- GotoState(&Klaymen::stCrashDown);
- break;
- case 0x4817:
- setDoDeltaX(param.asInteger());
- gotoNextStateExt();
- break;
- }
- return 0;
-}
-
-KmScene1306::KmScene1306(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
- : Klaymen(vm, parentScene, x, y) {
-
- // Empty
-}
-
-uint32 KmScene1306::xHandleMessage(int messageNum, const MessageParam &param) {
- uint32 messageResult = 0;
- switch (messageNum) {
- case 0x2000:
- _isSittingInTeleporter = param.asInteger() != 0;
- messageResult = 1;
- break;
- case 0x4001:
- case 0x4800:
- startWalkToX(param.asPoint().x, false);
- break;
- case 0x4004:
- if (_isSittingInTeleporter)
- GotoState(&Klaymen::stSitIdleTeleporter);
- else
- GotoState(&Klaymen::stTryStandIdle);
- break;
- case 0x4812:
- if (param.asInteger() == 2)
- GotoState(&Klaymen::stPickUpNeedle);
- else if (param.asInteger() == 1)
- GotoState(&Klaymen::stPickUpTube);
- else
- GotoState(&Klaymen::stPickUpGeneric);
- break;
- case 0x4816:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stPressButton);
- else if (param.asInteger() == 2)
- GotoState(&Klaymen::stPressFloorButton);
- else
- GotoState(&Klaymen::stPressButtonSide);
- break;
- case 0x4817:
- setDoDeltaX(param.asInteger());
- gotoNextStateExt();
- break;
- case 0x481A:
- GotoState(&Klaymen::stInsertDisk);
- break;
- case 0x481B:
- if (param.asPoint().y != 0)
- startWalkToXDistance(param.asPoint().y, param.asPoint().x);
- else
- startWalkToAttachedSpriteXDistance(param.asPoint().x);
- break;
- case 0x481D:
- if (_isSittingInTeleporter)
- GotoState(&Klaymen::stTurnToUseInTeleporter);
- else
- GotoState(&Klaymen::stTurnToUse);
- break;
- case 0x481E:
- if (_isSittingInTeleporter)
- GotoState(&Klaymen::stReturnFromUseInTeleporter);
- else
- GotoState(&Klaymen::stReturnFromUse);
- break;
- case 0x481F:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stWonderAboutAfter);
- else if (param.asInteger() == 0)
- GotoState(&Klaymen::stWonderAboutHalf);
- else if (param.asInteger() == 4)
- GotoState(&Klaymen::stTurnAwayFromUse);
- else if (param.asInteger() == 3)
- GotoState(&Klaymen::stTurnToUseHalf);
- else
- GotoState(&Klaymen::stWonderAbout);
- break;
- case 0x482D:
- setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
- gotoNextStateExt();
- break;
- case 0x482E:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stWalkToFrontNoStep);
- else
- GotoState(&Klaymen::stWalkToFront);
- break;
- case 0x482F:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stTurnToFront);
- else
- GotoState(&Klaymen::stTurnToBack);
- break;
- case 0x4834:
- GotoState(&Klaymen::stStepOver);
- break;
- case 0x4835:
- sendMessage(_parentScene, 0x2000, 1);
- _isSittingInTeleporter = true;
- GotoState(&Klaymen::stSitInTeleporter);
- break;
- case 0x4836:
- sendMessage(_parentScene, 0x2000, 0);
- _isSittingInTeleporter = false;
- GotoState(&Klaymen::stGetUpFromTeleporter);
- break;
- case 0x483D:
- teleporterAppear(0xEE084A04);
- break;
- case 0x483E:
- teleporterDisappear(0xB86A4274);
- break;
- case 0x483F:
- startSpecialWalkRight(param.asInteger());
- break;
- case 0x4840:
- startSpecialWalkLeft(param.asInteger());
- break;
- }
- return messageResult;
-}
-
-KmScene1308::KmScene1308(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
- : Klaymen(vm, parentScene, x, y) {
-
- // Empty
-}
-
-uint32 KmScene1308::xHandleMessage(int messageNum, const MessageParam &param) {
- switch (messageNum) {
- case 0x4001:
- case 0x4800:
- startWalkToX(param.asPoint().x, false);
- break;
- case 0x4004:
- GotoState(&Klaymen::stTryStandIdle);
- break;
- case 0x480A:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stMoveObjectSkipTurnFaceObject);
- else
- GotoState(&Klaymen::stMoveObjectFaceObject);
- break;
- case 0x480D:
- GotoState(&Klaymen::stUseLever);
- break;
- case 0x4812:
- if (param.asInteger() == 2)
- GotoState(&Klaymen::stPickUpNeedle);
- else if (param.asInteger() == 1)
- GotoState(&Klaymen::stPickUpTube);
- else
- GotoState(&Klaymen::stPickUpGeneric);
- break;
- case 0x4817:
- setDoDeltaX(param.asInteger());
- gotoNextStateExt();
- break;
- case 0x481A:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stInsertKey);
- else
- GotoState(&Klaymen::stInsertDisk);
- break;
- case 0x481B:
- if (param.asPoint().y != 0)
- startWalkToXDistance(param.asPoint().y, param.asPoint().x);
- else
- startWalkToAttachedSpriteXDistance(param.asPoint().x);
- break;
- case 0x481D:
- GotoState(&Klaymen::stTurnToUse);
- break;
- case 0x481E:
- GotoState(&Klaymen::stReturnFromUse);
- break;
- case 0x4827:
- GotoState(&Klaymen::stReleaseLever);
- break;
- case 0x4834:
- GotoState(&Klaymen::stStepOver);
- break;
- case 0x483F:
- startSpecialWalkRight(param.asInteger());
- break;
- case 0x4840:
- startSpecialWalkLeft(param.asInteger());
- break;
- }
- return 0;
-}
-
-// KmScene1401
-
-KmScene1401::KmScene1401(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
- : Klaymen(vm, parentScene, x, y) {
-
- // Empty
-}
-
-uint32 KmScene1401::xHandleMessage(int messageNum, const MessageParam &param) {
- switch (messageNum) {
- case 0x4001:
- case 0x4800:
- startWalkToX(param.asPoint().x, false);
- break;
- case 0x4004:
- GotoState(&Klaymen::stTryStandIdle);
- break;
- case 0x480A:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stMoveObjectSkipTurnFaceObject);
- else
- GotoState(&Klaymen::stMoveObjectFaceObject);
- break;
- case 0x4816:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stPressButton);
- else if (param.asInteger() == 2)
- GotoState(&Klaymen::stPressFloorButton);
- else
- GotoState(&Klaymen::stPressButtonSide);
- break;
- case 0x4817:
- setDoDeltaX(param.asInteger());
- gotoNextStateExt();
- break;
- case 0x481B:
- if (param.asPoint().y != 0)
- startWalkToXDistance(param.asPoint().y, param.asPoint().x);
- else
- startWalkToAttachedSpriteXDistance(param.asPoint().x);
- break;
- case 0x481F:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stTurnAwayFromUse);
- else if (param.asInteger() == 0)
- GotoState(&Klaymen::stTurnToUseHalf);
- else
- GotoState(&Klaymen::stWonderAbout);
- break;
- case 0x482D:
- setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
- gotoNextStateExt();
- break;
- case 0x482E:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stWalkToFrontNoStep);
- else
- GotoState(&Klaymen::stWalkToFront);
- break;
- case 0x482F:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stTurnToFront);
- else
- GotoState(&Klaymen::stTurnToBack);
- break;
- }
- return 0;
-}
-
-// KmScene1402
-
-KmScene1402::KmScene1402(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
- : Klaymen(vm, parentScene, x, y) {
-
- SetFilterY(&Sprite::defFilterY);
-}
-
-uint32 KmScene1402::xHandleMessage(int messageNum, const MessageParam &param) {
- switch (messageNum) {
- case 0x4001:
- case 0x4800:
- startWalkToX(param.asPoint().x, false);
- break;
- case 0x4004:
- GotoState(&Klaymen::stTryStandIdle);
- break;
- case 0x480A:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stMoveObjectSkipTurnFaceObject);
- else
- GotoState(&Klaymen::stMoveObjectFaceObject);
- break;
- case 0x4817:
- setDoDeltaX(param.asInteger());
- gotoNextStateExt();
- break;
- case 0x481B:
- if (param.asPoint().y != 0)
- startWalkToXDistance(param.asPoint().y, param.asPoint().x);
- else
- startWalkToAttachedSpriteXDistance(param.asPoint().x);
- break;
- case 0x481D:
- GotoState(&Klaymen::stTurnToUse);
- break;
- case 0x481E:
- GotoState(&Klaymen::stReturnFromUse);
- break;
- }
- return 0;
-}
-
-// KmScene1403
-
-KmScene1403::KmScene1403(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
- : Klaymen(vm, parentScene, x, y) {
-
- setKlaymenIdleTable(klaymenIdleTable4, ARRAYSIZE(klaymenIdleTable4));
-}
-
-uint32 KmScene1403::xHandleMessage(int messageNum, const MessageParam &param) {
- switch (messageNum) {
- case 0x4001:
- case 0x4800:
- startWalkToX(param.asPoint().x, false);
- break;
- case 0x4004:
- GotoState(&Klaymen::stTryStandIdle);
- break;
- case 0x480A:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stMoveObjectSkipTurnFaceObject);
- else
- GotoState(&Klaymen::stMoveObjectFaceObject);
- break;
- case 0x480D:
- GotoState(&Klaymen::stUseLever);
- break;
- case 0x4812:
- if (param.asInteger() == 2)
- GotoState(&Klaymen::stPickUpNeedle);
- else if (param.asInteger() == 1)
- GotoState(&Klaymen::stPickUpTube);
- else
- GotoState(&Klaymen::stPickUpGeneric);
- break;
- case 0x4817:
- setDoDeltaX(param.asInteger());
- gotoNextStateExt();
- break;
- case 0x481B:
- if (param.asPoint().y != 0)
- startWalkToXDistance(param.asPoint().y, param.asPoint().x);
- else
- startWalkToAttachedSpriteXDistance(param.asPoint().x);
- break;
- case 0x4827:
- GotoState(&Klaymen::stReleaseLever);
- break;
- case 0x483F:
- startSpecialWalkRight(param.asInteger());
- break;
- case 0x4840:
- startSpecialWalkLeft(param.asInteger());
- break;
- }
- return 0;
-}
-
-// KmScene1404
-
-KmScene1404::KmScene1404(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
- : Klaymen(vm, parentScene, x, y) {
-
- // Empty
-}
-
-uint32 KmScene1404::xHandleMessage(int messageNum, const MessageParam &param) {
- switch (messageNum) {
- case 0x4001:
- case 0x4800:
- startWalkToX(param.asPoint().x, false);
- break;
- case 0x4004:
- GotoState(&Klaymen::stTryStandIdle);
- break;
- case 0x480A:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stMoveObjectSkipTurnFaceObject);
- else
- GotoState(&Klaymen::stMoveObjectFaceObject);
- break;
- case 0x4812:
- if (param.asInteger() == 2)
- GotoState(&Klaymen::stPickUpNeedle);
- else if (param.asInteger() == 1)
- GotoState(&Klaymen::stPickUpTube);
- else
- GotoState(&Klaymen::stPickUpGeneric);
- break;
- case 0x4817:
- setDoDeltaX(param.asInteger());
- gotoNextStateExt();
- break;
- case 0x481A:
- GotoState(&Klaymen::stInsertDisk);
- break;
- case 0x481B:
- if (param.asPoint().y != 0)
- startWalkToXDistance(param.asPoint().y, param.asPoint().x);
- else
- startWalkToAttachedSpriteXDistance(param.asPoint().x);
- break;
- case 0x481D:
- GotoState(&Klaymen::stTurnToUse);
- break;
- case 0x481E:
- GotoState(&Klaymen::stReturnFromUse);
- break;
- case 0x481F:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stWonderAboutAfter);
- else if (param.asInteger() == 0)
- GotoState(&Klaymen::stWonderAboutHalf);
- else if (param.asInteger() == 4)
- GotoState(&Klaymen::stTurnAwayFromUse);
- else if (param.asInteger() == 3)
- GotoState(&Klaymen::stTurnToUseHalf);
- else
- GotoState(&Klaymen::stWonderAbout);
- break;
- case 0x482D:
- setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
- gotoNextStateExt();
- break;
- case 0x483F:
- startSpecialWalkRight(param.asInteger());
- break;
- case 0x4840:
- startSpecialWalkLeft(param.asInteger());
- break;
- }
- return 0;
-}
-
-KmScene1608::KmScene1608(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
- : Klaymen(vm, parentScene, x, y) {
-
- // Empty
-}
-
-uint32 KmScene1608::xHandleMessage(int messageNum, const MessageParam &param) {
- uint32 messageResult = 0;
- switch (messageNum) {
- case 0x2032:
- _isSittingInTeleporter = param.asInteger() != 0;
- messageResult = 1;
- break;
- case 0x4001:
- case 0x4800:
- startWalkToX(param.asPoint().x, false);
- break;
- case 0x4004:
- if (_isSittingInTeleporter)
- GotoState(&Klaymen::stSitIdleTeleporter);
- else
- GotoState(&Klaymen::stTryStandIdle);
- break;
- case 0x4812:
- if (param.asInteger() == 2)
- GotoState(&Klaymen::stPickUpNeedle);
- else if (param.asInteger() == 1)
- GotoState(&Klaymen::stPickUpTube);
- else
- GotoState(&Klaymen::stPickUpGeneric);
- break;
- case 0x4817:
- setDoDeltaX(param.asInteger());
- gotoNextStateExt();
- break;
- case 0x481B:
- if (param.asPoint().y != 0)
- startWalkToXDistance(param.asPoint().y, param.asPoint().x);
- else
- startWalkToAttachedSpriteXDistance(param.asPoint().x);
- break;
- case 0x481D:
- if (_isSittingInTeleporter)
- GotoState(&Klaymen::stTurnToUseInTeleporter);
- break;
- case 0x481E:
- if (_isSittingInTeleporter)
- GotoState(&Klaymen::stReturnFromUseInTeleporter);
- break;
- case 0x481F:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stWonderAboutAfter);
- else if (param.asInteger() == 0)
- GotoState(&Klaymen::stWonderAboutHalf);
- else if (param.asInteger() == 4)
- GotoState(&Klaymen::stTurnAwayFromUse);
- else if (param.asInteger() == 3)
- GotoState(&Klaymen::stTurnToUseHalf);
- else
- GotoState(&Klaymen::stWonderAbout);
- break;
- case 0x482D:
- setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
- gotoNextStateExt();
- break;
- case 0x4834:
- GotoState(&Klaymen::stStepOver);
- break;
- case 0x4835:
- sendMessage(_parentScene, 0x2032, 1);
- _isSittingInTeleporter = true;
- GotoState(&Klaymen::stSitInTeleporter);
- break;
- case 0x4836:
- sendMessage(_parentScene, 0x2032, 0);
- _isSittingInTeleporter = false;
- GotoState(&Klaymen::stGetUpFromTeleporter);
- break;
- case 0x483F:
- startSpecialWalkRight(param.asInteger());
- break;
- case 0x4840:
- startSpecialWalkLeft(param.asInteger());
- break;
- }
- return messageResult;
-}
-
-// KmScene1705
-
-KmScene1705::KmScene1705(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
- : Klaymen(vm, parentScene, x, y) {
-
- // Empty
-}
-
-uint32 KmScene1705::xHandleMessage(int messageNum, const MessageParam &param) {
- uint32 messageResult = 0;
- switch (messageNum) {
- case 0x2000:
- _isSittingInTeleporter = param.asInteger() != 0;
- messageResult = 1;
- break;
- case 0x4001:
- case 0x4800:
- startWalkToX(param.asPoint().x, false);
- break;
- case 0x4004:
- if (_isSittingInTeleporter)
- GotoState(&Klaymen::stSitIdleTeleporter);
- else
- GotoState(&Klaymen::stTryStandIdle);
- break;
- case 0x4803:
- GotoState(&Klaymen::stFallSkipJump);
- break;
- case 0x4812:
- if (param.asInteger() == 2)
- GotoState(&Klaymen::stPickUpNeedle);
- else if (param.asInteger() == 1)
- GotoState(&Klaymen::stPickUpTube);
- else
- GotoState(&Klaymen::stPickUpGeneric);
- break;
- case 0x4817:
- setDoDeltaX(param.asInteger());
- gotoNextStateExt();
- break;
- case 0x481B:
- if (param.asPoint().y != 0)
- startWalkToXDistance(param.asPoint().y, param.asPoint().x);
- else
- startWalkToAttachedSpriteXDistance(param.asPoint().x);
- break;
- case 0x481D:
- if (_isSittingInTeleporter) {
- GotoState(&Klaymen::stTurnToUseInTeleporter);
- }
- break;
- case 0x481E:
- if (_isSittingInTeleporter)
- GotoState(&Klaymen::stReturnFromUseInTeleporter);
- break;
- case 0x481F:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stWonderAboutAfter);
- else if (param.asInteger() == 0)
- GotoState(&Klaymen::stWonderAboutHalf);
- else if (param.asInteger() == 4)
- GotoState(&Klaymen::stTurnAwayFromUse);
- else if (param.asInteger() == 3)
- GotoState(&Klaymen::stTurnToUseHalf);
- else
- GotoState(&Klaymen::stWonderAbout);
- break;
- case 0x4834:
- GotoState(&Klaymen::stStepOver);
- break;
- case 0x4835:
- sendMessage(_parentScene, 0x2000, 1);
- _isSittingInTeleporter = true;
- GotoState(&Klaymen::stSitInTeleporter);
- break;
- case 0x4836:
- sendMessage(_parentScene, 0x2000, 0);
- _isSittingInTeleporter = false;
- GotoState(&Klaymen::stGetUpFromTeleporter);
- break;
- case 0x483D:
- teleporterAppear(0x5E0A4905);
- break;
- case 0x483E:
- teleporterDisappear(0xD86E4477);
- break;
- }
- return messageResult;
-}
-
-KmScene1901::KmScene1901(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
- : Klaymen(vm, parentScene, x, y) {
-
- // Empty
-}
-
-uint32 KmScene1901::xHandleMessage(int messageNum, const MessageParam &param) {
- switch (messageNum) {
- case 0x4001:
- case 0x4800:
- startWalkToX(param.asPoint().x, false);
- break;
- case 0x4004:
- GotoState(&Klaymen::stTryStandIdle);
- break;
- case 0x4817:
- setDoDeltaX(param.asInteger());
- gotoNextStateExt();
- break;
- case 0x481D:
- GotoState(&Klaymen::stTurnToUse);
- break;
- case 0x481E:
- GotoState(&Klaymen::stReturnFromUse);
- break;
- case 0x482D:
- setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
- gotoNextStateExt();
- break;
- case 0x483F:
- startSpecialWalkRight(param.asInteger());
- break;
- case 0x4840:
- startSpecialWalkLeft(param.asInteger());
- break;
- }
- return 0;
-}
-
-KmScene2001::KmScene2001(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
- : Klaymen(vm, parentScene, x, y) {
-
- // Empty
-}
-
-uint32 KmScene2001::xHandleMessage(int messageNum, const MessageParam &param) {
- uint32 messageResult = 0;
- switch (messageNum) {
- case 0x2000:
- _isSittingInTeleporter = param.asInteger() != 0;
- messageResult = 1;
- break;
- case 0x4001:
- case 0x4800:
- startWalkToX(param.asPoint().x, false);
- break;
- case 0x4004:
- if (_isSittingInTeleporter)
- GotoState(&Klaymen::stSitIdleTeleporter);
- else
- GotoState(&Klaymen::stTryStandIdle);
- break;
- case 0x4804:
- if (param.asInteger() != 0) {
- _destX = param.asInteger();
- GotoState(&Klaymen::stWalkingFirst);
- } else
- GotoState(&Klaymen::stPeekWall);
- break;
- case 0x4817:
- setDoDeltaX(param.asInteger());
- gotoNextStateExt();
- break;
- case 0x481D:
- if (_isSittingInTeleporter)
- GotoState(&Klaymen::stTurnToUseInTeleporter);
- break;
- case 0x481E:
- if (_isSittingInTeleporter)
- GotoState(&Klaymen::stReturnFromUseInTeleporter);
- break;
- case 0x4834:
- GotoState(&Klaymen::stStepOver);
- break;
- case 0x4835:
- sendMessage(_parentScene, 0x2000, 1);
- _isSittingInTeleporter = true;
- GotoState(&Klaymen::stSitInTeleporter);
- break;
- case 0x4836:
- sendMessage(_parentScene, 0x2000, 0);
- _isSittingInTeleporter = false;
- GotoState(&Klaymen::stGetUpFromTeleporter);
- break;
- case 0x483D:
- teleporterAppear(0xBE68CC54);
- break;
- case 0x483E:
- teleporterDisappear(0x18AB4ED4);
- break;
- }
- return messageResult;
-}
-
-KmScene2101::KmScene2101(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
- : Klaymen(vm, parentScene, x, y) {
-
- // Empty
-}
-
-uint32 KmScene2101::xHandleMessage(int messageNum, const MessageParam &param) {
- uint32 messageResult = 0;
- switch (messageNum) {
- case 0x2000:
- _isSittingInTeleporter = param.asInteger() != 0;
- messageResult = 1;
- break;
- case 0x4001:
- case 0x4800:
- startWalkToX(param.asPoint().x, false);
- break;
- case 0x4004:
- if (_isSittingInTeleporter)
- GotoState(&Klaymen::stSitIdleTeleporter);
- else
- GotoState(&Klaymen::stTryStandIdle);
- break;
- case 0x4811:
- GotoState(&Klaymen::stHitByDoor);
- break;
- case 0x4812:
- if (param.asInteger() == 2)
- GotoState(&Klaymen::stPickUpNeedle);
- else if (param.asInteger() == 1)
- GotoState(&Klaymen::stPickUpTube);
- else
- GotoState(&Klaymen::stPickUpGeneric);
- break;
- case 0x4816:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stPressButton);
- else if (param.asInteger() == 2)
- GotoState(&Klaymen::stPressFloorButton);
- else
- GotoState(&Klaymen::stPressButtonSide);
- break;
- case 0x4817:
- setDoDeltaX(param.asInteger());
- gotoNextStateExt();
- break;
- case 0x481B:
- if (param.asPoint().y != 0)
- startWalkToXDistance(param.asPoint().y, param.asPoint().x);
- else
- startWalkToAttachedSpriteXDistance(param.asPoint().x);
- break;
- case 0x481D:
- if (_isSittingInTeleporter)
- GotoState(&Klaymen::stTurnToUseInTeleporter);
- break;
- case 0x481E:
- if (_isSittingInTeleporter)
- GotoState(&Klaymen::stReturnFromUseInTeleporter);
- break;
- case 0x4834:
- GotoState(&Klaymen::stStepOver);
- break;
- case 0x4835:
- sendMessage(_parentScene, 0x2000, 1);
- _isSittingInTeleporter = true;
- GotoState(&Klaymen::stSitInTeleporter);
- break;
- case 0x4836:
- sendMessage(_parentScene, 0x2000, 0);
- _isSittingInTeleporter = false;
- GotoState(&Klaymen::stGetUpFromTeleporter);
- break;
- case 0x483D:
- teleporterAppear(0xFF290E30);
- break;
- case 0x483E:
- teleporterDisappear(0x9A28CA1C);
- break;
- }
- return messageResult;
-}
-
-KmScene2201::KmScene2201(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y, NRect *clipRects, int clipRectsCount)
- : Klaymen(vm, parentScene, x, y) {
-
- _surface->setClipRects(clipRects, clipRectsCount);
- _dataResource.load(0x04104242);
-}
-
-uint32 KmScene2201::xHandleMessage(int messageNum, const MessageParam &param) {
- switch (messageNum) {
- case 0x4001:
- case 0x4800:
- startWalkToX(param.asPoint().x, false);
- break;
- case 0x4004:
- GotoState(&Klaymen::stTryStandIdle);
- break;
- case 0x4812:
- GotoState(&Klaymen::stPickUpGeneric);
- break;
- case 0x4816:
- if (param.asInteger() == 0)
- GotoState(&Klaymen::stPressButtonSide);
- break;
- case 0x4817:
- setDoDeltaX(param.asInteger() ? 1 : 0);
- gotoNextStateExt();
- break;
- case 0x4818:
- startWalkToX(_dataResource.getPoint(param.asInteger()).x, false);
- break;
- case 0x481B:
- if (param.asPoint().y != 0)
- startWalkToXDistance(param.asPoint().y, param.asPoint().x);
- else
- startWalkToAttachedSpriteXDistance(param.asPoint().x);
- break;
- case 0x481D:
- GotoState(&Klaymen::stTurnToUse);
- break;
- case 0x481E:
- GotoState(&Klaymen::stReturnFromUse);
- break;
- case 0x482D:
- setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
- gotoNextStateExt();
- break;
- case 0x482E:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stWalkToFrontNoStep);
- else
- GotoState(&Klaymen::stWalkToFront);
- break;
- case 0x482F:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stTurnToFront);
- else
- GotoState(&Klaymen::stTurnToBack);
- break;
- case 0x483F:
- startSpecialWalkRight(param.asInteger());
- break;
- case 0x4840:
- startSpecialWalkLeft(param.asInteger());
- break;
- }
- return 0;
-}
-
-KmScene2203::KmScene2203(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
- : Klaymen(vm, parentScene, x, y) {
-
- // Empty
-}
-
-uint32 KmScene2203::xHandleMessage(int messageNum, const MessageParam &param) {
- switch (messageNum) {
- case 0x4001:
- case 0x4800:
- startWalkToX(param.asPoint().x, false);
- break;
- case 0x4004:
- GotoState(&Klaymen::stTryStandIdle);
- break;
- case 0x4812:
- if (param.asInteger() == 2)
- GotoState(&Klaymen::stPickUpNeedle);
- else if (param.asInteger() == 1)
- GotoState(&Klaymen::stPickUpTube);
- else
- GotoState(&Klaymen::stPickUpGeneric);
- break;
- case 0x4816:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stPressButton);
- else if (param.asInteger() == 2)
- GotoState(&Klaymen::stPressFloorButton);
- else
- GotoState(&Klaymen::stPressButtonSide);
- break;
- case 0x4817:
- setDoDeltaX(param.asInteger());
- gotoNextStateExt();
- break;
- case 0x4818:
- startWalkToX(_dataResource.getPoint(param.asInteger()).x, false);
- break;
- case 0x4819:
- GotoState(&Klaymen::stClayDoorOpen);
- break;
- case 0x481A:
- GotoState(&Klaymen::stInsertDisk);
- break;
- case 0x481B:
- if (param.asPoint().y != 0)
- startWalkToXDistance(param.asPoint().y, param.asPoint().x);
- else
- startWalkToAttachedSpriteXDistance(param.asPoint().x);
- break;
- case 0x481D:
- GotoState(&Klaymen::stTurnToUse);
- break;
- case 0x481E:
- GotoState(&Klaymen::stReturnFromUse);
- break;
- case 0x482D:
- setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
- gotoNextStateExt();
- break;
- case 0x483F:
- startSpecialWalkRight(param.asInteger());
- break;
- case 0x4840:
- startSpecialWalkLeft(param.asInteger());
- break;
- }
- return 0;
-}
-
-KmScene2205::KmScene2205(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
- : Klaymen(vm, parentScene, x, y) {
-
- // Empty
-}
-
-void KmScene2205::xUpdate() {
- setGlobalVar(V_KLAYMEN_FRAMEINDEX, _currFrameIndex);
-}
-
-uint32 KmScene2205::xHandleMessage(int messageNum, const MessageParam &param) {
- switch (messageNum) {
- case 0x4001:
- case 0x4800:
- startWalkToX(param.asPoint().x, false);
- break;
- case 0x4004:
- GotoState(&Klaymen::stTryStandIdle);
- break;
- case 0x4804:
- if (param.asInteger() != 0) {
- _destX = param.asInteger();
- GotoState(&Klaymen::stStartWalkingResume);
- } else
- GotoState(&Klaymen::stPeekWall);
- break;
- case 0x4816:
- if (param.asInteger() == 0)
- GotoState(&Klaymen::stPressButtonSide);
- break;
- case 0x4817:
- setDoDeltaX(param.asInteger());
- gotoNextStateExt();
- break;
- case 0x4818:
- startWalkToX(_dataResource.getPoint(param.asInteger()).x, false);
- break;
- case 0x483F:
- startSpecialWalkRight(param.asInteger());
- break;
- case 0x4840:
- startSpecialWalkLeft(param.asInteger());
- break;
- }
- return 0;
-}
-
-KmScene2206::KmScene2206(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
- : Klaymen(vm, parentScene, x, y) {
-
- _walkResumeFrameIncr = 1;
- _vm->_soundMan->addSound(0x80101800, 0xD3B02847);
-}
-
-KmScene2206::~KmScene2206() {
- _vm->_soundMan->deleteSoundGroup(0x80101800);
-}
-
-void KmScene2206::xUpdate() {
- setGlobalVar(V_KLAYMEN_FRAMEINDEX, _currFrameIndex);
-}
-
-uint32 KmScene2206::xHandleMessage(int messageNum, const MessageParam &param) {
- switch (messageNum) {
- case 0x4001:
- case 0x4800:
- startWalkToX(param.asPoint().x, false);
- break;
- case 0x4004:
- GotoState(&Klaymen::stTryStandIdle);
- break;
- case 0x4803:
- GotoState(&Klaymen::stRidePlatformDown);
- break;
- case 0x4804:
- if (param.asInteger() != 0) {
- _destX = param.asInteger();
- GotoState(&Klaymen::stStartWalkingResume);
- } else
- GotoState(&Klaymen::stPeekWall);
- break;
- case 0x4812:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stPickUpTube);
- else
- GotoState(&Klaymen::stPickUpGeneric);
- break;
- case 0x4816:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stPressButton);
- else if (param.asInteger() == 2)
- GotoState(&Klaymen::stPressFloorButton);
- else
- GotoState(&Klaymen::stPressButtonSide);
- break;
- case 0x4817:
- setDoDeltaX(param.asInteger());
- gotoNextStateExt();
- break;
- case 0x481B:
- if (param.asPoint().y != 0)
- startWalkToXDistance(param.asPoint().y, param.asPoint().x);
- else
- startWalkToAttachedSpriteXDistance(param.asPoint().x);
- break;
- case 0x481F:
- if (param.asInteger() == 0)
- GotoState(&Klaymen::stWonderAboutHalf);
- else if (param.asInteger() == 1)
- GotoState(&Klaymen::stWonderAboutAfter);
- else if (param.asInteger() == 3)
- GotoState(&Klaymen::stTurnToUseHalf);
- else if (param.asInteger() == 4)
- GotoState(&Klaymen::stTurnAwayFromUse);
- else
- GotoState(&Klaymen::stWonderAbout);
- break;
- case 0x482D:
- setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
- gotoNextStateExt();
- break;
- case 0x482E:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stWalkToFrontNoStep);
- else
- GotoState(&Klaymen::stWalkToFront);
- break;
- case 0x482F:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stTurnToFront);
- else
- GotoState(&Klaymen::stTurnToBack);
- break;
- case 0x4837:
- stopWalking();
- break;
- case 0x483F:
- startSpecialWalkRight(param.asInteger());
- break;
- case 0x4840:
- startSpecialWalkLeft(param.asInteger());
- break;
- }
- return 0;
-}
-
-KmScene2207::KmScene2207(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
- : Klaymen(vm, parentScene, x, y) {
-
- // Empty
-}
-
-uint32 KmScene2207::xHandleMessage(int messageNum, const MessageParam &param) {
- switch (messageNum) {
- case 0x2001:
- GotoState(&Klaymen::stRidePlatform);
- break;
- case 0x2005:
- suRidePlatform();
- GotoState(&Klaymen::stTryStandIdle);
- break;
- case 0x4001:
- case 0x4800:
- startWalkToX(param.asPoint().x, false);
- break;
- case 0x4004:
- GotoState(&Klaymen::stTryStandIdle);
- break;
- case 0x480D:
- GotoState(&Klaymen::stInteractLever);
- break;
- case 0x4812:
- GotoState(&Klaymen::stPickUpGeneric);
- break;
- case 0x4816:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stPressButton);
- else if (param.asInteger() == 2)
- GotoState(&Klaymen::stPressFloorButton);
- else
- GotoState(&Klaymen::stPressButtonSide);
- break;
- case 0x4817:
- setDoDeltaX(param.asInteger());
- gotoNextStateExt();
- break;
- case 0x481B:
- if (param.asPoint().y != 0)
- startWalkToXDistance(param.asPoint().y, param.asPoint().x);
- else
- startWalkToAttachedSpriteXDistance(param.asPoint().x);
- break;
- case 0x4827:
- GotoState(&Klaymen::stReleaseLever);
- break;
- case 0x482D:
- setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
- gotoNextStateExt();
- break;
- case 0x483F:
- startSpecialWalkRight(param.asInteger());
- break;
- case 0x4840:
- startSpecialWalkLeft(param.asInteger());
- break;
- }
- return 0;
-}
-
-KmScene2242::KmScene2242(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
- : Klaymen(vm, parentScene, x, y) {
-
- // Empty
-}
-
-void KmScene2242::xUpdate() {
- setGlobalVar(V_KLAYMEN_FRAMEINDEX, _currFrameIndex);
-}
-
-uint32 KmScene2242::xHandleMessage(int messageNum, const MessageParam &param) {
- switch (messageNum) {
- case 0x4001:
- case 0x4800:
- startWalkToX(param.asPoint().x, false);
- break;
- case 0x4004:
- GotoState(&Klaymen::stTryStandIdle);
- break;
- case 0x4804:
- if (param.asInteger() != 0) {
- _destX = param.asInteger();
- GotoState(&Klaymen::stStartWalkingResume);
- } else
- GotoState(&Klaymen::stPeekWall);
- break;
- case 0x4812:
- if (param.asInteger() == 2)
- GotoState(&Klaymen::stPickUpNeedle);
- else if (param.asInteger() == 1)
- GotoState(&Klaymen::stPickUpTube);
- else
- GotoState(&Klaymen::stPickUpGeneric);
- break;
- case 0x4817:
- setDoDeltaX(param.asInteger());
- gotoNextStateExt();
- break;
- case 0x481B:
- if (param.asPoint().y != 0)
- startWalkToXDistance(param.asPoint().y, param.asPoint().x);
- else
- startWalkToAttachedSpriteXDistance(param.asPoint().x);
- break;
- case 0x481F:
- if (param.asInteger() == 0)
- GotoState(&Klaymen::stWonderAboutHalf);
- else if (param.asInteger() == 1)
- GotoState(&Klaymen::stWonderAboutAfter);
- else if (param.asInteger() == 3)
- GotoState(&Klaymen::stTurnToUseHalf);
- else if (param.asInteger() == 4)
- GotoState(&Klaymen::stTurnAwayFromUse);
- else
- GotoState(&Klaymen::stWonderAbout);
- break;
- case 0x482D:
- setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
- gotoNextStateExt();
- break;
- case 0x4837:
- stopWalking();
- break;
- }
- return 0;
-}
-
-KmHallOfRecords::KmHallOfRecords(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
- : Klaymen(vm, parentScene, x, y) {
- // Empty
-}
-
-void KmHallOfRecords::xUpdate() {
- setGlobalVar(V_KLAYMEN_FRAMEINDEX, _currFrameIndex);
-}
-
-uint32 KmHallOfRecords::xHandleMessage(int messageNum, const MessageParam &param) {
- switch (messageNum) {
- case 0x4001:
- case 0x4800:
- startWalkToX(param.asPoint().x, false);
- break;
- case 0x4004:
- GotoState(&Klaymen::stTryStandIdle);
- break;
- case 0x4804:
- if (param.asInteger() != 0) {
- _destX = param.asInteger();
- GotoState(&Klaymen::stStartWalkingResume);
- } else
- GotoState(&Klaymen::stPeekWall);
- break;
- case 0x4817:
- setDoDeltaX(param.asInteger());
- gotoNextStateExt();
- break;
- case 0x481F:
- if (param.asInteger() == 0)
- GotoState(&Klaymen::stWonderAboutHalf);
- else if (param.asInteger() == 1)
- GotoState(&Klaymen::stWonderAboutAfter);
- else if (param.asInteger() == 3)
- GotoState(&Klaymen::stTurnToUseHalf);
- else if (param.asInteger() == 4)
- GotoState(&Klaymen::stTurnAwayFromUse);
- else
- GotoState(&Klaymen::stWonderAbout);
- break;
- case 0x482D:
- setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
- gotoNextStateExt();
- break;
- case 0x4837:
- stopWalking();
- break;
- }
- return 0;
-}
-
-KmScene2247::KmScene2247(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
- : Klaymen(vm, parentScene, x, y) {
-
- // Empty
-}
-
-void KmScene2247::xUpdate() {
- setGlobalVar(V_KLAYMEN_FRAMEINDEX, _currFrameIndex);
-}
-
-uint32 KmScene2247::xHandleMessage(int messageNum, const MessageParam &param) {
- switch (messageNum) {
- case 0x4001:
- case 0x4800:
- startWalkToX(param.asPoint().x, false);
- break;
- case 0x4004:
- GotoState(&Klaymen::stTryStandIdle);
- break;
- case 0x4804:
- if (param.asInteger() != 0) {
- _destX = param.asInteger();
- GotoState(&Klaymen::stStartWalkingResume);
- } else
- GotoState(&Klaymen::stPeekWall);
- break;
- case 0x4817:
- setDoDeltaX(param.asInteger());
- gotoNextStateExt();
- break;
- case 0x481F:
- if (param.asInteger() == 0)
- GotoState(&Klaymen::stWonderAboutHalf);
- else if (param.asInteger() == 1)
- GotoState(&Klaymen::stWonderAboutAfter);
- else if (param.asInteger() == 3)
- GotoState(&Klaymen::stTurnToUseHalf);
- else if (param.asInteger() == 4)
- GotoState(&Klaymen::stTurnAwayFromUse);
- else
- GotoState(&Klaymen::stWonderAbout);
- break;
- case 0x482D:
- setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
- gotoNextStateExt();
- break;
- case 0x4837:
- stopWalking();
- break;
- }
- return 0;
-}
-
-KmScene2401::KmScene2401(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
- : Klaymen(vm, parentScene, x, y) {
-
- // Empty
-}
-
-uint32 KmScene2401::xHandleMessage(int messageNum, const MessageParam &param) {
- uint32 messageResult = 0;
- switch (messageNum) {
- case 0x4001:
- case 0x4800:
- startWalkToX(param.asPoint().x, false);
- break;
- case 0x4004:
- GotoState(&Klaymen::stTryStandIdle);
- break;
- case 0x4816:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stPressButton);
- else if (param.asInteger() == 2)
- GotoState(&Klaymen::stPressFloorButton);
- else
- GotoState(&Klaymen::stPressButtonSide);
- break;
- case 0x4817:
- setDoDeltaX(param.asInteger());
- gotoNextStateExt();
- break;
- case 0x481B:
- if (param.asPoint().y != 0)
- startWalkToXDistance(param.asPoint().y, param.asPoint().x);
- else
- startWalkToAttachedSpriteXDistance(param.asPoint().x);
- break;
- case 0x481F:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stTurnAwayFromUse);
- else if (param.asInteger() == 0)
- GotoState(&Klaymen::stTurnToUseHalf);
- else
- GotoState(&Klaymen::stWonderAbout);
- break;
- case 0x482D:
- setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
- gotoNextStateExt();
- break;
- case 0x482E:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stWalkToFrontNoStep);
- else
- GotoState(&Klaymen::stWalkToFront);
- break;
- case 0x482F:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stTurnToFront);
- else
- GotoState(&Klaymen::stTurnToBack);
- break;
- case 0x4832:
- GotoState(&Klaymen::stUseTube);
- break;
- case 0x4833:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stWonderAbout);
- else {
- _spitPipeIndex = sendMessage(_parentScene, 0x2000, 0);
- GotoState(&Klaymen::stTrySpitIntoPipe);
- }
- break;
- case 0x483F:
- startSpecialWalkRight(param.asInteger());
- break;
- case 0x4840:
- startSpecialWalkLeft(param.asInteger());
- break;
- }
- return messageResult;
-}
-
-KmScene2402::KmScene2402(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
- : Klaymen(vm, parentScene, x, y) {
-
- // Empty
-}
-
-uint32 KmScene2402::xHandleMessage(int messageNum, const MessageParam &param) {
- uint32 messageResult = 0;
- switch (messageNum) {
- case 0x4001:
- case 0x4800:
- startWalkToX(param.asPoint().x, false);
- break;
- case 0x4004:
- if (!getGlobalVar(V_TV_JOKE_TOLD))
- GotoState(&Klaymen::stStandWonderAbout);
- else
- GotoState(&Klaymen::stTryStandIdle);
- break;
- case 0x4804:
- if (param.asInteger() != 0) {
- _destX = param.asInteger();
- GotoState(&Klaymen::stWalkingFirst);
- } else
- GotoState(&Klaymen::stPeekWall);
- break;
- case 0x4812:
- GotoState(&Klaymen::stPickUpGeneric);
- break;
- case 0x4816:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stPressButton);
- else if (param.asInteger() == 2)
- GotoState(&Klaymen::stPressFloorButton);
- else
- GotoState(&Klaymen::stPressButtonSide);
- break;
- case 0x4817:
- setDoDeltaX(param.asInteger());
- gotoNextStateExt();
- break;
- case 0x481B:
- if (param.asPoint().y != 0)
- startWalkToXDistance(param.asPoint().y, param.asPoint().x);
- else
- startWalkToAttachedSpriteXDistance(param.asPoint().x);
- break;
- case 0x481F:
- if (param.asInteger() == 0)
- GotoState(&Klaymen::stWonderAboutHalf);
- else if (param.asInteger() == 1)
- GotoState(&Klaymen::stWonderAboutAfter);
- else if (param.asInteger() == 3)
- GotoState(&Klaymen::stTurnToUseHalf);
- else if (param.asInteger() == 4)
- GotoState(&Klaymen::stTurnAwayFromUse);
- else
- GotoState(&Klaymen::stWonderAbout);
- break;
- case 0x483F:
- startSpecialWalkRight(param.asInteger());
- break;
- case 0x4840:
- startSpecialWalkLeft(param.asInteger());
- break;
- }
- return messageResult;
-}
-
-KmScene2403::KmScene2403(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
- : Klaymen(vm, parentScene, x, y) {
-
- // Empty
-}
-
-uint32 KmScene2403::xHandleMessage(int messageNum, const MessageParam &param) {
- uint32 messageResult = 0;
- switch (messageNum) {
- case 0x4001:
- case 0x4800:
- startWalkToX(param.asPoint().x, false);
- break;
- case 0x4004:
- GotoState(&Klaymen::stTryStandIdle);
- break;
- case 0x480D:
- GotoState(&Klaymen::stPullCord);
- break;
- case 0x4812:
- GotoState(&Klaymen::stPickUpGeneric);
- break;
- case 0x4816:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stPressButton);
- else if (param.asInteger() == 2)
- GotoState(&Klaymen::stPressFloorButton);
- else
- GotoState(&Klaymen::stPressButtonSide);
- break;
- case 0x4817:
- setDoDeltaX(param.asInteger());
- gotoNextStateExt();
- break;
- case 0x481B:
- if (param.asPoint().y != 0)
- startWalkToXDistance(param.asPoint().y, param.asPoint().x);
- else
- startWalkToAttachedSpriteXDistance(param.asPoint().x);
- break;
- case 0x481F:
- if (param.asInteger() == 0)
- GotoState(&Klaymen::stWonderAboutHalf);
- else if (param.asInteger() == 1)
- GotoState(&Klaymen::stWonderAboutAfter);
- else if (param.asInteger() == 3)
- GotoState(&Klaymen::stTurnToUseHalf);
- else if (param.asInteger() == 4)
- GotoState(&Klaymen::stTurnAwayFromUse);
- else
- GotoState(&Klaymen::stWonderAbout);
- break;
- case 0x4820:
- sendMessage(_parentScene, 0x2000, 0);
- GotoState(&Klaymen::stContinueClimbLadderUp);
- break;
- case 0x4821:
- sendMessage(_parentScene, 0x2000, 0);
- _destY = param.asInteger();
- GotoState(&Klaymen::stStartClimbLadderDown);
- break;
- case 0x4822:
- sendMessage(_parentScene, 0x2000, 0);
- _destY = param.asInteger();
- GotoState(&Klaymen::stStartClimbLadderUp);
- break;
- case 0x4823:
- sendMessage(_parentScene, 0x2001, 0);
- GotoState(&Klaymen::stClimbLadderHalf);
- break;
- case 0x482D:
- setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
- gotoNextStateExt();
- break;
- case 0x483F:
- startSpecialWalkRight(param.asInteger());
- break;
- case 0x4840:
- startSpecialWalkLeft(param.asInteger());
- break;
- }
- return messageResult;
-}
-
-KmScene2406::KmScene2406(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y, NRect *clipRects, int clipRectsCount)
- : Klaymen(vm, parentScene, x, y) {
-
- _surface->setClipRects(clipRects, clipRectsCount);
-}
-
-uint32 KmScene2406::xHandleMessage(int messageNum, const MessageParam &param) {
- uint32 messageResult = 0;
- switch (messageNum) {
- case 0x4001:
- case 0x4800:
- startWalkToX(param.asPoint().x, false);
- break;
- case 0x4004:
- GotoState(&Klaymen::stTryStandIdle);
- break;
- case 0x4804:
- if (param.asInteger() != 0) {
- _destX = param.asInteger();
- GotoState(&Klaymen::stWalkingFirst);
- } else
- GotoState(&Klaymen::stPeekWall);
- break;
- case 0x4812:
- if (param.asInteger() == 2)
- GotoState(&Klaymen::stPickUpNeedle);
- else if (param.asInteger() == 1)
- GotoState(&Klaymen::stPickUpTube);
- else
- GotoState(&Klaymen::stPickUpGeneric);
- break;
- case 0x4817:
- setDoDeltaX(param.asInteger());
- gotoNextStateExt();
- break;
- case 0x481A:
- GotoState(&Klaymen::stInsertDisk);
- break;
- case 0x481B:
- if (param.asPoint().y != 0)
- startWalkToXDistance(param.asPoint().y, param.asPoint().x);
- else
- startWalkToAttachedSpriteXDistance(param.asPoint().x);
- break;
- case 0x481D:
- GotoState(&Klaymen::stTurnToUse);
- break;
- case 0x481E:
- GotoState(&Klaymen::stReturnFromUse);
- break;
- case 0x481F:
- if (param.asInteger() == 0)
- GotoState(&Klaymen::stWonderAboutHalf);
- else if (param.asInteger() == 1)
- GotoState(&Klaymen::stWonderAboutAfter);
- else if (param.asInteger() == 3)
- GotoState(&Klaymen::stTurnToUseHalf);
- else if (param.asInteger() == 4)
- GotoState(&Klaymen::stTurnAwayFromUse);
- else
- GotoState(&Klaymen::stWonderAbout);
- break;
- case 0x4820:
- sendMessage(_parentScene, 0x2000, 0);
- GotoState(&Klaymen::stContinueClimbLadderUp);
- break;
- case 0x4821:
- sendMessage(_parentScene, 0x2000, 0);
- _destY = param.asInteger();
- GotoState(&Klaymen::stStartClimbLadderDown);
- break;
- case 0x4822:
- sendMessage(_parentScene, 0x2000, 0);
- _destY = param.asInteger();
- GotoState(&Klaymen::stStartClimbLadderUp);
- break;
- case 0x4823:
- sendMessage(_parentScene, 0x2001, 0);
- GotoState(&Klaymen::stClimbLadderHalf);
- break;
- case 0x483F:
- startSpecialWalkRight(param.asInteger());
- break;
- case 0x4840:
- startSpecialWalkLeft(param.asInteger());
- break;
- }
- return messageResult;
-}
-
-KmScene2501::KmScene2501(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
- : Klaymen(vm, parentScene, x, y) {
-
- // Empty
-}
-
-uint32 KmScene2501::xHandleMessage(int messageNum, const MessageParam &param) {
- uint32 messageResult = 0;
- switch (messageNum) {
- case 0x2000:
- _isSittingInTeleporter = param.asInteger() != 0;
- messageResult = 1;
- break;
- case 0x4001:
- case 0x4800:
- startWalkToX(param.asPoint().x, false);
- break;
- case 0x4004:
- if (_isSittingInTeleporter)
- GotoState(&Klaymen::stSitIdleTeleporter);
- else
- GotoState(&Klaymen::stTryStandIdle);
- break;
- case 0x4817:
- setDoDeltaX(param.asInteger());
- gotoNextStateExt();
- break;
- case 0x481D:
- if (_isSittingInTeleporter)
- GotoState(&Klaymen::stTurnToUseInTeleporter);
- break;
- case 0x481E:
- if (_isSittingInTeleporter)
- GotoState(&Klaymen::stReturnFromUseInTeleporter);
- break;
- case 0x4834:
- GotoState(&Klaymen::stStepOver);
- break;
- case 0x4835:
- sendMessage(_parentScene, 0x2000, 1);
- _isSittingInTeleporter = true;
- GotoState(&Klaymen::stSitInTeleporter);
- break;
- case 0x4836:
- sendMessage(_parentScene, 0x2000, 0);
- _isSittingInTeleporter = false;
- GotoState(&Klaymen::stGetUpFromTeleporter);
- break;
- }
- return messageResult;
-}
-
-KmScene2732::KmScene2732(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
- : Klaymen(vm, parentScene, x, y) {
-
- // Empty
-}
-
-uint32 KmScene2732::xHandleMessage(int messageNum, const MessageParam &param) {
- switch (messageNum) {
- case 0x4804:
- GotoState(&Klaymen::stPeekInside);
- break;
- case 0x483C:
- GotoState(&Klaymen::stPeekInsideReturn);
- break;
- }
- return 0;
-}
-
-KmScene2801::KmScene2801(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
- : Klaymen(vm, parentScene, x, y) {
-
- // Empty
-}
-
-uint32 KmScene2801::xHandleMessage(int messageNum, const MessageParam &param) {
- switch (messageNum) {
- case 0x4001:
- case 0x4800:
- startWalkToX(param.asPoint().x, false);
- break;
- case 0x4004:
- GotoState(&Klaymen::stTryStandIdle);
- break;
- case 0x4812:
- GotoState(&Klaymen::stPickUpGeneric);
- break;
- case 0x4817:
- setDoDeltaX(param.asInteger());
- gotoNextStateExt();
- break;
- case 0x481B:
- if (param.asPoint().y != 0)
- startWalkToXDistance(param.asPoint().y, param.asPoint().x);
- else
- startWalkToAttachedSpriteXDistance(param.asPoint().x);
- break;
- case 0x481D:
- GotoState(&Klaymen::stTurnToUse);
- break;
- case 0x481E:
- GotoState(&Klaymen::stReturnFromUse);
- break;
- case 0x481F:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stWonderAboutAfter);
- else if (param.asInteger() == 0)
- GotoState(&Klaymen::stWonderAboutHalf);
- else if (param.asInteger() == 4)
- GotoState(&Klaymen::stTurnAwayFromUse);
- else if (param.asInteger() == 3)
- GotoState(&Klaymen::stTurnToUseHalf);
- else
- GotoState(&Klaymen::stWonderAbout);
- break;
- case 0x482D:
- setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
- gotoNextStateExt();
- break;
- case 0x482E:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stWalkToFrontNoStep);
- else
- GotoState(&Klaymen::stWalkToFront);
- break;
- case 0x482F:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stTurnToFront);
- else
- GotoState(&Klaymen::stTurnToBack);
- break;
- case 0x4837:
- stopWalking();
- break;
- }
- return 0;
-}
-
-KmScene2803::KmScene2803(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y, NRect *clipRects, int clipRectsCount)
- : Klaymen(vm, parentScene, x, y) {
-
- _surface->setClipRects(clipRects, clipRectsCount);
- _dataResource.load(0x00900849);
-}
-
-uint32 KmScene2803::xHandleMessage(int messageNum, const MessageParam &param) {
- switch (messageNum) {
- case 0x4001:
- case 0x4800:
- startWalkToX(param.asPoint().x, false);
- break;
- case 0x4004:
- GotoState(&Klaymen::stTryStandIdle);
- break;
- case 0x4803:
- _destY = param.asInteger();
- GotoState(&Klaymen::stJumpToGrab);
- break;
- case 0x4804:
- if (param.asInteger() == 3)
- GotoState(&Klaymen::stFinishGrow);
- break;
- case 0x480D:
- GotoState(&Klaymen::stPullCord);
- break;
- case 0x4817:
- setDoDeltaX(param.asInteger());
- gotoNextStateExt();
- break;
- case 0x4818:
- startWalkToX(_dataResource.getPoint(param.asInteger()).x, false);
- break;
- case 0x481D:
- GotoState(&Klaymen::stTurnToUse);
- break;
- case 0x481E:
- GotoState(&Klaymen::stReturnFromUse);
- break;
- case 0x481F:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stWonderAboutAfter);
- else
- GotoState(&Klaymen::stWonderAboutHalf);
- break;
- case 0x482E:
- GotoState(&Klaymen::stWalkToFront);
- break;
- case 0x482F:
- GotoState(&Klaymen::stTurnToBack);
- break;
- case 0x4834:
- GotoState(&Klaymen::stStepOver);
- break;
- case 0x4838:
- GotoState(&Klaymen::stJumpToGrabRelease);
- break;
- }
- return 0;
-}
-
-KmScene2803Small::KmScene2803Small(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
- : Klaymen(vm, parentScene, x, y) {
-
- _dataResource.load(0x81120132);
-}
-
-uint32 KmScene2803Small::xHandleMessage(int messageNum, const MessageParam &param) {
- switch (messageNum) {
- case 0x4001:
- case 0x4800:
- startWalkToXSmall(param.asPoint().x);
- break;
- case 0x4004:
- GotoState(&Klaymen::stStandIdleSmall);
- break;
- case 0x4817:
- setDoDeltaX(param.asInteger());
- gotoNextStateExt();
- break;
- case 0x4818:
- startWalkToXSmall(_dataResource.getPoint(param.asInteger()).x);
- break;
- case 0x481F:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stWonderAboutAfterSmall);
- else if (param.asInteger() == 0)
- GotoState(&Klaymen::stWonderAboutHalfSmall);
- else
- GotoState(&Klaymen::stWonderAboutSmall);
- break;
- case 0x482E:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stWalkToFrontNoStepSmall);
- else if (param.asInteger() == 2)
- GotoState(&Klaymen::stWalkToFront2Small);
- else
- GotoState(&Klaymen::stWalkToFrontSmall);
- break;
- case 0x482F:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stTurnToBackHalfSmall);
- else if (param.asInteger() == 2)
- GotoState(&Klaymen::stTurnToBackWalkSmall);
- else
- GotoState(&Klaymen::stTurnToBackSmall);
- break;
- case 0x4830:
- GotoState(&Klaymen::stShrink);
- break;
- }
- return 0;
-}
-
-KmScene2805::KmScene2805(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
- : Klaymen(vm, parentScene, x, y) {
-
- // Empty
-}
-
-uint32 KmScene2805::xHandleMessage(int messageNum, const MessageParam &param) {
- uint32 messageResult = 0;
- switch (messageNum) {
- case 0x2000:
- _isSittingInTeleporter = param.asInteger() != 0;
- messageResult = 1;
- break;
- case 0x4001:
- case 0x4800:
- startWalkToX(param.asPoint().x, false);
- break;
- case 0x4004:
- if (_isSittingInTeleporter)
- GotoState(&Klaymen::stSitIdleTeleporter);
- else
- GotoState(&Klaymen::stTryStandIdle);
- break;
- case 0x4817:
- setDoDeltaX(param.asInteger());
- gotoNextStateExt();
- break;
- case 0x481D:
- if (_isSittingInTeleporter)
- GotoState(&Klaymen::stTurnToUseInTeleporter);
- break;
- case 0x481E:
- if (_isSittingInTeleporter)
- GotoState(&Klaymen::stReturnFromUseInTeleporter);
- break;
- case 0x4834:
- GotoState(&Klaymen::stStepOver);
- break;
- case 0x4835:
- sendMessage(_parentScene, 0x2000, 1);
- _isSittingInTeleporter = true;
- GotoState(&Klaymen::stSitInTeleporter);
- break;
- case 0x4836:
- sendMessage(_parentScene, 0x2000, 0);
- _isSittingInTeleporter = false;
- GotoState(&Klaymen::stGetUpFromTeleporter);
- break;
- case 0x483D:
- teleporterAppear(0xDE284B74);
- break;
- case 0x483E:
- teleporterDisappear(0xD82A4094);
- break;
- }
- return messageResult;
-}
-
-KmScene2806::KmScene2806(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y,
- bool needsLargeSurface, NRect *clipRects, uint clipRectsCount)
- : Klaymen(vm, parentScene, x, y) {
-
- if (needsLargeSurface) {
- NDimensions dimensions = _animResource.loadSpriteDimensions(0x2838C010);
- delete _surface;
- createSurface(1000, dimensions.width, dimensions.height);
- loadSound(3, 0x58E0C341);
- loadSound(4, 0x40A00342);
- loadSound(5, 0xD0A1C348);
- loadSound(6, 0x166FC6E0);
- loadSound(7, 0x00018040);
- }
-
- _dataResource.load(0x98182003);
- _surface->setClipRects(clipRects, clipRectsCount);
-}
-
-uint32 KmScene2806::xHandleMessage(int messageNum, const MessageParam &param) {
- switch (messageNum) {
- case 0x4001:
- case 0x4800:
- startWalkToX(param.asPoint().x, false);
- break;
- case 0x4004:
- GotoState(&Klaymen::stTryStandIdle);
- break;
- case 0x4804:
- startWalkToX(440, true);
- break;
- case 0x480D:
- GotoState(&Klaymen::stPullCord);
- break;
- case 0x4816:
- if (param.asInteger() == 0)
- GotoState(&Klaymen::stPressButtonSide);
- break;
- case 0x4817:
- setDoDeltaX(param.asInteger());
- gotoNextStateExt();
- break;
- case 0x4818:
- startWalkToX(_dataResource.getPoint(param.asInteger()).x, false);
- break;
- case 0x4831:
- GotoState(&Klaymen::stGrow);
- break;
- case 0x4832:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stDrinkPotion);
- else
- GotoState(&Klaymen::stUseTube);
- break;
- }
- return 0;
-}
-
-KmScene2809::KmScene2809(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y,
- bool needsLargeSurface, NRect *clipRects, uint clipRectsCount)
- : Klaymen(vm, parentScene, x, y) {
-
- if (needsLargeSurface) {
- NDimensions dimensions = _animResource.loadSpriteDimensions(0x2838C010);
- delete _surface;
- createSurface(1000, dimensions.width, dimensions.height);
- loadSound(3, 0x58E0C341);
- loadSound(4, 0x40A00342);
- loadSound(5, 0xD0A1C348);
- loadSound(6, 0x166FC6E0);
- loadSound(7, 0x00018040);
- }
-
- _dataResource.load(0x1830009A);
- _surface->setClipRects(clipRects, clipRectsCount);
-}
-
-uint32 KmScene2809::xHandleMessage(int messageNum, const MessageParam &param) {
- switch (messageNum) {
- case 0x4001:
- case 0x4800:
- startWalkToX(param.asPoint().x, false);
- break;
- case 0x4004:
- GotoState(&Klaymen::stTryStandIdle);
- break;
- case 0x4804:
- startWalkToX(226, true);
- break;
- case 0x480D:
- GotoState(&Klaymen::stPullCord);
- break;
- case 0x4816:
- if (param.asInteger() == 0)
- GotoState(&Klaymen::stPressButtonSide);
- break;
- case 0x4817:
- setDoDeltaX(param.asInteger());
- gotoNextStateExt();
- break;
- case 0x4818:
- startWalkToX(_dataResource.getPoint(param.asInteger()).x, false);
- break;
- case 0x4831:
- GotoState(&Klaymen::stGrow);
- break;
- case 0x4832:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stDrinkPotion);
- else
- GotoState(&Klaymen::stUseTube);
- break;
- }
- return 0;
-}
-
-KmScene2810Small::KmScene2810Small(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
- : Klaymen(vm, parentScene, x, y) {
-
- // Empty
-}
-
-uint32 KmScene2810Small::xHandleMessage(int messageNum, const MessageParam &param) {
- switch (messageNum) {
- case 0x4001:
- case 0x4800:
- startWalkToXSmall(param.asPoint().x);
- break;
- case 0x4004:
- GotoState(&Klaymen::stStandIdleSmall);
- break;
- case 0x4817:
- setDoDeltaX(param.asInteger());
- gotoNextStateExt();
- break;
- case 0x4818:
- startWalkToXSmall(_dataResource.getPoint(param.asInteger()).x);
- break;
- case 0x481F:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stWonderAboutAfterSmall);
- else if (param.asInteger() == 0)
- GotoState(&Klaymen::stWonderAboutHalfSmall);
- else
- GotoState(&Klaymen::stWonderAboutSmall);
- break;
- case 0x482E:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stWalkToFrontNoStepSmall);
- else
- GotoState(&Klaymen::stWalkToFrontSmall);
- break;
- case 0x482F:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stTurnToBackHalfSmall);
- else
- GotoState(&Klaymen::stTurnToBackSmall);
- break;
- case 0x4837:
- stopWalking();
- break;
- }
- return 0;
-}
-
-KmScene2810::KmScene2810(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y, NRect *clipRects, uint clipRectsCount)
- : Klaymen(vm, parentScene, x, y) {
-
- _surface->setClipRects(clipRects, clipRectsCount);
-}
-
-uint32 KmScene2810::xHandleMessage(int messageNum, const MessageParam &param) {
- switch (messageNum) {
- case 0x4001:
- case 0x4800:
- startWalkToX(param.asPoint().x, false);
- break;
- case 0x4004:
- GotoState(&Klaymen::stTryStandIdle);
- break;
- case 0x4803:
- _destY = param.asInteger();
- GotoState(&Klaymen::stJumpToGrab);
- break;
- case 0x4804:
- if (param.asInteger() == 3)
- GotoState(&Klaymen::stFinishGrow);
- break;
- case 0x4812:
- GotoState(&Klaymen::stPickUpGeneric);
- break;
- case 0x4817:
- setDoDeltaX(param.asInteger());
- gotoNextStateExt();
- break;
- case 0x4818:
- startWalkToX(_dataResource.getPoint(param.asInteger()).x, false);
- break;
- case 0x481B:
- if (param.asPoint().y != 0)
- startWalkToXDistance(param.asPoint().y, param.asPoint().x);
- else
- startWalkToAttachedSpriteXDistance(param.asPoint().x);
- break;
- case 0x481F:
- if (param.asInteger() == 0)
- GotoState(&Klaymen::stWonderAboutHalf);
- else if (param.asInteger() == 1)
- GotoState(&Klaymen::stWonderAboutAfter);
- else if (param.asInteger() == 3)
- GotoState(&Klaymen::stTurnToUseHalf);
- else if (param.asInteger() == 4)
- GotoState(&Klaymen::stTurnAwayFromUse);
- else if (param.asInteger() == 5)
- GotoState(&Klaymen::stTurnToUseExt);
- else
- GotoState(&Klaymen::stWonderAbout);
- break;
- case 0x4820:
- sendMessage(_parentScene, 0x2000, 0);
- GotoState(&Klaymen::stContinueClimbLadderUp);
- break;
- case 0x4821:
- sendMessage(_parentScene, 0x2000, 0);
- _destY = param.asInteger();
- GotoState(&Klaymen::stStartClimbLadderDown);
- break;
- case 0x4822:
- sendMessage(_parentScene, 0x2000, 0);
- _destY = param.asInteger();
- GotoState(&Klaymen::stStartClimbLadderUp);
- break;
- case 0x4823:
- sendMessage(_parentScene, 0x2001, 0);
- GotoState(&Klaymen::stClimbLadderHalf);
- break;
- case 0x4824:
- sendMessage(_parentScene, 0x2000, 0);
- _destY = _dataResource.getPoint(param.asInteger()).y;
- GotoState(&Klaymen::stStartClimbLadderDown);
- break;
- case 0x4825:
- sendMessage(_parentScene, 0x2000, 0);
- _destY = _dataResource.getPoint(param.asInteger()).y;
- GotoState(&Klaymen::stStartClimbLadderUp);
- break;
- case 0x482D:
- setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
- gotoNextStateExt();
- break;
- case 0x4837:
- stopWalking();
- break;
- }
- return 0;
-}
-
-KmScene2812::KmScene2812(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
- : Klaymen(vm, parentScene, x, y) {
-
- // Empty
-}
-
-uint32 KmScene2812::xHandleMessage(int messageNum, const MessageParam &param) {
- switch (messageNum) {
- case 0x4001:
- case 0x4800:
- startWalkToX(param.asPoint().x, false);
- break;
- case 0x4004:
- GotoState(&Klaymen::stTryStandIdle);
- break;
- case 0x4805:
- _destY = param.asInteger();
- GotoState(&Klaymen::stJumpToGrabFall);
- break;
- case 0x4812:
- if (param.asInteger() == 2)
- GotoState(&Klaymen::stPickUpNeedle);
- else if (param.asInteger() == 1)
- GotoState(&Klaymen::stPickUpTube);
- else
- GotoState(&Klaymen::stPickUpGeneric);
- break;
- case 0x4817:
- setDoDeltaX(param.asInteger());
- gotoNextStateExt();
- break;
- case 0x481A:
- GotoState(&Klaymen::stInsertDisk);
- break;
- case 0x481B:
- if (param.asPoint().y != 0)
- startWalkToXDistance(param.asPoint().y, param.asPoint().x);
- else
- startWalkToAttachedSpriteXDistance(param.asPoint().x);
- break;
- case 0x481D:
- GotoState(&Klaymen::stTurnToUse);
- break;
- case 0x481E:
- GotoState(&Klaymen::stReturnFromUse);
- break;
- case 0x4820:
- sendMessage(_parentScene, 0x2001, 0);
- GotoState(&Klaymen::stContinueClimbLadderUp);
- break;
- case 0x4821:
- sendMessage(_parentScene, 0x2001, 0);
- _destY = param.asInteger();
- GotoState(&Klaymen::stStartClimbLadderDown);
- break;
- case 0x4822:
- sendMessage(_parentScene, 0x2001, 0);
- _destY = param.asInteger();
- GotoState(&Klaymen::stStartClimbLadderUp);
- break;
- case 0x4823:
- sendMessage(_parentScene, 0x2002, 0);
- GotoState(&Klaymen::stClimbLadderHalf);
- break;
- case 0x482D:
- setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
- gotoNextStateExt();
- break;
- case 0x482E:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stWalkToFrontNoStep);
- else
- GotoState(&Klaymen::stWalkToFront);
- break;
- case 0x482F:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stTurnToFront);
- else
- GotoState(&Klaymen::stTurnToBack);
- break;
- case 0x483F:
- startSpecialWalkRight(param.asInteger());
- break;
- case 0x4840:
- startSpecialWalkLeft(param.asInteger());
- break;
- }
- return 0;
-}
-
} // End of namespace Neverhood
diff --git a/engines/neverhood/klaymen.h b/engines/neverhood/klaymen.h
index 9e461a9c9c..a614560fc0 100644
--- a/engines/neverhood/klaymen.h
+++ b/engines/neverhood/klaymen.h
@@ -33,7 +33,6 @@ namespace Neverhood {
// TODO This code is horrible and weird and a lot of stuff needs renaming once a better name is found
// TODO Also the methods should probably rearranged and be grouped together more consistently
-class Klaymen;
class Scene;
const uint32 kKlaymenSpeedUpHash = 0x004A2148;
@@ -67,29 +66,25 @@ public:
void startIdleAnimation(uint32 fileHash, AnimationCb callback);
void upIdleAnimation();
+ // Idle animations - start
void stIdlePickEar();
void evIdlePickEarDone();
- uint32 hmIdlePickEar(int messageNum, const MessageParam &param, Entity *sender);
-
void stIdleSpinHead();
- uint32 hmIdleSpinHead(int messageNum, const MessageParam &param, Entity *sender);
-
void stIdleArms();
void evIdleArmsDone();
- uint32 hmIdleArms(int messageNum, const MessageParam &param, Entity *sender);
-
void stIdleChest();
- uint32 hmIdleChest(int messageNum, const MessageParam &param, Entity *sender);
-
void stIdleHeadOff();
- uint32 hmIdleHeadOff(int messageNum, const MessageParam &param, Entity *sender);
-
void stIdleWonderAbout();
-
void stIdleTeleporterHands();
-
void stIdleTeleporterHands2();
+ uint32 hmIdlePickEar(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 hmIdleSpinHead(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 hmIdleArms(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 hmIdleChest(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 hmIdleHeadOff(int messageNum, const MessageParam &param, Entity *sender);
+ // Idle animations - end
+
void stTryStandIdle();
void stStandAround();
void upStandIdle();
@@ -150,12 +145,6 @@ public:
void stInsertKey();
uint32 hmInsertKey(int messageNum, const MessageParam &param, Entity *sender);
- void stReadNote();
- uint32 hmReadNote(int messageNum, const MessageParam &param, Entity *sender);
-
- void stHitByDoor();
- uint32 hmHitByDoor(int messageNum, const MessageParam &param, Entity *sender);
-
void stPeekWall();
uint32 hmPeekWall(int messageNum, const MessageParam &param, Entity *sender);
@@ -166,21 +155,8 @@ public:
void upPeekWallBlink();
void stPeekWall1();
-
void stPeekWall2();
- void stPullHammerLever();
- uint32 hmPullHammerLever(int messageNum, const MessageParam &param, Entity *sender);
-
- void stRidePlatformDown();
- void suRidePlatformDown();
-
- void stCrashDown();
- void stCrashDownFinished();
-
- void stShrink();
- uint32 hmShrink(int messageNum, const MessageParam &param, Entity *sender);
-
void stGrow();
uint32 hmGrow(int messageNum, const MessageParam &param, Entity *sender);
@@ -203,11 +179,6 @@ public:
void stLetGoOfLever();
void evLeverReleasedEvent();
- void stWakeUp();
-
- void stSleeping();
- uint32 hmSleeping(int messageNum, const MessageParam &param, Entity *sender);
-
void stPressButton();
void stPressFloorButton();
void stPressButtonSide();
@@ -228,20 +199,6 @@ public:
void stClimbLadderHalf();
uint32 hmClimbLadderHalf(int messageNum, const MessageParam &param, Entity *sender);
- void setupJumpToRing();
- void stJumpToRing1();
- void stJumpToRing2();
- void stJumpToRing4();
- uint32 hmJumpToRing(int messageNum, const MessageParam &param, Entity *sender);
-
- void stHangOnRing();
-
- void stJumpToRing3();
- uint32 hmJumpToRing3(int messageNum, const MessageParam &param, Entity *sender);
-
- void stHoldRing3();
- uint32 hmHoldRing3(int messageNum, const MessageParam &param, Entity *sender);
-
void stReleaseRing();
void stLandOnFeet();
@@ -272,24 +229,17 @@ public:
void stSitIdleTeleporter();
void upSitIdleTeleporter();
-
void stSitIdleTeleporterBlink();
-
void stSitIdleTeleporterBlinkSecond();
void stTurnToUseInTeleporter();
-
void stReturnFromUseInTeleporter();
-
void stGetUpFromTeleporter();
void teleporterAppear(uint32 fileHash);
void teleporterDisappear(uint32 fileHash);
uint32 hmTeleporterAppearDisappear(int messageNum, const MessageParam &param, Entity *sender);
- void stClayDoorOpen();
- uint32 hmClayDoorOpen(int messageNum, const MessageParam &param, Entity *sender);
-
void stFallSkipJump();
void suFallSkipJump();
@@ -298,19 +248,6 @@ public:
uint32 hmMoveObject(int messageNum, const MessageParam &param, Entity *sender);
void upMoveObject();
- void stCloseEyes();
-
- void stTumbleHeadless();
- uint32 hmTumbleHeadless(int messageNum, const MessageParam &param, Entity *sender);
-
- void stFetchMatch();
- void stLightMatch();
- uint32 hmMatch(int messageNum, const MessageParam &param, Entity *sender);
-
- void stHitByBoxingGlove();
- uint32 hmHitByBoxingGlove(int messageNum, const MessageParam &param, Entity *sender);
- void evHitByBoxingGloveDone();
-
void stStandIdleSmall();
void stWonderAboutSmall();
void stWonderAboutHalfSmall();
@@ -327,34 +264,17 @@ public:
void stFinishGrow();
uint32 hmFinishGrow(int messageNum, const MessageParam &param, Entity *sender);
- void stJumpToRingVenusFlyTrap();
- uint32 hmJumpToRingVenusFlyTrap(int messageNum, const MessageParam &param, Entity *sender);
-
- void stDropFromRing();
-
void stStandIdleSpecial();
uint32 hmStandIdleSpecial(int messageNum, const MessageParam &param, Entity *sender);
- void stPressDoorButton();
- uint32 hmPressDoorButton(int messageNum, const MessageParam &param, Entity *sender);
-
void stSpitOutFall0();
void stSpitOutFall2();
void suFallDown();
void upSpitOutFall();
- void stJumpAndFall();
- uint32 hmJumpAndFall(int messageNum, const MessageParam &param, Entity *sender);
-
void stFalling();
void stFallTouchdown();
- void stMoveVenusFlyTrap();
- void stContinueMovingVenusFlyTrap();
- uint32 hmMoveVenusFlyTrap(int messageNum, const MessageParam &param, Entity *sender);
- uint32 hmFirstMoveVenusFlyTrap(int messageNum, const MessageParam &param, Entity *sender);
- void evMoveVenusFlyTrapDone();
-
void stPeekInside();
void stPeekInsideReturn();
void stPeekInsideBlink();
@@ -378,11 +298,6 @@ public:
void setSoundFlag(bool value) { _soundFlag = value; }
- void spitIntoPipe();
- void stTrySpitIntoPipe();
- void stContSpitIntoPipe();
- uint32 hmSpit(int messageNum, const MessageParam &param, Entity *sender);
-
void stRidePlatform();
void suRidePlatform();
void stPullLever();
@@ -432,13 +347,6 @@ protected:
int _moveObjectCountdown;
- bool _canSpitPipe;
- bool _contSpitPipe;
- bool _readyToSpit;
- uint32 _spitPipeIndex;
- uint32 _spitDestPipeIndex;
- uint32 _spitContDestPipeIndex;
-
virtual void xUpdate();
virtual uint32 xHandleMessage(int messageNum, const MessageParam &param);
@@ -459,311 +367,6 @@ protected:
void enterIdleAnimation(uint idleAnimation);
void walkAlongPathPoints();
-
-};
-
-class KmScene1001 : public Klaymen {
-public:
- KmScene1001(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
-protected:
- uint32 xHandleMessage(int messageNum, const MessageParam &param);
-};
-
-class KmScene1002 : public Klaymen {
-public:
- KmScene1002(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
-protected:
- void xUpdate();
- uint32 xHandleMessage(int messageNum, const MessageParam &param);
-};
-
-class KmScene1004 : public Klaymen {
-public:
- KmScene1004(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
-protected:
- uint32 xHandleMessage(int messageNum, const MessageParam &param);
-};
-
-class KmScene1109 : public Klaymen {
-public:
- KmScene1109(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
-protected:
- uint32 xHandleMessage(int messageNum, const MessageParam &param);
-};
-
-class KmScene1201 : public Klaymen {
-public:
- KmScene1201(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
-protected:
- uint32 xHandleMessage(int messageNum, const MessageParam &param);
-};
-
-class KmScene1303 : public Klaymen {
-public:
- KmScene1303(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
-protected:
- uint32 xHandleMessage(int messageNum, const MessageParam &param);
-};
-
-class KmScene1304 : public Klaymen {
-public:
- KmScene1304(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
-protected:
- uint32 xHandleMessage(int messageNum, const MessageParam &param);
-};
-
-class KmScene1305 : public Klaymen {
-public:
- KmScene1305(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
-protected:
- uint32 xHandleMessage(int messageNum, const MessageParam &param);
-};
-
-class KmScene1306 : public Klaymen {
-public:
- KmScene1306(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
-protected:
- uint32 xHandleMessage(int messageNum, const MessageParam &param);
-};
-
-class KmScene1308 : public Klaymen {
-public:
- KmScene1308(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
-protected:
- uint32 xHandleMessage(int messageNum, const MessageParam &param);
-};
-
-class KmScene1401 : public Klaymen {
-public:
- KmScene1401(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
-protected:
- uint32 xHandleMessage(int messageNum, const MessageParam &param);
-};
-
-class KmScene1402 : public Klaymen {
-public:
- KmScene1402(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
-protected:
- uint32 xHandleMessage(int messageNum, const MessageParam &param);
-};
-
-class KmScene1403 : public Klaymen {
-public:
- KmScene1403(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
-protected:
- uint32 xHandleMessage(int messageNum, const MessageParam &param);
-};
-
-class KmScene1404 : public Klaymen {
-public:
- KmScene1404(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
-protected:
- uint32 xHandleMessage(int messageNum, const MessageParam &param);
-};
-
-class KmScene1608 : public Klaymen {
-public:
- KmScene1608(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
-protected:
- uint32 xHandleMessage(int messageNum, const MessageParam &param);
-};
-
-class KmScene1705 : public Klaymen {
-public:
- KmScene1705(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
-protected:
- uint32 xHandleMessage(int messageNum, const MessageParam &param);
-};
-
-class KmScene1901 : public Klaymen {
-public:
- KmScene1901(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
-protected:
- uint32 xHandleMessage(int messageNum, const MessageParam &param);
-};
-
-class KmScene2001 : public Klaymen {
-public:
- KmScene2001(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
-protected:
- uint32 xHandleMessage(int messageNum, const MessageParam &param);
-};
-
-class KmScene2101 : public Klaymen {
-public:
- KmScene2101(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
-protected:
- uint32 xHandleMessage(int messageNum, const MessageParam &param);
-};
-
-class KmScene2201 : public Klaymen {
-public:
- KmScene2201(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y, NRect *clipRects, int clipRectsCount);
-protected:
- uint32 xHandleMessage(int messageNum, const MessageParam &param);
-};
-
-class KmScene2203 : public Klaymen {
-public:
- KmScene2203(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
-protected:
- uint32 xHandleMessage(int messageNum, const MessageParam &param);
-};
-
-class KmScene2205 : public Klaymen {
-public:
- KmScene2205(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
-protected:
- void xUpdate();
- uint32 xHandleMessage(int messageNum, const MessageParam &param);
-};
-
-class KmScene2206 : public Klaymen {
-public:
- KmScene2206(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
- ~KmScene2206();
-protected:
- void xUpdate();
- uint32 xHandleMessage(int messageNum, const MessageParam &param);
-};
-
-class KmScene2207 : public Klaymen {
-public:
- KmScene2207(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
-protected:
- uint32 xHandleMessage(int messageNum, const MessageParam &param);
-};
-
-class KmScene2242 : public Klaymen {
-public:
- KmScene2242(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
-protected:
- void xUpdate();
- uint32 xHandleMessage(int messageNum, const MessageParam &param);
-};
-
-class KmHallOfRecords : public Klaymen {
-public:
- KmHallOfRecords(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
-protected:
- void xUpdate();
- uint32 xHandleMessage(int messageNum, const MessageParam &param);
-};
-
-class KmScene2247 : public Klaymen {
-public:
- KmScene2247(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
-protected:
- void xUpdate();
- uint32 xHandleMessage(int messageNum, const MessageParam &param);
-};
-
-class KmScene2401 : public Klaymen {
-public:
- KmScene2401(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
-protected:
- uint32 xHandleMessage(int messageNum, const MessageParam &param);
-};
-
-class KmScene2402 : public Klaymen {
-public:
- KmScene2402(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
-protected:
- uint32 xHandleMessage(int messageNum, const MessageParam &param);
-};
-
-class KmScene2403 : public Klaymen {
-public:
- KmScene2403(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
-protected:
- uint32 xHandleMessage(int messageNum, const MessageParam &param);
-};
-
-class KmScene2406 : public Klaymen {
-public:
- KmScene2406(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y, NRect *clipRects, int clipRectsCount);
-protected:
- uint32 xHandleMessage(int messageNum, const MessageParam &param);
-};
-
-class KmScene2501 : public Klaymen {
-public:
- KmScene2501(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
-protected:
- uint32 xHandleMessage(int messageNum, const MessageParam &param);
-};
-
-class KmScene2732 : public Klaymen {
-public:
- KmScene2732(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
-protected:
- uint32 xHandleMessage(int messageNum, const MessageParam &param);
-};
-
-class KmScene2801 : public Klaymen {
-public:
- KmScene2801(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
-protected:
- uint32 xHandleMessage(int messageNum, const MessageParam &param);
-};
-
-class KmScene2803 : public Klaymen {
-public:
- KmScene2803(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y, NRect *clipRects, int clipRectsCount);
-protected:
- uint32 xHandleMessage(int messageNum, const MessageParam &param);
-};
-
-class KmScene2803Small : public Klaymen {
-public:
- KmScene2803Small(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
-protected:
- uint32 xHandleMessage(int messageNum, const MessageParam &param);
-};
-
-class KmScene2805 : public Klaymen {
-public:
- KmScene2805(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
-protected:
- uint32 xHandleMessage(int messageNum, const MessageParam &param);
-};
-
-class KmScene2806 : public Klaymen {
-public:
- KmScene2806(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y,
- bool needsLargeSurface, NRect *clipRects, uint clipRectsCount);
-protected:
- uint32 xHandleMessage(int messageNum, const MessageParam &param);
-};
-
-class KmScene2809 : public Klaymen {
-public:
- KmScene2809(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y,
- bool needsLargeSurface, NRect *clipRects, uint clipRectsCount);
-protected:
- uint32 xHandleMessage(int messageNum, const MessageParam &param);
-};
-
-class KmScene2810Small : public Klaymen {
-public:
- KmScene2810Small(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
-protected:
- uint32 xHandleMessage(int messageNum, const MessageParam &param);
-};
-
-class KmScene2810 : public Klaymen {
-public:
- KmScene2810(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y,
- NRect *clipRects, uint clipRectsCount);
-protected:
- uint32 xHandleMessage(int messageNum, const MessageParam &param);
-};
-
-class KmScene2812 : public Klaymen {
-public:
- KmScene2812(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
-protected:
- uint32 xHandleMessage(int messageNum, const MessageParam &param);
};
} // End of namespace Neverhood
diff --git a/engines/neverhood/menumodule.cpp b/engines/neverhood/menumodule.cpp
index 362f5270e3..b332418cf5 100644
--- a/engines/neverhood/menumodule.cpp
+++ b/engines/neverhood/menumodule.cpp
@@ -112,7 +112,7 @@ void MenuModule::createScene(int sceneNum, int which) {
_childObject = new CreditsScene(_vm, this, true);
break;
case MAKING_OF:
- createSmackerScene(kMakingOfSmackerFileHashList, false, true, true);
+ createSmackerScene(kMakingOfSmackerFileHashList, ConfMan.getBool("scalemakingofvideos"), true, true);
break;
case LOAD_GAME_MENU:
createLoadGameMenu();
@@ -150,7 +150,6 @@ void MenuModule::updateScene() {
leaveModule(0);
break;
case kMainMenuQuitGame:
- leaveModule(0);
_vm->quitGame();
break;
case kMainMenuCredits:
@@ -195,6 +194,14 @@ void MenuModule::updateScene() {
}
uint32 MenuModule::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ switch(messageNum) {
+ case NM_KEYPRESS_ESC:
+ leaveModule(0);
+ break;
+ default:
+ break;
+ }
+
return Module::handleMessage(messageNum, param, sender);;
}
@@ -374,7 +381,7 @@ MainMenu::MainMenu(NeverhoodEngine *vm, Module *parentModule)
uint32 MainMenu::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x2000:
+ case NM_ANIMATION_UPDATE:
leaveScene(param.asInteger());
break;
}
@@ -446,17 +453,17 @@ void CreditsScene::update() {
uint32 CreditsScene::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x0009:
+ case NM_KEYPRESS_SPACE:
leaveScene(0);
break;
case 0x000B:
if (param.asInteger() == Common::KEYCODE_ESCAPE && _canAbort)
leaveScene(0);
break;
- case 0x101D:
+ case NM_MOUSE_HIDE:
_ticksDuration = _ticksTime - _vm->_system->getMillis();
break;
- case 0x101E:
+ case NM_MOUSE_SHOW:
_ticksTime = _ticksDuration + _vm->_system->getMillis();
break;
}
@@ -574,6 +581,7 @@ TextEditWidget::TextEditWidget(NeverhoodEngine *vm, int16 x, int16 y, GameStateM
_maxVisibleChars = (_rect.x2 - _rect.x1) / _fontSurface->getCharWidth();
_cursorPos = 0;
+ _textLabelWidget = NULL;
SetUpdateHandler(&TextEditWidget::update);
SetMessageHandler(&TextEditWidget::handleMessage);
@@ -994,7 +1002,7 @@ uint32 GameStateMenu::handleMessage(int messageNum, const MessageParam &param, E
setCurrWidget(_textEditWidget);
}
break;
- case 0x2000:
+ case NM_ANIMATION_UPDATE:
// Handle menu button click
switch (param.asInteger()) {
case 0:
@@ -1017,6 +1025,12 @@ uint32 GameStateMenu::handleMessage(int messageNum, const MessageParam &param, E
break;
}
break;
+ case NM_MOUSE_WHEELUP:
+ _listBox->scrollUp();
+ break;
+ case NM_MOUSE_WHEELDOWN:
+ _listBox->scrollDown();
+ break;
}
return 0;
}
@@ -1069,7 +1083,7 @@ static const NRect kLoadGameMenuButtonCollisionBounds[] = {
{ 182, 358, 241, 433 }
};
-static const NRect kLoadGameMenuListBoxRect = { 0, 0, 320, 271 };
+static const NRect kLoadGameMenuListBoxRect = { 0, 0, 320, 272 };
static const NRect kLoadGameMenuTextEditRect = { 0, 0, 320, 17 };
static const NRect kLoadGameMenuMouseRect = { 263, 48, 583, 65 };
@@ -1102,7 +1116,7 @@ static const NRect kDeleteGameMenuButtonCollisionBounds[] = {
{ 395, 278, 452, 372 }
};
-static const NRect kDeleteGameMenuListBoxRect = { 0, 0, 320, 271 };
+static const NRect kDeleteGameMenuListBoxRect = { 0, 0, 320, 272 };
static const NRect kDeleteGameMenuTextEditRect = { 0, 0, 320, 17 };
DeleteGameMenu::DeleteGameMenu(NeverhoodEngine *vm, Module *parentModule, SavegameList *savegameList)
@@ -1163,7 +1177,7 @@ QueryOverwriteMenu::QueryOverwriteMenu(NeverhoodEngine *vm, Module *parentModule
uint32 QueryOverwriteMenu::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x2000:
+ case NM_ANIMATION_UPDATE:
// Handle menu button click
leaveScene(param.asInteger());
break;
diff --git a/engines/neverhood/messages.h b/engines/neverhood/messages.h
index 78c66868d5..5f1e1b87dd 100644
--- a/engines/neverhood/messages.h
+++ b/engines/neverhood/messages.h
@@ -26,10 +26,50 @@
namespace Neverhood {
enum NeverhoodMessage {
- NM_KLAYMEN_PICKUP = 0x4812,
- NM_KLAYMEN_PRESS_BUTTON = 0x4816,
- NM_KLAYMEN_INSERT_DISK = 0x481A,
- NM_KLAYMEN_RELEASE_LEVER = 0x4827
+ NM_MOUSE_MOVE = 0x0000,
+ NM_MOUSE_CLICK = 0x0001,
+ NM_MOUSE_RELEASE = 0x0002,
+ NM_MOUSE_HIDE = 0x101D,
+ NM_MOUSE_SHOW = 0x101E,
+ NM_KEYPRESS_SPACE = 0x0009,
+ NM_KEYPRESS_ESC = 0x000C,
+ NM_ANIMATION_START = 0x100D,
+ NM_SCENE_LEAVE = 0x1019,
+ NM_PRIORITY_CHANGE = 0x1022,
+ NM_ANIMATION_UPDATE = 0x2000,
+ NM_POSITION_CHANGE = 0x2002,
+ NM_KLAYMEN_CLIMB_LADDER = 0x2005,
+ NM_KLAYMEN_STOP_CLIMBING = 0x2006,
+
+ NM_CAR_MOVE_TO_PREV_POINT = 0x2007,
+ NM_CAR_MOVE_TO_NEXT_POINT = 0x2008,
+ NM_CAR_ENTER = 0x2009,
+ NM_CAR_LEAVE = 0x200A,
+ NM_CAR_TURN = 0x200E,
+ NM_CAR_AT_HOME = 0x200F,
+
+ NM_ANIMATION_STOP = 0x3002,
+
+ NM_KLAYMEN_STAND_IDLE = 0x4004,
+ NM_KLAYMEN_USE_OBJECT = 0x4806,
+ NM_KLAYMEN_RAISE_LEVER = 0x4807,
+ NM_KLAYMEN_OPEN_DOOR = 0x4808,
+ NM_KLAYMEN_CLOSE_DOOR = 0x4809,
+ NM_KLAYMEN_MOVE_OBJECT = 0x480A,
+ NM_KLAYMEN_LOWER_LEVER = 0x480F,
+ NM_KLAYMEN_PICKUP = 0x4812,
+ NM_KLAYMEN_PRESS_BUTTON = 0x4816,
+ NM_KLAYMEN_INSERT_DISK = 0x481A,
+ NM_KLAYMEN_TURN_TO_USE = 0x481D,
+ NM_KLAYMEN_RETURN_FROM_USE = 0x481E,
+ NM_KLAYMEN_RELEASE_LEVER = 0x4827,
+
+ NM_MOVE_TO_BACK = 0x482A,
+ NM_MOVE_TO_FRONT = 0x482B,
+
+ // New to ScummVM
+ NM_MOUSE_WHEELUP = 0xF000,
+ NM_MOUSE_WHEELDOWN = 0xF001
};
} // End of namespace Neverhood
diff --git a/engines/neverhood/module.cpp b/engines/neverhood/module.cpp
index d1578e680c..3ef4554334 100644
--- a/engines/neverhood/module.cpp
+++ b/engines/neverhood/module.cpp
@@ -48,7 +48,7 @@ void Module::draw() {
uint32 Module::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
switch (messageNum) {
case 0x0008:
- sendMessage(_parentModule, 8, 0);
+ sendMessage(_parentModule, 0x0008, 0);
return 0;
case 0x1009:
_moduleResult = param.asInteger();
diff --git a/engines/neverhood/module.mk b/engines/neverhood/module.mk
index 052c830182..9c1220134c 100644
--- a/engines/neverhood/module.mk
+++ b/engines/neverhood/module.mk
@@ -15,27 +15,44 @@ MODULE_OBJS = \
microtiles.o \
module.o \
modules/module1000.o \
+ modules/module1000_sprites.o \
modules/module1100.o \
+ modules/module1100_sprites.o \
modules/module1200.o \
+ modules/module1200_sprites.o \
modules/module1300.o \
+ modules/module1300_sprites.o \
modules/module1400.o \
+ modules/module1400_sprites.o \
modules/module1500.o \
modules/module1600.o \
+ modules/module1600_sprites.o \
modules/module1700.o \
+ modules/module1700_sprites.o \
modules/module1800.o \
modules/module1900.o \
+ modules/module1900_sprites.o \
modules/module2000.o \
+ modules/module2000_sprites.o \
modules/module2100.o \
+ modules/module2100_sprites.o \
modules/module2200.o \
+ modules/module2200_sprites.o \
modules/module2300.o \
modules/module2400.o \
+ modules/module2400_sprites.o \
modules/module2500.o \
+ modules/module2500_sprites.o \
modules/module2600.o \
+ modules/module2600_sprites.o \
modules/module2700.o \
+ modules/module2700_sprites.o \
modules/module2800.o \
modules/module2800_sprites.o \
modules/module2900.o \
+ modules/module2900_sprites.o \
modules/module3000.o \
+ modules/module3000_sprites.o \
mouse.o \
navigationscene.o \
neverhood.o \
diff --git a/engines/neverhood/modules/module1000.cpp b/engines/neverhood/modules/module1000.cpp
index 08fb88ad72..788e22dc1b 100644
--- a/engines/neverhood/modules/module1000.cpp
+++ b/engines/neverhood/modules/module1000.cpp
@@ -21,6 +21,7 @@
*/
#include "neverhood/modules/module1000.h"
+#include "neverhood/modules/module1000_sprites.h"
namespace Neverhood {
@@ -118,219 +119,6 @@ void Module1000::updateScene() {
}
}
-// Scene1001
-
-AsScene1001Door::AsScene1001Door(NeverhoodEngine *vm)
- : AnimatedSprite(vm, 1100) {
-
- createSurface(800, 137, 242);
- _x = 726;
- _y = 440;
- stShowIdleDoor();
- loadSound(1, 0xED403E03);
- SetUpdateHandler(&AnimatedSprite::update);
- SetMessageHandler(&AsScene1001Door::handleMessage);
-}
-
-uint32 AsScene1001Door::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x2000:
- hammerHitsDoor();
- break;
- case 0x3002:
- gotoNextState();
- break;
- }
- return 0;
-}
-
-void AsScene1001Door::hammerHitsDoor() {
- switch (getGlobalVar(V_DOOR_STATUS)) {
- case 0:
- case 1:
- playSound(0, 0x65482F03);
- startAnimation(0x624C0498, 1, 3);
- NextState(&AsScene1001Door::stShowIdleDoor);
- break;
- case 2:
- playSound(1);
- startAnimation(0x624C0498, 6, 6);
- NextState(&AsScene1001Door::stBustedDoorMove);
- break;
- default:
- // Nothing
- break;
- }
- incGlobalVar(V_DOOR_STATUS, 1);
-}
-
-void AsScene1001Door::stShowIdleDoor() {
- switch (getGlobalVar(V_DOOR_STATUS)) {
- case 1:
- startAnimation(0x624C0498, 4, -1);
- _newStickFrameIndex = 4;
- break;
- case 2:
- startAnimation(0x624C0498, 1, -1);
- _newStickFrameIndex = 1;
- break;
- case 3:
- stopAnimation();
- setVisible(false);
- break;
- default:
- startAnimation(0x624C0498, 0, -1);
- _newStickFrameIndex = 0;
- break;
- }
-}
-
-void AsScene1001Door::stBustedDoorMove() {
- setGlobalVar(V_DOOR_BUSTED, 1);
- startAnimation(0x624C0498, 6, 6);
- NextState(&AsScene1001Door::stBustedDoorGone);
- _x = 30;
-}
-
-void AsScene1001Door::stBustedDoorGone() {
- playSound(0);
- stopAnimation();
- setVisible(false);
-}
-
-AsScene1001Hammer::AsScene1001Hammer(NeverhoodEngine *vm, Sprite *asDoor)
- : AnimatedSprite(vm, 1100), _asDoor(asDoor) {
-
- _x = 547;
- _y = 206;
- createSurface(900, 177, 192);
- startAnimation(0x022C90D4, -1, -1);
- _newStickFrameIndex = STICK_LAST_FRAME;
- SetUpdateHandler(&AnimatedSprite::update);
- SetMessageHandler(&AsScene1001Hammer::handleMessage);
-}
-
-uint32 AsScene1001Hammer::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x100D:
- if (param.asInteger() == 0x00352100)
- sendMessage(_asDoor, 0x2000, 0);
- else if (param.asInteger() == 0x0A1A0109)
- playSound(0, 0x66410886);
- break;
- case 0x2000:
- startAnimation(0x022C90D4, 1, -1);
- playSound(0, 0xE741020A);
- _newStickFrameIndex = STICK_LAST_FRAME;
- break;
- }
- return 0;
-}
-
-AsScene1001Window::AsScene1001Window(NeverhoodEngine *vm)
- : AnimatedSprite(vm, 1200) {
-
- _x = 320;
- _y = 240;
- createSurface(100, 66, 129);
- startAnimation(0xC68C2299, 0, -1);
- _newStickFrameIndex = 0;
- SetUpdateHandler(&AnimatedSprite::update);
- SetMessageHandler(&AsScene1001Window::handleMessage);
-}
-
-uint32 AsScene1001Window::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x100D:
- if (param.asInteger() == 0x0E0A1410)
- playSound(0, 0x60803F10);
- break;
- case 0x2001:
- startAnimation(0xC68C2299, 0, -1);
- break;
- case 0x3002:
- SetMessageHandler(NULL);
- setGlobalVar(V_WINDOW_OPEN, 1);
- setVisible(false);
- break;
- }
- return 0;
-}
-
-AsScene1001Lever::AsScene1001Lever(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y, int deltaXType)
- : AnimatedSprite(vm, 1100), _parentScene(parentScene) {
-
- createSurface(1010, 71, 73);
- setDoDeltaX(deltaXType);
- startAnimation(0x04A98C36, 0, -1);
- _newStickFrameIndex = 0;
- _x = x;
- _y = y;
- SetUpdateHandler(&AnimatedSprite::update);
- SetMessageHandler(&AsScene1001Lever::handleMessage);
-}
-
-uint32 AsScene1001Lever::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x100D:
- if (param.asInteger() == 0x00C0C444)
- sendMessage(_parentScene, 0x480F, 0);
- else if (param.asInteger() == 0xC41A02C0)
- playSound(0, 0x40581882);
- break;
- case 0x1011:
- sendMessage(_parentScene, 0x4826, 0);
- messageResult = 1;
- break;
- case 0x3002:
- startAnimation(0x04A98C36, 0, -1);
- _newStickFrameIndex = 0;
- break;
- case 0x480F:
- startAnimation(0x04A98C36, 0, -1);
- break;
- case 0x482A:
- sendMessage(_parentScene, 0x1022, 990);
- break;
- case 0x482B:
- sendMessage(_parentScene, 0x1022, 1010);
- break;
- }
- return messageResult;
-}
-
-SsCommonButtonSprite::SsCommonButtonSprite(NeverhoodEngine *vm, Scene *parentScene, uint32 fileHash, int surfacePriority, uint32 soundFileHash)
- : StaticSprite(vm, fileHash, surfacePriority), _parentScene(parentScene), _countdown(0) {
-
- _priority = 1100;
- _soundFileHash = soundFileHash ? soundFileHash : 0x44141000;
- setVisible(false);
- SetUpdateHandler(&SsCommonButtonSprite::update);
- SetMessageHandler(&SsCommonButtonSprite::handleMessage);
-}
-
-void SsCommonButtonSprite::update() {
- if (_countdown != 0 && (--_countdown) == 0)
- setVisible(false);
-}
-
-uint32 SsCommonButtonSprite::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x480B:
- sendMessage(_parentScene, 0x480B, 0);
- setVisible(true);
- _countdown = 8;
- playSound(0, _soundFileHash);
- break;
- }
- return messageResult;
-}
-
Scene1001::Scene1001(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule), _asDoor(NULL), _asWindow(NULL) {
@@ -404,7 +192,7 @@ uint32 Scene1001::handleMessage(int messageNum, const MessageParam &param, Entit
uint32 messageResult = 0;
Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0x00342624) {
sendEntityMessage(_klaymen, 0x1014, _asLever);
setMessageList2(0x004B4910);
@@ -426,732 +214,19 @@ uint32 Scene1001::handleMessage(int messageNum, const MessageParam &param, Entit
}
}
break;
- case 0x2002:
+ case NM_POSITION_CHANGE:
setRectList(0x004B49F0);
break;
case 0x480B:
sendMessage(_asWindow, 0x2001, 0);
break;
- case 0x480F:
+ case NM_KLAYMEN_LOWER_LEVER:
sendMessage(_asHammer, 0x2000, 0);
break;
}
return messageResult;
}
-// Scene1002
-
-AsScene1002Ring::AsScene1002Ring(NeverhoodEngine *vm, Scene *parentScene, bool isSpecial, int16 x, int16 y, int16 clipY1, bool isRingLow)
- : AnimatedSprite(vm, 1100), _parentScene(parentScene), _isSpecial(isSpecial) {
-
- SetUpdateHandler(&AsScene1002Ring::update);
-
- if (_isSpecial) {
- createSurface(990, 68, 314);
- if (isRingLow) {
- startAnimation(0x04103090, 0, -1);
- SetMessageHandler(&AsScene1002Ring::hmRingHangingLow);
- } else {
- startAnimation(0xA85C4011, _vm->_rnd->getRandomNumber(15), -1);
- SetMessageHandler(&AsScene1002Ring::hmRingIdle);
- }
- } else {
- createSurface(990, 68, 138);
- startAnimation(0xA85C4011, _vm->_rnd->getRandomNumber(15), -1);
- SetMessageHandler(&AsScene1002Ring::hmRingIdle);
- }
-
- setClipRect(0, clipY1, 640, 480);
-
- _x = x;
- _y = y;
-
- setDoDeltaX(_vm->_rnd->getRandomNumber(1));
-
-}
-
-void AsScene1002Ring::update() {
- updateAnim();
- updatePosition();
-}
-
-uint32 AsScene1002Ring::hmRingIdle(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x4806:
- setDoDeltaX(((Sprite*)sender)->isDoDeltaX() ? 1 : 0);
- sendMessage(_parentScene, 0x4806, 0);
- SetMessageHandler(&AsScene1002Ring::hmRingPulled1);
- startAnimation(_isSpecial ? 0x87502558 : 0x80DD4010, 0, -1);
- break;
- case 0x480F:
- setDoDeltaX(((Sprite*)sender)->isDoDeltaX() ? 1 : 0);
- sendMessage(_parentScene, 0x480F, 0);
- SetMessageHandler(&AsScene1002Ring::hmRingPulled2);
- startAnimation(0x861A2020, 0, -1);
- break;
- case 0x482A:
- sendMessage(_parentScene, 0x1022, 990);
- break;
- case 0x482B:
- sendMessage(_parentScene, 0x1022, 1010);
- break;
- }
- return messageResult;
-}
-
-uint32 AsScene1002Ring::hmRingPulled1(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x3002:
- startAnimation(_isSpecial ? 0x78D0A812 : 0xB85D2A10, 0, -1);
- SetMessageHandler(&AsScene1002Ring::hmRingHangingLow);
- break;
- case 0x4807:
- sendMessage(_parentScene, 0x4807, 0);
- setDoDeltaX(_vm->_rnd->getRandomNumber(1));
- startAnimation(0x8258A030, 0, -1);
- SetMessageHandler(&AsScene1002Ring::hmRingReleased);
- break;
- case 0x482A:
- sendMessage(_parentScene, 0x1022, 990);
- break;
- case 0x482B:
- sendMessage(_parentScene, 0x1022, 1010);
- break;
- }
- return messageResult;
-}
-
-uint32 AsScene1002Ring::hmRingPulled2(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x3002:
- startAnimation(0x04103090, 0, -1);
- SetMessageHandler(&AsScene1002Ring::hmRingHangingLow);
- break;
- case 0x482A:
- sendMessage(_parentScene, 0x1022, 990);
- break;
- case 0x482B:
- sendMessage(_parentScene, 0x1022, 1010);
- break;
- }
- return messageResult;
-}
-
-uint32 AsScene1002Ring::hmRingHangingLow(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x4807:
- sendMessage(_parentScene, 0x4807, 0);
- setDoDeltaX(_vm->_rnd->getRandomNumber(1));
- startAnimation(0x8258A030, 0, -1);
- SetMessageHandler(&AsScene1002Ring::hmRingReleased);
- break;
- case 0x482A:
- sendMessage(_parentScene, 0x1022, 990);
- break;
- case 0x482B:
- sendMessage(_parentScene, 0x1022, 1010);
- break;
- }
- return messageResult;
-}
-
-uint32 AsScene1002Ring::hmRingReleased(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = hmRingIdle(messageNum, param, sender);
- switch (messageNum) {
- case 0x100D:
- if (param.asInteger() == 0x05410F72)
- playSound(0, 0x21EE40A9);
- break;
- case 0x3002:
- startAnimation(0xA85C4011, 0, -1);
- break;
- case 0x482A:
- sendMessage(_parentScene, 0x1022, 990);
- break;
- case 0x482B:
- sendMessage(_parentScene, 0x1022, 1010);
- break;
- }
- return messageResult;
-}
-
-AsScene1002Door::AsScene1002Door(NeverhoodEngine *vm, NRect &clipRect)
- : StaticSprite(vm, 1200) {
-
- loadSprite(0x1052370F, kSLFDefDrawOffset | kSLFSetPosition, 800, 526, getGlobalVar(V_FLYTRAP_RING_DOOR) ? 49 : 239);
- setClipRect(clipRect);
- SetUpdateHandler(&AsScene1002Door::update);
- SetMessageHandler(&AsScene1002Door::handleMessage);
- SetSpriteUpdate(NULL);
-}
-
-void AsScene1002Door::update() {
- handleSpriteUpdate();
- updatePosition();
-}
-
-uint32 AsScene1002Door::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x4808:
- setGlobalVar(V_FLYTRAP_RING_DOOR, 1);
- SetSpriteUpdate(&AsScene1002Door::suOpenDoor);
- break;
- case 0x4809:
- setGlobalVar(V_FLYTRAP_RING_DOOR, 0);
- SetSpriteUpdate(&AsScene1002Door::suCloseDoor);
- break;
- }
- return messageResult;
-}
-
-void AsScene1002Door::suOpenDoor() {
- if (_y > 49) {
- _y -= 8;
- if (_y < 49) {
- SetSpriteUpdate(NULL);
- _y = 49;
- }
- _needRefresh = true;
- }
-}
-
-void AsScene1002Door::suCloseDoor() {
- if (_y < 239) {
- _y += 8;
- if (_y > 239) {
- SetSpriteUpdate(NULL);
- _y = 239;
- }
- _needRefresh = true;
- }
-}
-
-AsScene1002BoxingGloveHitEffect::AsScene1002BoxingGloveHitEffect(NeverhoodEngine *vm)
- : AnimatedSprite(vm, 1400) {
-
- createSurface(1025, 88, 165);
- setVisible(false);
- SetUpdateHandler(&AnimatedSprite::update);
- SetMessageHandler(&AsScene1002BoxingGloveHitEffect::handleMessage);
-}
-
-uint32 AsScene1002BoxingGloveHitEffect::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x2004:
- _x = ((Sprite*)sender)->getX() - 98;
- _y = ((Sprite*)sender)->getY() - 111;
- startAnimation(0x0422255A, 0, -1);
- setVisible(true);
- break;
- case 0x3002:
- stopAnimation();
- setVisible(false);
- break;
- }
- return messageResult;
-}
-
-AsScene1002DoorSpy::AsScene1002DoorSpy(NeverhoodEngine *vm, NRect &clipRect, Scene *parentScene, Sprite *asDoor, Sprite *asScene1002BoxingGloveHitEffect)
- : AnimatedSprite(vm, 1300), _clipRect(clipRect), _parentScene(parentScene), _asDoor(asDoor), _asBoxingGloveHitEffect(asScene1002BoxingGloveHitEffect) {
-
- createSurface(800, 136, 147);
- setClipRect(clipRect);
- suDoorSpy();
- loadSound(0, 0xC0C40298);
- startAnimation(0x586C1D48, 0, 0);
- SetUpdateHandler(&AnimatedSprite::update);
- SetMessageHandler(&AsScene1002DoorSpy::handleMessage);
- SetSpriteUpdate(&AsScene1002DoorSpy::suDoorSpy);
-}
-
-uint32 AsScene1002DoorSpy::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x100D:
- if (param.asInteger() == 0xA61CA1C2)
- sendMessage(_asBoxingGloveHitEffect, 0x2004, 0);
- else if (param.asInteger() == 0x14CE0620)
- playSound(0);
- break;
- case 0x2003:
- stDoorSpyBoxingGlove();
- break;
- }
- return messageResult;
-}
-
-uint32 AsScene1002DoorSpy::hmDoorSpyAnimation(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x3002:
- gotoNextState();
- break;
- }
- return messageResult;
-}
-
-void AsScene1002DoorSpy::suDoorSpy() {
- _x = _asDoor->getX() + 34;
- _y = _asDoor->getY() + 175;
-}
-
-void AsScene1002DoorSpy::stDoorSpyIdle() {
- setClipRect(_clipRect);
- _parentScene->setSurfacePriority(getSurface(), 800);
- startAnimation(0x586C1D48, 0, 0);
- SetMessageHandler(&AsScene1002DoorSpy::handleMessage);
-}
-
-void AsScene1002DoorSpy::stDoorSpyBoxingGlove() {
- setClipRect(0, 0, 640, 480);
- _parentScene->setSurfacePriority(getSurface(), 1200);
- startAnimation(0x586C1D48, 1, -1);
- SetMessageHandler(&AsScene1002DoorSpy::hmDoorSpyAnimation);
- NextState(&AsScene1002DoorSpy::stDoorSpyIdle);
-}
-
-SsCommonPressButton::SsCommonPressButton(NeverhoodEngine *vm, Scene *parentScene, uint32 fileHash1, uint32 fileHash2, int surfacePriority, uint32 soundFileHash)
- : StaticSprite(vm, 1100), _parentScene(parentScene), _status(0), _countdown(0) {
-
- _soundFileHash = soundFileHash != 0 ? soundFileHash : 0x44141000;
- _fileHashes[0] = fileHash1;
- _fileHashes[1] = fileHash2;
- createSurface(surfacePriority, 40, 40);
- loadSprite(fileHash1, kSLFDefDrawOffset | kSLFDefPosition);
- setVisible(false);
- SetUpdateHandler(&SsCommonPressButton::update);
- SetMessageHandler(&SsCommonPressButton::handleMessage);
-}
-
-void SsCommonPressButton::setFileHashes(uint32 fileHash1, uint32 fileHash2) {
- _fileHashes[0] = fileHash1;
- _fileHashes[1] = fileHash2;
- loadSprite(_status == 2 ? fileHash2 : fileHash1, kSLFDefDrawOffset | kSLFDefPosition);
-}
-
-void SsCommonPressButton::update() {
- if (_countdown != 0 && (--_countdown) == 0) {
- if (_status == 1) {
- _status = 2;
- loadSprite(_fileHashes[1], kSLFDefDrawOffset | kSLFDefPosition);
- _countdown = 4;
- } else if (_status == 2) {
- _status = 3;
- loadSprite(_fileHashes[0], kSLFDefDrawOffset | kSLFDefPosition);
- _countdown = 4;
- } else if (_status == 3) {
- _status = 0;
- setVisible(false);
- }
- }
-}
-
-uint32 SsCommonPressButton::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x480B:
- sendMessage(_parentScene, 0x480B, 0);
- _status = 1;
- _countdown = 4;
- setVisible(true);
- playSound(0, _soundFileHash);
- break;
- }
- return messageResult;
-}
-
-AsScene1002VenusFlyTrap::AsScene1002VenusFlyTrap(NeverhoodEngine *vm, Scene *parentScene, Sprite *klaymen, bool isSecond)
- : AnimatedSprite(vm, 1100), _parentScene(parentScene), _klaymen(klaymen), _isSecond(isSecond), _countdown(0) {
-
- createSurface(995, 175, 195);
- if (!_isSecond) {
- if (getGlobalVar(V_FLYTRAP_RING_DOOR)) {
- setDoDeltaX(1);
- _x = 366;
- _y = 435;
- stRingGrabbed();
- } else {
- _x = 174 + getGlobalVar(V_FLYTRAP_POSITION_1) * 32;
- _y = 435;
- stIdle();
- }
- } else {
- _x = 186 + getGlobalVar(V_FLYTRAP_POSITION_2) * 32;
- _y = 364;
- if (getGlobalVar(V_FLYTRAP_RING_BRIDGE) || getGlobalVar(V_FLYTRAP_RING_FENCE)) {
- stRingGrabbed();
- } else {
- stIdle();
- }
- }
- _flags = 4;
- SetUpdateHandler(&AsScene1002VenusFlyTrap::update);
- SetMessageHandler(&AsScene1002VenusFlyTrap::handleMessage);
- SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
-}
-
-void AsScene1002VenusFlyTrap::update() {
- if (_countdown != 0 && (--_countdown == 0))
- gotoNextState();
- AnimatedSprite::update();
-}
-
-void AsScene1002VenusFlyTrap::upIdle() {
- if (_countdown == 0 && _klaymen->getX() - 20 > _x)
- setDoDeltaX(1);
- else if (_klaymen->getX() + 20 < _x)
- setDoDeltaX(0);
- update();
-}
-
-uint32 AsScene1002VenusFlyTrap::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x100D:
- if (param.asInteger() == 0x000890C4)
- playSound(0, 0xC21190D8);
- else if (param.asInteger() == 0x522200A0)
- playSound(0, 0x931080C8);
- break;
- case 0x1011:
- if (_isSecond) {
- if (_x >= 154 && _x <= 346) {
- sendMessage(_parentScene, 0x2000, 0);
- messageResult = 1;
- }
- } else {
- if (_x >= 174 && _x <= 430) {
- sendMessage(_parentScene, 0x2000, 0);
- messageResult = 1;
- }
- }
- break;
- case 0x480B:
- setDoDeltaX(param.asInteger() != 0 ? 1 : 0);
- if (!_isSecond) {
- if (getGlobalVar(V_FLYTRAP_RING_DOOR))
- stRelease();
- else
- stWalk();
- } else {
- if (getGlobalVar(V_FLYTRAP_RING_BRIDGE) || getGlobalVar(V_FLYTRAP_RING_FENCE))
- stRelease();
- else
- stWalk();
- }
- break;
- case 0x480C:
- if (_isSecond) {
- if (_x >= 154 && _x <= 346)
- messageResult = 1;
- else
- messageResult = 0;
- } else {
- if (_x >= 174 && _x <= 430)
- messageResult = 1;
- else
- messageResult = 0;
- }
- break;
- case 0x480E:
- if (param.asInteger() == 1)
- stGrabRing();
- break;
- case 0x4810:
- swallowKlaymen();
- break;
- case 0x482A:
- sendMessage(_parentScene, 0x1022, 995);
- break;
- case 0x482B:
- sendMessage(_parentScene, 0x1022, 1015);
- break;
- }
- return messageResult;
-}
-
-uint32 AsScene1002VenusFlyTrap::hmAnimationSimple(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x3002:
- gotoNextState();
- break;
- }
- return messageResult;
-}
-
-uint32 AsScene1002VenusFlyTrap::hmAnimationExt(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x100D:
- if (param.asInteger() == 0x000890C4)
- playSound(0, 0xC21190D8);
- else if (param.asInteger() == 0x41881801) {
- if (_isSecond) {
- if (_x > 330)
- sendMessage(_klaymen, 0x4811, 2);
- else
- sendMessage(_klaymen, 0x4811, 0);
- } else {
- sendMessage(_klaymen, 0x4811, 0);
- }
- } else if (param.asInteger() == 0x522200A0)
- playSound(0, 0x931080C8);
- break;
- case 0x3002:
- gotoNextState();
- break;
- case 0x482A:
- sendMessage(_parentScene, 0x1022, 995);
- break;
- case 0x482B:
- sendMessage(_parentScene, 0x1022, 1015);
- break;
- }
- return messageResult;
-}
-
-void AsScene1002VenusFlyTrap::stWalkBack() {
- setDoDeltaX(2);
- startAnimation(0xC4080034, 0, -1);
- SetUpdateHandler(&AsScene1002VenusFlyTrap::update);
- SetMessageHandler(&AsScene1002VenusFlyTrap::hmAnimationExt);
- NextState(&AsScene1002VenusFlyTrap::stIdle);
-}
-
-void AsScene1002VenusFlyTrap::stWalk() {
- startAnimation(0xC4080034, 0, -1);
- SetUpdateHandler(&AsScene1002VenusFlyTrap::update);
- SetMessageHandler(&AsScene1002VenusFlyTrap::hmAnimationSimple);
- NextState(&AsScene1002VenusFlyTrap::stIdle);
-}
-
-void AsScene1002VenusFlyTrap::stRelease() {
- sendMessage(_parentScene, 0x4807, 0);
- startAnimation(0x82292851, 0, -1);
- SetUpdateHandler(&AsScene1002VenusFlyTrap::update);
- SetMessageHandler(&AsScene1002VenusFlyTrap::hmAnimationSimple);
- NextState(&AsScene1002VenusFlyTrap::stIdle);
-}
-
-void AsScene1002VenusFlyTrap::stGrabRing() {
- setDoDeltaX(1);
- startAnimation(0x86A82A11, 0, -1);
- SetUpdateHandler(&AsScene1002VenusFlyTrap::update);
- SetMessageHandler(&AsScene1002VenusFlyTrap::hmAnimationSimple);
- NextState(&AsScene1002VenusFlyTrap::stRingGrabbed);
-}
-
-void AsScene1002VenusFlyTrap::stRingGrabbed() {
- startAnimation(0xB5A86034, 0, -1);
- SetUpdateHandler(&AsScene1002VenusFlyTrap::update);
- SetMessageHandler(&AsScene1002VenusFlyTrap::handleMessage);
-}
-
-void AsScene1002VenusFlyTrap::stKlaymenInside() {
- startAnimation(0x31303094, 0, -1);
- SetUpdateHandler(&AsScene1002VenusFlyTrap::update);
- SetMessageHandler(NULL);
- NextState(&AsScene1002VenusFlyTrap::stKlaymenInsideMoving);
- _countdown = 24;
-}
-
-void AsScene1002VenusFlyTrap::stIdle() {
- startAnimation(0xC8204250, 0, -1);
- SetUpdateHandler(&AsScene1002VenusFlyTrap::upIdle);
- SetMessageHandler(&AsScene1002VenusFlyTrap::handleMessage);
- if (_isSecond) {
- if (_x >= 154 && _x <= 346)
- setGlobalVar(V_FLYTRAP_POSITION_2, (_x - 186) / 32);
- else {
- NextState(&AsScene1002VenusFlyTrap::stWalkBack);
- _countdown = 12;
- }
- } else {
- if (_x >= 174 && _x <= 430)
- setGlobalVar(V_FLYTRAP_POSITION_1, (_x - 174) / 32);
- else {
- NextState(&AsScene1002VenusFlyTrap::stWalkBack);
- _countdown = 12;
- }
- }
-}
-
-void AsScene1002VenusFlyTrap::stKlaymenInsideMoving() {
- startAnimation(0x152920C4, 0, -1);
- SetUpdateHandler(&AsScene1002VenusFlyTrap::update);
- SetMessageHandler(&AsScene1002VenusFlyTrap::hmAnimationExt);
- NextState(&AsScene1002VenusFlyTrap::stSpitOutKlaymen);
-}
-
-void AsScene1002VenusFlyTrap::stSpitOutKlaymen() {
- startAnimation(0x84001117, 0, -1);
- SetUpdateHandler(&AsScene1002VenusFlyTrap::update);
- SetMessageHandler(&AsScene1002VenusFlyTrap::hmAnimationExt);
- NextState(&AsScene1002VenusFlyTrap::stIdle);
-}
-
-void AsScene1002VenusFlyTrap::swallowKlaymen() {
- if (_x - 15 < _klaymen->getX() && _x + 15 > _klaymen->getX()) {
- if (_isSecond)
- setDoDeltaX(_x > 265 && _x < 330 ? 1 : 0);
- else
- setDoDeltaX(_x > 320 ? 1 : 0);
- sendMessage(_klaymen, 0x2001, 0);
- startAnimation(0x8C2C80D4, 0, -1);
- SetUpdateHandler(&AsScene1002VenusFlyTrap::update);
- SetMessageHandler(&AsScene1002VenusFlyTrap::hmAnimationExt);
- NextState(&AsScene1002VenusFlyTrap::stKlaymenInside);
- }
-}
-
-AsScene1002OutsideDoorBackground::AsScene1002OutsideDoorBackground(NeverhoodEngine *vm)
- : AnimatedSprite(vm, 1200), _countdown(0) {
-
- createSurface(850, 186, 212);
- _x = 320;
- _y = 240;
- if (getGlobalVar(V_FLYTRAP_RING_DOOR)) {
- startAnimation(0x004A4495, -1, -1);
- _newStickFrameIndex = STICK_LAST_FRAME;
- } else
- setVisible(false);
- SetUpdateHandler(&AsScene1002OutsideDoorBackground::update);
- SetMessageHandler(&AsScene1002OutsideDoorBackground::handleMessage);
-}
-
-void AsScene1002OutsideDoorBackground::update() {
- if (_countdown != 0 && (--_countdown == 0)) {
- if (_isDoorClosed)
- stCloseDoor();
- else
- stOpenDoor();
- }
- AnimatedSprite::update();
-}
-
-uint32 AsScene1002OutsideDoorBackground::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageResult) {
- case 0x4808:
- _isDoorClosed = false;
- _countdown = 2;
- break;
- case 0x4809:
- _isDoorClosed = true;
- _countdown = 2;
- break;
- }
- return messageResult;
-}
-
-uint32 AsScene1002OutsideDoorBackground::hmAnimation(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = handleMessage(messageNum, param, sender);
- switch (messageResult) {
- case 0x3002:
- gotoNextState();
- break;
- }
- return messageResult;
-}
-
-void AsScene1002OutsideDoorBackground::stOpenDoor() {
- startAnimation(0x004A4495, 0, -1);
- _newStickFrameIndex = STICK_LAST_FRAME;
- setVisible(true);
- SetMessageHandler(&AsScene1002OutsideDoorBackground::handleMessage);
-}
-
-void AsScene1002OutsideDoorBackground::stCloseDoor() {
- startAnimation(0x004A4495, -1, -1);
- _playBackwards = true;
- setVisible(true);
- SetMessageHandler(&AsScene1002OutsideDoorBackground::hmAnimation);
- NextState(&AsScene1002OutsideDoorBackground::stDoorClosed);
-}
-
-void AsScene1002OutsideDoorBackground::stDoorClosed() {
- setVisible(false);
- stopAnimation();
-}
-
-AsScene1002KlaymenLadderHands::AsScene1002KlaymenLadderHands(NeverhoodEngine *vm, Klaymen *klaymen)
- : AnimatedSprite(vm, 1200), _klaymen(klaymen) {
-
- createSurface(1200, 40, 163);
- setVisible(false);
- SetUpdateHandler(&AsScene1002KlaymenLadderHands::update);
- SetMessageHandler(&Sprite::handleMessage);
-}
-
-void AsScene1002KlaymenLadderHands::update() {
- if (_klaymen->getCurrAnimFileHash() == 0x3A292504) {
- startAnimation(0xBA280522, _klaymen->getFrameIndex(), -1);
- _newStickFrameIndex = _klaymen->getFrameIndex();
- setVisible(true);
- _x = _klaymen->getX();
- _y = _klaymen->getY();
- setDoDeltaX(_klaymen->isDoDeltaX() ? 1 : 0);
- } else if (_klaymen->getCurrAnimFileHash() == 0x122D1505) {
- startAnimation(0x1319150C, _klaymen->getFrameIndex(), -1);
- _newStickFrameIndex = _klaymen->getFrameIndex();
- setVisible(true);
- _x = _klaymen->getX();
- _y = _klaymen->getY();
- setDoDeltaX(_klaymen->isDoDeltaX() ? 1 : 0);
- } else
- setVisible(false);
- AnimatedSprite::update();
-}
-
-AsScene1002KlaymenPeekHand::AsScene1002KlaymenPeekHand(NeverhoodEngine *vm, Scene *parentScene, Klaymen *klaymen)
- : AnimatedSprite(vm, 1200), _parentScene(parentScene), _klaymen(klaymen),
- _isClipRectSaved(false) {
-
- createSurface(1000, 33, 41);
- setVisible(false);
- SetUpdateHandler(&AsScene1002KlaymenPeekHand::update);
- SetMessageHandler(&AsScene1002KlaymenPeekHand::handleMessage);
-}
-
-void AsScene1002KlaymenPeekHand::update() {
- if (_klaymen->getCurrAnimFileHash() == 0xAC20C012 && _klaymen->getFrameIndex() < 50) {
- startAnimation(0x9820C913, _klaymen->getFrameIndex(), -1);
- _newStickFrameIndex = _klaymen->getFrameIndex();
- setVisible(true);
- _x = _klaymen->getX();
- _y = _klaymen->getY();
- setDoDeltaX(_klaymen->isDoDeltaX() ? 1 : 0);
- } else
- setVisible(false);
- AnimatedSprite::update();
-}
-
-uint32 AsScene1002KlaymenPeekHand::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x100D:
- if (param.asInteger() == 0x4AB28209) {
- sendMessage(_parentScene, 0x1022, 1200);
- _isClipRectSaved = true;
- _savedClipRect = _surface->getClipRect();
- setClipRect(0, 0, 640, 480);
- } else if (param.asInteger() == 0x88001184) {
- sendMessage(_parentScene, 0x1022, 1000);
- if (_isClipRectSaved)
- setClipRect(_savedClipRect);
- }
- break;
- }
- return messageResult;
-}
-
Scene1002::Scene1002(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule), _isKlaymenFloor(false), _isClimbingLadder(false) {
@@ -1242,7 +317,7 @@ Scene1002::Scene1002(NeverhoodEngine *vm, Module *parentModule, int which)
_asVenusFlyTrap = insertSprite<AsScene1002VenusFlyTrap>(this, _klaymen, false);
addCollisionSprite(_asVenusFlyTrap);
- sendEntityMessage(_klaymen, 0x2007, _asVenusFlyTrap);
+ sendEntityMessage(_klaymen, NM_CAR_MOVE_TO_PREV_POINT, _asVenusFlyTrap);
_asOutsideDoorBackground = insertSprite<AsScene1002OutsideDoorBackground>();
@@ -1272,7 +347,7 @@ uint32 Scene1002::handleMessage(int messageNum, const MessageParam &param, Entit
uint32 messageResult = 0;
Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0xE6EE60E1) {
if (getGlobalVar(V_FLYTRAP_RING_DOOR))
setMessageList(0x004B4428);
@@ -1306,7 +381,7 @@ uint32 Scene1002::handleMessage(int messageNum, const MessageParam &param, Entit
case 0x1024:
sendMessage(_parentModule, 0x1024, param.asInteger());
break;
- case 0x2000:
+ case NM_ANIMATION_UPDATE:
if (_isClimbingLadder) {
setMessageList2(0x004B43D0);
} else {
@@ -1320,18 +395,18 @@ uint32 Scene1002::handleMessage(int messageNum, const MessageParam &param, Entit
}
}
break;
- case 0x2002:
+ case NM_POSITION_CHANGE:
_messageList = NULL;
break;
- case 0x2005:
+ case NM_KLAYMEN_CLIMB_LADDER:
_isClimbingLadder = true;
setRectList(0x004B4418);
break;
- case 0x2006:
+ case NM_KLAYMEN_STOP_CLIMBING:
_isClimbingLadder = false;
setRectList(0x004B43A0);
break;
- case 0x4806:
+ case NM_KLAYMEN_USE_OBJECT:
if (sender == _asRing1) {
setGlobalVar(V_RADIO_ENABLED, 0);
playSound(0, 0x665198C0);
@@ -1341,8 +416,8 @@ uint32 Scene1002::handleMessage(int messageNum, const MessageParam &param, Entit
} else if (sender == _asRing3) {
setGlobalVar(V_RADIO_ENABLED, 0);
playSound(1);
- sendMessage(_asDoor, 0x4808, 0);
- sendMessage(_asOutsideDoorBackground, 0x4808, 0);
+ sendMessage(_asDoor, NM_KLAYMEN_OPEN_DOOR, 0);
+ sendMessage(_asOutsideDoorBackground, NM_KLAYMEN_OPEN_DOOR, 0);
} else if (sender == _asRing4) {
setGlobalVar(V_RADIO_ENABLED, 0);
playSound(0, 0xE0558848);
@@ -1351,25 +426,25 @@ uint32 Scene1002::handleMessage(int messageNum, const MessageParam &param, Entit
playSound(0, 0x44014282);
}
break;
- case 0x4807:
+ case NM_KLAYMEN_RAISE_LEVER:
if (sender == _asRing3) {
playSound(2);
- sendMessage(_asDoor, 0x4809, 0);
- sendMessage(_asOutsideDoorBackground, 0x4809, 0);
+ sendMessage(_asDoor, NM_KLAYMEN_CLOSE_DOOR, 0);
+ sendMessage(_asOutsideDoorBackground, NM_KLAYMEN_CLOSE_DOOR, 0);
} else if (sender == _asVenusFlyTrap) {
if (getGlobalVar(V_FLYTRAP_RING_DOOR)) {
- sendMessage(_asRing3, 0x4807, 0);
+ sendMessage(_asRing3, NM_KLAYMEN_RAISE_LEVER, 0);
}
}
break;
case 0x480B:
sendEntityMessage(_klaymen, 0x1014, _asDoorSpy);
break;
- case 0x480F:
+ case NM_KLAYMEN_LOWER_LEVER:
setGlobalVar(V_RADIO_ENABLED, 0);
playSound(1);
- sendMessage(_asDoor, 0x4808, 0);
- sendMessage(_asOutsideDoorBackground, 0x4808, 0);
+ sendMessage(_asDoor, NM_KLAYMEN_OPEN_DOOR, 0);
+ sendMessage(_asOutsideDoorBackground, NM_KLAYMEN_OPEN_DOOR, 0);
break;
case 0x8000:
setSpriteSurfacePriority(_ssCeiling, 995);
@@ -1383,38 +458,6 @@ uint32 Scene1002::handleMessage(int messageNum, const MessageParam &param, Entit
return messageResult;
}
-// Scene1004
-
-AsScene1004TrashCan::AsScene1004TrashCan(NeverhoodEngine *vm)
- : AnimatedSprite(vm, 1100) {
-
- _x = 330;
- _y = 327;
- createSurface(800, 56, 50);
- setVisible(false);
- SetUpdateHandler(&AnimatedSprite::update);
- SetMessageHandler(&AsScene1004TrashCan::handleMessage);
-}
-
-uint32 AsScene1004TrashCan::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x100D:
- if (param.asInteger() == 0x225A8587)
- playSound(0, 0x109AFC4C);
- break;
- case 0x2002:
- startAnimation(0xEB312C11, 0, -1);
- setVisible(true);
- break;
- case 0x3002:
- stopAnimation();
- setVisible(false);
- break;
- }
- return 0;
-}
-
Scene1004::Scene1004(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule), _paletteAreaStatus(-1) {
@@ -1478,20 +521,20 @@ uint32 Scene1004::handleMessage(int messageNum, const MessageParam &param, Entit
uint32 messageResult = 0;
Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0x926500A1) {
setMessageList(0x004B7C20);
messageResult = 1;
}
break;
- case 0x2000:
+ case NM_ANIMATION_UPDATE:
loadDataResource(0x01900A04);
break;
case 0x2001:
setRectList(0x004B7C70);
break;
- case 0x2002:
- sendMessage(_asTrashCan, 0x2002, 0);
+ case NM_POSITION_CHANGE:
+ sendMessage(_asTrashCan, NM_POSITION_CHANGE, 0);
break;
}
return messageResult;
@@ -1513,8 +556,6 @@ void Scene1004::updatePaletteArea() {
}
}
-// Scene1005
-
Scene1005::Scene1005(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule) {
@@ -1540,7 +581,7 @@ Scene1005::Scene1005(NeverhoodEngine *vm, Module *parentModule, int which)
uint32 Scene1005::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x0001:
+ case NM_MOUSE_CLICK:
if (param.asPoint().x <= 20 || param.asPoint().x >= 620)
leaveScene(0);
break;
diff --git a/engines/neverhood/modules/module1000.h b/engines/neverhood/modules/module1000.h
index 9e97e822f6..4b17c92b3b 100644
--- a/engines/neverhood/modules/module1000.h
+++ b/engines/neverhood/modules/module1000.h
@@ -29,8 +29,6 @@
namespace Neverhood {
-// Module1000
-
class Module1000 : public Module {
public:
Module1000(NeverhoodEngine *vm, Module *parentModule, int which);
@@ -42,53 +40,6 @@ protected:
void updateScene();
};
-// Scene1001
-
-class AsScene1001Door : public AnimatedSprite {
-public:
- AsScene1001Door(NeverhoodEngine *vm);
-protected:
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- void hammerHitsDoor();
- void stShowIdleDoor();
- void stBustedDoorMove();
- void stBustedDoorGone();
-};
-
-class AsScene1001Hammer : public AnimatedSprite {
-public:
- AsScene1001Hammer(NeverhoodEngine *vm, Sprite *asDoor);
-protected:
- Sprite *_asDoor;
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
-
-class AsScene1001Window : public AnimatedSprite {
-public:
- AsScene1001Window(NeverhoodEngine *vm);
-protected:
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
-
-class AsScene1001Lever : public AnimatedSprite {
-public:
- AsScene1001Lever(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y, int deltaXType);
-protected:
- Scene *_parentScene;
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
-
-class SsCommonButtonSprite : public StaticSprite {
-public:
- SsCommonButtonSprite(NeverhoodEngine *vm, Scene *parentScene, uint32 fileHash, int surfacePriority, uint32 soundFileHash);
-protected:
- Scene *_parentScene;
- uint32 _soundFileHash;
- int16 _countdown;
- void update();
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
-
class Scene1001 : public Scene {
public:
Scene1001(NeverhoodEngine *vm, Module *parentModule, int which);
@@ -102,127 +53,6 @@ protected:
uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
};
-// Scene1002
-
-class AsScene1002Ring : public AnimatedSprite {
-public:
- AsScene1002Ring(NeverhoodEngine *vm, Scene *parentScene, bool isSpecial, int16 x, int16 y, int16 clipY1, bool isRingLow);
-protected:
- Scene *_parentScene;
- bool _isSpecial;
- void update();
- uint32 hmRingIdle(int messageNum, const MessageParam &param, Entity *sender);
- uint32 hmRingPulled1(int messageNum, const MessageParam &param, Entity *sender);
- uint32 hmRingPulled2(int messageNum, const MessageParam &param, Entity *sender);
- uint32 hmRingHangingLow(int messageNum, const MessageParam &param, Entity *sender);
- uint32 hmRingReleased(int messageNum, const MessageParam &param, Entity *sender);
-};
-
-class AsScene1002Door : public StaticSprite {
-public:
- AsScene1002Door(NeverhoodEngine *vm, NRect &clipRect);
-protected:
- void update();
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- void suOpenDoor();
- void suCloseDoor();
-};
-
-class AsScene1002BoxingGloveHitEffect : public AnimatedSprite {
-public:
- AsScene1002BoxingGloveHitEffect(NeverhoodEngine *vm);
-protected:
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
-
-class AsScene1002DoorSpy : public AnimatedSprite {
-public:
- AsScene1002DoorSpy(NeverhoodEngine *vm, NRect &clipRect, Scene *parentScene, Sprite *asDoor, Sprite *asScene1002BoxingGloveHitEffect);
-protected:
- Scene *_parentScene;
- Sprite *_asDoor;
- Sprite *_asBoxingGloveHitEffect;
- NRect _clipRect;
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- uint32 hmDoorSpyAnimation(int messageNum, const MessageParam &param, Entity *sender);
- void suDoorSpy();
- void stDoorSpyIdle();
- void stDoorSpyBoxingGlove();
-};
-
-class SsCommonPressButton : public StaticSprite {
-public:
- SsCommonPressButton(NeverhoodEngine *vm, Scene *parentScene, uint32 fileHash1, uint32 fileHash2, int surfacePriority, uint32 soundFileHash);
- void setFileHashes(uint32 fileHash1, uint32 fileHash2);
-protected:
- Scene *_parentScene;
- uint32 _soundFileHash;
- uint32 _fileHashes[2];
- int _status;
- int _countdown;
- void update();
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
-
-class AsScene1002VenusFlyTrap : public AnimatedSprite {
-public:
- AsScene1002VenusFlyTrap(NeverhoodEngine *vm, Scene *parentScene, Sprite *klaymen, bool isSecond);
-protected:
- Scene *_parentScene;
- Sprite *_klaymen;
- int _countdown;
- bool _isSecond;
- void update();
- void upIdle();
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- uint32 hmAnimationSimple(int messageNum, const MessageParam &param, Entity *sender);
- uint32 hmAnimationExt(int messageNum, const MessageParam &param, Entity *sender);
- void stWalkBack();
- void stWalk();
- void stRelease();
- void stGrabRing();
- void stRingGrabbed();
- void stKlaymenInside();
- void stIdle();
- void stKlaymenInsideMoving();
- void stSpitOutKlaymen();
- void swallowKlaymen();
-};
-
-class AsScene1002OutsideDoorBackground : public AnimatedSprite {
-public:
- AsScene1002OutsideDoorBackground(NeverhoodEngine *vm);
-protected:
- int _countdown;
- bool _isDoorClosed;
- void update();
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- uint32 hmAnimation(int messageNum, const MessageParam &param, Entity *sender);
- void stOpenDoor();
- void stCloseDoor();
- void stDoorClosed();
-};
-
-class AsScene1002KlaymenLadderHands : public AnimatedSprite {
-public:
- AsScene1002KlaymenLadderHands(NeverhoodEngine *vm, Klaymen *klaymen);
-protected:
- Klaymen *_klaymen;
- void update();
-};
-
-class AsScene1002KlaymenPeekHand : public AnimatedSprite {
-public:
- AsScene1002KlaymenPeekHand(NeverhoodEngine *vm, Scene *parentScene, Klaymen *klaymen);
-protected:
- Scene *_parentScene;
- Klaymen *_klaymen;
- bool _isClipRectSaved;
- NRect _savedClipRect;
- void update();
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
-
class Scene1002 : public Scene {
public:
Scene1002(NeverhoodEngine *vm, Module *parentModule, int which);
@@ -251,15 +81,6 @@ protected:
uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
};
-// Scene1004
-
-class AsScene1004TrashCan : public AnimatedSprite {
-public:
- AsScene1004TrashCan(NeverhoodEngine *vm);
-protected:
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
-
class Scene1004 : public Scene {
public:
Scene1004(NeverhoodEngine *vm, Module *parentModule, int which);
@@ -272,8 +93,6 @@ protected:
void updatePaletteArea();
};
-// Scene1005
-
class Scene1005 : public Scene {
public:
Scene1005(NeverhoodEngine *vm, Module *parentModule, int which);
diff --git a/engines/neverhood/modules/module1000_sprites.cpp b/engines/neverhood/modules/module1000_sprites.cpp
new file mode 100644
index 0000000000..a028df4b10
--- /dev/null
+++ b/engines/neverhood/modules/module1000_sprites.cpp
@@ -0,0 +1,1632 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public 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 "neverhood/modules/module1000_sprites.h"
+
+namespace Neverhood {
+
+AsScene1001Door::AsScene1001Door(NeverhoodEngine *vm)
+ : AnimatedSprite(vm, 1100) {
+
+ createSurface(800, 137, 242);
+ _x = 726;
+ _y = 440;
+ stShowIdleDoor();
+ loadSound(1, 0xED403E03);
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsScene1001Door::handleMessage);
+}
+
+uint32 AsScene1001Door::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case NM_ANIMATION_UPDATE:
+ hammerHitsDoor();
+ break;
+ case NM_ANIMATION_STOP:
+ gotoNextState();
+ break;
+ }
+ return 0;
+}
+
+void AsScene1001Door::hammerHitsDoor() {
+ switch (getGlobalVar(V_DOOR_STATUS)) {
+ case 0:
+ case 1:
+ playSound(0, 0x65482F03);
+ startAnimation(0x624C0498, 1, 3);
+ NextState(&AsScene1001Door::stShowIdleDoor);
+ break;
+ case 2:
+ playSound(1);
+ startAnimation(0x624C0498, 6, 6);
+ NextState(&AsScene1001Door::stBustedDoorMove);
+ break;
+ default:
+ // Nothing
+ break;
+ }
+ incGlobalVar(V_DOOR_STATUS, 1);
+}
+
+void AsScene1001Door::stShowIdleDoor() {
+ switch (getGlobalVar(V_DOOR_STATUS)) {
+ case 1:
+ startAnimation(0x624C0498, 4, -1);
+ _newStickFrameIndex = 4;
+ break;
+ case 2:
+ startAnimation(0x624C0498, 1, -1);
+ _newStickFrameIndex = 1;
+ break;
+ case 3:
+ stopAnimation();
+ setVisible(false);
+ break;
+ default:
+ startAnimation(0x624C0498, 0, -1);
+ _newStickFrameIndex = 0;
+ break;
+ }
+}
+
+void AsScene1001Door::stBustedDoorMove() {
+ setGlobalVar(V_DOOR_BUSTED, 1);
+ startAnimation(0x624C0498, 6, 6);
+ NextState(&AsScene1001Door::stBustedDoorGone);
+ _x = 30;
+}
+
+void AsScene1001Door::stBustedDoorGone() {
+ playSound(0);
+ stopAnimation();
+ setVisible(false);
+}
+
+AsScene1001Hammer::AsScene1001Hammer(NeverhoodEngine *vm, Sprite *asDoor)
+ : AnimatedSprite(vm, 1100), _asDoor(asDoor) {
+
+ _x = 547;
+ _y = 206;
+ createSurface(900, 177, 192);
+ startAnimation(0x022C90D4, -1, -1);
+ _newStickFrameIndex = STICK_LAST_FRAME;
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsScene1001Hammer::handleMessage);
+}
+
+uint32 AsScene1001Hammer::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case NM_ANIMATION_START:
+ if (param.asInteger() == 0x00352100)
+ sendMessage(_asDoor, 0x2000, 0);
+ else if (param.asInteger() == 0x0A1A0109)
+ playSound(0, 0x66410886);
+ break;
+ case NM_ANIMATION_UPDATE:
+ startAnimation(0x022C90D4, 1, -1);
+ playSound(0, 0xE741020A);
+ _newStickFrameIndex = STICK_LAST_FRAME;
+ break;
+ }
+ return 0;
+}
+
+AsScene1001Window::AsScene1001Window(NeverhoodEngine *vm)
+ : AnimatedSprite(vm, 1200) {
+
+ _x = 320;
+ _y = 240;
+ createSurface(100, 66, 129);
+ startAnimation(0xC68C2299, 0, -1);
+ _newStickFrameIndex = 0;
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsScene1001Window::handleMessage);
+}
+
+uint32 AsScene1001Window::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case NM_ANIMATION_START:
+ if (param.asInteger() == 0x0E0A1410)
+ playSound(0, 0x60803F10);
+ break;
+ case 0x2001:
+ startAnimation(0xC68C2299, 0, -1);
+ break;
+ case NM_ANIMATION_STOP:
+ SetMessageHandler(NULL);
+ setGlobalVar(V_WINDOW_OPEN, 1);
+ setVisible(false);
+ break;
+ }
+ return 0;
+}
+
+AsScene1001Lever::AsScene1001Lever(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y, int deltaXType)
+ : AnimatedSprite(vm, 1100), _parentScene(parentScene) {
+
+ createSurface(1010, 71, 73);
+ setDoDeltaX(deltaXType);
+ startAnimation(0x04A98C36, 0, -1);
+ _newStickFrameIndex = 0;
+ _x = x;
+ _y = y;
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsScene1001Lever::handleMessage);
+}
+
+uint32 AsScene1001Lever::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case NM_ANIMATION_START:
+ if (param.asInteger() == 0x00C0C444)
+ sendMessage(_parentScene, NM_KLAYMEN_LOWER_LEVER, 0);
+ else if (param.asInteger() == 0xC41A02C0)
+ playSound(0, 0x40581882);
+ break;
+ case 0x1011:
+ sendMessage(_parentScene, 0x4826, 0);
+ messageResult = 1;
+ break;
+ case NM_ANIMATION_STOP:
+ startAnimation(0x04A98C36, 0, -1);
+ _newStickFrameIndex = 0;
+ break;
+ case NM_KLAYMEN_LOWER_LEVER:
+ startAnimation(0x04A98C36, 0, -1);
+ break;
+ case NM_MOVE_TO_BACK:
+ sendMessage(_parentScene, NM_PRIORITY_CHANGE, 990);
+ break;
+ case NM_MOVE_TO_FRONT:
+ sendMessage(_parentScene, NM_PRIORITY_CHANGE, 1010);
+ break;
+ }
+ return messageResult;
+}
+
+SsCommonButtonSprite::SsCommonButtonSprite(NeverhoodEngine *vm, Scene *parentScene, uint32 fileHash, int surfacePriority, uint32 soundFileHash)
+ : StaticSprite(vm, fileHash, surfacePriority), _parentScene(parentScene), _countdown(0) {
+
+ _priority = 1100;
+ _soundFileHash = soundFileHash ? soundFileHash : 0x44141000;
+ setVisible(false);
+ SetUpdateHandler(&SsCommonButtonSprite::update);
+ SetMessageHandler(&SsCommonButtonSprite::handleMessage);
+}
+
+void SsCommonButtonSprite::update() {
+ if (_countdown != 0 && (--_countdown) == 0)
+ setVisible(false);
+}
+
+uint32 SsCommonButtonSprite::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x480B:
+ sendMessage(_parentScene, 0x480B, 0);
+ setVisible(true);
+ _countdown = 8;
+ playSound(0, _soundFileHash);
+ break;
+ }
+ return messageResult;
+}
+
+AsScene1002Ring::AsScene1002Ring(NeverhoodEngine *vm, Scene *parentScene, bool isSpecial, int16 x, int16 y, int16 clipY1, bool isRingLow)
+ : AnimatedSprite(vm, 1100), _parentScene(parentScene), _isSpecial(isSpecial) {
+
+ SetUpdateHandler(&AsScene1002Ring::update);
+
+ if (_isSpecial) {
+ createSurface(990, 68, 314);
+ if (isRingLow) {
+ startAnimation(0x04103090, 0, -1);
+ SetMessageHandler(&AsScene1002Ring::hmRingHangingLow);
+ } else {
+ startAnimation(0xA85C4011, _vm->_rnd->getRandomNumber(15), -1);
+ SetMessageHandler(&AsScene1002Ring::hmRingIdle);
+ }
+ } else {
+ createSurface(990, 68, 138);
+ startAnimation(0xA85C4011, _vm->_rnd->getRandomNumber(15), -1);
+ SetMessageHandler(&AsScene1002Ring::hmRingIdle);
+ }
+
+ setClipRect(0, clipY1, 640, 480);
+
+ _x = x;
+ _y = y;
+
+ setDoDeltaX(_vm->_rnd->getRandomNumber(1));
+
+}
+
+void AsScene1002Ring::update() {
+ updateAnim();
+ updatePosition();
+}
+
+uint32 AsScene1002Ring::hmRingIdle(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case NM_KLAYMEN_USE_OBJECT:
+ setDoDeltaX(((Sprite*)sender)->isDoDeltaX() ? 1 : 0);
+ sendMessage(_parentScene, NM_KLAYMEN_USE_OBJECT, 0);
+ SetMessageHandler(&AsScene1002Ring::hmRingPulled1);
+ startAnimation(_isSpecial ? 0x87502558 : 0x80DD4010, 0, -1);
+ break;
+ case NM_KLAYMEN_LOWER_LEVER:
+ setDoDeltaX(((Sprite*)sender)->isDoDeltaX() ? 1 : 0);
+ sendMessage(_parentScene, NM_KLAYMEN_LOWER_LEVER, 0);
+ SetMessageHandler(&AsScene1002Ring::hmRingPulled2);
+ startAnimation(0x861A2020, 0, -1);
+ break;
+ case NM_MOVE_TO_BACK:
+ sendMessage(_parentScene, NM_PRIORITY_CHANGE, 990);
+ break;
+ case NM_MOVE_TO_FRONT:
+ sendMessage(_parentScene, NM_PRIORITY_CHANGE, 1010);
+ break;
+ }
+ return messageResult;
+}
+
+uint32 AsScene1002Ring::hmRingPulled1(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case NM_ANIMATION_STOP:
+ startAnimation(_isSpecial ? 0x78D0A812 : 0xB85D2A10, 0, -1);
+ SetMessageHandler(&AsScene1002Ring::hmRingHangingLow);
+ break;
+ case NM_KLAYMEN_RAISE_LEVER:
+ sendMessage(_parentScene, NM_KLAYMEN_RAISE_LEVER, 0);
+ setDoDeltaX(_vm->_rnd->getRandomNumber(1));
+ startAnimation(0x8258A030, 0, -1);
+ SetMessageHandler(&AsScene1002Ring::hmRingReleased);
+ break;
+ case NM_MOVE_TO_BACK:
+ sendMessage(_parentScene, NM_PRIORITY_CHANGE, 990);
+ break;
+ case NM_MOVE_TO_FRONT:
+ sendMessage(_parentScene, NM_PRIORITY_CHANGE, 1010);
+ break;
+ }
+ return messageResult;
+}
+
+uint32 AsScene1002Ring::hmRingPulled2(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case NM_ANIMATION_STOP:
+ startAnimation(0x04103090, 0, -1);
+ SetMessageHandler(&AsScene1002Ring::hmRingHangingLow);
+ break;
+ case NM_MOVE_TO_BACK:
+ sendMessage(_parentScene, NM_PRIORITY_CHANGE, 990);
+ break;
+ case NM_MOVE_TO_FRONT:
+ sendMessage(_parentScene, NM_PRIORITY_CHANGE, 1010);
+ break;
+ }
+ return messageResult;
+}
+
+uint32 AsScene1002Ring::hmRingHangingLow(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case NM_KLAYMEN_RAISE_LEVER:
+ sendMessage(_parentScene, NM_KLAYMEN_RAISE_LEVER, 0);
+ setDoDeltaX(_vm->_rnd->getRandomNumber(1));
+ startAnimation(0x8258A030, 0, -1);
+ SetMessageHandler(&AsScene1002Ring::hmRingReleased);
+ break;
+ case NM_MOVE_TO_BACK:
+ sendMessage(_parentScene, NM_PRIORITY_CHANGE, 990);
+ break;
+ case NM_MOVE_TO_FRONT:
+ sendMessage(_parentScene, NM_PRIORITY_CHANGE, 1010);
+ break;
+ }
+ return messageResult;
+}
+
+uint32 AsScene1002Ring::hmRingReleased(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = hmRingIdle(messageNum, param, sender);
+ switch (messageNum) {
+ case NM_ANIMATION_START:
+ if (param.asInteger() == 0x05410F72)
+ playSound(0, 0x21EE40A9);
+ break;
+ case NM_ANIMATION_STOP:
+ startAnimation(0xA85C4011, 0, -1);
+ break;
+ case NM_MOVE_TO_BACK:
+ sendMessage(_parentScene, NM_PRIORITY_CHANGE, 990);
+ break;
+ case NM_MOVE_TO_FRONT:
+ sendMessage(_parentScene, NM_PRIORITY_CHANGE, 1010);
+ break;
+ }
+ return messageResult;
+}
+
+AsScene1002Door::AsScene1002Door(NeverhoodEngine *vm, NRect &clipRect)
+ : StaticSprite(vm, 1200) {
+
+ loadSprite(0x1052370F, kSLFDefDrawOffset | kSLFSetPosition, 800, 526, getGlobalVar(V_FLYTRAP_RING_DOOR) ? 49 : 239);
+ setClipRect(clipRect);
+ SetUpdateHandler(&AsScene1002Door::update);
+ SetMessageHandler(&AsScene1002Door::handleMessage);
+ SetSpriteUpdate(NULL);
+}
+
+void AsScene1002Door::update() {
+ handleSpriteUpdate();
+ updatePosition();
+}
+
+uint32 AsScene1002Door::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case NM_KLAYMEN_OPEN_DOOR:
+ setGlobalVar(V_FLYTRAP_RING_DOOR, 1);
+ SetSpriteUpdate(&AsScene1002Door::suOpenDoor);
+ break;
+ case NM_KLAYMEN_CLOSE_DOOR:
+ setGlobalVar(V_FLYTRAP_RING_DOOR, 0);
+ SetSpriteUpdate(&AsScene1002Door::suCloseDoor);
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene1002Door::suOpenDoor() {
+ if (_y > 49) {
+ _y -= 8;
+ if (_y < 49) {
+ SetSpriteUpdate(NULL);
+ _y = 49;
+ }
+ _needRefresh = true;
+ }
+}
+
+void AsScene1002Door::suCloseDoor() {
+ if (_y < 239) {
+ _y += 8;
+ if (_y > 239) {
+ SetSpriteUpdate(NULL);
+ _y = 239;
+ }
+ _needRefresh = true;
+ }
+}
+
+AsScene1002BoxingGloveHitEffect::AsScene1002BoxingGloveHitEffect(NeverhoodEngine *vm)
+ : AnimatedSprite(vm, 1400) {
+
+ createSurface(1025, 88, 165);
+ setVisible(false);
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsScene1002BoxingGloveHitEffect::handleMessage);
+}
+
+uint32 AsScene1002BoxingGloveHitEffect::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x2004:
+ _x = ((Sprite*)sender)->getX() - 98;
+ _y = ((Sprite*)sender)->getY() - 111;
+ startAnimation(0x0422255A, 0, -1);
+ setVisible(true);
+ break;
+ case NM_ANIMATION_STOP:
+ stopAnimation();
+ setVisible(false);
+ break;
+ }
+ return messageResult;
+}
+
+AsScene1002DoorSpy::AsScene1002DoorSpy(NeverhoodEngine *vm, NRect &clipRect, Scene *parentScene, Sprite *asDoor, Sprite *asScene1002BoxingGloveHitEffect)
+ : AnimatedSprite(vm, 1300), _clipRect(clipRect), _parentScene(parentScene), _asDoor(asDoor), _asBoxingGloveHitEffect(asScene1002BoxingGloveHitEffect) {
+
+ createSurface(800, 136, 147);
+ setClipRect(clipRect);
+ suDoorSpy();
+ loadSound(0, 0xC0C40298);
+ startAnimation(0x586C1D48, 0, 0);
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsScene1002DoorSpy::handleMessage);
+ SetSpriteUpdate(&AsScene1002DoorSpy::suDoorSpy);
+}
+
+uint32 AsScene1002DoorSpy::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case NM_ANIMATION_START:
+ if (param.asInteger() == 0xA61CA1C2)
+ sendMessage(_asBoxingGloveHitEffect, 0x2004, 0);
+ else if (param.asInteger() == 0x14CE0620)
+ playSound(0);
+ break;
+ case 0x2003:
+ stDoorSpyBoxingGlove();
+ break;
+ }
+ return messageResult;
+}
+
+uint32 AsScene1002DoorSpy::hmDoorSpyAnimation(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case NM_ANIMATION_STOP:
+ gotoNextState();
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene1002DoorSpy::suDoorSpy() {
+ _x = _asDoor->getX() + 34;
+ _y = _asDoor->getY() + 175;
+}
+
+void AsScene1002DoorSpy::stDoorSpyIdle() {
+ setClipRect(_clipRect);
+ _parentScene->setSurfacePriority(getSurface(), 800);
+ startAnimation(0x586C1D48, 0, 0);
+ SetMessageHandler(&AsScene1002DoorSpy::handleMessage);
+}
+
+void AsScene1002DoorSpy::stDoorSpyBoxingGlove() {
+ setClipRect(0, 0, 640, 480);
+ _parentScene->setSurfacePriority(getSurface(), 1200);
+ startAnimation(0x586C1D48, 1, -1);
+ SetMessageHandler(&AsScene1002DoorSpy::hmDoorSpyAnimation);
+ NextState(&AsScene1002DoorSpy::stDoorSpyIdle);
+}
+
+SsCommonPressButton::SsCommonPressButton(NeverhoodEngine *vm, Scene *parentScene, uint32 fileHash1, uint32 fileHash2, int surfacePriority, uint32 soundFileHash)
+ : StaticSprite(vm, 1100), _parentScene(parentScene), _status(0), _countdown(0) {
+
+ _soundFileHash = soundFileHash != 0 ? soundFileHash : 0x44141000;
+ _fileHashes[0] = fileHash1;
+ _fileHashes[1] = fileHash2;
+ createSurface(surfacePriority, 40, 40);
+ loadSprite(fileHash1, kSLFDefDrawOffset | kSLFDefPosition);
+ setVisible(false);
+ SetUpdateHandler(&SsCommonPressButton::update);
+ SetMessageHandler(&SsCommonPressButton::handleMessage);
+}
+
+void SsCommonPressButton::setFileHashes(uint32 fileHash1, uint32 fileHash2) {
+ _fileHashes[0] = fileHash1;
+ _fileHashes[1] = fileHash2;
+ loadSprite(_status == 2 ? fileHash2 : fileHash1, kSLFDefDrawOffset | kSLFDefPosition);
+}
+
+void SsCommonPressButton::update() {
+ if (_countdown != 0 && (--_countdown) == 0) {
+ if (_status == 1) {
+ _status = 2;
+ loadSprite(_fileHashes[1], kSLFDefDrawOffset | kSLFDefPosition);
+ _countdown = 4;
+ } else if (_status == 2) {
+ _status = 3;
+ loadSprite(_fileHashes[0], kSLFDefDrawOffset | kSLFDefPosition);
+ _countdown = 4;
+ } else if (_status == 3) {
+ _status = 0;
+ setVisible(false);
+ }
+ }
+}
+
+uint32 SsCommonPressButton::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x480B:
+ sendMessage(_parentScene, 0x480B, 0);
+ _status = 1;
+ _countdown = 4;
+ setVisible(true);
+ playSound(0, _soundFileHash);
+ break;
+ }
+ return messageResult;
+}
+
+AsScene1002VenusFlyTrap::AsScene1002VenusFlyTrap(NeverhoodEngine *vm, Scene *parentScene, Sprite *klaymen, bool isSecond)
+ : AnimatedSprite(vm, 1100), _parentScene(parentScene), _klaymen(klaymen), _isSecond(isSecond), _countdown(0) {
+
+ createSurface(995, 175, 195);
+ if (!_isSecond) {
+ if (getGlobalVar(V_FLYTRAP_RING_DOOR)) {
+ setDoDeltaX(1);
+ _x = 366;
+ _y = 435;
+ stRingGrabbed();
+ } else {
+ _x = 174 + getGlobalVar(V_FLYTRAP_POSITION_1) * 32;
+ _y = 435;
+ stIdle();
+ }
+ } else {
+ _x = 186 + getGlobalVar(V_FLYTRAP_POSITION_2) * 32;
+ _y = 364;
+ if (getGlobalVar(V_FLYTRAP_RING_BRIDGE) || getGlobalVar(V_FLYTRAP_RING_FENCE)) {
+ stRingGrabbed();
+ } else {
+ stIdle();
+ }
+ }
+ _flags = 4;
+ SetUpdateHandler(&AsScene1002VenusFlyTrap::update);
+ SetMessageHandler(&AsScene1002VenusFlyTrap::handleMessage);
+ SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
+}
+
+void AsScene1002VenusFlyTrap::update() {
+ if (_countdown != 0 && (--_countdown == 0))
+ gotoNextState();
+ AnimatedSprite::update();
+}
+
+void AsScene1002VenusFlyTrap::upIdle() {
+ if (_countdown == 0 && _klaymen->getX() - 20 > _x)
+ setDoDeltaX(1);
+ else if (_klaymen->getX() + 20 < _x)
+ setDoDeltaX(0);
+ update();
+}
+
+uint32 AsScene1002VenusFlyTrap::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case NM_ANIMATION_START:
+ if (param.asInteger() == 0x000890C4)
+ playSound(0, 0xC21190D8);
+ else if (param.asInteger() == 0x522200A0)
+ playSound(0, 0x931080C8);
+ break;
+ case 0x1011:
+ if (_isSecond) {
+ if (_x >= 154 && _x <= 346) {
+ sendMessage(_parentScene, 0x2000, 0);
+ messageResult = 1;
+ }
+ } else {
+ if (_x >= 174 && _x <= 430) {
+ sendMessage(_parentScene, 0x2000, 0);
+ messageResult = 1;
+ }
+ }
+ break;
+ case 0x480B:
+ setDoDeltaX(param.asInteger() != 0 ? 1 : 0);
+ if (!_isSecond) {
+ if (getGlobalVar(V_FLYTRAP_RING_DOOR))
+ stRelease();
+ else
+ stWalk();
+ } else {
+ if (getGlobalVar(V_FLYTRAP_RING_BRIDGE) || getGlobalVar(V_FLYTRAP_RING_FENCE))
+ stRelease();
+ else
+ stWalk();
+ }
+ break;
+ case 0x480C:
+ if (_isSecond) {
+ if (_x >= 154 && _x <= 346)
+ messageResult = 1;
+ else
+ messageResult = 0;
+ } else {
+ if (_x >= 174 && _x <= 430)
+ messageResult = 1;
+ else
+ messageResult = 0;
+ }
+ break;
+ case 0x480E:
+ if (param.asInteger() == 1)
+ stGrabRing();
+ break;
+ case 0x4810:
+ swallowKlaymen();
+ break;
+ case NM_MOVE_TO_BACK:
+ sendMessage(_parentScene, NM_PRIORITY_CHANGE, 995);
+ break;
+ case NM_MOVE_TO_FRONT:
+ sendMessage(_parentScene, NM_PRIORITY_CHANGE, 1015);
+ break;
+ }
+ return messageResult;
+}
+
+uint32 AsScene1002VenusFlyTrap::hmAnimationSimple(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case NM_ANIMATION_STOP:
+ gotoNextState();
+ break;
+ }
+ return messageResult;
+}
+
+uint32 AsScene1002VenusFlyTrap::hmAnimationExt(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case NM_ANIMATION_START:
+ if (param.asInteger() == 0x000890C4)
+ playSound(0, 0xC21190D8);
+ else if (param.asInteger() == 0x41881801) {
+ if (_isSecond) {
+ if (_x > 330)
+ sendMessage(_klaymen, 0x4811, 2);
+ else
+ sendMessage(_klaymen, 0x4811, 0);
+ } else {
+ sendMessage(_klaymen, 0x4811, 0);
+ }
+ } else if (param.asInteger() == 0x522200A0)
+ playSound(0, 0x931080C8);
+ break;
+ case NM_ANIMATION_STOP:
+ gotoNextState();
+ break;
+ case NM_MOVE_TO_BACK:
+ sendMessage(_parentScene, NM_PRIORITY_CHANGE, 995);
+ break;
+ case NM_MOVE_TO_FRONT:
+ sendMessage(_parentScene, NM_PRIORITY_CHANGE, 1015);
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene1002VenusFlyTrap::stWalkBack() {
+ setDoDeltaX(2);
+ startAnimation(0xC4080034, 0, -1);
+ SetUpdateHandler(&AsScene1002VenusFlyTrap::update);
+ SetMessageHandler(&AsScene1002VenusFlyTrap::hmAnimationExt);
+ NextState(&AsScene1002VenusFlyTrap::stIdle);
+}
+
+void AsScene1002VenusFlyTrap::stWalk() {
+ startAnimation(0xC4080034, 0, -1);
+ SetUpdateHandler(&AsScene1002VenusFlyTrap::update);
+ SetMessageHandler(&AsScene1002VenusFlyTrap::hmAnimationSimple);
+ NextState(&AsScene1002VenusFlyTrap::stIdle);
+}
+
+void AsScene1002VenusFlyTrap::stRelease() {
+ sendMessage(_parentScene, NM_KLAYMEN_RAISE_LEVER, 0);
+ startAnimation(0x82292851, 0, -1);
+ SetUpdateHandler(&AsScene1002VenusFlyTrap::update);
+ SetMessageHandler(&AsScene1002VenusFlyTrap::hmAnimationSimple);
+ NextState(&AsScene1002VenusFlyTrap::stIdle);
+}
+
+void AsScene1002VenusFlyTrap::stGrabRing() {
+ setDoDeltaX(1);
+ startAnimation(0x86A82A11, 0, -1);
+ SetUpdateHandler(&AsScene1002VenusFlyTrap::update);
+ SetMessageHandler(&AsScene1002VenusFlyTrap::hmAnimationSimple);
+ NextState(&AsScene1002VenusFlyTrap::stRingGrabbed);
+}
+
+void AsScene1002VenusFlyTrap::stRingGrabbed() {
+ startAnimation(0xB5A86034, 0, -1);
+ SetUpdateHandler(&AsScene1002VenusFlyTrap::update);
+ SetMessageHandler(&AsScene1002VenusFlyTrap::handleMessage);
+}
+
+void AsScene1002VenusFlyTrap::stKlaymenInside() {
+ startAnimation(0x31303094, 0, -1);
+ SetUpdateHandler(&AsScene1002VenusFlyTrap::update);
+ SetMessageHandler(NULL);
+ NextState(&AsScene1002VenusFlyTrap::stKlaymenInsideMoving);
+ _countdown = 24;
+}
+
+void AsScene1002VenusFlyTrap::stIdle() {
+ startAnimation(0xC8204250, 0, -1);
+ SetUpdateHandler(&AsScene1002VenusFlyTrap::upIdle);
+ SetMessageHandler(&AsScene1002VenusFlyTrap::handleMessage);
+ if (_isSecond) {
+ if (_x >= 154 && _x <= 346)
+ setGlobalVar(V_FLYTRAP_POSITION_2, (_x - 186) / 32);
+ else {
+ NextState(&AsScene1002VenusFlyTrap::stWalkBack);
+ _countdown = 12;
+ }
+ } else {
+ if (_x >= 174 && _x <= 430)
+ setGlobalVar(V_FLYTRAP_POSITION_1, (_x - 174) / 32);
+ else {
+ NextState(&AsScene1002VenusFlyTrap::stWalkBack);
+ _countdown = 12;
+ }
+ }
+}
+
+void AsScene1002VenusFlyTrap::stKlaymenInsideMoving() {
+ startAnimation(0x152920C4, 0, -1);
+ SetUpdateHandler(&AsScene1002VenusFlyTrap::update);
+ SetMessageHandler(&AsScene1002VenusFlyTrap::hmAnimationExt);
+ NextState(&AsScene1002VenusFlyTrap::stSpitOutKlaymen);
+}
+
+void AsScene1002VenusFlyTrap::stSpitOutKlaymen() {
+ startAnimation(0x84001117, 0, -1);
+ SetUpdateHandler(&AsScene1002VenusFlyTrap::update);
+ SetMessageHandler(&AsScene1002VenusFlyTrap::hmAnimationExt);
+ NextState(&AsScene1002VenusFlyTrap::stIdle);
+}
+
+void AsScene1002VenusFlyTrap::swallowKlaymen() {
+ if (_x - 15 < _klaymen->getX() && _x + 15 > _klaymen->getX()) {
+ if (_isSecond)
+ setDoDeltaX(_x > 265 && _x < 330 ? 1 : 0);
+ else
+ setDoDeltaX(_x > 320 ? 1 : 0);
+ sendMessage(_klaymen, 0x2001, 0);
+ startAnimation(0x8C2C80D4, 0, -1);
+ SetUpdateHandler(&AsScene1002VenusFlyTrap::update);
+ SetMessageHandler(&AsScene1002VenusFlyTrap::hmAnimationExt);
+ NextState(&AsScene1002VenusFlyTrap::stKlaymenInside);
+ }
+}
+
+AsScene1002OutsideDoorBackground::AsScene1002OutsideDoorBackground(NeverhoodEngine *vm)
+ : AnimatedSprite(vm, 1200), _countdown(0), _isDoorClosed(true) {
+
+ createSurface(850, 186, 212);
+ _x = 320;
+ _y = 240;
+ if (getGlobalVar(V_FLYTRAP_RING_DOOR)) {
+ startAnimation(0x004A4495, -1, -1);
+ _newStickFrameIndex = STICK_LAST_FRAME;
+ } else
+ setVisible(false);
+ SetUpdateHandler(&AsScene1002OutsideDoorBackground::update);
+ SetMessageHandler(&AsScene1002OutsideDoorBackground::handleMessage);
+}
+
+void AsScene1002OutsideDoorBackground::update() {
+ if (_countdown != 0 && (--_countdown == 0)) {
+ if (_isDoorClosed)
+ stCloseDoor();
+ else
+ stOpenDoor();
+ }
+ AnimatedSprite::update();
+}
+
+uint32 AsScene1002OutsideDoorBackground::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageResult) {
+ case NM_KLAYMEN_OPEN_DOOR:
+ _isDoorClosed = false;
+ _countdown = 2;
+ break;
+ case NM_KLAYMEN_CLOSE_DOOR:
+ _isDoorClosed = true;
+ _countdown = 2;
+ break;
+ }
+ return messageResult;
+}
+
+uint32 AsScene1002OutsideDoorBackground::hmAnimation(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = handleMessage(messageNum, param, sender);
+ switch (messageResult) {
+ case NM_ANIMATION_STOP:
+ gotoNextState();
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene1002OutsideDoorBackground::stOpenDoor() {
+ startAnimation(0x004A4495, 0, -1);
+ _newStickFrameIndex = STICK_LAST_FRAME;
+ setVisible(true);
+ SetMessageHandler(&AsScene1002OutsideDoorBackground::handleMessage);
+}
+
+void AsScene1002OutsideDoorBackground::stCloseDoor() {
+ startAnimation(0x004A4495, -1, -1);
+ _playBackwards = true;
+ setVisible(true);
+ SetMessageHandler(&AsScene1002OutsideDoorBackground::hmAnimation);
+ NextState(&AsScene1002OutsideDoorBackground::stDoorClosed);
+}
+
+void AsScene1002OutsideDoorBackground::stDoorClosed() {
+ setVisible(false);
+ stopAnimation();
+}
+
+AsScene1002KlaymenLadderHands::AsScene1002KlaymenLadderHands(NeverhoodEngine *vm, Klaymen *klaymen)
+ : AnimatedSprite(vm, 1200), _klaymen(klaymen) {
+
+ createSurface(1200, 40, 163);
+ setVisible(false);
+ SetUpdateHandler(&AsScene1002KlaymenLadderHands::update);
+ SetMessageHandler(&Sprite::handleMessage);
+}
+
+void AsScene1002KlaymenLadderHands::update() {
+ if (_klaymen->getCurrAnimFileHash() == 0x3A292504) {
+ startAnimation(0xBA280522, _klaymen->getFrameIndex(), -1);
+ _newStickFrameIndex = _klaymen->getFrameIndex();
+ setVisible(true);
+ _x = _klaymen->getX();
+ _y = _klaymen->getY();
+ setDoDeltaX(_klaymen->isDoDeltaX() ? 1 : 0);
+ } else if (_klaymen->getCurrAnimFileHash() == 0x122D1505) {
+ startAnimation(0x1319150C, _klaymen->getFrameIndex(), -1);
+ _newStickFrameIndex = _klaymen->getFrameIndex();
+ setVisible(true);
+ _x = _klaymen->getX();
+ _y = _klaymen->getY();
+ setDoDeltaX(_klaymen->isDoDeltaX() ? 1 : 0);
+ } else
+ setVisible(false);
+ AnimatedSprite::update();
+}
+
+AsScene1002KlaymenPeekHand::AsScene1002KlaymenPeekHand(NeverhoodEngine *vm, Scene *parentScene, Klaymen *klaymen)
+ : AnimatedSprite(vm, 1200), _parentScene(parentScene), _klaymen(klaymen),
+ _isClipRectSaved(false) {
+
+ createSurface(1000, 33, 41);
+ setVisible(false);
+ SetUpdateHandler(&AsScene1002KlaymenPeekHand::update);
+ SetMessageHandler(&AsScene1002KlaymenPeekHand::handleMessage);
+}
+
+void AsScene1002KlaymenPeekHand::update() {
+ if (_klaymen->getCurrAnimFileHash() == 0xAC20C012 && _klaymen->getFrameIndex() < 50) {
+ startAnimation(0x9820C913, _klaymen->getFrameIndex(), -1);
+ _newStickFrameIndex = _klaymen->getFrameIndex();
+ setVisible(true);
+ _x = _klaymen->getX();
+ _y = _klaymen->getY();
+ setDoDeltaX(_klaymen->isDoDeltaX() ? 1 : 0);
+ } else
+ setVisible(false);
+ AnimatedSprite::update();
+}
+
+uint32 AsScene1002KlaymenPeekHand::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case NM_ANIMATION_START:
+ if (param.asInteger() == 0x4AB28209) {
+ sendMessage(_parentScene, NM_PRIORITY_CHANGE, 1200);
+ _isClipRectSaved = true;
+ _savedClipRect = _surface->getClipRect();
+ setClipRect(0, 0, 640, 480);
+ } else if (param.asInteger() == 0x88001184) {
+ sendMessage(_parentScene, NM_PRIORITY_CHANGE, 1000);
+ if (_isClipRectSaved)
+ setClipRect(_savedClipRect);
+ }
+ break;
+ }
+ return messageResult;
+}
+
+AsScene1004TrashCan::AsScene1004TrashCan(NeverhoodEngine *vm)
+ : AnimatedSprite(vm, 1100) {
+
+ _x = 330;
+ _y = 327;
+ createSurface(800, 56, 50);
+ setVisible(false);
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsScene1004TrashCan::handleMessage);
+}
+
+uint32 AsScene1004TrashCan::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case NM_ANIMATION_START:
+ if (param.asInteger() == 0x225A8587)
+ playSound(0, 0x109AFC4C);
+ break;
+ case NM_POSITION_CHANGE:
+ startAnimation(0xEB312C11, 0, -1);
+ setVisible(true);
+ break;
+ case NM_ANIMATION_STOP:
+ stopAnimation();
+ setVisible(false);
+ break;
+ }
+ return 0;
+}
+
+static const KlaymenIdleTableItem klaymenIdleTable1002[] = {
+ {1, kIdlePickEar},
+ {2, kIdleWonderAbout}
+};
+
+KmScene1001::KmScene1001(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
+ : Klaymen(vm, parentScene, x, y) {
+}
+
+uint32 KmScene1001::xHandleMessage(int messageNum, const MessageParam &param) {
+ switch (messageNum) {
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case NM_KLAYMEN_STAND_IDLE:
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x4804:
+ if (param.asInteger() == 2)
+ GotoState(&KmScene1001::stSleeping);
+ break;
+ case 0x480D:
+ GotoState(&KmScene1001::stPullHammerLever);
+ break;
+ case NM_KLAYMEN_PICKUP:
+ GotoState(&Klaymen::stPickUpGeneric);
+ break;
+ case NM_KLAYMEN_PRESS_BUTTON:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stPressButton);
+ else if (param.asInteger() == 2)
+ GotoState(&Klaymen::stPressFloorButton);
+ else
+ GotoState(&Klaymen::stPressButtonSide);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ gotoNextStateExt();
+ break;
+ case 0x481B:
+ if (param.asPoint().y != 0)
+ startWalkToXDistance(param.asPoint().y, param.asPoint().x);
+ else
+ startWalkToAttachedSpriteXDistance(param.asPoint().x);
+ break;
+ case 0x481F:
+ if (param.asInteger() == 0)
+ GotoState(&Klaymen::stWonderAboutHalf);
+ else if (param.asInteger() == 1)
+ GotoState(&Klaymen::stWonderAboutAfter);
+ else if (param.asInteger() == 3)
+ GotoState(&Klaymen::stTurnToUseHalf);
+ else if (param.asInteger() == 4)
+ GotoState(&Klaymen::stTurnAwayFromUse);
+ else
+ GotoState(&Klaymen::stWonderAbout);
+ break;
+ case 0x482D:
+ setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
+ gotoNextStateExt();
+ break;
+ case 0x4836:
+ if (param.asInteger() == 1) {
+ sendMessage(_parentScene, NM_POSITION_CHANGE, 0);
+ GotoState(&KmScene1001::stWakeUp);
+ }
+ break;
+ case 0x483F:
+ startSpecialWalkRight(param.asInteger());
+ break;
+ case 0x4840:
+ startSpecialWalkLeft(param.asInteger());
+ break;
+ }
+ return 0;
+}
+
+void KmScene1001::stWakeUp() {
+ _busyStatus = 1;
+ _acceptInput = false;
+ startAnimation(0x527AC970, 0, -1);
+ SetUpdateHandler(&Klaymen::update);
+ SetMessageHandler(&Klaymen::hmLowLevelAnimation);
+ SetSpriteUpdate(NULL);
+}
+
+void KmScene1001::stSleeping() {
+ _busyStatus = 0;
+ _acceptInput = true;
+ startAnimation(0x5A38C110, 0, -1);
+ SetUpdateHandler(&Klaymen::update);
+ SetMessageHandler(&KmScene1001::hmSleeping);
+ SetSpriteUpdate(NULL);
+}
+
+uint32 KmScene1001::hmSleeping(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = hmLowLevel(messageNum, param, sender);
+ switch (messageNum) {
+ case NM_ANIMATION_START:
+ if (param.asInteger() == 0x03060012) {
+ playSound(0, 0xC0238244);
+ }
+ break;
+ }
+ return messageResult;
+}
+
+void KmScene1001::stPullHammerLever() {
+ if (!stStartAction(AnimationCallback(&KmScene1001::stPullHammerLever))) {
+ _busyStatus = 2;
+ _acceptInput = false;
+ startAnimation(0x00648953, 0, -1);
+ SetUpdateHandler(&Klaymen::update);
+ SetMessageHandler(&KmScene1001::hmPullHammerLever);
+ SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
+ }
+}
+
+uint32 KmScene1001::hmPullHammerLever(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Klaymen::hmLever(messageNum, param, sender);
+ switch (messageNum) {
+ case NM_ANIMATION_START:
+ if (param.asInteger() == 0x4AB28209)
+ sendMessage(_attachedSprite, NM_KLAYMEN_LOWER_LEVER, 0);
+ break;
+ }
+ return messageResult;
+}
+
+KmScene1002::KmScene1002(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
+ : Klaymen(vm, parentScene, x, y) {
+
+ setKlaymenIdleTable1();
+}
+
+void KmScene1002::xUpdate() {
+ if (_x >= 250 && _x <= 435 && _y >= 420) {
+ if (_idleTableNum == 0) {
+ setKlaymenIdleTable(klaymenIdleTable1002, ARRAYSIZE(klaymenIdleTable1002));
+ _idleTableNum = 1;
+ }
+ } else if (_idleTableNum == 1) {
+ setKlaymenIdleTable1();
+ _idleTableNum = 0;
+ }
+}
+
+uint32 KmScene1002::xHandleMessage(int messageNum, const MessageParam &param) {
+ switch (messageNum) {
+ case 0x2001:
+ GotoState(&Klaymen::stStandIdleSpecial);
+ break;
+ case NM_CAR_MOVE_TO_PREV_POINT:
+ _otherSprite = (Sprite*)param.asEntity();
+ break;
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case NM_KLAYMEN_STAND_IDLE:
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x4803:
+ if (param.asInteger() == 1)
+ GotoState(&KmScene1002::stJumpAndFall);
+ else if (param.asInteger() == 2)
+ GotoState(&KmScene1002::stDropFromRing);
+ break;
+ case 0x4804:
+ GotoState(&Klaymen::stPeekWall);
+ break;
+ case 0x4805:
+ switch (param.asInteger()) {
+ case 1:
+ GotoState(&KmScene1002::stJumpToRing1);
+ break;
+ case 2:
+ GotoState(&KmScene1002::stJumpToRing2);
+ break;
+ case 3:
+ GotoState(&KmScene1002::stJumpToRing3);
+ break;
+ case 4:
+ GotoState(&KmScene1002::stJumpToRing4);
+ break;
+ }
+ break;
+ case NM_KLAYMEN_MOVE_OBJECT:
+ GotoState(&KmScene1002::stMoveVenusFlyTrap);
+ break;
+ case 0x480D:
+ GotoState(&KmScene1002::stJumpToRingVenusFlyTrap);
+ break;
+ case NM_KLAYMEN_PRESS_BUTTON:
+ if (param.asInteger() == 0)
+ GotoState(&KmScene1002::stPressDoorButton);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ gotoNextStateExt();
+ break;
+ case 0x481B:
+ startWalkToAttachedSpriteXDistance(param.asInteger());
+ break;
+ case 0x4820:
+ sendMessage(_parentScene, NM_KLAYMEN_CLIMB_LADDER, 0);
+ GotoState(&Klaymen::stContinueClimbLadderUp);
+ break;
+ case 0x4821:
+ sendMessage(_parentScene, NM_KLAYMEN_CLIMB_LADDER, 0);
+ _destY = param.asInteger();
+ GotoState(&Klaymen::stStartClimbLadderDown);
+ break;
+ case 0x4822:
+ sendMessage(_parentScene, NM_KLAYMEN_CLIMB_LADDER, 0);
+ _destY = param.asInteger();
+ GotoState(&Klaymen::stStartClimbLadderUp);
+ break;
+ case 0x4823:
+ sendMessage(_parentScene, NM_KLAYMEN_STOP_CLIMBING, 0);
+ GotoState(&Klaymen::stClimbLadderHalf);
+ break;
+ case 0x482E:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stWalkToFrontNoStep);
+ else
+ GotoState(&Klaymen::stWalkToFront);
+ break;
+ case 0x482F:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stTurnToFront);
+ else
+ GotoState(&Klaymen::stTurnToBack);
+ break;
+ case 0x483F:
+ startSpecialWalkRight(param.asInteger());
+ break;
+ case 0x4840:
+ startSpecialWalkLeft(param.asInteger());
+ break;
+ }
+ return 0;
+}
+
+void KmScene1002::setupJumpToRing() {
+ _acceptInput = false;
+ SetUpdateHandler(&Klaymen::update);
+ SetMessageHandler(&KmScene1002::hmJumpToRing);
+ SetSpriteUpdate(&Klaymen::suUpdateDestX);
+ NextState(&KmScene1002::stHangOnRing);
+ sendMessage(_attachedSprite, NM_MOVE_TO_FRONT, 0);
+}
+
+uint32 KmScene1002::hmJumpToRing(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = hmLowLevelAnimation(messageNum, param, sender);
+ switch (messageNum) {
+ case NM_ANIMATION_START:
+ if (param.asInteger() == 0x168050A0) {
+ sendMessage(_attachedSprite, NM_KLAYMEN_USE_OBJECT, 0);
+ _acceptInput = true;
+ } else if (param.asInteger() == 0x320AC306) {
+ playSound(0, 0x5860C640);
+ } else if (param.asInteger() == 0x4AB28209) {
+ sendMessage(_attachedSprite, NM_MOVE_TO_BACK, 0);
+ } else if (param.asInteger() == 0x88001184) {
+ sendMessage(_attachedSprite, NM_MOVE_TO_FRONT, 0);
+ }
+ break;
+ }
+ return messageResult;
+}
+
+void KmScene1002::stHangOnRing() {
+ _busyStatus = 0;
+ _acceptInput = true;
+ startAnimation(0x4829E0B8, 0, -1);
+ SetUpdateHandler(&Klaymen::update);
+ SetMessageHandler(&Klaymen::hmLowLevel);
+ SetSpriteUpdate(NULL);
+}
+
+void KmScene1002::stJumpToRing1() {
+ if (!stStartAction(AnimationCallback(&KmScene1002::stJumpToRing1))) {
+ _busyStatus = 0;
+ startAnimation(0xD82890BA, 0, -1);
+ setupJumpToRing();
+ }
+}
+
+void KmScene1002::stJumpToRing2() {
+ if (!stStartAction(AnimationCallback(&KmScene1002::stJumpToRing2))) {
+ _busyStatus = 0;
+ startAnimation(0x900980B2, 0, -1);
+ setupJumpToRing();
+ }
+}
+
+void KmScene1002::stJumpToRing3() {
+ if (!stStartAction(AnimationCallback(&KmScene1002::stJumpToRing3))) {
+ _busyStatus = 0;
+ _acceptInput = false;
+ startAnimation(0xBA1910B2, 0, -1);
+ SetUpdateHandler(&Klaymen::update);
+ SetSpriteUpdate(&Klaymen::suUpdateDestX);
+ SetMessageHandler(&KmScene1002::hmJumpToRing3);
+ NextState(&KmScene1002::stHoldRing3);
+ sendMessage(_attachedSprite, NM_MOVE_TO_FRONT, 0);
+ }
+}
+
+uint32 KmScene1002::hmJumpToRing3(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = hmLowLevelAnimation(messageNum, param, sender);
+ switch (messageNum) {
+ case NM_ANIMATION_START:
+ if (param.asInteger() == 0x168050A0) {
+ sendMessage(_attachedSprite, NM_KLAYMEN_USE_OBJECT, 0);
+ } else if (param.asInteger() == 0x320AC306) {
+ playSound(0, 0x5860C640);
+ } else if (param.asInteger() == 0x4AB28209) {
+ sendMessage(_attachedSprite, NM_MOVE_TO_BACK, 0);
+ } else if (param.asInteger() == 0x88001184) {
+ sendMessage(_attachedSprite, NM_MOVE_TO_FRONT, 0);
+ }
+ break;
+ }
+ return messageResult;
+}
+
+void KmScene1002::stHoldRing3() {
+ _busyStatus = 0;
+ _acceptInput = true;
+ startAnimation(0x4A293FB0, 0, -1);
+ SetUpdateHandler(&Klaymen::update);
+ SetMessageHandler(&KmScene1002::hmHoldRing3);
+ SetSpriteUpdate(NULL);
+}
+
+uint32 KmScene1002::hmHoldRing3(int messageNum, const MessageParam &param, Entity *sender) {
+ if (messageNum == 0x1008) {
+ stReleaseRing();
+ return 0;
+ }
+ return hmLowLevel(messageNum, param, sender);
+}
+
+void KmScene1002::stJumpToRing4() {
+ if (!stStartAction(AnimationCallback(&KmScene1002::stJumpToRing4))) {
+ _busyStatus = 0;
+ startAnimation(0xB8699832, 0, -1);
+ setupJumpToRing();
+ }
+}
+
+void KmScene1002::stJumpToRingVenusFlyTrap() {
+ if (!stStartAction(AnimationCallback(&KmScene1002::stJumpToRingVenusFlyTrap))) {
+ _busyStatus = 2;
+ _acceptInput = false;
+ startAnimation(0x584984B4, 0, -1);
+ SetUpdateHandler(&Klaymen::update);
+ SetMessageHandler(&KmScene1002::hmJumpToRingVenusFlyTrap);
+ SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
+ NextState(&KmScene1002::stLandOnFeet);
+ sendMessage(_attachedSprite, NM_MOVE_TO_FRONT, 0);
+ }
+}
+
+uint32 KmScene1002::hmJumpToRingVenusFlyTrap(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = hmLowLevelAnimation(messageNum, param, sender);
+ switch (messageNum) {
+ case NM_ANIMATION_START:
+ if (param.asInteger() == 0x168050A0) {
+ sendMessage(_attachedSprite, NM_KLAYMEN_LOWER_LEVER, 0);
+ } else if (param.asInteger() == 0x586B0300) {
+ sendMessage(_otherSprite, 0x480E, 1);
+ } else if (param.asInteger() == 0x4AB28209) {
+ sendMessage(_attachedSprite, NM_MOVE_TO_BACK, 0);
+ } else if (param.asInteger() == 0x88001184) {
+ sendMessage(_attachedSprite, NM_MOVE_TO_FRONT, 0);
+ }
+ break;
+ }
+ return messageResult;
+}
+
+void KmScene1002::stJumpAndFall() {
+ if (!stStartAction(AnimationCallback(&KmScene1002::stJumpAndFall))) {
+ sendMessage(_parentScene, 0x1024, 3);
+ _busyStatus = 2;
+ _acceptInput = false;
+ startAnimation(0xB93AB151, 0, -1);
+ SetUpdateHandler(&Klaymen::update);
+ SetMessageHandler(&KmScene1002::hmJumpAndFall);
+ SetSpriteUpdate(&Klaymen::suFallDown);
+ NextState(&KmScene1002::stLandOnFeet);
+ }
+}
+
+void KmScene1002::stDropFromRing() {
+ if (_attachedSprite) {
+ _x = _attachedSprite->getX();
+ sendMessage(_attachedSprite, NM_KLAYMEN_RAISE_LEVER, 0);
+ _attachedSprite = NULL;
+ }
+ _busyStatus = 2;
+ _acceptInput = false;
+ startAnimation(0x586984B1, 0, -1);
+ SetUpdateHandler(&Klaymen::update);
+ SetMessageHandler(&Klaymen::hmLowLevel);
+ SetSpriteUpdate(&Klaymen::suFallDown);
+ NextState(&KmScene1002::stLandOnFeet);
+}
+
+uint32 KmScene1002::hmJumpAndFall(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = hmLowLevel(messageNum, param, sender);
+ switch (messageNum) {
+ case NM_ANIMATION_START:
+ if (param.asInteger() == 0x1307050A) {
+ playSound(0, 0x40428A09);
+ }
+ break;
+ }
+ return messageResult;
+}
+
+void KmScene1002::stMoveVenusFlyTrap() {
+ if (!stStartAction(AnimationCallback(&KmScene1002::stMoveVenusFlyTrap))) {
+ _busyStatus = 2;
+ _isMoveObjectRequested = false;
+ _acceptInput = true;
+ setDoDeltaX(_attachedSprite->getX() < _x ? 1 : 0);
+ startAnimation(0x5C01A870, 0, -1);
+ SetUpdateHandler(&Klaymen::update);
+ SetMessageHandler(&KmScene1002::hmMoveVenusFlyTrap);
+ SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
+ FinalizeState(&KmScene1002::evMoveVenusFlyTrapDone);
+ }
+}
+
+void KmScene1002::stContinueMovingVenusFlyTrap() {
+ _isMoveObjectRequested = false;
+ _acceptInput = true;
+ startAnimationByHash(0x5C01A870, 0x01084280, 0);
+ SetUpdateHandler(&Klaymen::update);
+ SetMessageHandler(&KmScene1002::hmMoveVenusFlyTrap);
+ SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
+ FinalizeState(&KmScene1002::evMoveVenusFlyTrapDone);
+}
+
+void KmScene1002::evMoveVenusFlyTrapDone() {
+ sendMessage(_attachedSprite, NM_MOVE_TO_BACK, 0);
+}
+
+uint32 KmScene1002::hmMoveVenusFlyTrap(int messageNum, const MessageParam &param, Entity *sender) {
+ switch (messageNum) {
+ case NM_ANIMATION_START:
+ if (param.asInteger() == 0x01084280) {
+ sendMessage(_attachedSprite, 0x480B, (uint32)_doDeltaX);
+ } else if (param.asInteger() == 0x02421405) {
+ if (_isMoveObjectRequested) {
+ if (sendMessage(_attachedSprite, 0x480C, (uint32)_doDeltaX) != 0)
+ stContinueMovingVenusFlyTrap();
+ } else {
+ SetMessageHandler(&KmScene1002::hmFirstMoveVenusFlyTrap);
+ }
+ } else if (param.asInteger() == 0x4AB28209) {
+ sendMessage(_attachedSprite, NM_MOVE_TO_BACK, 0);
+ } else if (param.asInteger() == 0x88001184) {
+ sendMessage(_attachedSprite, NM_MOVE_TO_FRONT, 0);
+ } else if (param.asInteger() == 0x32180101) {
+ playSound(0, 0x405002D8);
+ } else if (param.asInteger() == 0x0A2A9098) {
+ playSound(0, 0x0460E2FA);
+ }
+ break;
+ case NM_KLAYMEN_MOVE_OBJECT:
+ _isMoveObjectRequested = true;
+ return 0;
+ }
+ return hmLowLevelAnimation(messageNum, param, sender);
+}
+
+uint32 KmScene1002::hmFirstMoveVenusFlyTrap(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = hmLowLevelAnimation(messageNum, param, sender);
+ switch (messageNum) {
+ case NM_ANIMATION_START:
+ if (param.asInteger() == 0x4AB28209) {
+ sendMessage(_attachedSprite, NM_MOVE_TO_BACK, 0);
+ } else if (param.asInteger() == 0x88001184) {
+ sendMessage(_attachedSprite, NM_MOVE_TO_FRONT, 0);
+ } else if (param.asInteger() == 0x32180101) {
+ playSound(0, 0x405002D8);
+ } else if (param.asInteger() == 0x0A2A9098) {
+ playSound(0, 0x0460E2FA);
+ }
+ break;
+ }
+ return messageResult;
+}
+
+void KmScene1002::stPressDoorButton() {
+ _busyStatus = 2;
+ _acceptInput = true;
+ setDoDeltaX(0);
+ startAnimation(0x1CD89029, 0, -1);
+ SetUpdateHandler(&Klaymen::update);
+ SetMessageHandler(&KmScene1002::hmPressDoorButton);
+ SetSpriteUpdate(&Klaymen::suAction);
+}
+
+void KmScene1002::stHitByBoxingGlove() {
+ _busyStatus = 1;
+ _acceptInput = false;
+ startAnimation(0x35AA8059, 0, -1);
+ SetUpdateHandler(&Klaymen::update);
+ SetMessageHandler(&KmScene1002::hmHitByBoxingGlove);
+ SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
+ FinalizeState(&KmScene1002::evHitByBoxingGloveDone);
+}
+
+void KmScene1002::evHitByBoxingGloveDone() {
+ sendMessage(_parentScene, 0x1024, 1);
+}
+
+uint32 KmScene1002::hmPressDoorButton(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = hmLowLevelAnimation(messageNum, param, sender);
+ switch (messageNum) {
+ case NM_ANIMATION_START:
+ if (param.asInteger() == 0x942D2081) {
+ _acceptInput = false;
+ sendMessage(_attachedSprite, 0x2003, 0);
+ } else if (param.asInteger() == 0xDA600012) {
+ stHitByBoxingGlove();
+ } else if (param.asInteger() == 0x0D01B294) {
+ _acceptInput = false;
+ sendMessage(_attachedSprite, 0x480B, 0);
+ }
+ break;
+ }
+ return messageResult;
+}
+
+uint32 KmScene1002::hmHitByBoxingGlove(int messageNum, const MessageParam &param, Entity *sender) {
+ int16 speedUpFrameIndex;
+ uint32 messageResult = hmLowLevelAnimation(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x1008:
+ speedUpFrameIndex = getFrameIndex(kKlaymenSpeedUpHash);
+ if (_currFrameIndex < speedUpFrameIndex) {
+ startAnimation(0x35AA8059, speedUpFrameIndex, -1);
+ _y = 435;
+ }
+ messageResult = 0;
+ break;
+ case NM_ANIMATION_START:
+ if (param.asInteger() == 0x1A1A0785) {
+ playSound(0, 0x40F0A342);
+ } else if (param.asInteger() == 0x60428026) {
+ playSound(0, 0x40608A59);
+ }
+ break;
+ }
+ return messageResult;
+}
+
+KmScene1004::KmScene1004(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
+ : Klaymen(vm, parentScene, x, y) {
+
+ _dataResource.load(0x01900A04);
+}
+
+uint32 KmScene1004::xHandleMessage(int messageNum, const MessageParam &param) {
+ switch (messageNum) {
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case NM_KLAYMEN_STAND_IDLE:
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ gotoNextStateExt();
+ break;
+ case 0x4818:
+ startWalkToX(_dataResource.getPoint(param.asInteger()).x, false);
+ break;
+ case NM_KLAYMEN_RETURN_FROM_USE:
+ GotoState(&KmScene1004::stReadNote);
+ break;
+ case 0x4820:
+ sendMessage(_parentScene, 0x2000, 0);
+ GotoState(&Klaymen::stContinueClimbLadderUp);
+ break;
+ case 0x4821:
+ sendMessage(_parentScene, 0x2000, 0);
+ _destY = param.asInteger();
+ GotoState(&Klaymen::stStartClimbLadderDown);
+ break;
+ case 0x4822:
+ sendMessage(_parentScene, 0x2000, 0);
+ _destY = param.asInteger();
+ GotoState(&Klaymen::stStartClimbLadderUp);
+ break;
+ case 0x4823:
+ sendMessage(_parentScene, 0x2001, 0);
+ GotoState(&Klaymen::stClimbLadderHalf);
+ break;
+ case 0x4824:
+ sendMessage(_parentScene, 0x2000, 0);
+ _destY = _dataResource.getPoint(param.asInteger()).y;
+ GotoState(&Klaymen::stStartClimbLadderDown);
+ break;
+ case 0x4825:
+ sendMessage(_parentScene, 0x2000, 0);
+ _destY = _dataResource.getPoint(param.asInteger()).y;
+ GotoState(&Klaymen::stStartClimbLadderUp);
+ break;
+ case 0x4828:
+ GotoState(&Klaymen::stTurnToBackToUse);
+ break;
+ case 0x483F:
+ startSpecialWalkRight(param.asInteger());
+ break;
+ case 0x4840:
+ startSpecialWalkLeft(param.asInteger());
+ break;
+ }
+ return 0;
+}
+
+uint32 KmScene1004::hmReadNote(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = hmLowLevelAnimation(messageNum, param, sender);
+ switch (messageNum) {
+ case NM_ANIMATION_START:
+ if (param.asInteger() == 0x04684052) {
+ _acceptInput = true;
+ sendMessage(_parentScene, NM_POSITION_CHANGE, 0);
+ }
+ break;
+ }
+ return messageResult;
+}
+
+void KmScene1004::stReadNote() {
+ _busyStatus = 2;
+ _acceptInput = false;
+ startAnimation(0x123E9C9F, 0, -1);
+ SetUpdateHandler(&Klaymen::update);
+ SetMessageHandler(&KmScene1004::hmReadNote);
+ SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
+}
+
+} // End of namespace Neverhood
diff --git a/engines/neverhood/modules/module1000_sprites.h b/engines/neverhood/modules/module1000_sprites.h
new file mode 100644
index 0000000000..564b3cc335
--- /dev/null
+++ b/engines/neverhood/modules/module1000_sprites.h
@@ -0,0 +1,262 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public 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 NEVERHOOD_MODULES_MODULE1000_SPRITES_H
+#define NEVERHOOD_MODULES_MODULE1000_SPRITES_H
+
+#include "neverhood/neverhood.h"
+#include "neverhood/module.h"
+#include "neverhood/scene.h"
+
+namespace Neverhood {
+
+class AsScene1001Door : public AnimatedSprite {
+public:
+ AsScene1001Door(NeverhoodEngine *vm);
+protected:
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ void hammerHitsDoor();
+ void stShowIdleDoor();
+ void stBustedDoorMove();
+ void stBustedDoorGone();
+};
+
+class AsScene1001Hammer : public AnimatedSprite {
+public:
+ AsScene1001Hammer(NeverhoodEngine *vm, Sprite *asDoor);
+protected:
+ Sprite *_asDoor;
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class AsScene1001Window : public AnimatedSprite {
+public:
+ AsScene1001Window(NeverhoodEngine *vm);
+protected:
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class AsScene1001Lever : public AnimatedSprite {
+public:
+ AsScene1001Lever(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y, int deltaXType);
+protected:
+ Scene *_parentScene;
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class SsCommonButtonSprite : public StaticSprite {
+public:
+ SsCommonButtonSprite(NeverhoodEngine *vm, Scene *parentScene, uint32 fileHash, int surfacePriority, uint32 soundFileHash);
+protected:
+ Scene *_parentScene;
+ uint32 _soundFileHash;
+ int16 _countdown;
+ void update();
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class AsScene1002Ring : public AnimatedSprite {
+public:
+ AsScene1002Ring(NeverhoodEngine *vm, Scene *parentScene, bool isSpecial, int16 x, int16 y, int16 clipY1, bool isRingLow);
+protected:
+ Scene *_parentScene;
+ bool _isSpecial;
+ void update();
+ uint32 hmRingIdle(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 hmRingPulled1(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 hmRingPulled2(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 hmRingHangingLow(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 hmRingReleased(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class AsScene1002Door : public StaticSprite {
+public:
+ AsScene1002Door(NeverhoodEngine *vm, NRect &clipRect);
+protected:
+ void update();
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ void suOpenDoor();
+ void suCloseDoor();
+};
+
+class AsScene1002BoxingGloveHitEffect : public AnimatedSprite {
+public:
+ AsScene1002BoxingGloveHitEffect(NeverhoodEngine *vm);
+protected:
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class AsScene1002DoorSpy : public AnimatedSprite {
+public:
+ AsScene1002DoorSpy(NeverhoodEngine *vm, NRect &clipRect, Scene *parentScene, Sprite *asDoor, Sprite *asScene1002BoxingGloveHitEffect);
+protected:
+ Scene *_parentScene;
+ Sprite *_asDoor;
+ Sprite *_asBoxingGloveHitEffect;
+ NRect _clipRect;
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 hmDoorSpyAnimation(int messageNum, const MessageParam &param, Entity *sender);
+ void suDoorSpy();
+ void stDoorSpyIdle();
+ void stDoorSpyBoxingGlove();
+};
+
+class SsCommonPressButton : public StaticSprite {
+public:
+ SsCommonPressButton(NeverhoodEngine *vm, Scene *parentScene, uint32 fileHash1, uint32 fileHash2, int surfacePriority, uint32 soundFileHash);
+ void setFileHashes(uint32 fileHash1, uint32 fileHash2);
+protected:
+ Scene *_parentScene;
+ uint32 _soundFileHash;
+ uint32 _fileHashes[2];
+ int _status;
+ int _countdown;
+ void update();
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class AsScene1002VenusFlyTrap : public AnimatedSprite {
+public:
+ AsScene1002VenusFlyTrap(NeverhoodEngine *vm, Scene *parentScene, Sprite *klaymen, bool isSecond);
+protected:
+ Scene *_parentScene;
+ Sprite *_klaymen;
+ int _countdown;
+ bool _isSecond;
+ void update();
+ void upIdle();
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 hmAnimationSimple(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 hmAnimationExt(int messageNum, const MessageParam &param, Entity *sender);
+ void stWalkBack();
+ void stWalk();
+ void stRelease();
+ void stGrabRing();
+ void stRingGrabbed();
+ void stKlaymenInside();
+ void stIdle();
+ void stKlaymenInsideMoving();
+ void stSpitOutKlaymen();
+ void swallowKlaymen();
+};
+
+class AsScene1002OutsideDoorBackground : public AnimatedSprite {
+public:
+ AsScene1002OutsideDoorBackground(NeverhoodEngine *vm);
+protected:
+ int _countdown;
+ bool _isDoorClosed;
+ void update();
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 hmAnimation(int messageNum, const MessageParam &param, Entity *sender);
+ void stOpenDoor();
+ void stCloseDoor();
+ void stDoorClosed();
+};
+
+class AsScene1002KlaymenLadderHands : public AnimatedSprite {
+public:
+ AsScene1002KlaymenLadderHands(NeverhoodEngine *vm, Klaymen *klaymen);
+protected:
+ Klaymen *_klaymen;
+ void update();
+};
+
+class AsScene1002KlaymenPeekHand : public AnimatedSprite {
+public:
+ AsScene1002KlaymenPeekHand(NeverhoodEngine *vm, Scene *parentScene, Klaymen *klaymen);
+protected:
+ Scene *_parentScene;
+ Klaymen *_klaymen;
+ bool _isClipRectSaved;
+ NRect _savedClipRect;
+ void update();
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class AsScene1004TrashCan : public AnimatedSprite {
+public:
+ AsScene1004TrashCan(NeverhoodEngine *vm);
+protected:
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class KmScene1001 : public Klaymen {
+public:
+ KmScene1001(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
+protected:
+ void stWakeUp();
+ void stSleeping();
+ void stPullHammerLever();
+ uint32 hmSleeping(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 hmPullHammerLever(int messageNum, const MessageParam &param, Entity *sender);
+
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+};
+
+class KmScene1002 : public Klaymen {
+public:
+ KmScene1002(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
+protected:
+ void stJumpToRing1();
+ void stJumpToRing2();
+ void stJumpToRing3();
+ void stJumpToRing4();
+ void setupJumpToRing();
+ void stHangOnRing();
+ void stHoldRing3();
+ void stDropFromRing();
+ void stJumpToRingVenusFlyTrap();
+ void stJumpAndFall();
+ void stMoveVenusFlyTrap();
+ void stContinueMovingVenusFlyTrap();
+ void evMoveVenusFlyTrapDone();
+ void stPressDoorButton();
+ void stHitByBoxingGlove();
+ void evHitByBoxingGloveDone();
+
+ uint32 hmJumpToRing(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 hmJumpToRing3(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 hmHoldRing3(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 hmJumpToRingVenusFlyTrap(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 hmJumpAndFall(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 hmMoveVenusFlyTrap(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 hmFirstMoveVenusFlyTrap(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 hmPressDoorButton(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 hmHitByBoxingGlove(int messageNum, const MessageParam &param, Entity *sender);
+
+ void xUpdate();
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+};
+
+class KmScene1004 : public Klaymen {
+public:
+ KmScene1004(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
+protected:
+ void stReadNote();
+ uint32 hmReadNote(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+};
+
+} // End of namespace Neverhood
+
+#endif /* NEVERHOOD_MODULES_MODULE1000_SPRITES_H */
diff --git a/engines/neverhood/modules/module1100.cpp b/engines/neverhood/modules/module1100.cpp
index faa0516d7e..e40508e502 100644
--- a/engines/neverhood/modules/module1100.cpp
+++ b/engines/neverhood/modules/module1100.cpp
@@ -20,9 +20,10 @@
*
*/
-#include "neverhood/modules/module1100.h"
#include "neverhood/gamemodule.h"
#include "neverhood/navigationscene.h"
+#include "neverhood/modules/module1100.h"
+#include "neverhood/modules/module1100_sprites.h"
namespace Neverhood {
@@ -135,15 +136,20 @@ void Module1100::updateScene() {
switch (_sceneNum) {
case 0:
_countdown = 0;
- _vm->_soundMan->playTwoSounds(0x0002C818, 0x48498E46, 0x50399F64, 0);
_vm->_soundMan->setSoundVolume(0x48498E46, 65);
_vm->_soundMan->setSoundVolume(0x50399F64, 65);
- if (_moduleResult == 0)
+ if (_moduleResult == 0) {
+ _vm->_soundMan->playTwoSounds(0x0002C818, 0x48498E46, 0x50399F64, 0);
createScene(1, 0);
- else if (_moduleResult == 1)
+ } else if (_moduleResult == 1) {
+ /* NOTE This fixes a bug in the original where the "tunnel" footstep
+ sounds are played instead of the correct footsteps. */
+ _vm->_soundMan->playTwoSounds(0x0002C818, 0x41861371, 0x43A2507F, 0);
createScene(8, 0);
+ }
break;
case 1:
+ _countdown = 0;
_vm->_soundMan->playTwoSounds(0x0002C818, 0x41861371, 0x43A2507F, 0);
if (getGlobalVar(V_ROBOT_HIT)) {
if (_moduleResult == 0)
@@ -236,6 +242,13 @@ void Module1100::updateScene() {
}
}
+static const uint32 kScene1105BackgroundFileHashes[] = {
+ 0x20018662,
+ 0x20014202,
+ 0x20012202,
+ 0x20010002 // CHECKME: This used ??
+};
+
static const uint32 kScene1105FileHashes[] = {
0x00028006,
0x0100A425,
@@ -249,186 +262,6 @@ static const uint32 kScene1105FileHashes[] = {
0xB14A891E
};
-static const uint32 kScene1105BackgroundFileHashes[] = {
- 0x20018662,
- 0x20014202,
- 0x20012202,
- 0x20010002 // CHECKME: This used ??
-};
-
-static const uint32 kSsScene1105SymbolDieFileHashes[] = {
- 0,
- 0x90898414,
- 0x91098414,
- 0x92098414,
- 0x94098414,
- 0x98098414,
- 0x80098414,
- 0xB0098414,
- 0xD0098414,
- 0x10098414
-};
-
-SsScene1105Button::SsScene1105Button(NeverhoodEngine *vm, Scene *parentScene, uint32 fileHash, NRect &collisionBounds)
- : StaticSprite(vm, fileHash, 200), _parentScene(parentScene), _countdown(0) {
-
- _collisionBounds = collisionBounds;
- SetMessageHandler(&SsScene1105Button::handleMessage);
- SetUpdateHandler(&SsScene1105Button::update);
- setVisible(false);
-}
-
-void SsScene1105Button::update() {
- if (_countdown != 0 && (--_countdown == 0)) {
- sendMessage(_parentScene, 0x4807, 0);
- setVisible(false);
- }
-}
-
-uint32 SsScene1105Button::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x1011:
- if (_countdown == 0) {
- sendMessage(_parentScene, 0x4826, 0);
- messageResult = 1;
- }
- break;
- case 0x480B:
- _countdown = 8;
- setVisible(true);
- playSound(0, 0x44141000);
- break;
- }
- return messageResult;
-}
-
-SsScene1105Symbol::SsScene1105Symbol(NeverhoodEngine *vm, uint32 fileHash, int16 x, int16 y)
- : StaticSprite(vm, 0) {
-
- loadSprite(fileHash, kSLFCenteredDrawOffset | kSLFSetPosition, 200, x, y);
-}
-
-void SsScene1105Symbol::hide() {
- setVisible(false);
- _needRefresh = true;
- updatePosition();
-}
-
-SsScene1105SymbolDie::SsScene1105SymbolDie(NeverhoodEngine *vm, uint dieIndex, int16 x, int16 y)
- : StaticSprite(vm, 1100), _dieIndex(dieIndex) {
-
- _x = x;
- _y = y;
- createSurface(200, 50, 50);
- loadSymbolSprite();
- SetMessageHandler(&SsScene1105SymbolDie::handleMessage);
-}
-
-uint32 SsScene1105SymbolDie::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x2000:
- loadSymbolSprite();
- break;
- }
- return messageResult;
-}
-
-void SsScene1105SymbolDie::loadSymbolSprite() {
- loadSprite(kSsScene1105SymbolDieFileHashes[getSubVar(VA_CURR_DICE_NUMBERS, _dieIndex)], kSLFCenteredDrawOffset);
-}
-
-void SsScene1105SymbolDie::hide() {
- setVisible(false);
- _needRefresh = true;
- updatePosition();
-}
-
-AsScene1105TeddyBear::AsScene1105TeddyBear(NeverhoodEngine *vm, Scene *parentScene)
- : AnimatedSprite(vm, 1100), _parentScene(parentScene) {
-
- createSurface(100, 556, 328);
- _x = 320;
- _y = 240;
- SetUpdateHandler(&AnimatedSprite::update);
- SetMessageHandler(&AsScene1105TeddyBear::handleMessage);
- startAnimation(0x65084002, 0, -1);
- _newStickFrameIndex = 0;
- setVisible(false);
- _needRefresh = true;
- updatePosition();
- loadSound(0, 0xCE840261);
- loadSound(1, 0xCCA41A62);
-}
-
-uint32 AsScene1105TeddyBear::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x2002:
- if (getGlobalVar(V_ROBOT_TARGET)) {
- startAnimation(0x6B0C0432, 0, -1);
- playSound(0);
- } else {
- startAnimation(0x65084002, 0, -1);
- playSound(1);
- }
- break;
- case 0x3002:
- sendMessage(_parentScene, 0x2003, 0);
- stopAnimation();
- break;
- }
- return messageResult;
-}
-
-void AsScene1105TeddyBear::show() {
- setVisible(true);
- _needRefresh = true;
- updatePosition();
-}
-
-void AsScene1105TeddyBear::hide() {
- setVisible(false);
- _needRefresh = true;
- updatePosition();
-}
-
-SsScene1105OpenButton::SsScene1105OpenButton(NeverhoodEngine *vm, Scene *parentScene)
- : StaticSprite(vm, 900), _parentScene(parentScene), _countdown(0), _isClicked(false) {
-
- loadSprite(0x8228A46C, kSLFDefDrawOffset | kSLFDefPosition | kSLFDefCollisionBoundsOffset, 400);
- setVisible(false);
- loadSound(0, 0x44045140);
- SetUpdateHandler(&SsScene1105OpenButton::update);
- SetMessageHandler(&SsScene1105OpenButton::handleMessage);
-}
-
-void SsScene1105OpenButton::update() {
- updatePosition();
- if (_countdown != 0 && (--_countdown == 0)) {
- setVisible(false);
- sendMessage(_parentScene, 0x2001, 0);
- }
-}
-
-uint32 SsScene1105OpenButton::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = 0;
- Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x1011:
- if (_countdown == 0 && !_isClicked) {
- playSound(0);
- setVisible(true);
- _isClicked = true;
- _countdown = 4;
- }
- messageResult = 1;
- break;
- }
- return messageResult;
-}
-
Scene1105::Scene1105(NeverhoodEngine *vm, Module *parentModule)
: Scene(vm, parentModule), _countdown(0), _isPanelOpen(false), _isActionButtonClicked(false), _doMoveTeddy(false),
_isClosePanelDone(false), _leaveResult(0), _backgroundIndex(0) {
@@ -458,7 +291,7 @@ uint32 Scene1105::handleMessage(int messageNum, const MessageParam &param, Entit
uint32 messageResult = 0;
Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x0001:
+ case NM_MOUSE_CLICK:
if (param.asPoint().x <= 20 || param.asPoint().x >= 620) {
if (!_isActionButtonClicked && _backgroundIndex == 0) {
if (_isPanelOpen) {
@@ -481,7 +314,7 @@ uint32 Scene1105::handleMessage(int messageNum, const MessageParam &param, Entit
_leaveResult = 1;
SetUpdateHandler(&Scene1105::upClosePanel);
break;
- case 0x4807:
+ case NM_KLAYMEN_RAISE_LEVER:
if (sender == _ssActionButton) {
if (getSubVar(VA_GOOD_DICE_NUMBERS, 0) == getSubVar(VA_CURR_DICE_NUMBERS, 0) &&
getSubVar(VA_GOOD_DICE_NUMBERS, 1) == getSubVar(VA_CURR_DICE_NUMBERS, 1) &&
@@ -490,7 +323,7 @@ uint32 Scene1105::handleMessage(int messageNum, const MessageParam &param, Entit
playSound(2);
_doMoveTeddy = true;
} else {
- sendMessage(_asTeddyBear, 0x2002, 0);
+ sendMessage(_asTeddyBear, NM_POSITION_CHANGE, 0);
}
showMouse(false);
_isActionButtonClicked = true;
@@ -632,7 +465,7 @@ void Scene1105::update() {
if (_isClosePanelDone && !isSoundPlaying(1))
leaveScene(_leaveResult);
if (_doMoveTeddy && !isSoundPlaying(2)) {
- sendMessage(_asTeddyBear, 0x2002, 0);
+ sendMessage(_asTeddyBear, NM_POSITION_CHANGE, 0);
_doMoveTeddy = false;
}
}
@@ -685,7 +518,7 @@ Scene1109::Scene1109(NeverhoodEngine *vm, Module *parentModule, int which)
uint32 Scene1109::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x2000:
+ case NM_ANIMATION_UPDATE:
if (param.asInteger()) {
setRectList(0x004B63A8);
_klaymen->setKlaymenIdleTable3();
diff --git a/engines/neverhood/modules/module1100.h b/engines/neverhood/modules/module1100.h
index 373f6b703f..38bac1f298 100644
--- a/engines/neverhood/modules/module1100.h
+++ b/engines/neverhood/modules/module1100.h
@@ -29,8 +29,6 @@
namespace Neverhood {
-// Module1100
-
class Module1100 : public Module {
public:
Module1100(NeverhoodEngine *vm, Module *parentModule, int which);
@@ -42,52 +40,9 @@ protected:
void updateScene();
};
-class SsScene1105Button : public StaticSprite {
-public:
- SsScene1105Button(NeverhoodEngine *vm, Scene *parentScene, uint32 fileHash, NRect &collisionBounds);
-protected:
- Scene *_parentScene;
- int _countdown;
- void update();
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
-
-class SsScene1105Symbol : public StaticSprite {
-public:
- SsScene1105Symbol(NeverhoodEngine *vm, uint32 fileHash, int16 x, int16 y);
- void hide();
-};
-
-class SsScene1105SymbolDie : public StaticSprite {
-public:
- SsScene1105SymbolDie(NeverhoodEngine *vm, uint dieIndex, int16 x, int16 y);
- void hide();
-protected:
- uint _dieIndex;
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- void loadSymbolSprite();
-};
-
-class AsScene1105TeddyBear : public AnimatedSprite {
-public:
- AsScene1105TeddyBear(NeverhoodEngine *vm, Scene *parentScene);
- void show();
- void hide();
-protected:
- Scene *_parentScene;
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
-
-class SsScene1105OpenButton : public StaticSprite {
-public:
- SsScene1105OpenButton(NeverhoodEngine *vm, Scene *parentScene);
-protected:
- Scene *_parentScene;
- int _countdown;
- bool _isClicked;
- void update();
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
+class AsScene1105TeddyBear;
+class SsScene1105Symbol;
+class SsScene1105SymbolDie;
class Scene1105 : public Scene {
public:
diff --git a/engines/neverhood/modules/module1100_sprites.cpp b/engines/neverhood/modules/module1100_sprites.cpp
new file mode 100644
index 0000000000..49a388ffca
--- /dev/null
+++ b/engines/neverhood/modules/module1100_sprites.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 "neverhood/modules/module1100_sprites.h"
+
+namespace Neverhood {
+
+static const uint32 kSsScene1105SymbolDieFileHashes[] = {
+ 0,
+ 0x90898414,
+ 0x91098414,
+ 0x92098414,
+ 0x94098414,
+ 0x98098414,
+ 0x80098414,
+ 0xB0098414,
+ 0xD0098414,
+ 0x10098414
+};
+
+SsScene1105Button::SsScene1105Button(NeverhoodEngine *vm, Scene *parentScene, uint32 fileHash, NRect &collisionBounds)
+ : StaticSprite(vm, fileHash, 200), _parentScene(parentScene), _countdown(0) {
+
+ _collisionBounds = collisionBounds;
+ SetMessageHandler(&SsScene1105Button::handleMessage);
+ SetUpdateHandler(&SsScene1105Button::update);
+ setVisible(false);
+}
+
+void SsScene1105Button::update() {
+ if (_countdown != 0 && (--_countdown == 0)) {
+ sendMessage(_parentScene, NM_KLAYMEN_RAISE_LEVER, 0);
+ setVisible(false);
+ }
+}
+
+uint32 SsScene1105Button::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x1011:
+ if (_countdown == 0) {
+ sendMessage(_parentScene, 0x4826, 0);
+ messageResult = 1;
+ }
+ break;
+ case 0x480B:
+ _countdown = 8;
+ setVisible(true);
+ playSound(0, 0x44141000);
+ break;
+ }
+ return messageResult;
+}
+
+SsScene1105Symbol::SsScene1105Symbol(NeverhoodEngine *vm, uint32 fileHash, int16 x, int16 y)
+ : StaticSprite(vm, 0) {
+
+ loadSprite(fileHash, kSLFCenteredDrawOffset | kSLFSetPosition, 200, x, y);
+}
+
+void SsScene1105Symbol::hide() {
+ setVisible(false);
+ _needRefresh = true;
+ updatePosition();
+}
+
+SsScene1105SymbolDie::SsScene1105SymbolDie(NeverhoodEngine *vm, uint dieIndex, int16 x, int16 y)
+ : StaticSprite(vm, 1100), _dieIndex(dieIndex) {
+
+ _x = x;
+ _y = y;
+ createSurface(200, 50, 50);
+ loadSymbolSprite();
+ SetMessageHandler(&SsScene1105SymbolDie::handleMessage);
+}
+
+uint32 SsScene1105SymbolDie::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case NM_ANIMATION_UPDATE:
+ loadSymbolSprite();
+ break;
+ }
+ return messageResult;
+}
+
+void SsScene1105SymbolDie::loadSymbolSprite() {
+ loadSprite(kSsScene1105SymbolDieFileHashes[getSubVar(VA_CURR_DICE_NUMBERS, _dieIndex)], kSLFCenteredDrawOffset);
+}
+
+void SsScene1105SymbolDie::hide() {
+ setVisible(false);
+ _needRefresh = true;
+ updatePosition();
+}
+
+AsScene1105TeddyBear::AsScene1105TeddyBear(NeverhoodEngine *vm, Scene *parentScene)
+ : AnimatedSprite(vm, 1100), _parentScene(parentScene) {
+
+ createSurface(100, 556, 328);
+ _x = 320;
+ _y = 240;
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsScene1105TeddyBear::handleMessage);
+ startAnimation(0x65084002, 0, -1);
+ _newStickFrameIndex = 0;
+ setVisible(false);
+ _needRefresh = true;
+ updatePosition();
+ loadSound(0, 0xCE840261);
+ loadSound(1, 0xCCA41A62);
+}
+
+uint32 AsScene1105TeddyBear::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case NM_POSITION_CHANGE:
+ if (getGlobalVar(V_ROBOT_TARGET)) {
+ startAnimation(0x6B0C0432, 0, -1);
+ playSound(0);
+ } else {
+ startAnimation(0x65084002, 0, -1);
+ playSound(1);
+ }
+ break;
+ case NM_ANIMATION_STOP:
+ sendMessage(_parentScene, 0x2003, 0);
+ stopAnimation();
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene1105TeddyBear::show() {
+ setVisible(true);
+ _needRefresh = true;
+ updatePosition();
+}
+
+void AsScene1105TeddyBear::hide() {
+ setVisible(false);
+ _needRefresh = true;
+ updatePosition();
+}
+
+SsScene1105OpenButton::SsScene1105OpenButton(NeverhoodEngine *vm, Scene *parentScene)
+ : StaticSprite(vm, 900), _parentScene(parentScene), _countdown(0), _isClicked(false) {
+
+ loadSprite(0x8228A46C, kSLFDefDrawOffset | kSLFDefPosition | kSLFDefCollisionBoundsOffset, 400);
+ setVisible(false);
+ loadSound(0, 0x44045140);
+ SetUpdateHandler(&SsScene1105OpenButton::update);
+ SetMessageHandler(&SsScene1105OpenButton::handleMessage);
+}
+
+void SsScene1105OpenButton::update() {
+ updatePosition();
+ if (_countdown != 0 && (--_countdown == 0)) {
+ setVisible(false);
+ sendMessage(_parentScene, 0x2001, 0);
+ }
+}
+
+uint32 SsScene1105OpenButton::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = 0;
+ Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x1011:
+ if (_countdown == 0 && !_isClicked) {
+ playSound(0);
+ setVisible(true);
+ _isClicked = true;
+ _countdown = 4;
+ }
+ messageResult = 1;
+ break;
+ }
+ return messageResult;
+}
+
+KmScene1109::KmScene1109(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
+ : Klaymen(vm, parentScene, x, y) {
+
+ // Empty
+}
+
+uint32 KmScene1109::xHandleMessage(int messageNum, const MessageParam &param) {
+ uint32 messageResult = 0;
+ switch (messageNum) {
+ case NM_ANIMATION_UPDATE:
+ _isSittingInTeleporter = param.asInteger() != 0;
+ messageResult = 1;
+ break;
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case NM_KLAYMEN_STAND_IDLE:
+ if (_isSittingInTeleporter)
+ GotoState(&Klaymen::stSitIdleTeleporter);
+ else
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x4804:
+ if (param.asInteger() != 0) {
+ _destX = param.asInteger();
+ GotoState(&Klaymen::stWalkingFirst);
+ } else
+ GotoState(&Klaymen::stPeekWall);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ gotoNextStateExt();
+ break;
+ case NM_KLAYMEN_TURN_TO_USE:
+ if (_isSittingInTeleporter)
+ GotoState(&Klaymen::stTurnToUseInTeleporter);
+ break;
+ case NM_KLAYMEN_RETURN_FROM_USE:
+ if (_isSittingInTeleporter)
+ GotoState(&Klaymen::stReturnFromUseInTeleporter);
+ break;
+ case 0x4834:
+ GotoState(&Klaymen::stStepOver);
+ break;
+ case 0x4835:
+ sendMessage(_parentScene, 0x2000, 1);
+ _isSittingInTeleporter = true;
+ GotoState(&Klaymen::stSitInTeleporter);
+ break;
+ case 0x4836:
+ sendMessage(_parentScene, 0x2000, 0);
+ _isSittingInTeleporter = false;
+ GotoState(&Klaymen::stGetUpFromTeleporter);
+ break;
+ case 0x483D:
+ teleporterAppear(0x2C2A4A1C);
+ break;
+ case 0x483E:
+ teleporterDisappear(0x3C2E4245);
+ break;
+ }
+ return messageResult;
+}
+
+} // End of namespace Neverhood
diff --git a/engines/neverhood/modules/module1100_sprites.h b/engines/neverhood/modules/module1100_sprites.h
new file mode 100644
index 0000000000..c8e5a838da
--- /dev/null
+++ b/engines/neverhood/modules/module1100_sprites.h
@@ -0,0 +1,88 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public 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 NEVERHOOD_MODULES_MODULE1100_SPRITES_H
+#define NEVERHOOD_MODULES_MODULE1100_SPRITES_H
+
+#include "neverhood/neverhood.h"
+#include "neverhood/module.h"
+#include "neverhood/scene.h"
+
+namespace Neverhood {
+
+class SsScene1105Button : public StaticSprite {
+public:
+ SsScene1105Button(NeverhoodEngine *vm, Scene *parentScene, uint32 fileHash, NRect &collisionBounds);
+protected:
+ Scene *_parentScene;
+ int _countdown;
+ void update();
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class SsScene1105Symbol : public StaticSprite {
+public:
+ SsScene1105Symbol(NeverhoodEngine *vm, uint32 fileHash, int16 x, int16 y);
+ void hide();
+};
+
+class SsScene1105SymbolDie : public StaticSprite {
+public:
+ SsScene1105SymbolDie(NeverhoodEngine *vm, uint dieIndex, int16 x, int16 y);
+ void hide();
+protected:
+ uint _dieIndex;
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ void loadSymbolSprite();
+};
+
+class AsScene1105TeddyBear : public AnimatedSprite {
+public:
+ AsScene1105TeddyBear(NeverhoodEngine *vm, Scene *parentScene);
+ void show();
+ void hide();
+protected:
+ Scene *_parentScene;
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class SsScene1105OpenButton : public StaticSprite {
+public:
+ SsScene1105OpenButton(NeverhoodEngine *vm, Scene *parentScene);
+protected:
+ Scene *_parentScene;
+ int _countdown;
+ bool _isClicked;
+ void update();
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class KmScene1109 : public Klaymen {
+public:
+ KmScene1109(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
+protected:
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+};
+
+} // End of namespace Neverhood
+
+#endif /* NEVERHOOD_MODULES_MODULE1100_SPRITES_H */
diff --git a/engines/neverhood/modules/module1200.cpp b/engines/neverhood/modules/module1200.cpp
index e7766419f9..8bf42b3b96 100644
--- a/engines/neverhood/modules/module1200.cpp
+++ b/engines/neverhood/modules/module1200.cpp
@@ -21,6 +21,7 @@
*/
#include "neverhood/modules/module1200.h"
+#include "neverhood/modules/module1200_sprites.h"
namespace Neverhood {
@@ -92,566 +93,10 @@ void Module1200::updateScene() {
}
}
-// Scene1201
-
static const uint32 kScene1201InitArray[] = {
1, 0, 2, 4, 5, 3, 6, 7, 8, 10, 9, 11, 13, 14, 12, 16, 17, 15
};
-static const NPoint kScene1201PointArray[] = {
- {218, 193}, {410, 225}, {368, 277},
- {194, 227}, {366, 174}, {458, 224},
- {242, 228}, {512, 228}, {458, 277},
- {217, 233}, {458, 173}, {410, 276},
- {203, 280}, {371, 226}, {508, 279},
- {230, 273}, {410, 171}, {493, 174}
-};
-
-static const uint32 kScene1201TntFileHashList1[] = {
- 0x2098212D, 0x1600437E, 0x1600437E,
- 0x00A840E3, 0x1A1830F6, 0x1A1830F6,
- 0x00212062, 0x384010B6, 0x384010B6,
- 0x07A01080, 0xD80C2837, 0xD80C2837,
- 0x03A22092, 0xD8802CB6, 0xD8802CB6,
- 0x03A93831, 0xDA460476, 0xDA460476
-};
-
-static const uint32 kScene1201TntFileHashList2[] = {
- 0x3040C676, 0x10914448, 0x10914448,
- 0x3448A066, 0x1288C049, 0x1288C049,
- 0x78C0E026, 0x3098D05A, 0x3098D05A,
- 0x304890E6, 0x1284E048, 0x1284E048,
- 0xB140A1E6, 0x5088A068, 0x5088A068,
- 0x74C4C866, 0x3192C059, 0x3192C059
-};
-
-SsScene1201Tnt::SsScene1201Tnt(NeverhoodEngine *vm, uint32 elemIndex, uint32 pointIndex, int16 clipY2)
- : StaticSprite(vm, 900) {
-
- int16 x = kScene1201PointArray[pointIndex].x;
- int16 y = kScene1201PointArray[pointIndex].y;
- if (x < 300)
- loadSprite(kScene1201TntFileHashList1[elemIndex], kSLFDefDrawOffset | kSLFDefPosition, 50);
- else
- loadSprite(kScene1201TntFileHashList2[elemIndex], kSLFCenteredDrawOffset | kSLFSetPosition, 50, x, y - 20);
- setClipRect(0, 0, 640, clipY2);
-}
-
-AsScene1201Tape::AsScene1201Tape(NeverhoodEngine *vm, Scene *parentScene, uint32 nameHash, int surfacePriority, int16 x, int16 y, uint32 fileHash)
- : AnimatedSprite(vm, fileHash, surfacePriority, x, y), _parentScene(parentScene), _nameHash(nameHash) {
-
- if (!getSubVar(VA_HAS_TAPE, _nameHash) && !getSubVar(VA_IS_TAPE_INSERTED, _nameHash)) {
- SetMessageHandler(&AsScene1201Tape::handleMessage);
- } else {
- setVisible(false);
- SetMessageHandler(NULL);
- }
-}
-
-uint32 AsScene1201Tape::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x1011:
- sendMessage(_parentScene, 0x4826, 0);
- messageResult = 1;
- break;
- case 0x4806:
- setSubVar(VA_HAS_TAPE, _nameHash, 1);
- setVisible(false);
- SetMessageHandler(NULL);
- break;
- }
- return messageResult;
-}
-
-AsScene1201TntManRope::AsScene1201TntManRope(NeverhoodEngine *vm, bool isDummyHanging)
- : AnimatedSprite(vm, 1200) {
-
- SetUpdateHandler(&AnimatedSprite::update);
- SetMessageHandler(&AsScene1201TntManRope::handleMessage);
- createSurface(10, 34, 149);
- _x = 202;
- _y = -32;
- if (isDummyHanging) {
- startAnimation(0x928F0C10, 15, -1);
- _newStickFrameIndex = STICK_LAST_FRAME;
- } else {
- startAnimation(0x928F0C10, 0, -1);
- _newStickFrameIndex = 0;
- }
-}
-
-uint32 AsScene1201TntManRope::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x100D:
- if (param.asInteger() == 0x02060018)
- playSound(0, 0x47900E06);
- break;
- case 0x2006:
- startAnimation(0x928F0C10, 1, -1);
- _newStickFrameIndex = STICK_LAST_FRAME;
- break;
- }
- return messageResult;
-}
-
-AsScene1201RightDoor::AsScene1201RightDoor(NeverhoodEngine *vm, Sprite *klaymen, bool isOpen)
- : AnimatedSprite(vm, 1100), _klaymen(klaymen), _countdown(0) {
-
- createSurface1(0xD088AC30, 100);
- _x = 320;
- _y = 240;
- SetUpdateHandler(&AsScene1201RightDoor::update);
- SetMessageHandler(&AsScene1201RightDoor::handleMessage);
- _newStickFrameIndex = STICK_LAST_FRAME;
- if (isOpen) {
- startAnimation(0xD088AC30, -1, -1);
- _newStickFrameIndex = STICK_LAST_FRAME;
- _countdown = 25;
- } else {
- stopAnimation();
- setVisible(false);
- }
-}
-
-void AsScene1201RightDoor::update() {
- if (_countdown != 0 && (--_countdown == 0))
- stCloseDoor();
- AnimatedSprite::update();
-}
-
-uint32 AsScene1201RightDoor::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x3002:
- gotoNextState();
- break;
- case 0x4829:
- stOpenDoor();
- break;
- }
- return messageResult;
-}
-
-void AsScene1201RightDoor::stOpenDoor() {
- startAnimation(0xD088AC30, 0, -1);
- _newStickFrameIndex = STICK_LAST_FRAME;
- setVisible(true);
- playSound(0, calcHash("fxDoorOpen20"));
-}
-
-void AsScene1201RightDoor::stCloseDoor() {
- startAnimation(0xD088AC30, -1, -1);
- _playBackwards = true;
- setVisible(true);
- playSound(0, calcHash("fxDoorClose20"));
- NextState(&AsScene1201RightDoor::stCloseDoorDone);
-}
-
-void AsScene1201RightDoor::stCloseDoorDone() {
- stopAnimation();
- setVisible(false);
-}
-
-AsScene1201KlaymenHead::AsScene1201KlaymenHead(NeverhoodEngine *vm)
- : AnimatedSprite(vm, 1200) {
-
- createSurface(1200, 69, 98);
- SetUpdateHandler(&AnimatedSprite::update);
- SetMessageHandler(&AsScene1201KlaymenHead::handleMessage);
- SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
- setVisible(false);
-}
-
-uint32 AsScene1201KlaymenHead::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x2006:
- _x = 436;
- _y = 339;
- startAnimation(0xA060C599, 0, -1);
- setVisible(true);
- break;
- case 0x3002:
- stopAnimation();
- setVisible(false);
- gotoNextState();
- break;
- }
- return messageResult;
-}
-
-AsScene1201TntMan::AsScene1201TntMan(NeverhoodEngine *vm, Scene *parentScene, Sprite *asTntManRope, bool isComingDown)
- : AnimatedSprite(vm, 1100), _parentScene(parentScene), _asTntManRope(asTntManRope),
- _isMoving(false) {
-
- SetUpdateHandler(&AnimatedSprite::update);
- SetMessageHandler(&AsScene1201TntMan::handleMessage);
- createSurface(990, 106, 181);
- _x = 201;
- if (isComingDown) {
- _y = 297;
- stComingDown();
- } else {
- _y = 334;
- stStanding();
- }
-}
-
-AsScene1201TntMan::~AsScene1201TntMan() {
- _vm->_soundMan->deleteSoundGroup(0x01D00560);
-}
-
-uint32 AsScene1201TntMan::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x100D:
- if (param.asInteger() == 0x092870C0)
- sendMessage(_asTntManRope, 0x2006, 0);
- else if (param.asInteger() == 0x11CA0144)
- playSound(0, 0x51800A04);
- break;
- case 0x1011:
- sendMessage(_parentScene, 0x2002, 0);
- messageResult = 1;
- break;
- case 0x480B:
- if (!_isMoving) {
- _sprite = (Sprite*)sender;
- stMoving();
- }
- break;
- }
- return messageResult;
-
-}
-
-uint32 AsScene1201TntMan::hmComingDown(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = AsScene1201TntMan::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x3002:
- gotoNextState();
- break;
- }
- return messageResult;
-}
-
-void AsScene1201TntMan::suMoving() {
- _x = _sprite->getX() + 100;
-}
-
-void AsScene1201TntMan::stStanding() {
- startAnimation(0x654913D0, 0, -1);
- SetMessageHandler(&AsScene1201TntMan::handleMessage);
- SetSpriteUpdate(NULL);
-}
-
-void AsScene1201TntMan::stComingDown() {
- startAnimation(0x356803D0, 0, -1);
- SetMessageHandler(&AsScene1201TntMan::hmComingDown);
- SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
- NextState(&AsScene1201TntMan::stStanding);
-}
-
-void AsScene1201TntMan::stMoving() {
- _vm->_soundMan->addSound(0x01D00560, 0x4B044624);
- _vm->_soundMan->playSoundLooping(0x4B044624);
- _isMoving = true;
- startAnimation(0x85084190, 0, -1);
- SetMessageHandler(&AsScene1201TntMan::handleMessage);
- SetSpriteUpdate(&AsScene1201TntMan::suMoving);
- _newStickFrameIndex = STICK_LAST_FRAME;
-}
-
-AsScene1201TntManFlame::AsScene1201TntManFlame(NeverhoodEngine *vm, Sprite *asTntMan)
- : AnimatedSprite(vm, 1200), _asTntMan(asTntMan) {
-
- createSurface1(0x828C0411, 995);
- SetUpdateHandler(&AsScene1201TntManFlame::update);
- SetMessageHandler(&Sprite::handleMessage);
- SetSpriteUpdate(&AsScene1201TntManFlame::suUpdate);
- startAnimation(0x828C0411, 0, -1);
- setVisible(false);
-}
-
-AsScene1201TntManFlame::~AsScene1201TntManFlame() {
- _vm->_soundMan->deleteSoundGroup(0x041080A4);
-}
-
-void AsScene1201TntManFlame::update() {
- AnimatedSprite::update();
- if (getGlobalVar(V_TNT_DUMMY_FUSE_LIT)) {
- setVisible(true);
- SetUpdateHandler(&AnimatedSprite::update);
- _vm->_soundMan->addSound(0x041080A4, 0x460A1050);
- _vm->_soundMan->playSoundLooping(0x460A1050);
- }
-}
-
-void AsScene1201TntManFlame::suUpdate() {
- _x = _asTntMan->getX() - 18;
- _y = _asTntMan->getY() - 158;
-}
-
-AsScene1201Match::AsScene1201Match(NeverhoodEngine *vm, Scene *parentScene)
- : AnimatedSprite(vm, 1100), _parentScene(parentScene), _countdown(0) {
-
- createSurface(1100, 57, 60);
- SetUpdateHandler(&AsScene1201Match::update);
- SetMessageHandler(&AsScene1201Match::hmOnDoorFrameAboutToMove);
- SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
- switch (getGlobalVar(V_MATCH_STATUS)) {
- case 0:
- _x = 521;
- _y = 112;
- _status = 0;
- stIdleOnDoorFrame();
- break;
- case 1:
- _x = 521;
- _y = 112;
- _status = 2;
- stOnDoorFrameAboutToMove();
- loadSound(0, 0xD00230CD);
- break;
- case 2:
- setDoDeltaX(1);
- _x = 403;
- _y = 337;
- _status = 0;
- stIdleOnFloor();
- break;
- }
-}
-
-void AsScene1201Match::update() {
- if (_countdown != 0 && (--_countdown == 0))
- gotoNextState();
- updateAnim();
- handleSpriteUpdate();
- updatePosition();
-}
-
-uint32 AsScene1201Match::hmOnDoorFrameAboutToMove(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x100D:
- if (param.asInteger() == 0x86668011)
- playSound(0);
- break;
- }
- return messageResult;
-}
-
-uint32 AsScene1201Match::hmOnDoorFrameMoving(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = hmOnDoorFrameAboutToMove(messageNum, param, sender);
- switch (messageNum) {
- case 0x3002:
- gotoNextState();
- break;
- }
- return messageResult;
-}
-
-uint32 AsScene1201Match::hmIdle(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = hmOnDoorFrameAboutToMove(messageNum, param, sender);
- switch (messageNum) {
- case 0x1011:
- sendMessage(_parentScene, 0x2001, 0);
- messageResult = 1;
- break;
- case 0x4806:
- setVisible(false);
- setGlobalVar(V_MATCH_STATUS, 3);
- break;
- }
- return messageResult;
-}
-
-void AsScene1201Match::stOnDoorFrameMoving() {
- startAnimation(0x00842374, 0, -1);
- SetMessageHandler(&AsScene1201Match::hmOnDoorFrameMoving);
- if (_status == 0) {
- NextState(&AsScene1201Match::stFallingFromDoorFrame);
- } else {
- NextState(&AsScene1201Match::stOnDoorFrameAboutToMove);
- }
-}
-
-void AsScene1201Match::stFallingFromDoorFrame() {
- setGlobalVar(V_MATCH_STATUS, 2);
- _x -= 199;
- _y += 119;
- startAnimation(0x018D0240, 0, -1);
- SetMessageHandler(&AsScene1201Match::hmOnDoorFrameMoving);
- NextState(&AsScene1201Match::stIdleOnFloor);
-}
-
-void AsScene1201Match::stOnDoorFrameAboutToMove() {
- startAnimation(0x00842374, 0, -1);
- SetMessageHandler(&AsScene1201Match::hmOnDoorFrameAboutToMove);
- _newStickFrameIndex = 0;
- if (_status != 0) {
- _countdown = 36;
- _status--;
- NextState(&AsScene1201Match::stOnDoorFrameMoving);
- }
-}
-
-void AsScene1201Match::stIdleOnDoorFrame() {
- startAnimation(0x00842374, 0, -1);
- SetMessageHandler(&AsScene1201Match::hmIdle);
- _newStickFrameIndex = 0;
-}
-
-void AsScene1201Match::stIdleOnFloor() {
- setDoDeltaX(1);
- _x = 403;
- _y = 337;
- startAnimation(0x00842374, 0, -1);
- SetMessageHandler(&AsScene1201Match::hmIdle);
- _newStickFrameIndex = 0;
-}
-
-AsScene1201Creature::AsScene1201Creature(NeverhoodEngine *vm, Scene *parentScene, Sprite *klaymen)
- : AnimatedSprite(vm, 900), _parentScene(parentScene), _klaymen(klaymen), _klaymenTooClose(false) {
-
- // NOTE: _countdown2 and _countdown3 were unused/without effect and thus removed
-
- createSurface(1100, 203, 199);
- SetUpdateHandler(&AsScene1201Creature::update);
- SetMessageHandler(&AsScene1201Creature::hmWaiting);
- _x = 540;
- _y = 320;
- stWaiting();
-}
-
-void AsScene1201Creature::update() {
- bool oldKlaymenTooClose = _klaymenTooClose;
- _klaymenTooClose = _klaymen->getX() >= 385;
- if (_klaymenTooClose != oldKlaymenTooClose)
- stWaiting();
- if (_countdown != 0 && (--_countdown == 0))
- gotoNextState();
- updateAnim();
- handleSpriteUpdate();
- updatePosition();
-}
-
-uint32 AsScene1201Creature::hmWaiting(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x100D:
- if (param.asInteger() == 0x02060018)
- playSound(0, 0xCD298116);
- break;
- case 0x2004:
- GotoState(&AsScene1201Creature::stStartReachForTntDummy);
- break;
- case 0x2006:
- GotoState(&AsScene1201Creature::stPincerSnapKlaymen);
- break;
- }
- return messageResult;
-}
-
-uint32 AsScene1201Creature::hmPincerSnap(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = hmWaiting(messageNum, param, sender);
- switch (messageNum) {
- case 0x3002:
- gotoNextState();
- break;
- }
- return messageResult;
-}
-
-uint32 AsScene1201Creature::hmPincerSnapKlaymen(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x100D:
- if (param.asInteger() == 0x02060018) {
- playSound(0, 0xCD298116);
- sendMessage(_parentScene, 0x4814, 0);
- sendMessage(_klaymen, 0x4814, 0);
- }
- break;
- case 0x3002:
- gotoNextState();
- break;
- }
- return messageResult;
-}
-
-void AsScene1201Creature::stWaiting() {
- startAnimation(0x08081513, 0, -1);
- SetMessageHandler(&AsScene1201Creature::hmWaiting);
- NextState(&AsScene1201Creature::stPincerSnap);
- _countdown = 36;
-}
-
-void AsScene1201Creature::stPincerSnap() {
- if (!_klaymenTooClose) {
- startAnimation(0xCA287133, 0, -1);
- SetMessageHandler(&AsScene1201Creature::hmPincerSnap);
- NextState(&AsScene1201Creature::stWaiting);
- }
-}
-
-void AsScene1201Creature::stStartReachForTntDummy() {
- startAnimation(0x08081513, 0, -1);
- SetMessageHandler(&AsScene1201Creature::hmWaiting);
- NextState(&AsScene1201Creature::stReachForTntDummy);
- _countdown = 48;
-}
-
-void AsScene1201Creature::stReachForTntDummy() {
- startAnimation(0x5A201453, 0, -1);
- SetMessageHandler(&AsScene1201Creature::hmWaiting);
- _countdown = 0;
-}
-
-void AsScene1201Creature::stPincerSnapKlaymen() {
- startAnimation(0xCA287133, 0, -1);
- SetMessageHandler(&AsScene1201Creature::hmPincerSnapKlaymen);
- NextState(&AsScene1201Creature::stWaiting);
- _countdown = 0;
-}
-
-AsScene1201LeftDoor::AsScene1201LeftDoor(NeverhoodEngine *vm, Sprite *klaymen)
- : AnimatedSprite(vm, 1100), _klaymen(klaymen) {
-
- _x = 320;
- _y = 240;
- createSurface(800, 55, 199);
- if (_klaymen->getX() < 100) {
- startAnimation(0x508A111B, 0, -1);
- _newStickFrameIndex = STICK_LAST_FRAME;
- playSound(0, calcHash("fxDoorOpen03"));
- } else {
- startAnimation(0x508A111B, -1, -1);
- _newStickFrameIndex = STICK_LAST_FRAME;
- }
- SetUpdateHandler(&AnimatedSprite::update);
- SetMessageHandler(&AsScene1201LeftDoor::handleMessage);
-}
-
-uint32 AsScene1201LeftDoor::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x4809:
- stCloseDoor();
- break;
- }
- return messageResult;
-}
-
-void AsScene1201LeftDoor::stCloseDoor() {
- startAnimation(0x508A111B, -1, -1);
- _playBackwards = true;
- _newStickFrameIndex = 0;
-}
-
Scene1201::Scene1201(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule), _creatureExploded(false), _asMatch(NULL), _asTntMan(NULL),
_asCreature(NULL), _asTntManRope(NULL), _asLeftDoor(NULL), _asRightDoor(NULL), _asTape(NULL) {
@@ -851,15 +296,15 @@ void Scene1201::update() {
uint32 Scene1201::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0x07053000) {
_creatureExploded = true;
sendMessage(_asCreature, 0x2004, 0);
} else if (param.asInteger() == 0x140E5744)
- sendMessage(_asCreature, 0x2005, 0);
+ sendMessage(_asCreature, NM_KLAYMEN_CLIMB_LADDER, 0);
else if (param.asInteger() == 0x40253C40) {
_canAcceptInput = false;
- sendMessage(_asCreature, 0x2006, 0);
+ sendMessage(_asCreature, NM_KLAYMEN_STOP_CLIMBING, 0);
} else if (param.asInteger() == 0x090EB048) {
if (_klaymen->getX() < 572)
setMessageList2(0x004AEC90);
@@ -875,7 +320,7 @@ uint32 Scene1201::handleMessage(int messageNum, const MessageParam &param, Entit
setMessageList2(0x004AECC0);
}
break;
- case 0x2002:
+ case NM_POSITION_CHANGE:
if (getGlobalVar(V_TNT_DUMMY_FUSE_LIT)) {
// Move the TNT dummy if the fuse is burning
sendEntityMessage(_klaymen, 0x1014, _asTntMan);
@@ -902,101 +347,16 @@ uint32 Scene1201::handleMessage(int messageNum, const MessageParam &param, Entit
sendMessage(_asRightDoor, 0x4829, 0);
break;
case 0x8000:
- sendMessage(_asKlaymenHead, 0x2006, 0);
+ sendMessage(_asKlaymenHead, NM_KLAYMEN_STOP_CLIMBING, 0);
break;
}
return messageResult;
}
-// Scene1202
-
static const uint32 kScene1202Table[] = {
1, 2, 0, 4, 5, 3, 7, 8, 6, 10, 11, 9, 13, 14, 12, 16, 17, 15
};
-static const NPoint kScene1202Points[] = {
- {203, 140}, {316, 212}, {277, 264},
- {176, 196}, {275, 159}, {366, 212},
- {230, 195}, {412, 212}, {368, 263},
- {204, 192}, {365, 164}, {316, 262},
- {191, 255}, {280, 213}, {406, 266},
- {214, 254}, {316, 158}, {402, 161}
-};
-
-static const uint32 kScene1202FileHashes[] = {
- 0x1AC00B8, 0x1AC14B8, 0x1AC14B8,
- 0x1AC30B8, 0x1AC14B8, 0x1AC14B8,
- 0x1AC00B8, 0x1AC14B8, 0x1AC14B8,
- 0x1AC90B8, 0x1AC18B8, 0x1AC18B8,
- 0x1AC30B8, 0x1AC14B8, 0x1AC14B8,
- 0x1AC50B8, 0x1AC14B8, 0x1AC14B8
-};
-
-AsScene1202TntItem::AsScene1202TntItem(NeverhoodEngine *vm, Scene *parentScene, int itemIndex)
- : AnimatedSprite(vm, 900), _parentScene(parentScene), _itemIndex(itemIndex) {
-
- int positionIndex;
-
- SetUpdateHandler(&AnimatedSprite::update);
- SetMessageHandler(&AsScene1202TntItem::hmShowIdle);
- positionIndex = getSubVar(VA_TNT_POSITIONS, _itemIndex);
- createSurface(900, 37, 67);
- _x = kScene1202Points[positionIndex].x;
- _y = kScene1202Points[positionIndex].y;
- stShowIdle();
-}
-
-uint32 AsScene1202TntItem::hmShowIdle(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x1011:
- sendMessage(_parentScene, 0x2000, _itemIndex);
- messageResult = 1;
- break;
- case 0x2001:
- _newPosition = (int)param.asInteger();
- stChangePositionFadeOut();
- break;
- }
- return messageResult;
-}
-
-uint32 AsScene1202TntItem::hmChangePosition(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x3002:
- gotoNextState();
- break;
- }
- return messageResult;
-}
-
-void AsScene1202TntItem::stShowIdle() {
- startAnimation(kScene1202FileHashes[_itemIndex], 0, -1);
- SetMessageHandler(&AsScene1202TntItem::hmShowIdle);
- _newStickFrameIndex = 0;
-}
-
-void AsScene1202TntItem::stChangePositionFadeOut() {
- startAnimation(kScene1202FileHashes[_itemIndex], 0, -1);
- SetMessageHandler(&AsScene1202TntItem::hmChangePosition);
- NextState(&AsScene1202TntItem::stChangePositionFadeIn);
-}
-
-void AsScene1202TntItem::stChangePositionFadeIn() {
- _x = kScene1202Points[_newPosition].x;
- _y = kScene1202Points[_newPosition].y;
- startAnimation(kScene1202FileHashes[_itemIndex], 6, -1);
- _playBackwards = true;
- SetMessageHandler(&AsScene1202TntItem::hmChangePosition);
- NextState(&AsScene1202TntItem::stChangePositionDone);
-}
-
-void AsScene1202TntItem::stChangePositionDone() {
- sendMessage(_parentScene, 0x2002, _itemIndex);
- stShowIdle();
-}
-
Scene1202::Scene1202(NeverhoodEngine *vm, Module *parentModule)
: Scene(vm, parentModule), _paletteResource(vm),
_soundToggle(true), _isPuzzleSolved(false), _counter(0), _clickedIndex(-1) {
@@ -1067,14 +427,14 @@ uint32 Scene1202::handleMessage(int messageNum, const MessageParam &param, Entit
uint32 messageResult = 0;
Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x0001:
+ case NM_MOUSE_CLICK:
if ((param.asPoint().x <= 20 || param.asPoint().x >= 620) && !_isPuzzleSolved)
leaveScene(0);
break;
- case 0x2000:
+ case NM_ANIMATION_UPDATE:
_clickedIndex = (int)param.asInteger();
break;
- case 0x2002:
+ case NM_POSITION_CHANGE:
_counter--;
break;
}
@@ -1084,7 +444,7 @@ uint32 Scene1202::handleMessage(int messageNum, const MessageParam &param, Entit
uint32 Scene1202::hmSolved(int messageNum, const MessageParam &param, Entity *sender) {
Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x0001:
+ case NM_MOUSE_CLICK:
if (param.asPoint().x <= 20 || param.asPoint().x >= 620)
leaveScene(0);
break;
diff --git a/engines/neverhood/modules/module1200.h b/engines/neverhood/modules/module1200.h
index c97dc98986..d9d4dd11f2 100644
--- a/engines/neverhood/modules/module1200.h
+++ b/engines/neverhood/modules/module1200.h
@@ -29,8 +29,6 @@
namespace Neverhood {
-// Module1200
-
class Module1200 : public Module {
public:
Module1200(NeverhoodEngine *vm, Module *parentModule, int which);
@@ -41,123 +39,7 @@ protected:
void updateScene();
};
-// Scene1201
-
-class AsScene1201Tape : public AnimatedSprite {
-public:
- AsScene1201Tape(NeverhoodEngine *vm, Scene *parentScene, uint32 nameHash, int surfacePriority, int16 x, int16 y, uint32 fileHash);
-protected:
- Scene *_parentScene;
- uint32 _nameHash;
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
-
-class AsScene1201TntManRope : public AnimatedSprite {
-public:
- AsScene1201TntManRope(NeverhoodEngine *vm, bool isDummyHanging);
-protected:
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
-
-class AsScene1201RightDoor : public AnimatedSprite {
-public:
- AsScene1201RightDoor(NeverhoodEngine *vm, Sprite *klaymen, bool isOpen);
-protected:
- Sprite *_klaymen;
- int _countdown;
- void update();
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- void stOpenDoor();
- void stCloseDoor();
- void stCloseDoorDone();
-};
-
-class AsScene1201KlaymenHead : public AnimatedSprite {
-public:
- AsScene1201KlaymenHead(NeverhoodEngine *vm);
-protected:
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
-
-class AsScene1201TntMan : public AnimatedSprite {
-public:
- AsScene1201TntMan(NeverhoodEngine *vm, Scene *parentScene, Sprite *asTntManRope, bool isDown);
- virtual ~AsScene1201TntMan();
-protected:
- Scene *_parentScene;
- Sprite *_asTntManRope;
- Sprite *_sprite;
- bool _isMoving;
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- uint32 hmComingDown(int messageNum, const MessageParam &param, Entity *sender);
- void suMoving();
- void stStanding();
- void stComingDown();
- void stMoving();
-};
-
-class AsScene1201TntManFlame : public AnimatedSprite {
-public:
- AsScene1201TntManFlame(NeverhoodEngine *vm, Sprite *asTntMan);
- ~AsScene1201TntManFlame();
-protected:
- Sprite *_asTntMan;
- void update();
- void suUpdate();
-};
-
-class AsScene1201Match : public AnimatedSprite {
-public:
- AsScene1201Match(NeverhoodEngine *vm, Scene *parentScene);
-protected:
- Scene *_parentScene;
- int _countdown;
- int _status;
- void update();
- uint32 hmOnDoorFrameAboutToMove(int messageNum, const MessageParam &param, Entity *sender);
- uint32 hmOnDoorFrameMoving(int messageNum, const MessageParam &param, Entity *sender);
- uint32 hmIdle(int messageNum, const MessageParam &param, Entity *sender);
- void stOnDoorFrameMoving();
- void stFallingFromDoorFrame();
- void stOnDoorFrameAboutToMove();
- void stIdleOnDoorFrame();
- void stIdleOnFloor();
-};
-
-class AsScene1201Creature : public AnimatedSprite {
-public:
- AsScene1201Creature(NeverhoodEngine *vm, Scene *parentScene, Sprite *klaymen);
-protected:
- Scene *_parentScene;
- Sprite *_klaymen;
- int _countdown;
- bool _klaymenTooClose;
- void update();
- uint32 hmWaiting(int messageNum, const MessageParam &param, Entity *sender);
- uint32 hmPincerSnap(int messageNum, const MessageParam &param, Entity *sender);
- uint32 hmPincerSnapKlaymen(int messageNum, const MessageParam &param, Entity *sender);
- void stWaiting();
- void stPincerSnap();
- void stStartReachForTntDummy();
- void stReachForTntDummy();
- void stPincerSnapKlaymen();
-};
-
-class AsScene1201LeftDoor : public AnimatedSprite {
-public:
- AsScene1201LeftDoor(NeverhoodEngine *vm, Sprite *klaymen);
-protected:
- Sprite *_klaymen;
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- void stCloseDoor();
-};
-
-class SsScene1201Tnt : public StaticSprite {
-public:
- SsScene1201Tnt(NeverhoodEngine *vm, uint32 elemIndex, uint32 pointIndex, int16 clipY2);
-protected:
- uint32 _elemIndex;
-};
+class AsScene1201TntMan;
class Scene1201 : public Scene {
public:
@@ -177,22 +59,6 @@ protected:
uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
};
-// Scene1202
-
-class AsScene1202TntItem : public AnimatedSprite {
-public:
- AsScene1202TntItem(NeverhoodEngine *vm, Scene *parentScene, int index);
-protected:
- Scene *_parentScene;
- int _itemIndex, _newPosition;
- uint32 hmShowIdle(int messageNum, const MessageParam &param, Entity *sender);
- uint32 hmChangePosition(int messageNum, const MessageParam &param, Entity *sender);
- void stShowIdle();
- void stChangePositionFadeOut();
- void stChangePositionFadeIn();
- void stChangePositionDone();
-};
-
class Scene1202 : public Scene {
public:
Scene1202(NeverhoodEngine *vm, Module *parentModule);
diff --git a/engines/neverhood/modules/module1200_sprites.cpp b/engines/neverhood/modules/module1200_sprites.cpp
new file mode 100644
index 0000000000..5848e16092
--- /dev/null
+++ b/engines/neverhood/modules/module1200_sprites.cpp
@@ -0,0 +1,810 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public 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 "neverhood/modules/module1200_sprites.h"
+
+namespace Neverhood {
+
+static const uint32 kScene1201TntFileHashList1[] = {
+ 0x2098212D, 0x1600437E, 0x1600437E,
+ 0x00A840E3, 0x1A1830F6, 0x1A1830F6,
+ 0x00212062, 0x384010B6, 0x384010B6,
+ 0x07A01080, 0xD80C2837, 0xD80C2837,
+ 0x03A22092, 0xD8802CB6, 0xD8802CB6,
+ 0x03A93831, 0xDA460476, 0xDA460476
+};
+
+static const uint32 kScene1201TntFileHashList2[] = {
+ 0x3040C676, 0x10914448, 0x10914448,
+ 0x3448A066, 0x1288C049, 0x1288C049,
+ 0x78C0E026, 0x3098D05A, 0x3098D05A,
+ 0x304890E6, 0x1284E048, 0x1284E048,
+ 0xB140A1E6, 0x5088A068, 0x5088A068,
+ 0x74C4C866, 0x3192C059, 0x3192C059
+};
+
+SsScene1201Tnt::SsScene1201Tnt(NeverhoodEngine *vm, uint32 elemIndex, uint32 pointIndex, int16 clipY2)
+ : StaticSprite(vm, 900) {
+
+ int16 x = kScene1201PointArray[pointIndex].x;
+ int16 y = kScene1201PointArray[pointIndex].y;
+ if (x < 300)
+ loadSprite(kScene1201TntFileHashList1[elemIndex], kSLFDefDrawOffset | kSLFDefPosition, 50);
+ else
+ loadSprite(kScene1201TntFileHashList2[elemIndex], kSLFCenteredDrawOffset | kSLFSetPosition, 50, x, y - 20);
+ setClipRect(0, 0, 640, clipY2);
+}
+
+AsScene1201Tape::AsScene1201Tape(NeverhoodEngine *vm, Scene *parentScene, uint32 nameHash, int surfacePriority, int16 x, int16 y, uint32 fileHash)
+ : AnimatedSprite(vm, fileHash, surfacePriority, x, y), _parentScene(parentScene), _nameHash(nameHash) {
+
+ if (!getSubVar(VA_HAS_TAPE, _nameHash) && !getSubVar(VA_IS_TAPE_INSERTED, _nameHash)) {
+ SetMessageHandler(&AsScene1201Tape::handleMessage);
+ } else {
+ setVisible(false);
+ SetMessageHandler(NULL);
+ }
+}
+
+uint32 AsScene1201Tape::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x1011:
+ sendMessage(_parentScene, 0x4826, 0);
+ messageResult = 1;
+ break;
+ case NM_KLAYMEN_USE_OBJECT:
+ setSubVar(VA_HAS_TAPE, _nameHash, 1);
+ setVisible(false);
+ SetMessageHandler(NULL);
+ break;
+ }
+ return messageResult;
+}
+
+AsScene1201TntManRope::AsScene1201TntManRope(NeverhoodEngine *vm, bool isDummyHanging)
+ : AnimatedSprite(vm, 1200) {
+
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsScene1201TntManRope::handleMessage);
+ createSurface(10, 34, 149);
+ _x = 202;
+ _y = -32;
+ if (isDummyHanging) {
+ startAnimation(0x928F0C10, 15, -1);
+ _newStickFrameIndex = STICK_LAST_FRAME;
+ } else {
+ startAnimation(0x928F0C10, 0, -1);
+ _newStickFrameIndex = 0;
+ }
+}
+
+uint32 AsScene1201TntManRope::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case NM_ANIMATION_START:
+ if (param.asInteger() == 0x02060018)
+ playSound(0, 0x47900E06);
+ break;
+ case NM_KLAYMEN_STOP_CLIMBING:
+ startAnimation(0x928F0C10, 1, -1);
+ _newStickFrameIndex = STICK_LAST_FRAME;
+ break;
+ }
+ return messageResult;
+}
+
+AsScene1201RightDoor::AsScene1201RightDoor(NeverhoodEngine *vm, Sprite *klaymen, bool isOpen)
+ : AnimatedSprite(vm, 1100), _klaymen(klaymen), _countdown(0) {
+
+ createSurface1(0xD088AC30, 100);
+ _x = 320;
+ _y = 240;
+ SetUpdateHandler(&AsScene1201RightDoor::update);
+ SetMessageHandler(&AsScene1201RightDoor::handleMessage);
+ _newStickFrameIndex = STICK_LAST_FRAME;
+ if (isOpen) {
+ startAnimation(0xD088AC30, -1, -1);
+ _newStickFrameIndex = STICK_LAST_FRAME;
+ _countdown = 25;
+ } else {
+ stopAnimation();
+ setVisible(false);
+ }
+}
+
+void AsScene1201RightDoor::update() {
+ if (_countdown != 0 && (--_countdown == 0))
+ stCloseDoor();
+ AnimatedSprite::update();
+}
+
+uint32 AsScene1201RightDoor::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case NM_ANIMATION_STOP:
+ gotoNextState();
+ break;
+ case 0x4829:
+ stOpenDoor();
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene1201RightDoor::stOpenDoor() {
+ startAnimation(0xD088AC30, 0, -1);
+ _newStickFrameIndex = STICK_LAST_FRAME;
+ setVisible(true);
+ playSound(0, calcHash("fxDoorOpen20"));
+}
+
+void AsScene1201RightDoor::stCloseDoor() {
+ startAnimation(0xD088AC30, -1, -1);
+ _playBackwards = true;
+ setVisible(true);
+ playSound(0, calcHash("fxDoorClose20"));
+ NextState(&AsScene1201RightDoor::stCloseDoorDone);
+}
+
+void AsScene1201RightDoor::stCloseDoorDone() {
+ stopAnimation();
+ setVisible(false);
+}
+
+AsScene1201KlaymenHead::AsScene1201KlaymenHead(NeverhoodEngine *vm)
+ : AnimatedSprite(vm, 1200) {
+
+ createSurface(1200, 69, 98);
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsScene1201KlaymenHead::handleMessage);
+ SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
+ setVisible(false);
+}
+
+uint32 AsScene1201KlaymenHead::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case NM_KLAYMEN_STOP_CLIMBING:
+ _x = 436;
+ _y = 339;
+ startAnimation(0xA060C599, 0, -1);
+ setVisible(true);
+ break;
+ case NM_ANIMATION_STOP:
+ stopAnimation();
+ setVisible(false);
+ gotoNextState();
+ break;
+ }
+ return messageResult;
+}
+
+AsScene1201TntMan::AsScene1201TntMan(NeverhoodEngine *vm, Scene *parentScene, Sprite *asTntManRope, bool isComingDown)
+ : AnimatedSprite(vm, 1100), _parentScene(parentScene), _asTntManRope(asTntManRope),
+ _isMoving(false) {
+
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsScene1201TntMan::handleMessage);
+ createSurface(990, 106, 181);
+ _x = 201;
+ if (isComingDown) {
+ _y = 297;
+ stComingDown();
+ } else {
+ _y = 334;
+ stStanding();
+ }
+}
+
+AsScene1201TntMan::~AsScene1201TntMan() {
+ _vm->_soundMan->deleteSoundGroup(0x01D00560);
+}
+
+uint32 AsScene1201TntMan::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case NM_ANIMATION_START:
+ if (param.asInteger() == 0x092870C0)
+ sendMessage(_asTntManRope, NM_KLAYMEN_STOP_CLIMBING, 0);
+ else if (param.asInteger() == 0x11CA0144)
+ playSound(0, 0x51800A04);
+ break;
+ case 0x1011:
+ sendMessage(_parentScene, NM_POSITION_CHANGE, 0);
+ messageResult = 1;
+ break;
+ case 0x480B:
+ if (!_isMoving) {
+ _sprite = (Sprite*)sender;
+ stMoving();
+ }
+ break;
+ }
+ return messageResult;
+
+}
+
+uint32 AsScene1201TntMan::hmComingDown(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = AsScene1201TntMan::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case NM_ANIMATION_STOP:
+ gotoNextState();
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene1201TntMan::suMoving() {
+ _x = _sprite->getX() + 100;
+}
+
+void AsScene1201TntMan::stStanding() {
+ startAnimation(0x654913D0, 0, -1);
+ SetMessageHandler(&AsScene1201TntMan::handleMessage);
+ SetSpriteUpdate(NULL);
+}
+
+void AsScene1201TntMan::stComingDown() {
+ startAnimation(0x356803D0, 0, -1);
+ SetMessageHandler(&AsScene1201TntMan::hmComingDown);
+ SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
+ NextState(&AsScene1201TntMan::stStanding);
+}
+
+void AsScene1201TntMan::stMoving() {
+ _vm->_soundMan->addSound(0x01D00560, 0x4B044624);
+ _vm->_soundMan->playSoundLooping(0x4B044624);
+ _isMoving = true;
+ startAnimation(0x85084190, 0, -1);
+ SetMessageHandler(&AsScene1201TntMan::handleMessage);
+ SetSpriteUpdate(&AsScene1201TntMan::suMoving);
+ _newStickFrameIndex = STICK_LAST_FRAME;
+}
+
+AsScene1201TntManFlame::AsScene1201TntManFlame(NeverhoodEngine *vm, Sprite *asTntMan)
+ : AnimatedSprite(vm, 1200), _asTntMan(asTntMan) {
+
+ createSurface1(0x828C0411, 995);
+ SetUpdateHandler(&AsScene1201TntManFlame::update);
+ SetMessageHandler(&Sprite::handleMessage);
+ SetSpriteUpdate(&AsScene1201TntManFlame::suUpdate);
+ startAnimation(0x828C0411, 0, -1);
+ setVisible(false);
+}
+
+AsScene1201TntManFlame::~AsScene1201TntManFlame() {
+ _vm->_soundMan->deleteSoundGroup(0x041080A4);
+}
+
+void AsScene1201TntManFlame::update() {
+ AnimatedSprite::update();
+ if (getGlobalVar(V_TNT_DUMMY_FUSE_LIT)) {
+ setVisible(true);
+ SetUpdateHandler(&AnimatedSprite::update);
+ _vm->_soundMan->addSound(0x041080A4, 0x460A1050);
+ _vm->_soundMan->playSoundLooping(0x460A1050);
+ }
+}
+
+void AsScene1201TntManFlame::suUpdate() {
+ _x = _asTntMan->getX() - 18;
+ _y = _asTntMan->getY() - 158;
+}
+
+AsScene1201Match::AsScene1201Match(NeverhoodEngine *vm, Scene *parentScene)
+ : AnimatedSprite(vm, 1100), _parentScene(parentScene), _countdown(0) {
+
+ createSurface(1100, 57, 60);
+ SetUpdateHandler(&AsScene1201Match::update);
+ SetMessageHandler(&AsScene1201Match::hmOnDoorFrameAboutToMove);
+ SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
+ switch (getGlobalVar(V_MATCH_STATUS)) {
+ case 0:
+ _x = 521;
+ _y = 112;
+ _status = 0;
+ stIdleOnDoorFrame();
+ break;
+ case 1:
+ _x = 521;
+ _y = 112;
+ _status = 2;
+ stOnDoorFrameAboutToMove();
+ loadSound(0, 0xD00230CD);
+ break;
+ case 2:
+ setDoDeltaX(1);
+ _x = 403;
+ _y = 337;
+ _status = 0;
+ stIdleOnFloor();
+ break;
+ }
+}
+
+void AsScene1201Match::update() {
+ if (_countdown != 0 && (--_countdown == 0))
+ gotoNextState();
+ updateAnim();
+ handleSpriteUpdate();
+ updatePosition();
+}
+
+uint32 AsScene1201Match::hmOnDoorFrameAboutToMove(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case NM_ANIMATION_START:
+ if (param.asInteger() == 0x86668011)
+ playSound(0);
+ break;
+ }
+ return messageResult;
+}
+
+uint32 AsScene1201Match::hmOnDoorFrameMoving(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = hmOnDoorFrameAboutToMove(messageNum, param, sender);
+ switch (messageNum) {
+ case NM_ANIMATION_STOP:
+ gotoNextState();
+ break;
+ }
+ return messageResult;
+}
+
+uint32 AsScene1201Match::hmIdle(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = hmOnDoorFrameAboutToMove(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x1011:
+ sendMessage(_parentScene, 0x2001, 0);
+ messageResult = 1;
+ break;
+ case NM_KLAYMEN_USE_OBJECT:
+ setVisible(false);
+ setGlobalVar(V_MATCH_STATUS, 3);
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene1201Match::stOnDoorFrameMoving() {
+ startAnimation(0x00842374, 0, -1);
+ SetMessageHandler(&AsScene1201Match::hmOnDoorFrameMoving);
+ if (_status == 0) {
+ NextState(&AsScene1201Match::stFallingFromDoorFrame);
+ } else {
+ NextState(&AsScene1201Match::stOnDoorFrameAboutToMove);
+ }
+}
+
+void AsScene1201Match::stFallingFromDoorFrame() {
+ setGlobalVar(V_MATCH_STATUS, 2);
+ _x -= 199;
+ _y += 119;
+ startAnimation(0x018D0240, 0, -1);
+ SetMessageHandler(&AsScene1201Match::hmOnDoorFrameMoving);
+ NextState(&AsScene1201Match::stIdleOnFloor);
+}
+
+void AsScene1201Match::stOnDoorFrameAboutToMove() {
+ startAnimation(0x00842374, 0, -1);
+ SetMessageHandler(&AsScene1201Match::hmOnDoorFrameAboutToMove);
+ _newStickFrameIndex = 0;
+ if (_status != 0) {
+ _countdown = 36;
+ _status--;
+ NextState(&AsScene1201Match::stOnDoorFrameMoving);
+ }
+}
+
+void AsScene1201Match::stIdleOnDoorFrame() {
+ startAnimation(0x00842374, 0, -1);
+ SetMessageHandler(&AsScene1201Match::hmIdle);
+ _newStickFrameIndex = 0;
+}
+
+void AsScene1201Match::stIdleOnFloor() {
+ setDoDeltaX(1);
+ _x = 403;
+ _y = 337;
+ startAnimation(0x00842374, 0, -1);
+ SetMessageHandler(&AsScene1201Match::hmIdle);
+ _newStickFrameIndex = 0;
+}
+
+AsScene1201Creature::AsScene1201Creature(NeverhoodEngine *vm, Scene *parentScene, Sprite *klaymen)
+ : AnimatedSprite(vm, 900), _parentScene(parentScene), _klaymen(klaymen), _klaymenTooClose(false) {
+
+ // NOTE: _countdown2 and _countdown3 were unused/without effect and thus removed
+
+ createSurface(1100, 203, 199);
+ SetUpdateHandler(&AsScene1201Creature::update);
+ SetMessageHandler(&AsScene1201Creature::hmWaiting);
+ _x = 540;
+ _y = 320;
+ stWaiting();
+}
+
+void AsScene1201Creature::update() {
+ bool oldKlaymenTooClose = _klaymenTooClose;
+ _klaymenTooClose = _klaymen->getX() >= 385;
+ if (_klaymenTooClose != oldKlaymenTooClose)
+ stWaiting();
+ if (_countdown != 0 && (--_countdown == 0))
+ gotoNextState();
+ updateAnim();
+ handleSpriteUpdate();
+ updatePosition();
+}
+
+uint32 AsScene1201Creature::hmWaiting(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case NM_ANIMATION_START:
+ if (param.asInteger() == 0x02060018)
+ playSound(0, 0xCD298116);
+ break;
+ case 0x2004:
+ GotoState(&AsScene1201Creature::stStartReachForTntDummy);
+ break;
+ case NM_KLAYMEN_STOP_CLIMBING:
+ GotoState(&AsScene1201Creature::stPincerSnapKlaymen);
+ break;
+ }
+ return messageResult;
+}
+
+uint32 AsScene1201Creature::hmPincerSnap(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = hmWaiting(messageNum, param, sender);
+ switch (messageNum) {
+ case NM_ANIMATION_STOP:
+ gotoNextState();
+ break;
+ }
+ return messageResult;
+}
+
+uint32 AsScene1201Creature::hmPincerSnapKlaymen(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case NM_ANIMATION_START:
+ if (param.asInteger() == 0x02060018) {
+ playSound(0, 0xCD298116);
+ sendMessage(_parentScene, 0x4814, 0);
+ sendMessage(_klaymen, 0x4814, 0);
+ }
+ break;
+ case NM_ANIMATION_STOP:
+ gotoNextState();
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene1201Creature::stWaiting() {
+ startAnimation(0x08081513, 0, -1);
+ SetMessageHandler(&AsScene1201Creature::hmWaiting);
+ NextState(&AsScene1201Creature::stPincerSnap);
+ _countdown = 36;
+}
+
+void AsScene1201Creature::stPincerSnap() {
+ if (!_klaymenTooClose) {
+ startAnimation(0xCA287133, 0, -1);
+ SetMessageHandler(&AsScene1201Creature::hmPincerSnap);
+ NextState(&AsScene1201Creature::stWaiting);
+ }
+}
+
+void AsScene1201Creature::stStartReachForTntDummy() {
+ startAnimation(0x08081513, 0, -1);
+ SetMessageHandler(&AsScene1201Creature::hmWaiting);
+ NextState(&AsScene1201Creature::stReachForTntDummy);
+ _countdown = 48;
+}
+
+void AsScene1201Creature::stReachForTntDummy() {
+ startAnimation(0x5A201453, 0, -1);
+ SetMessageHandler(&AsScene1201Creature::hmWaiting);
+ _countdown = 0;
+}
+
+void AsScene1201Creature::stPincerSnapKlaymen() {
+ startAnimation(0xCA287133, 0, -1);
+ SetMessageHandler(&AsScene1201Creature::hmPincerSnapKlaymen);
+ NextState(&AsScene1201Creature::stWaiting);
+ _countdown = 0;
+}
+
+AsScene1201LeftDoor::AsScene1201LeftDoor(NeverhoodEngine *vm, Sprite *klaymen)
+ : AnimatedSprite(vm, 1100), _klaymen(klaymen) {
+
+ _x = 320;
+ _y = 240;
+ createSurface(800, 55, 199);
+ if (_klaymen->getX() < 100) {
+ startAnimation(0x508A111B, 0, -1);
+ _newStickFrameIndex = STICK_LAST_FRAME;
+ playSound(0, calcHash("fxDoorOpen03"));
+ } else {
+ startAnimation(0x508A111B, -1, -1);
+ _newStickFrameIndex = STICK_LAST_FRAME;
+ }
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsScene1201LeftDoor::handleMessage);
+}
+
+uint32 AsScene1201LeftDoor::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case NM_KLAYMEN_CLOSE_DOOR:
+ stCloseDoor();
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene1201LeftDoor::stCloseDoor() {
+ startAnimation(0x508A111B, -1, -1);
+ _playBackwards = true;
+ _newStickFrameIndex = 0;
+}
+
+static const NPoint kScene1202Points[] = {
+ {203, 140}, {316, 212}, {277, 264},
+ {176, 196}, {275, 159}, {366, 212},
+ {230, 195}, {412, 212}, {368, 263},
+ {204, 192}, {365, 164}, {316, 262},
+ {191, 255}, {280, 213}, {406, 266},
+ {214, 254}, {316, 158}, {402, 161}
+};
+
+static const uint32 kScene1202FileHashes[] = {
+ 0x1AC00B8, 0x1AC14B8, 0x1AC14B8,
+ 0x1AC30B8, 0x1AC14B8, 0x1AC14B8,
+ 0x1AC00B8, 0x1AC14B8, 0x1AC14B8,
+ 0x1AC90B8, 0x1AC18B8, 0x1AC18B8,
+ 0x1AC30B8, 0x1AC14B8, 0x1AC14B8,
+ 0x1AC50B8, 0x1AC14B8, 0x1AC14B8
+};
+
+AsScene1202TntItem::AsScene1202TntItem(NeverhoodEngine *vm, Scene *parentScene, int itemIndex)
+ : AnimatedSprite(vm, 900), _parentScene(parentScene), _itemIndex(itemIndex) {
+
+ int positionIndex;
+
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsScene1202TntItem::hmShowIdle);
+ positionIndex = getSubVar(VA_TNT_POSITIONS, _itemIndex);
+ createSurface(900, 37, 67);
+ _x = kScene1202Points[positionIndex].x;
+ _y = kScene1202Points[positionIndex].y;
+ stShowIdle();
+}
+
+uint32 AsScene1202TntItem::hmShowIdle(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x1011:
+ sendMessage(_parentScene, 0x2000, _itemIndex);
+ messageResult = 1;
+ break;
+ case 0x2001:
+ _newPosition = (int)param.asInteger();
+ stChangePositionFadeOut();
+ break;
+ }
+ return messageResult;
+}
+
+uint32 AsScene1202TntItem::hmChangePosition(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case NM_ANIMATION_STOP:
+ gotoNextState();
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene1202TntItem::stShowIdle() {
+ startAnimation(kScene1202FileHashes[_itemIndex], 0, -1);
+ SetMessageHandler(&AsScene1202TntItem::hmShowIdle);
+ _newStickFrameIndex = 0;
+}
+
+void AsScene1202TntItem::stChangePositionFadeOut() {
+ startAnimation(kScene1202FileHashes[_itemIndex], 0, -1);
+ SetMessageHandler(&AsScene1202TntItem::hmChangePosition);
+ NextState(&AsScene1202TntItem::stChangePositionFadeIn);
+}
+
+void AsScene1202TntItem::stChangePositionFadeIn() {
+ _x = kScene1202Points[_newPosition].x;
+ _y = kScene1202Points[_newPosition].y;
+ startAnimation(kScene1202FileHashes[_itemIndex], 6, -1);
+ _playBackwards = true;
+ SetMessageHandler(&AsScene1202TntItem::hmChangePosition);
+ NextState(&AsScene1202TntItem::stChangePositionDone);
+}
+
+void AsScene1202TntItem::stChangePositionDone() {
+ sendMessage(_parentScene, NM_POSITION_CHANGE, _itemIndex);
+ stShowIdle();
+}
+
+static const KlaymenIdleTableItem klaymenIdleTable1201[] = {
+ {1, kIdleSpinHead},
+ {1, kIdleChest},
+ {1, kIdleHeadOff},
+};
+
+KmScene1201::KmScene1201(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
+ : Klaymen(vm, parentScene, x, y) {
+
+ setKlaymenIdleTable(klaymenIdleTable1201, ARRAYSIZE(klaymenIdleTable1201));
+ _doYHitIncr = true;
+}
+
+uint32 KmScene1201::xHandleMessage(int messageNum, const MessageParam &param) {
+ switch (messageNum) {
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case NM_KLAYMEN_STAND_IDLE:
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case NM_KLAYMEN_MOVE_OBJECT:
+ GotoState(&Klaymen::stMoveObject);
+ break;
+ case NM_KLAYMEN_PICKUP:
+ GotoState(&Klaymen::stPickUpGeneric);
+ break;
+ case 0x4813:
+ GotoState(&KmScene1201::stFetchMatch);
+ break;
+ case 0x4814:
+ GotoState(&KmScene1201::stTumbleHeadless);
+ break;
+ case 0x4815:
+ GotoState(&KmScene1201::stCloseEyes);
+ break;
+ case NM_KLAYMEN_PRESS_BUTTON:
+ if (param.asInteger() == 0)
+ GotoState(&Klaymen::stPressButtonSide);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ gotoNextStateExt();
+ break;
+ case 0x481B:
+ if (param.asPoint().y != 0)
+ startWalkToXDistance(param.asPoint().y, param.asPoint().x);
+ else
+ startWalkToAttachedSpriteXDistance(param.asPoint().x);
+ break;
+ case NM_KLAYMEN_TURN_TO_USE:
+ GotoState(&Klaymen::stTurnToUse);
+ break;
+ case NM_KLAYMEN_RETURN_FROM_USE:
+ GotoState(&Klaymen::stReturnFromUse);
+ break;
+ case 0x481F:
+ GotoState(&Klaymen::stWonderAbout);
+ break;
+ case 0x482D:
+ setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
+ gotoNextStateExt();
+ break;
+ case 0x483F:
+ startSpecialWalkRight(param.asInteger());
+ break;
+ case 0x4840:
+ startSpecialWalkLeft(param.asInteger());
+ break;
+ }
+ return 0;
+}
+
+void KmScene1201::stTumbleHeadless() {
+ if (!stStartActionFromIdle(AnimationCallback(&KmScene1201::stTumbleHeadless))) {
+ _busyStatus = 1;
+ _acceptInput = false;
+ setDoDeltaX(0);
+ startAnimation(0x2821C590, 0, -1);
+ SetUpdateHandler(&Klaymen::update);
+ SetMessageHandler(&KmScene1201::hmTumbleHeadless);
+ SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
+ NextState(&Klaymen::stTryStandIdle);
+ sendMessage(_parentScene, 0x8000, 0);
+ playSound(0, 0x62E0A356);
+ }
+}
+
+void KmScene1201::stCloseEyes() {
+ if (!stStartActionFromIdle(AnimationCallback(&KmScene1201::stCloseEyes))) {
+ _busyStatus = 1;
+ _acceptInput = false;
+ startAnimation(0x5420E254, 0, -1);
+ SetUpdateHandler(&Klaymen::update);
+ SetMessageHandler(&Klaymen::hmLowLevel);
+ SetSpriteUpdate(NULL);
+ }
+}
+
+uint32 KmScene1201::hmMatch(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Klaymen::hmLowLevelAnimation(messageNum, param, sender);
+ switch (messageNum) {
+ case NM_ANIMATION_START:
+ if (param.asInteger() == 0x51281850) {
+ setGlobalVar(V_TNT_DUMMY_FUSE_LIT, 1);
+ } else if (param.asInteger() == 0x43000538) {
+ playSound(0, 0x21043059);
+ } else if (param.asInteger() == 0x02B20220) {
+ playSound(0, 0xC5408620);
+ } else if (param.asInteger() == 0x0A720138) {
+ playSound(0, 0xD4C08010);
+ } else if (param.asInteger() == 0xB613A180) {
+ playSound(0, 0x44051000);
+ }
+ break;
+ }
+ return messageResult;
+}
+
+void KmScene1201::stFetchMatch() {
+ if (!stStartAction(AnimationCallback(&KmScene1201::stFetchMatch))) {
+ _busyStatus = 0;
+ _acceptInput = false;
+ setDoDeltaX(_attachedSprite->getX() < _x ? 1 : 0);
+ startAnimation(0x9CAA0218, 0, -1);
+ SetUpdateHandler(&Klaymen::update);
+ SetMessageHandler(&KmScene1201::hmMatch);
+ SetSpriteUpdate(NULL);
+ NextState(&KmScene1201::stLightMatch);
+ }
+}
+
+void KmScene1201::stLightMatch() {
+ _busyStatus = 1;
+ _acceptInput = false;
+ setDoDeltaX(_attachedSprite->getX() < _x ? 1 : 0);
+ startAnimation(0x1222A513, 0, -1);
+ SetUpdateHandler(&Klaymen::update);
+ SetMessageHandler(&KmScene1201::hmMatch);
+ SetSpriteUpdate(NULL);
+}
+
+uint32 KmScene1201::hmTumbleHeadless(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Klaymen::hmLowLevelAnimation(messageNum, param, sender);
+ switch (messageNum) {
+ case NM_ANIMATION_START:
+ if (param.asInteger() == 0x000F0082) {
+ playSound(0, 0x74E2810F);
+ }
+ break;
+ }
+ return messageResult;
+}
+
+} // End of namespace Neverhood
diff --git a/engines/neverhood/modules/module1200_sprites.h b/engines/neverhood/modules/module1200_sprites.h
new file mode 100644
index 0000000000..ef1ec40ced
--- /dev/null
+++ b/engines/neverhood/modules/module1200_sprites.h
@@ -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.
+ *
+ */
+
+#ifndef NEVERHOOD_MODULES_MODULE1200_SPRITES_H
+#define NEVERHOOD_MODULES_MODULE1200_SPRITES_H
+
+#include "neverhood/neverhood.h"
+#include "neverhood/module.h"
+#include "neverhood/scene.h"
+
+namespace Neverhood {
+
+// Used for both the scene sprites and the scene itself (for clipping)
+static const NPoint kScene1201PointArray[] = {
+ {218, 193}, {410, 225}, {368, 277},
+ {194, 227}, {366, 174}, {458, 224},
+ {242, 228}, {512, 228}, {458, 277},
+ {217, 233}, {458, 173}, {410, 276},
+ {203, 280}, {371, 226}, {508, 279},
+ {230, 273}, {410, 171}, {493, 174}
+};
+
+class AsScene1201Tape : public AnimatedSprite {
+public:
+ AsScene1201Tape(NeverhoodEngine *vm, Scene *parentScene, uint32 nameHash, int surfacePriority, int16 x, int16 y, uint32 fileHash);
+protected:
+ Scene *_parentScene;
+ uint32 _nameHash;
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class AsScene1201TntManRope : public AnimatedSprite {
+public:
+ AsScene1201TntManRope(NeverhoodEngine *vm, bool isDummyHanging);
+protected:
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class AsScene1201RightDoor : public AnimatedSprite {
+public:
+ AsScene1201RightDoor(NeverhoodEngine *vm, Sprite *klaymen, bool isOpen);
+protected:
+ Sprite *_klaymen;
+ int _countdown;
+ void update();
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ void stOpenDoor();
+ void stCloseDoor();
+ void stCloseDoorDone();
+};
+
+class AsScene1201KlaymenHead : public AnimatedSprite {
+public:
+ AsScene1201KlaymenHead(NeverhoodEngine *vm);
+protected:
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class AsScene1201TntMan : public AnimatedSprite {
+public:
+ AsScene1201TntMan(NeverhoodEngine *vm, Scene *parentScene, Sprite *asTntManRope, bool isDown);
+ virtual ~AsScene1201TntMan();
+protected:
+ Scene *_parentScene;
+ Sprite *_asTntManRope;
+ Sprite *_sprite;
+ bool _isMoving;
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 hmComingDown(int messageNum, const MessageParam &param, Entity *sender);
+ void suMoving();
+ void stStanding();
+ void stComingDown();
+ void stMoving();
+};
+
+class AsScene1201TntManFlame : public AnimatedSprite {
+public:
+ AsScene1201TntManFlame(NeverhoodEngine *vm, Sprite *asTntMan);
+ ~AsScene1201TntManFlame();
+protected:
+ Sprite *_asTntMan;
+ void update();
+ void suUpdate();
+};
+
+class AsScene1201Match : public AnimatedSprite {
+public:
+ AsScene1201Match(NeverhoodEngine *vm, Scene *parentScene);
+protected:
+ Scene *_parentScene;
+ int _countdown;
+ int _status;
+ void update();
+ uint32 hmOnDoorFrameAboutToMove(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 hmOnDoorFrameMoving(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 hmIdle(int messageNum, const MessageParam &param, Entity *sender);
+ void stOnDoorFrameMoving();
+ void stFallingFromDoorFrame();
+ void stOnDoorFrameAboutToMove();
+ void stIdleOnDoorFrame();
+ void stIdleOnFloor();
+};
+
+class AsScene1201Creature : public AnimatedSprite {
+public:
+ AsScene1201Creature(NeverhoodEngine *vm, Scene *parentScene, Sprite *klaymen);
+protected:
+ Scene *_parentScene;
+ Sprite *_klaymen;
+ int _countdown;
+ bool _klaymenTooClose;
+ void update();
+ uint32 hmWaiting(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 hmPincerSnap(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 hmPincerSnapKlaymen(int messageNum, const MessageParam &param, Entity *sender);
+ void stWaiting();
+ void stPincerSnap();
+ void stStartReachForTntDummy();
+ void stReachForTntDummy();
+ void stPincerSnapKlaymen();
+};
+
+class AsScene1201LeftDoor : public AnimatedSprite {
+public:
+ AsScene1201LeftDoor(NeverhoodEngine *vm, Sprite *klaymen);
+protected:
+ Sprite *_klaymen;
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ void stCloseDoor();
+};
+
+class SsScene1201Tnt : public StaticSprite {
+public:
+ SsScene1201Tnt(NeverhoodEngine *vm, uint32 elemIndex, uint32 pointIndex, int16 clipY2);
+};
+
+class AsScene1202TntItem : public AnimatedSprite {
+public:
+ AsScene1202TntItem(NeverhoodEngine *vm, Scene *parentScene, int index);
+protected:
+ Scene *_parentScene;
+ int _itemIndex, _newPosition;
+ uint32 hmShowIdle(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 hmChangePosition(int messageNum, const MessageParam &param, Entity *sender);
+ void stShowIdle();
+ void stChangePositionFadeOut();
+ void stChangePositionFadeIn();
+ void stChangePositionDone();
+};
+
+class KmScene1201 : public Klaymen {
+public:
+ KmScene1201(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
+protected:
+ void stCloseEyes();
+ void stTumbleHeadless();
+ void stFetchMatch();
+ void stLightMatch();
+
+ uint32 hmTumbleHeadless(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 hmMatch(int messageNum, const MessageParam &param, Entity *sender);
+
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+};
+
+} // End of namespace Neverhood
+
+#endif /* NEVERHOOD_MODULES_MODULE1200_SPRITES_H */
diff --git a/engines/neverhood/modules/module1300.cpp b/engines/neverhood/modules/module1300.cpp
index c8a561af76..fe119c1732 100644
--- a/engines/neverhood/modules/module1300.cpp
+++ b/engines/neverhood/modules/module1300.cpp
@@ -20,16 +20,15 @@
*
*/
-#include "neverhood/modules/module1300.h"
-#include "neverhood/modules/module1000.h"
-#include "neverhood/modules/module1200.h"
-#include "neverhood/modules/module1400.h"
-#include "neverhood/modules/module2200.h"
-#include "neverhood/gamemodule.h"
#include "neverhood/diskplayerscene.h"
+#include "neverhood/gamemodule.h"
#include "neverhood/menumodule.h"
-#include "neverhood/navigationscene.h"
-#include "neverhood/smackerscene.h"
+#include "neverhood/modules/module1000_sprites.h"
+#include "neverhood/modules/module1200_sprites.h"
+#include "neverhood/modules/module1300.h"
+#include "neverhood/modules/module1300_sprites.h"
+#include "neverhood/modules/module1400_sprites.h"
+#include "neverhood/modules/module2200_sprites.h"
namespace Neverhood {
@@ -311,113 +310,6 @@ void Module1300::updateScene() {
}
}
-AsScene1302Bridge::AsScene1302Bridge(NeverhoodEngine *vm, Scene *parentScene)
- : AnimatedSprite(vm, 1100), _parentScene(parentScene) {
-
- _x = 320;
- _y = 240;
- createSurface1(0x88148150, 500);
- if (!getGlobalVar(V_FLYTRAP_RING_BRIDGE)) {
- startAnimation(0x88148150, 0, -1);
- _newStickFrameIndex = 0;
- } else {
- startAnimation(0x88148150, -1, -1);
- _newStickFrameIndex = STICK_LAST_FRAME;
- }
- loadSound(0, 0x68895082);
- loadSound(1, 0x689BD0C1);
- SetUpdateHandler(&AnimatedSprite::update);
- SetMessageHandler(&AsScene1302Bridge::handleMessage);
-}
-
-uint32 AsScene1302Bridge::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x3002:
- gotoNextState();
- break;
- case 0x4808:
- stLowerBridge();
- break;
- case 0x4809:
- stRaiseBridge();
- break;
- }
- return messageResult;
-}
-
-void AsScene1302Bridge::stLowerBridge() {
- startAnimation(0x88148150, 0, -1);
- playSound(1);
- NextState(&AsScene1302Bridge::cbLowerBridgeEvent);
-}
-
-void AsScene1302Bridge::stRaiseBridge() {
- startAnimation(0x88148150, 7, -1);
- _playBackwards = true;
- _newStickFrameIndex = 0;
- playSound(0);
-}
-
-void AsScene1302Bridge::cbLowerBridgeEvent() {
- sendMessage(_parentScene, 0x2032, 0);
- startAnimation(0x88148150, -1, -1);
- _newStickFrameIndex = STICK_LAST_FRAME;
-}
-
-SsScene1302Fence::SsScene1302Fence(NeverhoodEngine *vm)
- : StaticSprite(vm, 0x11122122, 200) {
-
- _firstY = _y;
- if (getGlobalVar(V_FLYTRAP_RING_FENCE))
- _y += 152;
- loadSound(0, 0x7A00400C);
- loadSound(1, 0x78184098);
- SetUpdateHandler(&SsScene1302Fence::update);
- SetMessageHandler(&SsScene1302Fence::handleMessage);
- SetSpriteUpdate(NULL);
-}
-
-void SsScene1302Fence::update() {
- handleSpriteUpdate();
- updatePosition();
-}
-
-uint32 SsScene1302Fence::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x4808:
- playSound(0);
- SetMessageHandler(NULL);
- SetSpriteUpdate(&SsScene1302Fence::suMoveDown);
- break;
- case 0x4809:
- playSound(1);
- SetMessageHandler(NULL);
- SetSpriteUpdate(&SsScene1302Fence::suMoveUp);
- break;
- }
- return messageResult;
-}
-
-void SsScene1302Fence::suMoveDown() {
- if (_y < _firstY + 152)
- _y += 8;
- else {
- SetMessageHandler(&SsScene1302Fence::handleMessage);
- SetSpriteUpdate(NULL);
- }
-}
-
-void SsScene1302Fence::suMoveUp() {
- if (_y > _firstY)
- _y -= 8;
- else {
- SetMessageHandler(&SsScene1302Fence::handleMessage);
- SetSpriteUpdate(NULL);
- }
-}
-
Scene1302::Scene1302(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule) {
@@ -458,7 +350,7 @@ Scene1302::Scene1302(NeverhoodEngine *vm, Module *parentModule, int which)
_asVenusFlyTrap = insertSprite<AsScene1002VenusFlyTrap>(this, _klaymen, true);
addCollisionSprite(_asVenusFlyTrap);
- sendEntityMessage(_klaymen, 0x2007, _asVenusFlyTrap);
+ sendEntityMessage(_klaymen, NM_CAR_MOVE_TO_PREV_POINT, _asVenusFlyTrap);
}
@@ -466,10 +358,10 @@ uint32 Scene1302::handleMessage(int messageNum, const MessageParam &param, Entit
uint32 messageResult = 0;
Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
- if (param.asInteger() == 0x4A845A00)
+ case NM_ANIMATION_START:
+ if (param.asInteger() == 0x4A845A00) {
sendEntityMessage(_klaymen, 0x1014, _asRing1);
- else if (param.asInteger() == 0x43807801) {
+ } else if (param.asInteger() == 0x43807801) {
if (!getGlobalVar(V_FLYTRAP_RING_BRIDGE)) {
sendEntityMessage(_klaymen, 0x1014, _asRing2);
if (_asVenusFlyTrap->getX() - 10 < 218 + 32 && _asVenusFlyTrap->getX() + 10 > 218 + 32)
@@ -479,9 +371,9 @@ uint32 Scene1302::handleMessage(int messageNum, const MessageParam &param, Entit
} else
setMessageList(0x004B0950);
messageResult = 1;
- } else if (param.asInteger() == 0x46C26A01)
+ } else if (param.asInteger() == 0x46C26A01) {
sendEntityMessage(_klaymen, 0x1014, _asRing3);
- else if (param.asInteger() == 0x468C7B11) {
+ } else if (param.asInteger() == 0x468C7B11) {
if (!getGlobalVar(V_FLYTRAP_RING_FENCE)) {
sendEntityMessage(_klaymen, 0x1014, _asRing4);
if (_asVenusFlyTrap->getX() - 10 < 218 + 32 + 32 + 32 && _asVenusFlyTrap->getX() + 10 > 218 + 32 + 32 + 32)
@@ -491,9 +383,9 @@ uint32 Scene1302::handleMessage(int messageNum, const MessageParam &param, Entit
} else
setMessageList(0x004B0950);
messageResult = 1;
- } else if (param.asInteger() == 0x42845B19)
+ } else if (param.asInteger() == 0x42845B19) {
sendEntityMessage(_klaymen, 0x1014, _asRing5);
- else if (param.asInteger() == 0x430A6060) {
+ } else if (param.asInteger() == 0x430A6060) {
if (getGlobalVar(V_FLYTRAP_RING_BRIDGE))
setMessageList2(0x004B0910);
else
@@ -510,66 +402,66 @@ uint32 Scene1302::handleMessage(int messageNum, const MessageParam &param, Entit
setMessageList(0x004B0978);
}
break;
- case 0x2000:
+ case NM_ANIMATION_UPDATE:
if (_klaymen->getY() > 360) {
sendEntityMessage(_klaymen, 0x1014, _asVenusFlyTrap);
setMessageList2(0x004B08F0);
} else
setMessageList2(0x004B0920);
break;
- case 0x2002:
+ case NM_POSITION_CHANGE:
if (_klaymen->getX() > 545)
leaveScene(1);
break;
case 0x2032:
_sprite2->setVisible(true);
break;
- case 0x4806:
+ case NM_KLAYMEN_USE_OBJECT:
sendMessage(_parentModule, 0x1024, 2);
if (sender == _asRing1)
playSound(0, 0x665198C0);
else if (sender == _asRing2) {
- sendMessage(_asBridge, 0x4808, 0);
+ sendMessage(_asBridge, NM_KLAYMEN_OPEN_DOOR, 0);
setGlobalVar(V_FLYTRAP_RING_BRIDGE, 1);
- } else if (sender == _asRing3)
+ } else if (sender == _asRing3) {
playSound(0, 0xE2D389C0);
- else if (sender == _asRing4) {
- sendMessage(_ssFence, 0x4808, 0);
+ } else if (sender == _asRing4) {
+ sendMessage(_ssFence, NM_KLAYMEN_OPEN_DOOR, 0);
setGlobalVar(V_FLYTRAP_RING_FENCE, 1);
} else if (sender == _asRing5)
playSound(0, 0x40428A09);
break;
- case 0x4807:
+ case NM_KLAYMEN_RAISE_LEVER:
if (sender == _asRing2) {
- sendMessage(_asBridge, 0x4809, 0);
+ sendMessage(_asBridge, NM_KLAYMEN_CLOSE_DOOR, 0);
setGlobalVar(V_FLYTRAP_RING_BRIDGE, 0);
_sprite2->setVisible(false);
} else if (sender == _asRing4) {
- sendMessage(_ssFence, 0x4809, 0);
+ sendMessage(_ssFence, NM_KLAYMEN_CLOSE_DOOR, 0);
setGlobalVar(V_FLYTRAP_RING_FENCE, 0);
} else if (sender == _asVenusFlyTrap) {
if (getGlobalVar(V_FLYTRAP_RING_BRIDGE))
- sendMessage(_asRing2, 0x4807, 0);
+ sendMessage(_asRing2, NM_KLAYMEN_RAISE_LEVER, 0);
else
- sendMessage(_asRing4, 0x4807, 0);
+ sendMessage(_asRing4, NM_KLAYMEN_RAISE_LEVER, 0);
}
break;
- case 0x480F:
+ case NM_KLAYMEN_LOWER_LEVER:
if (sender == _asRing2) {
playSound(0, 0x60755842);
- sendMessage(_asBridge, 0x4808, 0);
+ sendMessage(_asBridge, NM_KLAYMEN_OPEN_DOOR, 0);
setGlobalVar(V_FLYTRAP_RING_BRIDGE, 1);
} else if (sender == _asRing4) {
playSound(0, 0x60755842);
- sendMessage(_ssFence, 0x4808, 0);
+ sendMessage(_ssFence, NM_KLAYMEN_OPEN_DOOR, 0);
setGlobalVar(V_FLYTRAP_RING_FENCE, 1);
}
break;
- case 0x482A:
- sendMessage(_asVenusFlyTrap, 0x482B, 0);
+ case NM_MOVE_TO_BACK:
+ sendMessage(_asVenusFlyTrap, NM_MOVE_TO_FRONT, 0);
break;
- case 0x482B:
- sendMessage(_asVenusFlyTrap, 0x482A, 0);
+ case NM_MOVE_TO_FRONT:
+ sendMessage(_asVenusFlyTrap, NM_MOVE_TO_BACK, 0);
break;
case 0x8000:
setSpriteSurfacePriority(_class595, 995);
@@ -581,56 +473,8 @@ uint32 Scene1302::handleMessage(int messageNum, const MessageParam &param, Entit
return messageResult;
}
-AsScene1303Balloon::AsScene1303Balloon(NeverhoodEngine *vm, Scene *parentScene)
- : AnimatedSprite(vm, 1100), _parentScene(parentScene) {
-
- createSurface(200, 128, 315);
- _x = 289;
- _y = 390;
- startAnimation(0x800278D2, 0, -1);
- SetUpdateHandler(&AnimatedSprite::update);
- SetMessageHandler(&AsScene1303Balloon::handleMessage);
- SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
-}
-
-uint32 AsScene1303Balloon::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x1011:
- sendMessage(_parentScene, 0x4826, 0);
- messageResult = 1;
- break;
- case 0x2000:
- stPopBalloon();
- break;
- }
- return messageResult;
-}
-
-uint32 AsScene1303Balloon::hmBalloonPopped(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x100D:
- if (param.asInteger() == 0x020B0003)
- playSound(0, 0x742B0055);
- break;
- case 0x3002:
- playSound(0, 0x470007EE);
- stopAnimation();
- setVisible(false);
- SetMessageHandler(NULL);
- break;
- }
- return messageResult;
-}
-
-void AsScene1303Balloon::stPopBalloon() {
- startAnimation(0xAC004CD0, 0, -1);
- SetMessageHandler(&AsScene1303Balloon::hmBalloonPopped);
-}
-
Scene1303::Scene1303(NeverhoodEngine *vm, Module *parentModule)
- : Scene(vm, parentModule) {
+ : Scene(vm, parentModule), _asBalloon(NULL) {
SetMessageHandler(&Scene1303::handleMessage);
@@ -656,7 +500,7 @@ Scene1303::Scene1303(NeverhoodEngine *vm, Module *parentModule)
uint32 Scene1303::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x2000:
+ case NM_ANIMATION_UPDATE:
setGlobalVar(V_BALLOON_POPPED, 1);
sendMessage(_asBalloon, 0x2000, 0);
break;
@@ -668,29 +512,6 @@ uint32 Scene1303::handleMessage(int messageNum, const MessageParam &param, Entit
return 0;
}
-AsScene1304Needle::AsScene1304Needle(NeverhoodEngine *vm, Scene *parentScene, int surfacePriority, int16 x, int16 y)
- : AnimatedSprite(vm, 0x548E9411, surfacePriority, x, y), _parentScene(parentScene) {
-
- // NOTE: Skipped check if Klaymen already has the needle since that's done in the scene itself
- SetMessageHandler(&AsScene1304Needle::handleMessage);
-}
-
-uint32 AsScene1304Needle::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x1011:
- sendMessage(_parentScene, 0x4826, 0);
- messageResult = 1;
- break;
- case 0x4806:
- setGlobalVar(V_HAS_NEEDLE, 1);
- setVisible(false);
- SetMessageHandler(NULL);
- break;
- }
- return messageResult;
-}
-
Scene1304::Scene1304(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule), _asNeedle(NULL) {
@@ -734,7 +555,7 @@ Scene1304::Scene1304(NeverhoodEngine *vm, Module *parentModule, int which)
uint32 Scene1304::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0x415634A4) {
if (getGlobalVar(V_BALLOON_POPPED))
cancelMessageList();
@@ -781,91 +602,6 @@ uint32 Scene1305::handleMessage(int messageNum, const MessageParam &param, Entit
return Scene::handleMessage(messageNum, param, sender);
}
-AsScene1306Elevator::AsScene1306Elevator(NeverhoodEngine *vm, Scene *parentScene, AnimatedSprite *asElevatorDoor)
- : AnimatedSprite(vm, 1100), _parentScene(parentScene), _asElevatorDoor(asElevatorDoor), _isUp(false), _isDown(true),
- _countdown(0) {
-
- _x = 320;
- _y = 240;
- createSurface1(0x043B0270, 100);
- startAnimation(0x043B0270, 0, -1);
- _newStickFrameIndex = 0;
- loadSound(0, 0x1C100E83);
- loadSound(1, 0x1C08CEC5);
- loadSound(2, 0x5D011E87);
- SetMessageHandler(&AsScene1306Elevator::handleMessage);
-}
-
-void AsScene1306Elevator::update() {
- if (_isUp && _countdown != 0 && (--_countdown == 0))
- stGoingDown();
- AnimatedSprite::update();
- if (_currFrameIndex == 7 && _asElevatorDoor->getVisible()) {
- playSound(1);
- _asElevatorDoor->setVisible(false);
- }
-}
-
-void AsScene1306Elevator::upGoingDown() {
- AnimatedSprite::update();
- if (_currFrameIndex == 5)
- _asElevatorDoor->setVisible(true);
-}
-
-uint32 AsScene1306Elevator::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x2001:
- if (_isUp)
- _countdown = 144;
- messageResult = _isUp ? 1 : 0;
- break;
- case 0x3002:
- gotoNextState();
- break;
- case 0x4808:
- if (_isDown)
- stGoingUp();
- break;
- }
- return messageResult;
-}
-
-void AsScene1306Elevator::stGoingUp() {
- setVisible(true);
- _isDown = false;
- startAnimation(0x043B0270, 0, -1);
- playSound(0);
- SetUpdateHandler(&AsScene1306Elevator::update);
- NextState(&AsScene1306Elevator::cbGoingUpEvent);
-}
-
-void AsScene1306Elevator::cbGoingUpEvent() {
- sendMessage(_parentScene, 0x4808, 0);
- _isUp = true;
- _countdown = 144;
- stopAnimation();
- setVisible(false);
- SetUpdateHandler(&AsScene1306Elevator::update);
-}
-
-void AsScene1306Elevator::stGoingDown() {
- _isUp = false;
- setVisible(true);
- startAnimation(0x043B0270, -1, -1);
- _playBackwards = true;
- playSound(1);
- SetUpdateHandler(&AsScene1306Elevator::upGoingDown);
- NextState(&AsScene1306Elevator::cbGoingDownEvent);
-}
-
-void AsScene1306Elevator::cbGoingDownEvent() {
- _isDown = true;
- sendMessage(_parentScene, 0x4809, 0);
- stopAnimation();
- SetUpdateHandler(&AsScene1306Elevator::update);
-}
-
Scene1306::Scene1306(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule) {
@@ -893,7 +629,7 @@ Scene1306::Scene1306(NeverhoodEngine *vm, Module *parentModule, int which)
insertStaticSprite(0x00042313, 1100);
if (which < 0) {
- // Resoring game
+ // Restoring game
insertKlaymen<KmScene1306>(380, 440);
setMessageList(0x004AFAD0);
sendMessage(this, 0x2000, 0);
@@ -945,7 +681,7 @@ Scene1306::Scene1306(NeverhoodEngine *vm, Module *parentModule, int which)
sendMessage(this, 0x2000, 0);
SetMessageHandler(&Scene1306::handleMessage416EB0);
clearRectList();
- sendMessage(_asElevator, 0x4808, 0);
+ sendMessage(_asElevator, NM_KLAYMEN_OPEN_DOOR, 0);
}
}
@@ -957,7 +693,7 @@ Scene1306::~Scene1306() {
uint32 Scene1306::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0x402064D8)
sendEntityMessage(_klaymen, 0x1014, _ssButton);
else if (param.asInteger() == 0x01C66840) {
@@ -971,7 +707,7 @@ uint32 Scene1306::handleMessage(int messageNum, const MessageParam &param, Entit
SetMessageHandler(&Scene1306::handleMessage416EB0);
}
break;
- case 0x2000:
+ case NM_ANIMATION_UPDATE:
if (param.asInteger() != 0) {
setRectList(0x004AFD28);
_klaymen->setKlaymenIdleTable3();
@@ -982,7 +718,7 @@ uint32 Scene1306::handleMessage(int messageNum, const MessageParam &param, Entit
break;
case 0x480B:
if (sender == _ssButton)
- sendMessage(_asElevator, 0x4808, 0);
+ sendMessage(_asElevator, NM_KLAYMEN_OPEN_DOOR, 0);
break;
case 0x4826:
if (sender == _asKey) {
@@ -997,12 +733,12 @@ uint32 Scene1306::handleMessage(int messageNum, const MessageParam &param, Entit
}
}
break;
- case 0x482A:
+ case NM_MOVE_TO_BACK:
setSurfacePriority(_asElevator->getSurface(), 1100);
setSurfacePriority(_asElevatorDoor->getSurface(), 1090);
setSurfacePriority(_sprite1->getSurface(), 1080);
break;
- case 0x482B:
+ case NM_MOVE_TO_FRONT:
setSurfacePriority(_asElevator->getSurface(), 100);
setSurfacePriority(_asElevatorDoor->getSurface(), 90);
setSurfacePriority(_sprite1->getSurface(), 80);
@@ -1016,19 +752,19 @@ uint32 Scene1306::handleMessage(int messageNum, const MessageParam &param, Entit
uint32 Scene1306::handleMessage416EB0(int messageNum, const MessageParam &param, Entity *sender) {
Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x4808:
+ case NM_KLAYMEN_OPEN_DOOR:
setMessageList(0x004AFBD0);
SetMessageHandler(&Scene1306::handleMessage);
break;
- case 0x4809:
+ case NM_KLAYMEN_CLOSE_DOOR:
leaveScene(1);
break;
- case 0x482A:
+ case NM_MOVE_TO_BACK:
setSurfacePriority(_asElevator->getSurface(), 1100);
setSurfacePriority(_asElevatorDoor->getSurface(), 1090);
setSurfacePriority(_sprite1->getSurface(), 1080);
break;
- case 0x482B:
+ case NM_MOVE_TO_FRONT:
setSurfacePriority(_asElevator->getSurface(), 100);
setSurfacePriority(_asElevatorDoor->getSurface(), 90);
setSurfacePriority(_sprite1->getSurface(), 80);
@@ -1039,188 +775,6 @@ uint32 Scene1306::handleMessage416EB0(int messageNum, const MessageParam &param,
return 0;
}
-static const uint32 kAsScene1307KeyResourceList1[] = {
- 0x0438069C, 0x45B0023C, 0x05700217
-};
-
-static const uint32 kAsScene1307KeyResourceList2[] = {
- 0x04441334, 0x061433F0, 0x06019390
-};
-
-static const uint32 kAsScene1307KeyResourceList3[] = {
- 0x11A80030, 0x178812B1, 0x1488121C
-};
-
-static const uint32 *kAsScene1307KeyResourceLists[] = {
- kAsScene1307KeyResourceList1,
- kAsScene1307KeyResourceList2,
- kAsScene1307KeyResourceList3
-};
-
-static const int kAsScene1307KeySurfacePriorities[] = {
- 700, 500, 300, 100
-};
-
-const uint kAsScene1307KeyPointsCount = 12;
-
-static const NPoint kAsScene1307KeyPoints[] = {
- {-2, 0}, {-5, 0}, { 5, 0},
- {12, 0}, {17, 0}, {25, 0},
- {16, -2}, {10, -6}, { 0, -7},
- {-7, -3}, {-3, 4}, { 2, 2}
-};
-
-const uint kAsScene1307KeyFrameIndicesCount = 20;
-
-static const int16 kAsScene1307KeyFrameIndices[] = {
- 1, 4, 8, 11, 15, 16, 17, 17, 17, 16,
- 15, 14, 12, 10, 9, 7, 5, 3, 2, 1
-};
-
-const int kAsScene1307KeyDivValue = 200;
-const int16 kAsScene1307KeyXDelta = 70;
-const int16 kAsScene1307KeyYDelta = -12;
-
-AsScene1307Key::AsScene1307Key(NeverhoodEngine *vm, Scene *parentScene, uint keyIndex, NRect *clipRects)
- : AnimatedSprite(vm, 1100), _parentScene(parentScene), _keyIndex(keyIndex), _clipRects(clipRects),
- _isClickable(true) {
-
- NPoint pt;
- const uint32 *fileHashes = kAsScene1307KeyResourceLists[_keyIndex];
-
- _dataResource.load(0x22102142);
- _pointList = _dataResource.getPointArray(0xAC849240);
- pt = (*_pointList)[getSubVar(VA_CURR_KEY_SLOT_NUMBERS, _keyIndex)];
- _x = pt.x;
- _y = pt.y;
- createSurface(kAsScene1307KeySurfacePriorities[getSubVar(VA_CURR_KEY_SLOT_NUMBERS, _keyIndex) % 4], 190, 148);
- startAnimation(fileHashes[0], 0, -1);
- loadSound(0, 0xDC4A1280);
- loadSound(1, 0xCC021233);
- loadSound(2, 0xC4C23844);
- loadSound(3, 0xC4523208);
- SetUpdateHandler(&AnimatedSprite::update);
- SetMessageHandler(&AsScene1307Key::handleMessage);
-}
-
-uint32 AsScene1307Key::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x1011:
- if (_isClickable) {
- sendMessage(_parentScene, 0x4826, 0);
- stRemoveKey();
- messageResult = 1;
- }
- break;
- case 0x2000:
- _isClickable = param.asInteger() != 0;
- break;
- case 0x2001:
- setSubVar(VA_CURR_KEY_SLOT_NUMBERS, _keyIndex, param.asInteger());
- stMoveKey();
- break;
- case 0x2003:
- playSound(3);
- stUnlock();
- break;
- case 0x2004:
- playSound(2);
- stInsert();
- break;
- }
- return messageResult;
-}
-
-void AsScene1307Key::suRemoveKey() {
- if (_pointIndex < kAsScene1307KeyPointsCount) {
- _x += kAsScene1307KeyPoints[_pointIndex].x;
- _y += kAsScene1307KeyPoints[_pointIndex].y;
- updateBounds();
- _pointIndex++;
- } else {
- SetSpriteUpdate(NULL);
- }
-}
-
-void AsScene1307Key::suInsertKey() {
- if (_pointIndex < kAsScene1307KeyPointsCount) {
- _x -= kAsScene1307KeyPoints[kAsScene1307KeyPointsCount - _pointIndex - 1].x;
- _y -= kAsScene1307KeyPoints[kAsScene1307KeyPointsCount - _pointIndex - 1].y;
- updateBounds();
- _pointIndex++;
- if (_pointIndex == 7)
- playSound(0);
- } else {
- SetSpriteUpdate(NULL);
- sendMessage(_parentScene, 0x2002, 0);
- }
-}
-
-void AsScene1307Key::suMoveKey() {
- if (_pointIndex < kAsScene1307KeyFrameIndicesCount) {
- _frameIndex += kAsScene1307KeyFrameIndices[_pointIndex];
- _x = _prevX + (_deltaX * _frameIndex) / kAsScene1307KeyDivValue;
- _y = _prevY + (_deltaY * _frameIndex) / kAsScene1307KeyDivValue;
- updateBounds();
- _pointIndex++;
- } else {
- NPoint pt = (*_pointList)[getSubVar(VA_CURR_KEY_SLOT_NUMBERS, _keyIndex)];
- _x = pt.x + kAsScene1307KeyXDelta;
- _y = pt.y + kAsScene1307KeyYDelta;
- stInsertKey();
- }
-}
-
-void AsScene1307Key::stRemoveKey() {
- const uint32 *fileHashes = kAsScene1307KeyResourceLists[_keyIndex];
- _pointIndex = 0;
- startAnimation(fileHashes[0], 0, -1);
- playSound(1);
- SetSpriteUpdate(&AsScene1307Key::suRemoveKey);
-}
-
-void AsScene1307Key::stInsertKey() {
- _pointIndex = 0;
- sendMessage(_parentScene, 0x1022, kAsScene1307KeySurfacePriorities[getSubVar(VA_CURR_KEY_SLOT_NUMBERS, _keyIndex) % 4]);
- setClipRect(_clipRects[getSubVar(VA_CURR_KEY_SLOT_NUMBERS, _keyIndex) % 4]);
- _newStickFrameIndex = STICK_LAST_FRAME;
- SetSpriteUpdate(&AsScene1307Key::suInsertKey);
-}
-
-void AsScene1307Key::stMoveKey() {
- NPoint pt = (*_pointList)[getSubVar(VA_CURR_KEY_SLOT_NUMBERS, _keyIndex)];
- int16 newX = pt.x + kAsScene1307KeyXDelta;
- int16 newY = pt.y + kAsScene1307KeyYDelta;
- sendMessage(_parentScene, 0x1022, 1000);
- setClipRect(0, 0, 640, 480);
- _prevX = _x;
- _prevY = _y;
- if (newX == _x && newY == _y) {
- stInsertKey();
- } else {
- const uint32 *fileHashes = kAsScene1307KeyResourceLists[_keyIndex];
- _pointIndex = 0;
- _frameIndex = 0;
- _deltaX = newX - _x;
- _deltaY = newY - _y;
- startAnimation(fileHashes[0], 0, -1);
- SetSpriteUpdate(&AsScene1307Key::suMoveKey);
- }
-}
-
-void AsScene1307Key::stUnlock() {
- const uint32 *fileHashes = kAsScene1307KeyResourceLists[_keyIndex];
- startAnimation(fileHashes[1], 0, -1);
- _newStickFrameIndex = STICK_LAST_FRAME;
-}
-
-void AsScene1307Key::stInsert() {
- const uint32 *fileHashes = kAsScene1307KeyResourceLists[_keyIndex];
- startAnimation(fileHashes[2], 0, -1);
- _newStickFrameIndex = STICK_LAST_FRAME;
-}
-
Scene1307::Scene1307(NeverhoodEngine *vm, Module *parentModule)
: Scene(vm, parentModule), _countdown(0), _asCurrKey(NULL),
_isInsertingKey(false), _doLeaveScene(false), _isPuzzleSolved(false) {
@@ -1286,7 +840,7 @@ uint32 Scene1307::handleMessage(int messageNum, const MessageParam &param, Entit
uint32 messageResult = 0;
Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x0001:
+ case NM_MOUSE_CLICK:
if (!_isPuzzleSolved) {
if (param.asPoint().x > 20 && param.asPoint().x < 620) {
if (_asCurrKey && !_isInsertingKey) {
@@ -1319,7 +873,7 @@ uint32 Scene1307::handleMessage(int messageNum, const MessageParam &param, Entit
leaveScene(0);
}
break;
- case 0x2002:
+ case NM_POSITION_CHANGE:
// Check if all keys are in the correct keyholes
if (getSubVar(VA_IS_KEY_INSERTED, 0) && getSubVar(VA_CURR_KEY_SLOT_NUMBERS, 0) == getSubVar(VA_GOOD_KEY_SLOT_NUMBERS, 0) &&
getSubVar(VA_IS_KEY_INSERTED, 1) && getSubVar(VA_CURR_KEY_SLOT_NUMBERS, 1) == getSubVar(VA_GOOD_KEY_SLOT_NUMBERS, 1) &&
@@ -1360,164 +914,6 @@ static const uint32 kScene1308NumberFileHashes[] = {
0x00306322
};
-AsScene1308JaggyDoor::AsScene1308JaggyDoor(NeverhoodEngine *vm, Scene *parentScene)
- : AnimatedSprite(vm, 0xBA0AE050, 1100, 320, 240), _parentScene(parentScene) {
-
- setVisible(false);
- stopAnimation();
- SetMessageHandler(&AsScene1308JaggyDoor::handleMessage);
-}
-
-uint32 AsScene1308JaggyDoor::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x3002:
- gotoNextState();
- break;
- case 0x4808:
- stOpenDoor();
- break;
- case 0x4809:
- stCloseDoor();
- break;
- }
- return messageResult;
-}
-
-void AsScene1308JaggyDoor::stOpenDoor() {
- startAnimation(0xBA0AE050, 0, -1);
- setVisible(true);
- playSound(0, calcHash("fxDoorOpen38"));
- NextState(&AsScene1308JaggyDoor::stOpenDoorDone);
-}
-
-void AsScene1308JaggyDoor::stOpenDoorDone() {
- sendMessage(_parentScene, 0x2000, 0);
- stopAnimation();
- setVisible(false);
-}
-
-void AsScene1308JaggyDoor::stCloseDoor() {
- startAnimation(0xBA0AE050, -1, -1);
- _playBackwards = true;
- setVisible(true);
- playSound(0, calcHash("fxDoorClose38"));
- NextState(&AsScene1308JaggyDoor::stCloseDoorDone);
-}
-
-void AsScene1308JaggyDoor::stCloseDoorDone() {
- sendMessage(_parentScene, 0x2001, 0);
- stopAnimation();
-}
-
-AsScene1308KeyboardDoor::AsScene1308KeyboardDoor(NeverhoodEngine *vm, Scene *parentScene)
- : AnimatedSprite(vm, 0xA08A0851, 1100, 320, 240), _parentScene(parentScene) {
-
- playSound(0, 0x51456049);
- SetMessageHandler(&AsScene1308KeyboardDoor::handleMessage);
- NextState(&AsScene1308KeyboardDoor::stFallingKeys);
-}
-
-uint32 AsScene1308KeyboardDoor::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x3002:
- gotoNextState();
- break;
- }
- return messageResult;
-}
-
-void AsScene1308KeyboardDoor::stFallingKeys() {
- startAnimation(0x6238B191, 0, -1);
- _x = 580;
- _y = 383;
- NextState(&AsScene1308KeyboardDoor::stFallingKeysDone);
-}
-
-void AsScene1308KeyboardDoor::stFallingKeysDone() {
- sendMessage(_parentScene, 0x2004, 0);
- stopAnimation();
- setVisible(false);
-}
-
-AsScene1308LightWallSymbols::AsScene1308LightWallSymbols(NeverhoodEngine *vm, Scene *parentScene)
- : AnimatedSprite(vm, 0x80180A10, 100, 320, 240), _parentScene(parentScene) {
-
- setVisible(false);
- stopAnimation();
- Entity::_priority = 1200;
- SetMessageHandler(&AsScene1308LightWallSymbols::handleMessage);
-}
-
-uint32 AsScene1308LightWallSymbols::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x2002:
- stFadeIn();
- break;
- case 0x2003:
- stFadeOut();
- break;
- case 0x3002:
- gotoNextState();
- break;
- }
- return messageResult;
-}
-
-void AsScene1308LightWallSymbols::stFadeIn() {
- startAnimation(0x80180A10, 0, -1);
- setVisible(true);
- _newStickFrameIndex = STICK_LAST_FRAME;
-}
-
-void AsScene1308LightWallSymbols::stFadeOut() {
- startAnimation(0x80180A10, -1, -1);
- _playBackwards = true;
- NextState(&AsScene1308LightWallSymbols::stFadeOutDone);
-}
-
-void AsScene1308LightWallSymbols::stFadeOutDone() {
- sendMessage(_parentScene, 0x2003, 0);
- stopAnimation();
- setVisible(false);
-}
-
-SsScene1308Number::SsScene1308Number(NeverhoodEngine *vm, uint32 fileHash, int index)
- : StaticSprite(vm, fileHash, 100) {
-
- setVisible(false);
- _x = _spriteResource.getPosition().x + index * 20;
- updatePosition();
-}
-
-AsScene1308Mouse::AsScene1308Mouse(NeverhoodEngine *vm)
- : AnimatedSprite(vm, 1100) {
-
- _x = 286;
- _y = 429;
- createSurface1(0xA282C472, 100);
- startAnimation(0xA282C472, 0, -1);
- SetUpdateHandler(&AnimatedSprite::update);
- SetMessageHandler(&AsScene1308Mouse::handleMessage);
-}
-
-uint32 AsScene1308Mouse::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x100D:
- if (param.asInteger() == 0x66382026)
- playSound(0, 0x0CD84468);
- else if (param.asInteger() == 0x6E28061C)
- playSound(0, 0x78C8402C);
- else if (param.asInteger() == 0x462F0410)
- playSound(0, 0x60984E28);
- break;
- }
- return messageResult;
-}
-
Scene1308::Scene1308(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule), _isProjecting(false), _asProjector(NULL) {
@@ -1585,7 +981,7 @@ Scene1308::Scene1308(NeverhoodEngine *vm, Module *parentModule, int which)
// Klaymen entering from the left
insertKlaymen<KmScene1308>(41, 440);
setMessageList(0x004B57D0);
- sendMessage(_asJaggyDoor, 0x4808, 0);
+ sendMessage(_asJaggyDoor, NM_KLAYMEN_OPEN_DOOR, 0);
_sprite1->setVisible(false);
if (getGlobalVar(V_KEYDOOR_UNLOCKED)) {
_sprite4 = insertStaticSprite(0x0101A624, 1100);
@@ -1613,7 +1009,7 @@ Scene1308::Scene1308(NeverhoodEngine *vm, Module *parentModule, int which)
uint32 Scene1308::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0x88C11390) {
setRectList(0x004B59A0);
_isProjecting = true;
@@ -1626,12 +1022,12 @@ uint32 Scene1308::handleMessage(int messageNum, const MessageParam &param, Entit
_isProjecting = false;
} else if (param.asInteger() == 0x4AC68808) {
clearRectList();
- sendMessage(_asJaggyDoor, 0x4809, 0);
+ sendMessage(_asJaggyDoor, NM_KLAYMEN_CLOSE_DOOR, 0);
_sprite1->setVisible(false);
_klaymen->setVisible(false);
}
break;
- case 0x1022:
+ case NM_PRIORITY_CHANGE:
if (sender == _asProjector) {
if (param.asInteger() >= 1000)
setSurfacePriority(_sprite3->getSurface(), 1100);
@@ -1639,7 +1035,7 @@ uint32 Scene1308::handleMessage(int messageNum, const MessageParam &param, Entit
setSurfacePriority(_sprite3->getSurface(), 995);
}
break;
- case 0x2000:
+ case NM_ANIMATION_UPDATE:
if (getGlobalVar(V_KEYDOOR_UNLOCKED))
setRectList(0x004B5990);
else
@@ -1660,11 +1056,11 @@ uint32 Scene1308::handleMessage(int messageNum, const MessageParam &param, Entit
_sprite4->setVisible(true);
setRectList(0x004B5990);
break;
- case 0x4807:
+ case NM_KLAYMEN_RAISE_LEVER:
sendMessage(_asLightWallSymbols, 0x2003, 0);
break;
- case 0x480F:
- sendMessage(_asLightWallSymbols, 0x2002, 0);
+ case NM_KLAYMEN_LOWER_LEVER:
+ sendMessage(_asLightWallSymbols, NM_POSITION_CHANGE, 0);
_ssNumber1->setVisible(true);
_ssNumber2->setVisible(true);
_ssNumber3->setVisible(true);
@@ -1745,7 +1141,7 @@ void Scene1317::upChooseKing() {
uint32 Scene1317::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x3002:
+ case NM_ANIMATION_STOP:
stChooseKing();
break;
}
@@ -1755,7 +1151,7 @@ uint32 Scene1317::handleMessage(int messageNum, const MessageParam &param, Entit
uint32 Scene1317::hmChooseKing(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x0001:
+ case NM_MOUSE_CLICK:
if (param.asPoint().x >= 21 && param.asPoint().y >= 24 &&
param.asPoint().x <= 261 && param.asPoint().y <= 280) {
stHoborgAsKing();
@@ -1774,7 +1170,7 @@ uint32 Scene1317::hmChooseKing(int messageNum, const MessageParam &param, Entity
uint32 Scene1317::hmHoborgAsKing(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x3002:
+ case NM_ANIMATION_STOP:
stEndMovie();
break;
}
@@ -1784,7 +1180,7 @@ uint32 Scene1317::hmHoborgAsKing(int messageNum, const MessageParam &param, Enti
uint32 Scene1317::hmEndMovie(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x3002:
+ case NM_ANIMATION_STOP:
leaveScene(0);
break;
}
diff --git a/engines/neverhood/modules/module1300.h b/engines/neverhood/modules/module1300.h
index 501f76304f..2f59ff16c2 100644
--- a/engines/neverhood/modules/module1300.h
+++ b/engines/neverhood/modules/module1300.h
@@ -30,8 +30,6 @@
namespace Neverhood {
-// Module1300
-
class Module1300 : public Module {
public:
Module1300(NeverhoodEngine *vm, Module *parentModule, int which);
@@ -43,28 +41,6 @@ protected:
void updateScene();
};
-class AsScene1302Bridge : public AnimatedSprite {
-public:
- AsScene1302Bridge(NeverhoodEngine *vm, Scene *parentScene);
-protected:
- Scene *_parentScene;
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- void stLowerBridge();
- void stRaiseBridge();
- void cbLowerBridgeEvent();
-};
-
-class SsScene1302Fence : public StaticSprite {
-public:
- SsScene1302Fence(NeverhoodEngine *vm);
-protected:
- int16 _firstY;
- void update();
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- void suMoveDown();
- void suMoveUp();
-};
-
class Scene1302 : public Scene {
public:
Scene1302(NeverhoodEngine *vm, Module *parentModule, int which);
@@ -84,16 +60,6 @@ protected:
uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
};
-class AsScene1303Balloon : public AnimatedSprite {
-public:
- AsScene1303Balloon(NeverhoodEngine *vm, Scene *parentScene);
-protected:
- Scene *_parentScene;
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- uint32 hmBalloonPopped(int messageNum, const MessageParam &param, Entity *sender);
- void stPopBalloon();
-};
-
class Scene1303 : public Scene {
public:
Scene1303(NeverhoodEngine *vm, Module *parentModule);
@@ -103,14 +69,6 @@ protected:
uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
};
-class AsScene1304Needle : public AnimatedSprite {
-public:
- AsScene1304Needle(NeverhoodEngine *vm, Scene *parentScene, int surfacePriority, int16 x, int16 y);
-protected:
- Scene *_parentScene;
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
-
class Scene1304 : public Scene {
public:
Scene1304(NeverhoodEngine *vm, Module *parentModule, int which);
@@ -128,24 +86,6 @@ protected:
uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
};
-class AsScene1306Elevator : public AnimatedSprite {
-public:
- AsScene1306Elevator(NeverhoodEngine *vm, Scene *parentScene, AnimatedSprite *asElevatorDoor);
-protected:
- Scene *_parentScene;
- AnimatedSprite *_asElevatorDoor;
- bool _isUp;
- bool _isDown;
- int _countdown;
- void update();
- void upGoingDown();
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- void stGoingUp();
- void cbGoingUpEvent();
- void stGoingDown();
- void cbGoingDownEvent();
-};
-
class Scene1306 : public Scene {
public:
Scene1306(NeverhoodEngine *vm, Module *parentModule, int which);
@@ -161,30 +101,6 @@ protected:
uint32 handleMessage416EB0(int messageNum, const MessageParam &param, Entity *sender);
};
-class AsScene1307Key : public AnimatedSprite {
-public:
- AsScene1307Key(NeverhoodEngine *vm, Scene *parentScene, uint keyIndex, NRect *clipRects);
-protected:
- Scene *_parentScene;
- NPointArray *_pointList;
- uint _pointIndex;
- int _frameIndex;
- uint _keyIndex;
- NRect *_clipRects;
- bool _isClickable;
- int16 _prevX, _prevY;
- int16 _deltaX, _deltaY;
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- void suRemoveKey();
- void suInsertKey();
- void suMoveKey();
- void stRemoveKey();
- void stInsertKey();
- void stMoveKey();
- void stUnlock();
- void stInsert();
-};
-
class Scene1307 : public Scene {
public:
Scene1307(NeverhoodEngine *vm, Module *parentModule);
@@ -202,51 +118,6 @@ protected:
uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
};
-class AsScene1308JaggyDoor : public AnimatedSprite {
-public:
- AsScene1308JaggyDoor(NeverhoodEngine *vm, Scene *parentScene);
-protected:
- Scene *_parentScene;
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- void stOpenDoor();
- void stOpenDoorDone();
- void stCloseDoor();
- void stCloseDoorDone();
-};
-
-class AsScene1308KeyboardDoor : public AnimatedSprite {
-public:
- AsScene1308KeyboardDoor(NeverhoodEngine *vm, Scene *parentScene);
-protected:
- Scene *_parentScene;
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- void stFallingKeys();
- void stFallingKeysDone();
-};
-
-class AsScene1308LightWallSymbols : public AnimatedSprite {
-public:
- AsScene1308LightWallSymbols(NeverhoodEngine *vm, Scene *parentScene);
-protected:
- Scene *_parentScene;
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- void stFadeIn();
- void stFadeOut();
- void stFadeOutDone();
-};
-
-class SsScene1308Number : public StaticSprite {
-public:
- SsScene1308Number(NeverhoodEngine *vm, uint32 fileHash, int index);
-};
-
-class AsScene1308Mouse : public AnimatedSprite {
-public:
- AsScene1308Mouse(NeverhoodEngine *vm);
-protected:
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
-
class Scene1308 : public Scene {
public:
Scene1308(NeverhoodEngine *vm, Module *parentModule, int which);
diff --git a/engines/neverhood/modules/module1300_sprites.cpp b/engines/neverhood/modules/module1300_sprites.cpp
new file mode 100644
index 0000000000..0c1632501e
--- /dev/null
+++ b/engines/neverhood/modules/module1300_sprites.cpp
@@ -0,0 +1,935 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public 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 "neverhood/modules/module1300_sprites.h"
+
+namespace Neverhood {
+
+AsScene1302Bridge::AsScene1302Bridge(NeverhoodEngine *vm, Scene *parentScene)
+ : AnimatedSprite(vm, 1100), _parentScene(parentScene) {
+
+ _x = 320;
+ _y = 240;
+ createSurface1(0x88148150, 500);
+ if (!getGlobalVar(V_FLYTRAP_RING_BRIDGE)) {
+ startAnimation(0x88148150, 0, -1);
+ _newStickFrameIndex = 0;
+ } else {
+ startAnimation(0x88148150, -1, -1);
+ _newStickFrameIndex = STICK_LAST_FRAME;
+ }
+ loadSound(0, 0x68895082);
+ loadSound(1, 0x689BD0C1);
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsScene1302Bridge::handleMessage);
+}
+
+uint32 AsScene1302Bridge::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case NM_ANIMATION_STOP:
+ gotoNextState();
+ break;
+ case NM_KLAYMEN_OPEN_DOOR:
+ stLowerBridge();
+ break;
+ case NM_KLAYMEN_CLOSE_DOOR:
+ stRaiseBridge();
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene1302Bridge::stLowerBridge() {
+ startAnimation(0x88148150, 0, -1);
+ playSound(1);
+ NextState(&AsScene1302Bridge::cbLowerBridgeEvent);
+}
+
+void AsScene1302Bridge::stRaiseBridge() {
+ startAnimation(0x88148150, 7, -1);
+ _playBackwards = true;
+ _newStickFrameIndex = 0;
+ playSound(0);
+}
+
+void AsScene1302Bridge::cbLowerBridgeEvent() {
+ sendMessage(_parentScene, 0x2032, 0);
+ startAnimation(0x88148150, -1, -1);
+ _newStickFrameIndex = STICK_LAST_FRAME;
+}
+
+SsScene1302Fence::SsScene1302Fence(NeverhoodEngine *vm)
+ : StaticSprite(vm, 0x11122122, 200) {
+
+ _firstY = _y;
+ if (getGlobalVar(V_FLYTRAP_RING_FENCE))
+ _y += 152;
+ loadSound(0, 0x7A00400C);
+ loadSound(1, 0x78184098);
+ SetUpdateHandler(&SsScene1302Fence::update);
+ SetMessageHandler(&SsScene1302Fence::handleMessage);
+ SetSpriteUpdate(NULL);
+}
+
+void SsScene1302Fence::update() {
+ handleSpriteUpdate();
+ updatePosition();
+}
+
+uint32 SsScene1302Fence::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case NM_KLAYMEN_OPEN_DOOR:
+ playSound(0);
+ SetMessageHandler(NULL);
+ SetSpriteUpdate(&SsScene1302Fence::suMoveDown);
+ break;
+ case NM_KLAYMEN_CLOSE_DOOR:
+ playSound(1);
+ SetMessageHandler(NULL);
+ SetSpriteUpdate(&SsScene1302Fence::suMoveUp);
+ break;
+ }
+ return messageResult;
+}
+
+void SsScene1302Fence::suMoveDown() {
+ if (_y < _firstY + 152)
+ _y += 8;
+ else {
+ SetMessageHandler(&SsScene1302Fence::handleMessage);
+ SetSpriteUpdate(NULL);
+ }
+}
+
+void SsScene1302Fence::suMoveUp() {
+ if (_y > _firstY)
+ _y -= 8;
+ else {
+ SetMessageHandler(&SsScene1302Fence::handleMessage);
+ SetSpriteUpdate(NULL);
+ }
+}
+
+AsScene1303Balloon::AsScene1303Balloon(NeverhoodEngine *vm, Scene *parentScene)
+ : AnimatedSprite(vm, 1100), _parentScene(parentScene) {
+
+ createSurface(200, 128, 315);
+ _x = 289;
+ _y = 390;
+ startAnimation(0x800278D2, 0, -1);
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsScene1303Balloon::handleMessage);
+ SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
+}
+
+uint32 AsScene1303Balloon::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x1011:
+ sendMessage(_parentScene, 0x4826, 0);
+ messageResult = 1;
+ break;
+ case NM_ANIMATION_UPDATE:
+ stPopBalloon();
+ break;
+ }
+ return messageResult;
+}
+
+uint32 AsScene1303Balloon::hmBalloonPopped(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case NM_ANIMATION_START:
+ if (param.asInteger() == 0x020B0003)
+ playSound(0, 0x742B0055);
+ break;
+ case NM_ANIMATION_STOP:
+ playSound(0, 0x470007EE);
+ stopAnimation();
+ setVisible(false);
+ SetMessageHandler(NULL);
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene1303Balloon::stPopBalloon() {
+ startAnimation(0xAC004CD0, 0, -1);
+ SetMessageHandler(&AsScene1303Balloon::hmBalloonPopped);
+}
+
+AsScene1304Needle::AsScene1304Needle(NeverhoodEngine *vm, Scene *parentScene, int surfacePriority, int16 x, int16 y)
+ : AnimatedSprite(vm, 0x548E9411, surfacePriority, x, y), _parentScene(parentScene) {
+
+ // NOTE: Skipped check if Klaymen already has the needle since that's done in the scene itself
+ SetMessageHandler(&AsScene1304Needle::handleMessage);
+}
+
+uint32 AsScene1304Needle::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x1011:
+ sendMessage(_parentScene, 0x4826, 0);
+ messageResult = 1;
+ break;
+ case NM_KLAYMEN_USE_OBJECT:
+ setGlobalVar(V_HAS_NEEDLE, 1);
+ setVisible(false);
+ SetMessageHandler(NULL);
+ break;
+ }
+ return messageResult;
+}
+
+AsScene1306Elevator::AsScene1306Elevator(NeverhoodEngine *vm, Scene *parentScene, AnimatedSprite *asElevatorDoor)
+ : AnimatedSprite(vm, 1100), _parentScene(parentScene), _asElevatorDoor(asElevatorDoor), _isUp(false), _isDown(true),
+ _countdown(0) {
+
+ _x = 320;
+ _y = 240;
+ createSurface1(0x043B0270, 100);
+ startAnimation(0x043B0270, 0, -1);
+ _newStickFrameIndex = 0;
+ loadSound(0, 0x1C100E83);
+ loadSound(1, 0x1C08CEC5);
+ loadSound(2, 0x5D011E87);
+ SetMessageHandler(&AsScene1306Elevator::handleMessage);
+}
+
+void AsScene1306Elevator::update() {
+ if (_isUp && _countdown != 0 && (--_countdown == 0))
+ stGoingDown();
+ AnimatedSprite::update();
+ if (_currFrameIndex == 7 && _asElevatorDoor->getVisible()) {
+ playSound(1);
+ _asElevatorDoor->setVisible(false);
+ }
+}
+
+void AsScene1306Elevator::upGoingDown() {
+ AnimatedSprite::update();
+ if (_currFrameIndex == 5)
+ _asElevatorDoor->setVisible(true);
+}
+
+uint32 AsScene1306Elevator::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x2001:
+ if (_isUp)
+ _countdown = 144;
+ messageResult = _isUp ? 1 : 0;
+ break;
+ case NM_ANIMATION_STOP:
+ gotoNextState();
+ break;
+ case NM_KLAYMEN_OPEN_DOOR:
+ if (_isDown)
+ stGoingUp();
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene1306Elevator::stGoingUp() {
+ setVisible(true);
+ _isDown = false;
+ startAnimation(0x043B0270, 0, -1);
+ playSound(0);
+ SetUpdateHandler(&AsScene1306Elevator::update);
+ NextState(&AsScene1306Elevator::cbGoingUpEvent);
+}
+
+void AsScene1306Elevator::cbGoingUpEvent() {
+ sendMessage(_parentScene, NM_KLAYMEN_OPEN_DOOR, 0);
+ _isUp = true;
+ _countdown = 144;
+ stopAnimation();
+ setVisible(false);
+ SetUpdateHandler(&AsScene1306Elevator::update);
+}
+
+void AsScene1306Elevator::stGoingDown() {
+ _isUp = false;
+ setVisible(true);
+ startAnimation(0x043B0270, -1, -1);
+ _playBackwards = true;
+ playSound(1);
+ SetUpdateHandler(&AsScene1306Elevator::upGoingDown);
+ NextState(&AsScene1306Elevator::cbGoingDownEvent);
+}
+
+void AsScene1306Elevator::cbGoingDownEvent() {
+ _isDown = true;
+ sendMessage(_parentScene, NM_KLAYMEN_CLOSE_DOOR, 0);
+ stopAnimation();
+ SetUpdateHandler(&AsScene1306Elevator::update);
+}
+
+static const uint32 kAsScene1307KeyResourceList1[] = {
+ 0x0438069C, 0x45B0023C, 0x05700217
+};
+
+static const uint32 kAsScene1307KeyResourceList2[] = {
+ 0x04441334, 0x061433F0, 0x06019390
+};
+
+static const uint32 kAsScene1307KeyResourceList3[] = {
+ 0x11A80030, 0x178812B1, 0x1488121C
+};
+
+static const uint32 *kAsScene1307KeyResourceLists[] = {
+ kAsScene1307KeyResourceList1,
+ kAsScene1307KeyResourceList2,
+ kAsScene1307KeyResourceList3
+};
+
+static const int kAsScene1307KeySurfacePriorities[] = {
+ 700, 500, 300, 100
+};
+
+const uint kAsScene1307KeyPointsCount = 12;
+
+static const NPoint kAsScene1307KeyPoints[] = {
+ {-2, 0}, {-5, 0}, { 5, 0},
+ {12, 0}, {17, 0}, {25, 0},
+ {16, -2}, {10, -6}, { 0, -7},
+ {-7, -3}, {-3, 4}, { 2, 2}
+};
+
+const uint kAsScene1307KeyFrameIndicesCount = 20;
+
+static const int16 kAsScene1307KeyFrameIndices[] = {
+ 1, 4, 8, 11, 15, 16, 17, 17, 17, 16,
+ 15, 14, 12, 10, 9, 7, 5, 3, 2, 1
+};
+
+const int kAsScene1307KeyDivValue = 200;
+const int16 kAsScene1307KeyXDelta = 70;
+const int16 kAsScene1307KeyYDelta = -12;
+
+AsScene1307Key::AsScene1307Key(NeverhoodEngine *vm, Scene *parentScene, uint keyIndex, NRect *clipRects)
+ : AnimatedSprite(vm, 1100), _parentScene(parentScene), _keyIndex(keyIndex), _clipRects(clipRects),
+ _isClickable(true) {
+
+ NPoint pt;
+ const uint32 *fileHashes = kAsScene1307KeyResourceLists[_keyIndex];
+
+ _dataResource.load(0x22102142);
+ _pointList = _dataResource.getPointArray(0xAC849240);
+ pt = (*_pointList)[getSubVar(VA_CURR_KEY_SLOT_NUMBERS, _keyIndex)];
+ _x = pt.x;
+ _y = pt.y;
+ createSurface(kAsScene1307KeySurfacePriorities[getSubVar(VA_CURR_KEY_SLOT_NUMBERS, _keyIndex) % 4], 190, 148);
+ startAnimation(fileHashes[0], 0, -1);
+ loadSound(0, 0xDC4A1280);
+ loadSound(1, 0xCC021233);
+ loadSound(2, 0xC4C23844);
+ loadSound(3, 0xC4523208);
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsScene1307Key::handleMessage);
+}
+
+uint32 AsScene1307Key::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x1011:
+ if (_isClickable) {
+ sendMessage(_parentScene, 0x4826, 0);
+ stRemoveKey();
+ messageResult = 1;
+ }
+ break;
+ case NM_ANIMATION_UPDATE:
+ _isClickable = param.asInteger() != 0;
+ break;
+ case 0x2001:
+ setSubVar(VA_CURR_KEY_SLOT_NUMBERS, _keyIndex, param.asInteger());
+ stMoveKey();
+ break;
+ case 0x2003:
+ playSound(3);
+ stUnlock();
+ break;
+ case 0x2004:
+ playSound(2);
+ stInsert();
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene1307Key::suRemoveKey() {
+ if (_pointIndex < kAsScene1307KeyPointsCount) {
+ _x += kAsScene1307KeyPoints[_pointIndex].x;
+ _y += kAsScene1307KeyPoints[_pointIndex].y;
+ updateBounds();
+ _pointIndex++;
+ } else {
+ SetSpriteUpdate(NULL);
+ }
+}
+
+void AsScene1307Key::suInsertKey() {
+ if (_pointIndex < kAsScene1307KeyPointsCount) {
+ _x -= kAsScene1307KeyPoints[kAsScene1307KeyPointsCount - _pointIndex - 1].x;
+ _y -= kAsScene1307KeyPoints[kAsScene1307KeyPointsCount - _pointIndex - 1].y;
+ updateBounds();
+ _pointIndex++;
+ if (_pointIndex == 7)
+ playSound(0);
+ } else {
+ SetSpriteUpdate(NULL);
+ sendMessage(_parentScene, NM_POSITION_CHANGE, 0);
+ }
+}
+
+void AsScene1307Key::suMoveKey() {
+ if (_pointIndex < kAsScene1307KeyFrameIndicesCount) {
+ _frameIndex += kAsScene1307KeyFrameIndices[_pointIndex];
+ _x = _prevX + (_deltaX * _frameIndex) / kAsScene1307KeyDivValue;
+ _y = _prevY + (_deltaY * _frameIndex) / kAsScene1307KeyDivValue;
+ updateBounds();
+ _pointIndex++;
+ } else {
+ NPoint pt = (*_pointList)[getSubVar(VA_CURR_KEY_SLOT_NUMBERS, _keyIndex)];
+ _x = pt.x + kAsScene1307KeyXDelta;
+ _y = pt.y + kAsScene1307KeyYDelta;
+ stInsertKey();
+ }
+}
+
+void AsScene1307Key::stRemoveKey() {
+ const uint32 *fileHashes = kAsScene1307KeyResourceLists[_keyIndex];
+ _pointIndex = 0;
+ startAnimation(fileHashes[0], 0, -1);
+ playSound(1);
+ SetSpriteUpdate(&AsScene1307Key::suRemoveKey);
+}
+
+void AsScene1307Key::stInsertKey() {
+ _pointIndex = 0;
+ sendMessage(_parentScene, NM_PRIORITY_CHANGE, kAsScene1307KeySurfacePriorities[getSubVar(VA_CURR_KEY_SLOT_NUMBERS, _keyIndex) % 4]);
+ setClipRect(_clipRects[getSubVar(VA_CURR_KEY_SLOT_NUMBERS, _keyIndex) % 4]);
+ _newStickFrameIndex = STICK_LAST_FRAME;
+ SetSpriteUpdate(&AsScene1307Key::suInsertKey);
+}
+
+void AsScene1307Key::stMoveKey() {
+ NPoint pt = (*_pointList)[getSubVar(VA_CURR_KEY_SLOT_NUMBERS, _keyIndex)];
+ int16 newX = pt.x + kAsScene1307KeyXDelta;
+ int16 newY = pt.y + kAsScene1307KeyYDelta;
+ sendMessage(_parentScene, NM_PRIORITY_CHANGE, 1000);
+ setClipRect(0, 0, 640, 480);
+ _prevX = _x;
+ _prevY = _y;
+ if (newX == _x && newY == _y) {
+ stInsertKey();
+ } else {
+ const uint32 *fileHashes = kAsScene1307KeyResourceLists[_keyIndex];
+ _pointIndex = 0;
+ _frameIndex = 0;
+ _deltaX = newX - _x;
+ _deltaY = newY - _y;
+ startAnimation(fileHashes[0], 0, -1);
+ SetSpriteUpdate(&AsScene1307Key::suMoveKey);
+ }
+}
+
+void AsScene1307Key::stUnlock() {
+ const uint32 *fileHashes = kAsScene1307KeyResourceLists[_keyIndex];
+ startAnimation(fileHashes[1], 0, -1);
+ _newStickFrameIndex = STICK_LAST_FRAME;
+}
+
+void AsScene1307Key::stInsert() {
+ const uint32 *fileHashes = kAsScene1307KeyResourceLists[_keyIndex];
+ startAnimation(fileHashes[2], 0, -1);
+ _newStickFrameIndex = STICK_LAST_FRAME;
+}
+
+AsScene1308JaggyDoor::AsScene1308JaggyDoor(NeverhoodEngine *vm, Scene *parentScene)
+ : AnimatedSprite(vm, 0xBA0AE050, 1100, 320, 240), _parentScene(parentScene) {
+
+ setVisible(false);
+ stopAnimation();
+ SetMessageHandler(&AsScene1308JaggyDoor::handleMessage);
+}
+
+uint32 AsScene1308JaggyDoor::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case NM_ANIMATION_STOP:
+ gotoNextState();
+ break;
+ case NM_KLAYMEN_OPEN_DOOR:
+ stOpenDoor();
+ break;
+ case NM_KLAYMEN_CLOSE_DOOR:
+ stCloseDoor();
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene1308JaggyDoor::stOpenDoor() {
+ startAnimation(0xBA0AE050, 0, -1);
+ setVisible(true);
+ playSound(0, calcHash("fxDoorOpen38"));
+ NextState(&AsScene1308JaggyDoor::stOpenDoorDone);
+}
+
+void AsScene1308JaggyDoor::stOpenDoorDone() {
+ sendMessage(_parentScene, 0x2000, 0);
+ stopAnimation();
+ setVisible(false);
+}
+
+void AsScene1308JaggyDoor::stCloseDoor() {
+ startAnimation(0xBA0AE050, -1, -1);
+ _playBackwards = true;
+ setVisible(true);
+ playSound(0, calcHash("fxDoorClose38"));
+ NextState(&AsScene1308JaggyDoor::stCloseDoorDone);
+}
+
+void AsScene1308JaggyDoor::stCloseDoorDone() {
+ sendMessage(_parentScene, 0x2001, 0);
+ stopAnimation();
+}
+
+AsScene1308KeyboardDoor::AsScene1308KeyboardDoor(NeverhoodEngine *vm, Scene *parentScene)
+ : AnimatedSprite(vm, 0xA08A0851, 1100, 320, 240), _parentScene(parentScene) {
+
+ playSound(0, 0x51456049);
+ SetMessageHandler(&AsScene1308KeyboardDoor::handleMessage);
+ NextState(&AsScene1308KeyboardDoor::stFallingKeys);
+}
+
+uint32 AsScene1308KeyboardDoor::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case NM_ANIMATION_STOP:
+ gotoNextState();
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene1308KeyboardDoor::stFallingKeys() {
+ startAnimation(0x6238B191, 0, -1);
+ _x = 580;
+ _y = 383;
+ NextState(&AsScene1308KeyboardDoor::stFallingKeysDone);
+}
+
+void AsScene1308KeyboardDoor::stFallingKeysDone() {
+ sendMessage(_parentScene, 0x2004, 0);
+ stopAnimation();
+ setVisible(false);
+}
+
+AsScene1308LightWallSymbols::AsScene1308LightWallSymbols(NeverhoodEngine *vm, Scene *parentScene)
+ : AnimatedSprite(vm, 0x80180A10, 100, 320, 240), _parentScene(parentScene) {
+
+ setVisible(false);
+ stopAnimation();
+ Entity::_priority = 1200;
+ SetMessageHandler(&AsScene1308LightWallSymbols::handleMessage);
+}
+
+uint32 AsScene1308LightWallSymbols::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case NM_POSITION_CHANGE:
+ stFadeIn();
+ break;
+ case 0x2003:
+ stFadeOut();
+ break;
+ case NM_ANIMATION_STOP:
+ gotoNextState();
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene1308LightWallSymbols::stFadeIn() {
+ startAnimation(0x80180A10, 0, -1);
+ setVisible(true);
+ _newStickFrameIndex = STICK_LAST_FRAME;
+}
+
+void AsScene1308LightWallSymbols::stFadeOut() {
+ startAnimation(0x80180A10, -1, -1);
+ _playBackwards = true;
+ NextState(&AsScene1308LightWallSymbols::stFadeOutDone);
+}
+
+void AsScene1308LightWallSymbols::stFadeOutDone() {
+ sendMessage(_parentScene, 0x2003, 0);
+ stopAnimation();
+ setVisible(false);
+}
+
+SsScene1308Number::SsScene1308Number(NeverhoodEngine *vm, uint32 fileHash, int index)
+ : StaticSprite(vm, fileHash, 100) {
+
+ setVisible(false);
+ _x = _spriteResource.getPosition().x + index * 20;
+ updatePosition();
+}
+
+AsScene1308Mouse::AsScene1308Mouse(NeverhoodEngine *vm)
+ : AnimatedSprite(vm, 1100) {
+
+ _x = 286;
+ _y = 429;
+ createSurface1(0xA282C472, 100);
+ startAnimation(0xA282C472, 0, -1);
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsScene1308Mouse::handleMessage);
+}
+
+uint32 AsScene1308Mouse::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case NM_ANIMATION_START:
+ if (param.asInteger() == 0x66382026)
+ playSound(0, 0x0CD84468);
+ else if (param.asInteger() == 0x6E28061C)
+ playSound(0, 0x78C8402C);
+ else if (param.asInteger() == 0x462F0410)
+ playSound(0, 0x60984E28);
+ break;
+ }
+ return messageResult;
+}
+
+KmScene1303::KmScene1303(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
+ : Klaymen(vm, parentScene, x, y) {
+
+ // Empty
+}
+
+uint32 KmScene1303::xHandleMessage(int messageNum, const MessageParam &param) {
+ switch (messageNum) {
+ case 0x4804:
+ GotoState(&Klaymen::stPeekWall1);
+ break;
+ case 0x483B:
+ GotoState(&Klaymen::stPeekWallReturn);
+ break;
+ case 0x483C:
+ GotoState(&Klaymen::stPeekWall2);
+ break;
+ }
+ return 0;
+}
+
+KmScene1304::KmScene1304(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
+ : Klaymen(vm, parentScene, x, y) {
+
+ // Empty
+}
+
+uint32 KmScene1304::xHandleMessage(int messageNum, const MessageParam &param) {
+ switch (messageNum) {
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case NM_KLAYMEN_STAND_IDLE:
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case NM_KLAYMEN_PICKUP:
+ if (param.asInteger() == 2)
+ GotoState(&Klaymen::stPickUpNeedle);
+ else if (param.asInteger() == 1)
+ GotoState(&Klaymen::stPickUpTube);
+ else
+ GotoState(&Klaymen::stPickUpGeneric);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ gotoNextStateExt();
+ break;
+ case 0x481B:
+ if (param.asPoint().y != 0)
+ startWalkToXDistance(param.asPoint().y, param.asPoint().x);
+ else
+ startWalkToAttachedSpriteXDistance(param.asPoint().x);
+ break;
+ case 0x481F:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stTurnAwayFromUse);
+ else if (param.asInteger() == 0)
+ GotoState(&Klaymen::stTurnToUseHalf);
+ else
+ GotoState(&Klaymen::stWonderAbout);
+ break;
+ case 0x483F:
+ startSpecialWalkRight(param.asInteger());
+ break;
+ case 0x4840:
+ startSpecialWalkLeft(param.asInteger());
+ break;
+ }
+ return 0;
+}
+
+KmScene1305::KmScene1305(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
+ : Klaymen(vm, parentScene, x, y) {
+
+ // Empty
+}
+
+uint32 KmScene1305::xHandleMessage(int messageNum, const MessageParam &param) {
+ switch (messageNum) {
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case NM_KLAYMEN_STAND_IDLE:
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x4804:
+ GotoState(&KmScene1305::stCrashDown);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ gotoNextStateExt();
+ break;
+ }
+ return 0;
+}
+
+void KmScene1305::stCrashDown() {
+ playSound(0, 0x41648271);
+ _busyStatus = 1;
+ _acceptInput = false;
+ startAnimationByHash(0x000BAB02, 0x88003000, 0);
+ SetUpdateHandler(&Klaymen::update);
+ SetSpriteUpdate(NULL);
+ SetMessageHandler(&Klaymen::hmLowLevelAnimation);
+ NextState(&KmScene1305::stCrashDownFinished);
+}
+
+void KmScene1305::stCrashDownFinished() {
+ setDoDeltaX(2);
+ stTryStandIdle();
+}
+
+KmScene1306::KmScene1306(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
+ : Klaymen(vm, parentScene, x, y) {
+
+ // Empty
+}
+
+uint32 KmScene1306::xHandleMessage(int messageNum, const MessageParam &param) {
+ uint32 messageResult = 0;
+ switch (messageNum) {
+ case NM_ANIMATION_UPDATE:
+ _isSittingInTeleporter = param.asInteger() != 0;
+ messageResult = 1;
+ break;
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case NM_KLAYMEN_STAND_IDLE:
+ if (_isSittingInTeleporter)
+ GotoState(&Klaymen::stSitIdleTeleporter);
+ else
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case NM_KLAYMEN_PICKUP:
+ if (param.asInteger() == 2)
+ GotoState(&Klaymen::stPickUpNeedle);
+ else if (param.asInteger() == 1)
+ GotoState(&Klaymen::stPickUpTube);
+ else
+ GotoState(&Klaymen::stPickUpGeneric);
+ break;
+ case NM_KLAYMEN_PRESS_BUTTON:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stPressButton);
+ else if (param.asInteger() == 2)
+ GotoState(&Klaymen::stPressFloorButton);
+ else
+ GotoState(&Klaymen::stPressButtonSide);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ gotoNextStateExt();
+ break;
+ case NM_KLAYMEN_INSERT_DISK:
+ GotoState(&Klaymen::stInsertDisk);
+ break;
+ case 0x481B:
+ if (param.asPoint().y != 0)
+ startWalkToXDistance(param.asPoint().y, param.asPoint().x);
+ else
+ startWalkToAttachedSpriteXDistance(param.asPoint().x);
+ break;
+ case NM_KLAYMEN_TURN_TO_USE:
+ if (_isSittingInTeleporter)
+ GotoState(&Klaymen::stTurnToUseInTeleporter);
+ else
+ GotoState(&Klaymen::stTurnToUse);
+ break;
+ case NM_KLAYMEN_RETURN_FROM_USE:
+ if (_isSittingInTeleporter)
+ GotoState(&Klaymen::stReturnFromUseInTeleporter);
+ else
+ GotoState(&Klaymen::stReturnFromUse);
+ break;
+ case 0x481F:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stWonderAboutAfter);
+ else if (param.asInteger() == 0)
+ GotoState(&Klaymen::stWonderAboutHalf);
+ else if (param.asInteger() == 4)
+ GotoState(&Klaymen::stTurnAwayFromUse);
+ else if (param.asInteger() == 3)
+ GotoState(&Klaymen::stTurnToUseHalf);
+ else
+ GotoState(&Klaymen::stWonderAbout);
+ break;
+ case 0x482D:
+ setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
+ gotoNextStateExt();
+ break;
+ case 0x482E:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stWalkToFrontNoStep);
+ else
+ GotoState(&Klaymen::stWalkToFront);
+ break;
+ case 0x482F:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stTurnToFront);
+ else
+ GotoState(&Klaymen::stTurnToBack);
+ break;
+ case 0x4834:
+ GotoState(&Klaymen::stStepOver);
+ break;
+ case 0x4835:
+ sendMessage(_parentScene, 0x2000, 1);
+ _isSittingInTeleporter = true;
+ GotoState(&Klaymen::stSitInTeleporter);
+ break;
+ case 0x4836:
+ sendMessage(_parentScene, 0x2000, 0);
+ _isSittingInTeleporter = false;
+ GotoState(&Klaymen::stGetUpFromTeleporter);
+ break;
+ case 0x483D:
+ teleporterAppear(0xEE084A04);
+ break;
+ case 0x483E:
+ teleporterDisappear(0xB86A4274);
+ break;
+ case 0x483F:
+ startSpecialWalkRight(param.asInteger());
+ break;
+ case 0x4840:
+ startSpecialWalkLeft(param.asInteger());
+ break;
+ }
+ return messageResult;
+}
+
+KmScene1308::KmScene1308(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
+ : Klaymen(vm, parentScene, x, y) {
+
+ // Empty
+}
+
+uint32 KmScene1308::xHandleMessage(int messageNum, const MessageParam &param) {
+ switch (messageNum) {
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case NM_KLAYMEN_STAND_IDLE:
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case NM_KLAYMEN_MOVE_OBJECT:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stMoveObjectSkipTurnFaceObject);
+ else
+ GotoState(&Klaymen::stMoveObjectFaceObject);
+ break;
+ case 0x480D:
+ GotoState(&Klaymen::stUseLever);
+ break;
+ case NM_KLAYMEN_PICKUP:
+ if (param.asInteger() == 2)
+ GotoState(&Klaymen::stPickUpNeedle);
+ else if (param.asInteger() == 1)
+ GotoState(&Klaymen::stPickUpTube);
+ else
+ GotoState(&Klaymen::stPickUpGeneric);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ gotoNextStateExt();
+ break;
+ case NM_KLAYMEN_INSERT_DISK:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stInsertKey);
+ else
+ GotoState(&Klaymen::stInsertDisk);
+ break;
+ case 0x481B:
+ if (param.asPoint().y != 0)
+ startWalkToXDistance(param.asPoint().y, param.asPoint().x);
+ else
+ startWalkToAttachedSpriteXDistance(param.asPoint().x);
+ break;
+ case NM_KLAYMEN_TURN_TO_USE:
+ GotoState(&Klaymen::stTurnToUse);
+ break;
+ case NM_KLAYMEN_RETURN_FROM_USE:
+ GotoState(&Klaymen::stReturnFromUse);
+ break;
+ case NM_KLAYMEN_RELEASE_LEVER:
+ GotoState(&Klaymen::stReleaseLever);
+ break;
+ case 0x4834:
+ GotoState(&Klaymen::stStepOver);
+ break;
+ case 0x483F:
+ startSpecialWalkRight(param.asInteger());
+ break;
+ case 0x4840:
+ startSpecialWalkLeft(param.asInteger());
+ break;
+ }
+ return 0;
+}
+
+} // End of namespace Neverhood
diff --git a/engines/neverhood/modules/module1300_sprites.h b/engines/neverhood/modules/module1300_sprites.h
new file mode 100644
index 0000000000..e044d3cec8
--- /dev/null
+++ b/engines/neverhood/modules/module1300_sprites.h
@@ -0,0 +1,200 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public 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 NEVERHOOD_MODULES_MODULE1300_SPRITES_H
+#define NEVERHOOD_MODULES_MODULE1300_SPRITES_H
+
+#include "neverhood/neverhood.h"
+#include "neverhood/module.h"
+#include "neverhood/scene.h"
+#include "neverhood/smackerplayer.h"
+
+namespace Neverhood {
+
+class AsScene1302Bridge : public AnimatedSprite {
+public:
+ AsScene1302Bridge(NeverhoodEngine *vm, Scene *parentScene);
+protected:
+ Scene *_parentScene;
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ void stLowerBridge();
+ void stRaiseBridge();
+ void cbLowerBridgeEvent();
+};
+
+class SsScene1302Fence : public StaticSprite {
+public:
+ SsScene1302Fence(NeverhoodEngine *vm);
+protected:
+ int16 _firstY;
+ void update();
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ void suMoveDown();
+ void suMoveUp();
+};
+
+class AsScene1303Balloon : public AnimatedSprite {
+public:
+ AsScene1303Balloon(NeverhoodEngine *vm, Scene *parentScene);
+protected:
+ Scene *_parentScene;
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 hmBalloonPopped(int messageNum, const MessageParam &param, Entity *sender);
+ void stPopBalloon();
+};
+
+class AsScene1304Needle : public AnimatedSprite {
+public:
+ AsScene1304Needle(NeverhoodEngine *vm, Scene *parentScene, int surfacePriority, int16 x, int16 y);
+protected:
+ Scene *_parentScene;
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class AsScene1306Elevator : public AnimatedSprite {
+public:
+ AsScene1306Elevator(NeverhoodEngine *vm, Scene *parentScene, AnimatedSprite *asElevatorDoor);
+protected:
+ Scene *_parentScene;
+ AnimatedSprite *_asElevatorDoor;
+ bool _isUp;
+ bool _isDown;
+ int _countdown;
+ void update();
+ void upGoingDown();
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ void stGoingUp();
+ void cbGoingUpEvent();
+ void stGoingDown();
+ void cbGoingDownEvent();
+};
+
+class AsScene1307Key : public AnimatedSprite {
+public:
+ AsScene1307Key(NeverhoodEngine *vm, Scene *parentScene, uint keyIndex, NRect *clipRects);
+protected:
+ Scene *_parentScene;
+ NPointArray *_pointList;
+ uint _pointIndex;
+ int _frameIndex;
+ uint _keyIndex;
+ NRect *_clipRects;
+ bool _isClickable;
+ int16 _prevX, _prevY;
+ int16 _deltaX, _deltaY;
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ void suRemoveKey();
+ void suInsertKey();
+ void suMoveKey();
+ void stRemoveKey();
+ void stInsertKey();
+ void stMoveKey();
+ void stUnlock();
+ void stInsert();
+};
+
+class AsScene1308JaggyDoor : public AnimatedSprite {
+public:
+ AsScene1308JaggyDoor(NeverhoodEngine *vm, Scene *parentScene);
+protected:
+ Scene *_parentScene;
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ void stOpenDoor();
+ void stOpenDoorDone();
+ void stCloseDoor();
+ void stCloseDoorDone();
+};
+
+class AsScene1308KeyboardDoor : public AnimatedSprite {
+public:
+ AsScene1308KeyboardDoor(NeverhoodEngine *vm, Scene *parentScene);
+protected:
+ Scene *_parentScene;
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ void stFallingKeys();
+ void stFallingKeysDone();
+};
+
+class AsScene1308LightWallSymbols : public AnimatedSprite {
+public:
+ AsScene1308LightWallSymbols(NeverhoodEngine *vm, Scene *parentScene);
+protected:
+ Scene *_parentScene;
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ void stFadeIn();
+ void stFadeOut();
+ void stFadeOutDone();
+};
+
+class SsScene1308Number : public StaticSprite {
+public:
+ SsScene1308Number(NeverhoodEngine *vm, uint32 fileHash, int index);
+};
+
+class AsScene1308Mouse : public AnimatedSprite {
+public:
+ AsScene1308Mouse(NeverhoodEngine *vm);
+protected:
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class KmScene1303 : public Klaymen {
+public:
+ KmScene1303(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
+protected:
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+};
+
+class KmScene1304 : public Klaymen {
+public:
+ KmScene1304(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
+protected:
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+};
+
+class KmScene1305 : public Klaymen {
+public:
+ KmScene1305(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
+protected:
+ void stCrashDown();
+ void stCrashDownFinished();
+
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+};
+
+class KmScene1306 : public Klaymen {
+public:
+ KmScene1306(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
+protected:
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+};
+
+class KmScene1308 : public Klaymen {
+public:
+ KmScene1308(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
+protected:
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+};
+
+} // End of namespace Neverhood
+
+#endif /* NEVERHOOD_MODULES_MODULE1300_SPRITES_H */
diff --git a/engines/neverhood/modules/module1400.cpp b/engines/neverhood/modules/module1400.cpp
index 0a029632b6..018f27e2b7 100644
--- a/engines/neverhood/modules/module1400.cpp
+++ b/engines/neverhood/modules/module1400.cpp
@@ -20,12 +20,14 @@
*
*/
-#include "neverhood/modules/module1400.h"
-#include "neverhood/modules/module1000.h"
-#include "neverhood/modules/module2100.h"
-#include "neverhood/modules/module2200.h"
#include "neverhood/diskplayerscene.h"
#include "neverhood/gamemodule.h"
+#include "neverhood/modules/module1000_sprites.h"
+#include "neverhood/modules/module1200_sprites.h"
+#include "neverhood/modules/module1400.h"
+#include "neverhood/modules/module1400_sprites.h"
+#include "neverhood/modules/module2100_sprites.h"
+#include "neverhood/modules/module2200_sprites.h"
namespace Neverhood {
@@ -135,497 +137,6 @@ void Module1400::updateScene() {
}
}
-// Scene1401
-
-AsScene1401Pipe::AsScene1401Pipe(NeverhoodEngine *vm)
- : AnimatedSprite(vm, 1100), _countdown1(0), _countdown2(0) {
-
- createSurface(900, 152, 147);
- _x = 454;
- _y = 217;
- startAnimation(0x4C210500, 0, -1);
- SetUpdateHandler(&AsScene1401Pipe::update);
- SetMessageHandler(&AsScene1401Pipe::handleMessage);
-}
-
-AsScene1401Pipe::~AsScene1401Pipe() {
- _vm->_soundMan->deleteSoundGroup(0x01104C08);
-}
-
-void AsScene1401Pipe::update() {
- AnimatedSprite::update();
- if (_countdown1 != 0 && (--_countdown1 == 0))
- stDoneSucking();
- if (_countdown2 != 0 && (--_countdown2 == 0)) {
- _vm->_soundMan->addSound(0x01104C08, 0x4A116437);
- _vm->_soundMan->playSoundLooping(0x4A116437);
- }
-}
-
-void AsScene1401Pipe::upSuckInProjector() {
- AnimatedSprite::update();
- if (_countdown1 != 0)
- _countdown1--;
-}
-
-uint32 AsScene1401Pipe::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x100D:
- if (param.asInteger() == 0x0A8A1490)
- playSound(1, 0x6AB6666F);
- break;
- case 0x2000:
- _countdown1 = 70;
- _countdown2 = 8;
- stStartSucking();
- break;
- case 0x483A:
- stSuckInProjector();
- break;
- }
- return messageResult;
-}
-
-uint32 AsScene1401Pipe::hmSuckInProjector(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x3002:
- if (_countdown1 != 0)
- stStartSucking();
- else
- stDoneSucking();
- SetMessageHandler(&AsScene1401Pipe::handleMessage);
- SetUpdateHandler(&AsScene1401Pipe::update);
- break;
- }
- return messageResult;
-}
-
-void AsScene1401Pipe::stStartSucking() {
- startAnimation(0x4C240100, 0, -1);
- playSound(0, 0x4A30063F);
-}
-
-void AsScene1401Pipe::stDoneSucking() {
- _vm->_soundMan->deleteSound(0x4A116437);
- playSound(0, 0x4A120435);
- startAnimation(0x4C210500, 0, -1);
-}
-
-void AsScene1401Pipe::stSuckInProjector() {
- startAnimation(0x6C210810, 0, -1);
- SetUpdateHandler(&AsScene1401Pipe::upSuckInProjector);
- SetMessageHandler(&AsScene1401Pipe::hmSuckInProjector);
-}
-
-AsScene1401Mouse::AsScene1401Mouse(NeverhoodEngine *vm)
- : AnimatedSprite(vm, 1100) {
-
- createSurface(100, 71, 41);
- _x = 478;
- _y = 433;
- startAnimation(0xA282C472, 0, -1);
- SetUpdateHandler(&AnimatedSprite::update);
- SetMessageHandler(&AsScene1401Mouse::handleMessage);
-}
-
-uint32 AsScene1401Mouse::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x100D:
- if (param.asInteger() == 0x66382026)
- playSound(0, 0x0CD84468);
- else if (param.asInteger() == 0x6E28061C)
- playSound(0, 0x78C8402C);
- else if (param.asInteger() == 0x462F0410)
- playSound(0, 0x60984E28);
- break;
- case 0x4839:
- stSuckedIn();
- break;
- }
- return messageResult;
-}
-
-void AsScene1401Mouse::suSuckedIn() {
- AnimatedSprite::updateDeltaXY();
- if (_collisionBounds.y1 <= 150) {
- playSound(0, 0x0E32247F);
- stopAnimation();
- setVisible(false);
- SetMessageHandler(NULL);
- SetSpriteUpdate(NULL);
- }
-}
-
-void AsScene1401Mouse::stSuckedIn() {
- startAnimation(0x34880040, 0, -1);
- SetSpriteUpdate(&AsScene1401Mouse::suSuckedIn);
-}
-
-AsScene1401Cheese::AsScene1401Cheese(NeverhoodEngine *vm)
- : AnimatedSprite(vm, 1100) {
-
- createSurface(200, 152, 147);
- _x = 427;
- _y = 433;
- startAnimation(0x461A1490, 0, -1);
- SetUpdateHandler(&AnimatedSprite::update);
- SetMessageHandler(&AsScene1401Cheese::handleMessage);
-}
-
-uint32 AsScene1401Cheese::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x4839:
- stSuckedIn();
- break;
- }
- return messageResult;
-}
-
-void AsScene1401Cheese::suSuckedIn() {
- AnimatedSprite::updateDeltaXY();
- if (_collisionBounds.y1 <= 150) {
- playSound(0, 0x18020439);
- stopAnimation();
- setVisible(false);
- SetMessageHandler(NULL);
- SetSpriteUpdate(NULL);
- }
-}
-
-void AsScene1401Cheese::stSuckedIn() {
- startAnimation(0x103B8020, 0, -1);
- SetSpriteUpdate(&AsScene1401Cheese::suSuckedIn);
-}
-
-AsScene1401BackDoor::AsScene1401BackDoor(NeverhoodEngine *vm, Sprite *klaymen, bool isOpen)
- : AnimatedSprite(vm, 1100), _klaymen(klaymen), _countdown(0), _isOpen(isOpen) {
-
- _x = 320;
- _y = 240;
- createSurface1(0x04551900, 100);
- if (isOpen) {
- startAnimation(0x04551900, -1, -1);
- _countdown = 48;
- } else {
- stopAnimation();
- setVisible(false);
- }
- _newStickFrameIndex = STICK_LAST_FRAME;
- SetUpdateHandler(&AsScene1401BackDoor::update);
- SetMessageHandler(&AsScene1401BackDoor::handleMessage);
-}
-
-void AsScene1401BackDoor::update() {
- if (_countdown != 0 && (--_countdown == 0))
- stCloseDoor();
- AnimatedSprite::update();
-}
-
-
-uint32 AsScene1401BackDoor::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x2001:
- if (_isOpen)
- _countdown = 168;
- messageResult = _isOpen ? 1 : 0;
- break;
- case 0x3002:
- gotoNextState();
- break;
- case 0x4808:
- _countdown = 168;
- if (!_isOpen)
- stOpenDoor();
- break;
- }
- return messageResult;
-}
-
-void AsScene1401BackDoor::stOpenDoor() {
- _isOpen = true;
- setVisible(true);
- startAnimation(0x04551900, 0, -1);
- _newStickFrameIndex = STICK_LAST_FRAME;
- playSound(0, calcHash("fxDoorOpen24"));
-}
-
-void AsScene1401BackDoor::stCloseDoor() {
- _isOpen = false;
- setVisible(true);
- startAnimation(0x04551900, -1, -1);
- playSound(0, calcHash("fxDoorClose24"));
- _playBackwards = true;
- NextState(&AsScene1401BackDoor::stCloseDoorDone);
-}
-
-void AsScene1401BackDoor::stCloseDoorDone() {
- stopAnimation();
- setVisible(false);
-}
-
-static const AsCommonProjectorItem kAsCommonProjectorItems[] = {
- {{154, 453}, 4, 2, 0, 0, 1},
- {{104, 391}, 4, -1, -1, 1, 1},
- {{ 22, 447}, 6, -1, -1, 1, 1},
- {{112, 406}, 2, -1, -1, 1, 0},
- {{262, 433}, 1, 1, 0, 0, 0}
-};
-
-AsCommonProjector::AsCommonProjector(NeverhoodEngine *vm, Scene *parentScene, Sprite *klaymen, Sprite *asPipe)
- : AnimatedSprite(vm, 1100), _parentScene(parentScene), _klaymen(klaymen), _asPipe(asPipe) {
-
- _asProjectorItem = &kAsCommonProjectorItems[getGlobalVar(V_PROJECTOR_LOCATION)];
- createSurface(990, 101, 182);
- startAnimation(0x10E3042B, 0, -1);
- SetUpdateHandler(&AnimatedSprite::update);
- SetMessageHandler(&AsCommonProjector::handleMessage);
- _x = getGlobalVar(V_PROJECTOR_SLOT) * 108 + _asProjectorItem->point.x;
- _lockedInSlot = true;
- moveProjector();
- setDoDeltaX(1);
- if ((int8)getGlobalVar(V_PROJECTOR_SLOT) == _asProjectorItem->lockSlotIndex)
- stStayLockedInSlot();
- loadSound(2, 0xC8C2507C);
-}
-
-AsCommonProjector::~AsCommonProjector() {
- _vm->_soundMan->deleteSoundGroup(0x05331081);
-}
-
-uint32 AsCommonProjector::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x1011:
- sendMessage(_parentScene, 0x4826, 0);
- messageResult = 1;
- break;
- case 0x4807:
- setGlobalVar(V_PROJECTOR_SLOT, (_x - _asProjectorItem->point.x) / 108);
- if ((int8)getGlobalVar(V_PROJECTOR_SLOT) == _asProjectorItem->lockSlotIndex)
- stStartLockedInSlot();
- else
- stIdle();
- break;
- case 0x480B:
- if (param.asInteger() != 1) {
- if ((int8)getGlobalVar(V_PROJECTOR_SLOT) < _asProjectorItem->maxSlotCount)
- incGlobalVar(V_PROJECTOR_SLOT, 1);
- } else if (getGlobalVar(V_PROJECTOR_SLOT) > 0)
- incGlobalVar(V_PROJECTOR_SLOT, -1);
- stMoving();
- break;
- case 0x480C:
- // Check if the projector can be moved
- if (param.asInteger() != 1)
- messageResult = (int8)getGlobalVar(V_PROJECTOR_SLOT) < _asProjectorItem->maxSlotCount ? 1 : 0;
- else
- messageResult = getGlobalVar(V_PROJECTOR_SLOT) > 0 ? 1 : 0;
- break;
- case 0x482A:
- sendMessage(_parentScene, 0x1022, 990);
- break;
- case 0x482B:
- sendMessage(_parentScene, 0x1022, 1010);
- break;
- case 0x4839:
- stStartSuckedIn();
- break;
- }
- return messageResult;
-}
-
-uint32 AsCommonProjector::hmLockedInSlot(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x1011:
- if (param.asPoint().x - _x >= 17 && param.asPoint().x - _x <= 56 &&
- param.asPoint().y - _y >= -120 && param.asPoint().y - _y <= -82) {
- sendMessage(_parentScene, 0x4826, 1);
- } else
- sendMessage(_parentScene, 0x4826, 0);
- messageResult = 1;
- break;
- case 0x4807:
- sendMessage(_parentScene, 0x4807, 0);
- stStopProjecting();
- break;
- case 0x480B:
- if (param.asInteger() != 1) {
- if ((int8)getGlobalVar(V_PROJECTOR_SLOT) < _asProjectorItem->maxSlotCount)
- incGlobalVar(V_PROJECTOR_SLOT, 1);
- } else if (getGlobalVar(V_PROJECTOR_SLOT) > 0)
- incGlobalVar(V_PROJECTOR_SLOT, -1);
- stTurnToFront();
- break;
- case 0x480C:
- // Check if the projector can be moved
- if (param.asInteger() != 1)
- messageResult = (int8)getGlobalVar(V_PROJECTOR_SLOT) < _asProjectorItem->maxSlotCount ? 1 : 0;
- else
- messageResult = getGlobalVar(V_PROJECTOR_SLOT) > 0 ? 1 : 0;
- break;
- case 0x480F:
- stStartProjecting();
- break;
- case 0x482A:
- sendMessage(_parentScene, 0x1022, 990);
- break;
- case 0x482B:
- sendMessage(_parentScene, 0x1022, 1010);
- break;
- }
- return messageResult;
-}
-
-uint32 AsCommonProjector::hmAnimation(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x3002:
- gotoNextState();
- break;
- }
- return messageResult;
-}
-
-void AsCommonProjector::suMoving() {
- if (_x <= _klaymen->getX())
- _x = _klaymen->getX() - 100;
- else
- _x = _klaymen->getX() + 100;
- moveProjector();
- if (_beforeMoveX == _x) {
- if (getGlobalVar(V_PROJECTOR_SLOT) == 0 && _asProjectorItem->leftBorderLeaves != 0) {
- sendMessage(_parentScene, 0x1019, 0);
- incGlobalVar(V_PROJECTOR_LOCATION, -1);
- setGlobalVar(V_PROJECTOR_SLOT, kAsCommonProjectorItems[getGlobalVar(V_PROJECTOR_LOCATION)].maxSlotCount);
- } else if ((int8)getGlobalVar(V_PROJECTOR_SLOT) == _asProjectorItem->maxSlotCount && _asProjectorItem->rightBorderLeaves != 0) {
- sendMessage(_parentScene, 0x1019, 1);
- incGlobalVar(V_PROJECTOR_LOCATION, +1);
- setGlobalVar(V_PROJECTOR_SLOT, 0);
- }
- }
- Sprite::updateBounds();
-}
-
-void AsCommonProjector::moveProjector() {
-
- bool nowLockedInSlot = false;
-
- _y = _asProjectorItem->point.y;
-
- if (_asProjectorItem->index1 != -1) {
- int16 elX = _asProjectorItem->index1 * 108 + _asProjectorItem->point.x;
- if (elX - 20 < _x && elX + 20 > _x) {
- nowLockedInSlot = true;
- _y = _asProjectorItem->point.y + 10;
- }
- }
-
- if (_asProjectorItem->lockSlotIndex != -1) {
- int16 elX = _asProjectorItem->lockSlotIndex * 108 + _asProjectorItem->point.x;
- if (elX - 20 < _x && elX + 20 > _x) {
- nowLockedInSlot = true;
- _y = _asProjectorItem->point.y + 10;
- }
- }
-
- if (_lockedInSlot && !nowLockedInSlot)
- _lockedInSlot = false;
- else if (!_lockedInSlot && nowLockedInSlot) {
- playSound(1, 0x5440E474);
- _lockedInSlot = true;
- }
-
-}
-
-void AsCommonProjector::stSuckedIn() {
- AnimatedSprite::updateDeltaXY();
- if (_collisionBounds.y1 <= 150) {
- sendMessage(_asPipe, 0x483A, 0);
- stopAnimation();
- setVisible(false);
- SetMessageHandler(&Sprite::handleMessage);
- SetSpriteUpdate(NULL);
- }
-}
-
-void AsCommonProjector::stIdle() {
- startAnimation(0x10E3042B, 0, -1);
- SetMessageHandler(&AsCommonProjector::handleMessage);
- SetSpriteUpdate(NULL);
-}
-
-void AsCommonProjector::stMoving() {
- _beforeMoveX = getGlobalVar(V_PROJECTOR_SLOT) * 108 + _asProjectorItem->point.x;
- startAnimation(0x14A10137, 0, -1);
- playSound(1, 0xEC008474);
- SetMessageHandler(&AsCommonProjector::handleMessage);
- SetSpriteUpdate(&AsCommonProjector::suMoving);
-}
-
-void AsCommonProjector::stStartLockedInSlot() {
- startAnimation(0x80C32213, 0, -1);
- SetMessageHandler(&AsCommonProjector::hmAnimation);
- SetSpriteUpdate(NULL);
- NextState(&AsCommonProjector::stStayLockedInSlot);
-}
-
-void AsCommonProjector::stStayLockedInSlot() {
- startAnimation(0xD23B207F, 0, -1);
- SetMessageHandler(&AsCommonProjector::hmLockedInSlot);
- SetSpriteUpdate(NULL);
-}
-
-void AsCommonProjector::stStartProjecting() {
- startAnimation(0x50A80517, 0, -1);
- setGlobalVar(V_PROJECTOR_ACTIVE, 1);
- playSound(0, 0xCC4A8456);
- _vm->_soundMan->addSound(0x05331081, 0xCE428854);
- _vm->_soundMan->playSoundLooping(0xCE428854);
- SetMessageHandler(&AsCommonProjector::hmAnimation);
- SetSpriteUpdate(NULL);
- NextState(&AsCommonProjector::stLockedInSlot);
-}
-
-void AsCommonProjector::stLockedInSlot() {
- sendMessage(_parentScene, 0x480F, 0);
- startAnimation(0xD833207F, 0, -1);
- SetMessageHandler(&AsCommonProjector::hmLockedInSlot);
- SetSpriteUpdate(NULL);
-}
-
-void AsCommonProjector::stStopProjecting() {
- startAnimation(0x50A94417, 0, -1);
- setGlobalVar(V_PROJECTOR_ACTIVE, 0);
- playSound(0, 0xCC4A8456);
- _vm->_soundMan->deleteSound(0xCE428854);
- SetMessageHandler(&AsCommonProjector::hmAnimation);
- SetSpriteUpdate(NULL);
- NextState(&AsCommonProjector::stStayLockedInSlot);
-}
-
-void AsCommonProjector::stTurnToFront() {
- _beforeMoveX = getGlobalVar(V_PROJECTOR_SLOT) * 108 + _asProjectorItem->point.x;
- startAnimation(0x22CB4A33, 0, -1);
- SetMessageHandler(&AsCommonProjector::hmAnimation);
- SetSpriteUpdate(&AsCommonProjector::suMoving);
- NextState(&AsCommonProjector::stMoving);
-}
-
-void AsCommonProjector::stStartSuckedIn() {
- setGlobalVar(V_PROJECTOR_LOCATION, 4);
- setGlobalVar(V_PROJECTOR_SLOT, 0);
- startAnimation(0x708D4712, 0, -1);
- playSound(2);
- SetMessageHandler(&Sprite::handleMessage);
- SetSpriteUpdate(&AsCommonProjector::stSuckedIn);
-}
-
Scene1401::Scene1401(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule), _projectorBorderFlag(false), _ssFloorButton(NULL), _asProjector(NULL),
_asPipe(NULL), _asMouse(NULL), _asCheese(NULL), _asBackDoor(NULL),
@@ -696,7 +207,7 @@ Scene1401::Scene1401(NeverhoodEngine *vm, Module *parentModule, int which)
_klaymen->setClipRect(_sprite3->getDrawRect().x, 0, 640, 480);
if (which == 0 && _asProjector)
- sendMessage(_asProjector, 0x482B, 0);
+ sendMessage(_asProjector, NM_MOVE_TO_FRONT, 0);
_asBackDoor = insertSprite<AsScene1401BackDoor>(_klaymen, which == 0);
@@ -714,7 +225,7 @@ void Scene1401::update() {
uint32 Scene1401::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0x02144CB1)
sendEntityMessage(_klaymen, 0x1014, _ssFloorButton);
else if (param.asInteger() == 0x402064D8)
@@ -726,7 +237,7 @@ uint32 Scene1401::handleMessage(int messageNum, const MessageParam &param, Entit
setMessageList(0x004B66B0);
}
break;
- case 0x1019:
+ case NM_SCENE_LEAVE:
if (param.asInteger() != 0)
leaveScene(2);
else
@@ -743,7 +254,7 @@ uint32 Scene1401::handleMessage(int messageNum, const MessageParam &param, Entit
if (_asProjector && _asProjector->getX() > 404 && _asProjector->getX() < 504)
sendMessage(_asProjector , 0x4839, 0);
} else if (sender == _ssButton)
- sendMessage(_asBackDoor, 0x4808, 0);
+ sendMessage(_asBackDoor, NM_KLAYMEN_OPEN_DOOR, 0);
break;
case 0x4826:
if (sender == _asProjector) {
@@ -754,91 +265,20 @@ uint32 Scene1401::handleMessage(int messageNum, const MessageParam &param, Entit
setMessageList2(0x004B65F0);
}
break;
- case 0x482A:
+ case NM_MOVE_TO_BACK:
_sprite1->setVisible(true);
if (_asProjector)
- sendMessage(_asProjector, 0x482B, 0);
+ sendMessage(_asProjector, NM_MOVE_TO_FRONT, 0);
break;
- case 0x482B:
+ case NM_MOVE_TO_FRONT:
_sprite1->setVisible(false);
if (_asProjector)
- sendMessage(_asProjector, 0x482A, 0);
+ sendMessage(_asProjector, NM_MOVE_TO_BACK, 0);
break;
}
return 0;
}
-// Scene1402
-
-SsScene1402BridgePart::SsScene1402BridgePart(NeverhoodEngine *vm, uint32 fileHash, int surfacePriority)
- : StaticSprite(vm, fileHash, surfacePriority) {
-
- SetFilterY(&Sprite::defFilterY);
- SetUpdateHandler(&StaticSprite::updatePosition);
-}
-
-AsScene1402PuzzleBox::AsScene1402PuzzleBox(NeverhoodEngine *vm, Scene *parentScene, int status)
- : AnimatedSprite(vm, 1100), _parentScene(parentScene) {
-
- createSurface(900, 347, 230);
-
- SetFilterY(&Sprite::defFilterY);
- SetUpdateHandler(&AnimatedSprite::update);
- SetMessageHandler(&AsScene1402PuzzleBox::handleMessage);
- _x = 279;
- _y = 270;
- if (status == 2) {
- // Puzzle box after the puzzle was solved
- startAnimation(0x20060259, 0, -1);
- playSound(0, 0x419014AC);
- loadSound(1, 0x61901C29);
- NextState(&AsScene1402PuzzleBox::stMoveDownSolvedDone);
- } else if (status == 1) {
- // Puzzle box appears
- startAnimation(0x210A0213, 0, -1);
- playSound(0, 0x41809C6C);
- NextState(&AsScene1402PuzzleBox::stMoveUpDone);
- } else {
- // Puzzle box is here
- startAnimation(0x20060259, -1, -1);
- loadSound(1, 0x61901C29);
- _newStickFrameIndex = STICK_LAST_FRAME;
- }
-}
-
-uint32 AsScene1402PuzzleBox::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x2002:
- playSound(1);
- startAnimation(0x20060259, -1, -1);
- _playBackwards = true;
- NextState(&AsScene1402PuzzleBox::stMoveDownDone);
- break;
- case 0x3002:
- gotoNextState();
- break;
- }
- return messageResult;
-}
-
-void AsScene1402PuzzleBox::stMoveUpDone() {
- sendMessage(_parentScene, 0x2000, 0);
- stopAnimation();
- setVisible(false);
-}
-
-void AsScene1402PuzzleBox::stMoveDownDone() {
- sendMessage(_parentScene, 0x2001, 0);
- stopAnimation();
- setVisible(false);
-}
-
-void AsScene1402PuzzleBox::stMoveDownSolvedDone() {
- sendMessage(_parentScene, 0x2003, 0);
- stopAnimation();
-}
-
Scene1402::Scene1402(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule), _isShaking(false), _asPuzzleBox(NULL), _asProjector(NULL) {
@@ -935,7 +375,7 @@ void Scene1402::upShaking() {
uint32 Scene1402::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0x00F43389) {
if (getGlobalVar(V_MOUSE_PUZZLE_SOLVED))
leaveScene(0);
@@ -943,18 +383,18 @@ uint32 Scene1402::handleMessage(int messageNum, const MessageParam &param, Entit
clearRectList();
_klaymen->setVisible(false);
showMouse(false);
- sendMessage(_asPuzzleBox, 0x2002, 0);
+ sendMessage(_asPuzzleBox, NM_POSITION_CHANGE, 0);
startShaking();
}
}
break;
- case 0x1019:
+ case NM_SCENE_LEAVE:
if (param.asInteger())
leaveScene(0);
else
leaveScene(1);
break;
- case 0x2000:
+ case NM_ANIMATION_UPDATE:
stopShaking();
showMouse(true);
setRectList(0x004B0C48);
@@ -988,237 +428,6 @@ void Scene1402::stopShaking() {
_isShaking = false;
}
-// Scene1407
-
-static const int16 kScene1407MouseFloorY[] = {
- 106, 150, 191, 230, 267, 308, 350, 395
-};
-
-static const struct {
- int16 x;
- int16 floorIndex;
- int16 sectionIndex;
- int16 nextHoleIndex;
-} kScene1407MouseHoles[] = {
- {125, 0, 0, 7},
- {452, 7, 21, 0},
- {337, 4, 11, 4},
- {286, 6, 17, 6},
- {348, 6, 17, 39},
- {536, 6, 18, 42},
- {111, 1, 3, 18},
- {203, 1, 3, 38},
- {270, 1, 3, 9},
- {197, 5, 14, 3},
- {252, 5, 14, 35},
- {297, 5, 14, 7},
- {359, 5, 14, 8},
- {422, 4, 12, 26},
- {467, 4, 12, 2},
- {539, 4, 12, 40},
- {111, 5, 13, 17},
- {211, 0, 1, 20},
- {258, 0, 1, 11},
- {322, 0, 1, 16},
- { 99, 6, 16, 31},
- {142, 6, 16, 27},
- {194, 6, 16, 12},
- {205, 2, 6, 45},
- {264, 2, 6, 10},
- { 98, 4, 10, 2},
- {152, 4, 10, 37},
- {199, 4, 10, 13},
- {258, 4, 10, 16},
- {100, 7, 19, 43},
- {168, 7, 19, 23},
- {123, 3, 8, 14},
- {181, 3, 8, 39},
- {230, 3, 8, 28},
- {292, 3, 8, 22},
- {358, 3, 8, 36},
- {505, 3, 9, 44},
- {400, 2, 7, 34},
- {454, 2, 7, 32},
- {532, 2, 7, 46},
- {484, 5, 15, 25},
- {529, 5, 15, 30},
- {251, 7, 20, 48},
- {303, 7, 20, 21},
- {360, 7, 20, 33},
- {503, 0, 2, 5},
- {459, 1, 4, 19},
- {530, 1, 4, 42},
- {111, 2, 5, 47},
- {442, 6, 18, 1}
-};
-
-static const struct {
- int16 x1, x2;
- int16 goodHoleIndex;
-} kScene1407MouseSections[] = {
- {100, 149, 0},
- {182, 351, 17},
- {430, 524, 45},
- { 89, 293, 7},
- {407, 555, 47},
- { 89, 132, 48},
- {178, 303, 23},
- {367, 551, 38},
- {105, 398, 31},
- {480, 537, 36},
- { 84, 275, 27},
- {318, 359, 2},
- {402, 560, 15},
- { 91, 132, 16},
- {179, 400, 10},
- {461, 552, 41},
- { 86, 218, 21},
- {267, 376, 4},
- {420, 560, 49},
- { 77, 188, 30},
- {237, 394, 44},
- {438, 515, 5}
-};
-
-AsScene1407Mouse::AsScene1407Mouse(NeverhoodEngine *vm, Scene *parentScene)
- : AnimatedSprite(vm, 1100), _parentScene(parentScene), _currSectionIndex(0) {
-
- createSurface(100, 117, 45);
- _x = 108;
- _y = 106;
- stIdleLookAtGoodHole();
- SetUpdateHandler(&AnimatedSprite::update);
-}
-
-void AsScene1407Mouse::suWalkTo() {
- int16 xdelta = _walkDestX - _x;
- if (xdelta > _deltaX)
- xdelta = _deltaX;
- else if (xdelta < -_deltaX)
- xdelta = -_deltaX;
- _deltaX = 0;
- if (_walkDestX == _x)
- sendMessage(this, 0x1019, 0);
- else {
- _x += xdelta;
- updateBounds();
- }
-}
-
-void AsScene1407Mouse::upGoThroughHole() {
- if (_countdown != 0 && (--_countdown == 0)) {
- SetUpdateHandler(&AnimatedSprite::update);
- gotoNextState();
- }
- AnimatedSprite::update();
-}
-
-uint32 AsScene1407Mouse::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x0001:
- {
- int16 mouseX = param.asPoint().x;
- int16 mouseY = param.asPoint().y;
- int holeIndex;
- for (holeIndex = 0; holeIndex < 50; holeIndex++) {
- int16 holeX = kScene1407MouseHoles[holeIndex].x;
- int16 holeY = kScene1407MouseFloorY[kScene1407MouseHoles[holeIndex].floorIndex];
- if (mouseX >= holeX - 14 && mouseX <= holeX + 14 && mouseY >= holeY - 36 && mouseY <= holeY)
- break;
- }
- if (holeIndex < 50 && kScene1407MouseHoles[holeIndex].sectionIndex == _currSectionIndex) {
- _nextHoleIndex = kScene1407MouseHoles[holeIndex].nextHoleIndex;
- _walkDestX = kScene1407MouseHoles[holeIndex].x;
- stWalkToHole();
- } else {
- if (mouseX < kScene1407MouseSections[_currSectionIndex].x1)
- _walkDestX = kScene1407MouseSections[_currSectionIndex].x1;
- else if (mouseX > kScene1407MouseSections[_currSectionIndex].x2)
- _walkDestX = kScene1407MouseSections[_currSectionIndex].x2;
- else
- _walkDestX = mouseX;
- stWalkToDest();
- }
- }
- break;
- case 0x1019:
- gotoNextState();
- break;
- case 0x2001:
- {
- // Reset the position
- // Find the nearest hole and go through it, and exit at the first hole
- int16 distance = 640;
- int matchIndex = 50;
- for (int index = 0; index < 50; index++)
- if (kScene1407MouseHoles[index].sectionIndex == _currSectionIndex &&
- ABS(kScene1407MouseHoles[index].x - _x) < distance) {
- matchIndex = index;
- distance = ABS(kScene1407MouseHoles[index].x - _x);
- }
- if (matchIndex < 50) {
- _nextHoleIndex = 0;
- _walkDestX = kScene1407MouseHoles[matchIndex].x;
- stWalkToHole();
- }
- }
- break;
- }
- return messageResult;
-}
-
-void AsScene1407Mouse::stIdleLookAtGoodHole() {
- setDoDeltaX(kScene1407MouseHoles[kScene1407MouseSections[_currSectionIndex].goodHoleIndex].x < _x ? 1 : 0);
- startAnimation(0x72215194, 0, -1);
- SetMessageHandler(&AsScene1407Mouse::handleMessage);
- SetSpriteUpdate(NULL);
-}
-
-void AsScene1407Mouse::stWalkToDest() {
- if (_walkDestX != _x) {
- setDoDeltaX(_walkDestX < _x ? 1 : 0);
- startAnimation(0x22291510, 0, -1);
- SetMessageHandler(&AsScene1407Mouse::handleMessage);
- SetSpriteUpdate(&AsScene1407Mouse::suWalkTo);
- NextState(&AsScene1407Mouse::stIdleLookAtGoodHole);
- }
-}
-
-void AsScene1407Mouse::stWalkToHole() {
- setDoDeltaX(_walkDestX < _x ? 1 : 0);
- startAnimation(0x22291510, 0, -1);
- SetMessageHandler(&AsScene1407Mouse::handleMessage);
- SetSpriteUpdate(&AsScene1407Mouse::suWalkTo);
- NextState(&AsScene1407Mouse::stGoThroughHole);
-}
-
-void AsScene1407Mouse::stGoThroughHole() {
- startAnimation(0x72215194, 0, -1);
- setVisible(false);
- _countdown = 12;
- SetUpdateHandler(&AsScene1407Mouse::upGoThroughHole);
- SetMessageHandler(NULL);
- SetSpriteUpdate(NULL);
- NextState(&AsScene1407Mouse::stArriveAtHole);
-}
-
-void AsScene1407Mouse::stArriveAtHole() {
- _currSectionIndex = kScene1407MouseHoles[_nextHoleIndex].sectionIndex;
- _x = kScene1407MouseHoles[_nextHoleIndex].x;
- _y = kScene1407MouseFloorY[kScene1407MouseHoles[_nextHoleIndex].floorIndex];
- if (_nextHoleIndex == 1) {
- sendMessage(_parentScene, 0x2000, 0);
- _walkDestX = 512;
- stWalkToDest();
- setVisible(true);
- } else {
- _walkDestX = _x + 14;
- stWalkToDest();
- setVisible(true);
- }
-}
-
Scene1407::Scene1407(NeverhoodEngine *vm, Module *parentModule)
: Scene(vm, parentModule), _puzzleSolvedCountdown(0), _resetButtonCountdown(0) {
@@ -1246,7 +455,7 @@ void Scene1407::update() {
uint32 Scene1407::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x0001:
+ case NM_MOUSE_CLICK:
if (_puzzleSolvedCountdown == 0) {
if (param.asPoint().x <= 20 || param.asPoint().x >= 620) {
// Exit scene
@@ -1264,7 +473,7 @@ uint32 Scene1407::handleMessage(int messageNum, const MessageParam &param, Entit
}
}
break;
- case 0x2000:
+ case NM_ANIMATION_UPDATE:
// The mouse got the cheese (nomnom)
setGlobalVar(V_MOUSE_PUZZLE_SOLVED, 1);
playSound(0, 0x68E25540);
@@ -1275,8 +484,6 @@ uint32 Scene1407::handleMessage(int messageNum, const MessageParam &param, Entit
return 0;
}
-// Scene1403
-
Scene1403::Scene1403(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule), _asProjector(NULL), _isProjecting(false) {
@@ -1327,7 +534,7 @@ Scene1403::Scene1403(NeverhoodEngine *vm, Module *parentModule, int which)
uint32 Scene1403::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0x88C11390) {
setRectList(0x004B2008);
_isProjecting = true;
@@ -1337,10 +544,10 @@ uint32 Scene1403::handleMessage(int messageNum, const MessageParam &param, Entit
_isProjecting = false;
}
break;
- case 0x1019:
+ case NM_SCENE_LEAVE:
leaveScene(0);
break;
- case 0x1022:
+ case NM_PRIORITY_CHANGE:
if (sender == _asProjector) {
if (param.asInteger() >= 1000)
setSurfacePriority(_sprite3->getSurface(), 1100);
@@ -1348,10 +555,10 @@ uint32 Scene1403::handleMessage(int messageNum, const MessageParam &param, Entit
setSurfacePriority(_sprite3->getSurface(), 995);
}
break;
- case 0x4807:
+ case NM_KLAYMEN_RAISE_LEVER:
_sprite1->setVisible(false);
break;
- case 0x480F:
+ case NM_KLAYMEN_LOWER_LEVER:
_sprite1->setVisible(true);
break;
case 0x4826:
@@ -1379,8 +586,6 @@ uint32 Scene1403::handleMessage(int messageNum, const MessageParam &param, Entit
return 0;
}
-// Scene1404
-
Scene1404::Scene1404(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule), _asProjector(NULL), _asKey(NULL) {
@@ -1450,7 +655,7 @@ Scene1404::~Scene1404() {
uint32 Scene1404::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0x410650C2) {
if (_asProjector && _asProjector->getX() == 220)
setMessageList(0x004B8C40);
@@ -1458,7 +663,7 @@ uint32 Scene1404::handleMessage(int messageNum, const MessageParam &param, Entit
setMessageList(0x004B8CE8);
}
break;
- case 0x1019:
+ case NM_SCENE_LEAVE:
leaveScene(0);
break;
case 0x4826:
@@ -1480,77 +685,6 @@ uint32 Scene1404::handleMessage(int messageNum, const MessageParam &param, Entit
return 0;
}
-// Scene1405
-
-static const NPoint kAsScene1405TileItemPositions[] = {
- {100, 80}, {162, 78}, {222, 76}, {292, 76},
- {356, 82}, {422, 84}, {488, 86}, {550, 90},
- {102, 134}, {164, 132}, {224, 136}, {294, 136},
- {360, 136}, {422, 138}, {484, 144}, {548, 146},
- { 98, 196}, {160, 200}, {228, 200}, {294, 202},
- {360, 198}, {424, 200}, {482, 202}, {548, 206},
- { 98, 260}, {160, 264}, {226, 260}, {296, 262},
- {358, 260}, {424, 262}, {486, 264}, {550, 266},
- { 94, 322}, {160, 316}, {226, 316}, {296, 320},
- {358, 322}, {422, 324}, {488, 322}, {550, 322},
- { 98, 380}, {160, 376}, {226, 376}, {294, 378},
- {356, 380}, {420, 380}, {490, 378}, {552, 376}
-};
-
-AsScene1405Tile::AsScene1405Tile(NeverhoodEngine *vm, Scene1405 *parentScene, uint32 tileIndex)
- : AnimatedSprite(vm, 1100), _parentScene(parentScene), _tileIndex(tileIndex), _countdown(0), _isShowing(false) {
-
- loadSound(0, 0x05308101);
- setSoundPan(0, (tileIndex % 8 * 4 + 4) * 25 / 8);
- _x = kAsScene1405TileItemPositions[_tileIndex].x;
- _y = kAsScene1405TileItemPositions[_tileIndex].y;
- createSurface1(0x844B805C, 1100);
- setVisible(false);
- if (getSubVar(VA_IS_TILE_MATCH, _tileIndex))
- _countdown = _vm->_rnd->getRandomNumber(36 - 1) + 1;
- startAnimation(0x844B805C, getSubVar(VA_TILE_SYMBOLS, _tileIndex), -1);
- _newStickFrameIndex = (int16)getSubVar(VA_TILE_SYMBOLS, _tileIndex);
- SetUpdateHandler(&AsScene1405Tile::update);
- SetMessageHandler(&AsScene1405Tile::handleMessage);
-}
-
-void AsScene1405Tile::update() {
- updateAnim();
- updatePosition();
- if (_countdown != 0 && (--_countdown == 0))
- show();
-}
-
-uint32 AsScene1405Tile::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x1011:
- if (getSubVar(VA_IS_TILE_MATCH, _tileIndex) == 0 && _parentScene->getCountdown() == 0) {
- show();
- sendMessage(_parentScene, 0x2000, _tileIndex);
- }
- messageResult = 1;
- break;
- }
- return messageResult;
-}
-
-void AsScene1405Tile::show() {
- if (!_isShowing) {
- _isShowing = true;
- playSound(0);
- setVisible(true);
- }
-}
-
-void AsScene1405Tile::hide() {
- if (_isShowing) {
- _isShowing = false;
- playSound(0);
- setVisible(false);
- }
-}
-
Scene1405::Scene1405(NeverhoodEngine *vm, Module *parentModule)
: Scene(vm, parentModule), _selectFirstTile(true), _tilesLeft(48), _countdown(0) {
@@ -1591,11 +725,11 @@ void Scene1405::update() {
uint32 Scene1405::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x0001:
+ case NM_MOUSE_CLICK:
if (param.asPoint().x <= 20 || param.asPoint().x >= 620)
leaveScene(0);
break;
- case 0x2000:
+ case NM_ANIMATION_UPDATE:
if (_selectFirstTile) {
_firstTileIndex = param.asInteger();
_selectFirstTile = false;
diff --git a/engines/neverhood/modules/module1400.h b/engines/neverhood/modules/module1400.h
index 9a592c2952..53ad7125ab 100644
--- a/engines/neverhood/modules/module1400.h
+++ b/engines/neverhood/modules/module1400.h
@@ -26,7 +26,6 @@
#include "neverhood/neverhood.h"
#include "neverhood/module.h"
#include "neverhood/scene.h"
-#include "neverhood/modules/module1200.h"
namespace Neverhood {
@@ -40,92 +39,9 @@ protected:
void updateScene();
};
-// Scene1401
-
-class AsScene1401Pipe : public AnimatedSprite {
-public:
- AsScene1401Pipe(NeverhoodEngine *vm);
- virtual ~AsScene1401Pipe();
-protected:
- int _countdown1;
- int _countdown2;
- void update();
- void upSuckInProjector();
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- uint32 hmSuckInProjector(int messageNum, const MessageParam &param, Entity *sender);
- void stStartSucking();
- void stDoneSucking();
- void stSuckInProjector();
-};
-
-class AsScene1401Mouse : public AnimatedSprite {
-public:
- AsScene1401Mouse(NeverhoodEngine *vm);
-protected:
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- void suSuckedIn();
- void stSuckedIn();
-};
-
-class AsScene1401Cheese : public AnimatedSprite {
-public:
- AsScene1401Cheese(NeverhoodEngine *vm);
-protected:
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- void suSuckedIn();
- void stSuckedIn();
-};
-
-class AsScene1401BackDoor : public AnimatedSprite {
-public:
- AsScene1401BackDoor(NeverhoodEngine *vm, Sprite *klaymen, bool isOpen);
-protected:
- Sprite *_klaymen;
- int _countdown;
- bool _isOpen;
- void update();
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- void stOpenDoor();
- void stCloseDoor();
- void stCloseDoorDone();
-};
-
-struct AsCommonProjectorItem {
- NPoint point;
- int8 maxSlotCount;
- int8 lockSlotIndex;
- int8 index1;
- int8 leftBorderLeaves;
- int8 rightBorderLeaves;
-};
-
-class AsCommonProjector : public AnimatedSprite {
-public:
- AsCommonProjector(NeverhoodEngine *vm, Scene *parentScene, Sprite *klaymen, Sprite *asPipe);
- virtual ~AsCommonProjector();
-protected:
- Scene *_parentScene;
- Sprite *_klaymen;
- Sprite *_asPipe;
- const AsCommonProjectorItem *_asProjectorItem;
- int16 _beforeMoveX;
- bool _lockedInSlot;
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- uint32 hmLockedInSlot(int messageNum, const MessageParam &param, Entity *sender);
- uint32 hmAnimation(int messageNum, const MessageParam &param, Entity *sender);
- void suMoving();
- void moveProjector();
- void stSuckedIn();
- void stIdle();
- void stMoving();
- void stStartLockedInSlot();
- void stStayLockedInSlot();
- void stStartProjecting();
- void stLockedInSlot();
- void stStopProjecting();
- void stTurnToFront();
- void stStartSuckedIn();
-};
+class AsCommonProjector;
+class AsScene1201Tape;
+class AsScene1405Tile;
class Scene1401 : public Scene {
public:
@@ -146,24 +62,6 @@ protected:
uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
};
-// Scene1402
-
-class SsScene1402BridgePart : public StaticSprite {
-public:
- SsScene1402BridgePart(NeverhoodEngine *vm, uint32 fileHash, int surfacePriority);
-};
-
-class AsScene1402PuzzleBox : public AnimatedSprite {
-public:
- AsScene1402PuzzleBox(NeverhoodEngine *vm, Scene *parentScene, int status);
-protected:
- Scene *_parentScene;
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- void stMoveUpDone();
- void stMoveDownDone();
- void stMoveDownSolvedDone();
-};
-
class Scene1402 : public Scene {
public:
Scene1402(NeverhoodEngine *vm, Module *parentModule, int which);
@@ -180,27 +78,6 @@ protected:
void stopShaking();
};
-// Scene1407
-
-class AsScene1407Mouse : public AnimatedSprite {
-public:
- AsScene1407Mouse(NeverhoodEngine *vm, Scene *parentScene);
-protected:
- Scene *_parentScene;
- int16 _walkDestX;
- int16 _currSectionIndex;
- int16 _nextHoleIndex;
- int _countdown;
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- void suWalkTo();
- void upGoThroughHole();
- void stIdleLookAtGoodHole();
- void stWalkToDest();
- void stWalkToHole();
- void stGoThroughHole();
- void stArriveAtHole();
-};
-
class Scene1407 : public Scene {
public:
Scene1407(NeverhoodEngine *vm, Module *parentModule);
@@ -213,8 +90,6 @@ protected:
uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
};
-// Scene1403
-
class Scene1403 : public Scene {
public:
Scene1403(NeverhoodEngine *vm, Module *parentModule, int which);
@@ -229,8 +104,6 @@ protected:
uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
};
-// Scene1404
-
class Scene1404 : public Scene {
public:
Scene1404(NeverhoodEngine *vm, Module *parentModule, int which);
@@ -243,24 +116,6 @@ protected:
uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
};
-// Scene1405
-
-class Scene1405;
-
-class AsScene1405Tile : public AnimatedSprite {
-public:
- AsScene1405Tile(NeverhoodEngine *vm, Scene1405 *parentScene, uint32 tileIndex);
- void show();
- void hide();
-protected:
- Scene1405 *_parentScene;
- bool _isShowing;
- uint32 _tileIndex;
- int _countdown;
- void update();
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
-
class Scene1405 : public Scene {
public:
Scene1405(NeverhoodEngine *vm, Module *parentModule);
diff --git a/engines/neverhood/modules/module1400_sprites.cpp b/engines/neverhood/modules/module1400_sprites.cpp
new file mode 100644
index 0000000000..478b328034
--- /dev/null
+++ b/engines/neverhood/modules/module1400_sprites.cpp
@@ -0,0 +1,1129 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public 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 "neverhood/modules/module1400_sprites.h"
+#include "neverhood/modules/module1400.h"
+
+namespace Neverhood {
+
+AsScene1401Pipe::AsScene1401Pipe(NeverhoodEngine *vm)
+ : AnimatedSprite(vm, 1100), _countdown1(0), _countdown2(0) {
+
+ createSurface(900, 152, 147);
+ _x = 454;
+ _y = 217;
+ startAnimation(0x4C210500, 0, -1);
+ SetUpdateHandler(&AsScene1401Pipe::update);
+ SetMessageHandler(&AsScene1401Pipe::handleMessage);
+}
+
+AsScene1401Pipe::~AsScene1401Pipe() {
+ _vm->_soundMan->deleteSoundGroup(0x01104C08);
+}
+
+void AsScene1401Pipe::update() {
+ AnimatedSprite::update();
+ if (_countdown1 != 0 && (--_countdown1 == 0))
+ stDoneSucking();
+ if (_countdown2 != 0 && (--_countdown2 == 0)) {
+ _vm->_soundMan->addSound(0x01104C08, 0x4A116437);
+ _vm->_soundMan->playSoundLooping(0x4A116437);
+ }
+}
+
+void AsScene1401Pipe::upSuckInProjector() {
+ AnimatedSprite::update();
+ if (_countdown1 != 0)
+ _countdown1--;
+}
+
+uint32 AsScene1401Pipe::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case NM_ANIMATION_START:
+ if (param.asInteger() == 0x0A8A1490)
+ playSound(1, 0x6AB6666F);
+ break;
+ case NM_ANIMATION_UPDATE:
+ _countdown1 = 70;
+ _countdown2 = 8;
+ stStartSucking();
+ break;
+ case 0x483A:
+ stSuckInProjector();
+ break;
+ }
+ return messageResult;
+}
+
+uint32 AsScene1401Pipe::hmSuckInProjector(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case NM_ANIMATION_STOP:
+ if (_countdown1 != 0)
+ stStartSucking();
+ else
+ stDoneSucking();
+ SetMessageHandler(&AsScene1401Pipe::handleMessage);
+ SetUpdateHandler(&AsScene1401Pipe::update);
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene1401Pipe::stStartSucking() {
+ startAnimation(0x4C240100, 0, -1);
+ playSound(0, 0x4A30063F);
+}
+
+void AsScene1401Pipe::stDoneSucking() {
+ _vm->_soundMan->deleteSound(0x4A116437);
+ playSound(0, 0x4A120435);
+ startAnimation(0x4C210500, 0, -1);
+}
+
+void AsScene1401Pipe::stSuckInProjector() {
+ startAnimation(0x6C210810, 0, -1);
+ SetUpdateHandler(&AsScene1401Pipe::upSuckInProjector);
+ SetMessageHandler(&AsScene1401Pipe::hmSuckInProjector);
+}
+
+AsScene1401Mouse::AsScene1401Mouse(NeverhoodEngine *vm)
+ : AnimatedSprite(vm, 1100) {
+
+ createSurface(100, 71, 41);
+ _x = 478;
+ _y = 433;
+ startAnimation(0xA282C472, 0, -1);
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsScene1401Mouse::handleMessage);
+}
+
+uint32 AsScene1401Mouse::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case NM_ANIMATION_START:
+ if (param.asInteger() == 0x66382026)
+ playSound(0, 0x0CD84468);
+ else if (param.asInteger() == 0x6E28061C)
+ playSound(0, 0x78C8402C);
+ else if (param.asInteger() == 0x462F0410)
+ playSound(0, 0x60984E28);
+ break;
+ case 0x4839:
+ stSuckedIn();
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene1401Mouse::suSuckedIn() {
+ AnimatedSprite::updateDeltaXY();
+ if (_collisionBounds.y1 <= 150) {
+ playSound(0, 0x0E32247F);
+ stopAnimation();
+ setVisible(false);
+ SetMessageHandler(NULL);
+ SetSpriteUpdate(NULL);
+ }
+}
+
+void AsScene1401Mouse::stSuckedIn() {
+ startAnimation(0x34880040, 0, -1);
+ SetSpriteUpdate(&AsScene1401Mouse::suSuckedIn);
+}
+
+AsScene1401Cheese::AsScene1401Cheese(NeverhoodEngine *vm)
+ : AnimatedSprite(vm, 1100) {
+
+ createSurface(200, 152, 147);
+ _x = 427;
+ _y = 433;
+ startAnimation(0x461A1490, 0, -1);
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsScene1401Cheese::handleMessage);
+}
+
+uint32 AsScene1401Cheese::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x4839:
+ stSuckedIn();
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene1401Cheese::suSuckedIn() {
+ AnimatedSprite::updateDeltaXY();
+ if (_collisionBounds.y1 <= 150) {
+ playSound(0, 0x18020439);
+ stopAnimation();
+ setVisible(false);
+ SetMessageHandler(NULL);
+ SetSpriteUpdate(NULL);
+ }
+}
+
+void AsScene1401Cheese::stSuckedIn() {
+ startAnimation(0x103B8020, 0, -1);
+ SetSpriteUpdate(&AsScene1401Cheese::suSuckedIn);
+}
+
+AsScene1401BackDoor::AsScene1401BackDoor(NeverhoodEngine *vm, Sprite *klaymen, bool isOpen)
+ : AnimatedSprite(vm, 1100), _klaymen(klaymen), _countdown(0), _isOpen(isOpen) {
+
+ _x = 320;
+ _y = 240;
+ createSurface1(0x04551900, 100);
+ if (isOpen) {
+ startAnimation(0x04551900, -1, -1);
+ _countdown = 48;
+ } else {
+ stopAnimation();
+ setVisible(false);
+ }
+ _newStickFrameIndex = STICK_LAST_FRAME;
+ SetUpdateHandler(&AsScene1401BackDoor::update);
+ SetMessageHandler(&AsScene1401BackDoor::handleMessage);
+}
+
+void AsScene1401BackDoor::update() {
+ if (_countdown != 0 && (--_countdown == 0))
+ stCloseDoor();
+ AnimatedSprite::update();
+}
+
+
+uint32 AsScene1401BackDoor::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x2001:
+ if (_isOpen)
+ _countdown = 168;
+ messageResult = _isOpen ? 1 : 0;
+ break;
+ case NM_ANIMATION_STOP:
+ gotoNextState();
+ break;
+ case NM_KLAYMEN_OPEN_DOOR:
+ _countdown = 168;
+ if (!_isOpen)
+ stOpenDoor();
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene1401BackDoor::stOpenDoor() {
+ _isOpen = true;
+ setVisible(true);
+ startAnimation(0x04551900, 0, -1);
+ _newStickFrameIndex = STICK_LAST_FRAME;
+ playSound(0, calcHash("fxDoorOpen24"));
+}
+
+void AsScene1401BackDoor::stCloseDoor() {
+ _isOpen = false;
+ setVisible(true);
+ startAnimation(0x04551900, -1, -1);
+ playSound(0, calcHash("fxDoorClose24"));
+ _playBackwards = true;
+ NextState(&AsScene1401BackDoor::stCloseDoorDone);
+}
+
+void AsScene1401BackDoor::stCloseDoorDone() {
+ stopAnimation();
+ setVisible(false);
+}
+
+static const AsCommonProjectorItem kAsCommonProjectorItems[] = {
+ {{154, 453}, 4, 2, 0, 0, 1},
+ {{104, 391}, 4, -1, -1, 1, 1},
+ {{ 22, 447}, 6, -1, -1, 1, 1},
+ {{112, 406}, 2, -1, -1, 1, 0},
+ {{262, 433}, 1, 1, 0, 0, 0}
+};
+
+AsCommonProjector::AsCommonProjector(NeverhoodEngine *vm, Scene *parentScene, Sprite *klaymen, Sprite *asPipe)
+ : AnimatedSprite(vm, 1100), _parentScene(parentScene), _klaymen(klaymen), _asPipe(asPipe) {
+
+ _asProjectorItem = &kAsCommonProjectorItems[getGlobalVar(V_PROJECTOR_LOCATION)];
+ createSurface(990, 101, 182);
+ startAnimation(0x10E3042B, 0, -1);
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsCommonProjector::handleMessage);
+ _x = getGlobalVar(V_PROJECTOR_SLOT) * 108 + _asProjectorItem->point.x;
+ _lockedInSlot = true;
+ moveProjector();
+ setDoDeltaX(1);
+ if ((int8)getGlobalVar(V_PROJECTOR_SLOT) == _asProjectorItem->lockSlotIndex)
+ stStayLockedInSlot();
+ loadSound(2, 0xC8C2507C);
+}
+
+AsCommonProjector::~AsCommonProjector() {
+ _vm->_soundMan->deleteSoundGroup(0x05331081);
+}
+
+uint32 AsCommonProjector::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x1011:
+ sendMessage(_parentScene, 0x4826, 0);
+ messageResult = 1;
+ break;
+ case NM_KLAYMEN_RAISE_LEVER:
+ setGlobalVar(V_PROJECTOR_SLOT, (_x - _asProjectorItem->point.x) / 108);
+ if ((int8)getGlobalVar(V_PROJECTOR_SLOT) == _asProjectorItem->lockSlotIndex)
+ stStartLockedInSlot();
+ else
+ stIdle();
+ break;
+ case 0x480B:
+ if (param.asInteger() != 1) {
+ if ((int8)getGlobalVar(V_PROJECTOR_SLOT) < _asProjectorItem->maxSlotCount)
+ incGlobalVar(V_PROJECTOR_SLOT, 1);
+ } else if (getGlobalVar(V_PROJECTOR_SLOT) > 0)
+ incGlobalVar(V_PROJECTOR_SLOT, -1);
+ stMoving();
+ break;
+ case 0x480C:
+ // Check if the projector can be moved
+ if (param.asInteger() != 1)
+ messageResult = (int8)getGlobalVar(V_PROJECTOR_SLOT) < _asProjectorItem->maxSlotCount ? 1 : 0;
+ else
+ messageResult = getGlobalVar(V_PROJECTOR_SLOT) > 0 ? 1 : 0;
+ break;
+ case NM_MOVE_TO_BACK:
+ sendMessage(_parentScene, NM_PRIORITY_CHANGE, 990);
+ break;
+ case NM_MOVE_TO_FRONT:
+ sendMessage(_parentScene, NM_PRIORITY_CHANGE, 1010);
+ break;
+ case 0x4839:
+ stStartSuckedIn();
+ break;
+ }
+ return messageResult;
+}
+
+uint32 AsCommonProjector::hmLockedInSlot(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x1011:
+ if (param.asPoint().x - _x >= 17 && param.asPoint().x - _x <= 56 &&
+ param.asPoint().y - _y >= -120 && param.asPoint().y - _y <= -82) {
+ sendMessage(_parentScene, 0x4826, 1);
+ } else
+ sendMessage(_parentScene, 0x4826, 0);
+ messageResult = 1;
+ break;
+ case NM_KLAYMEN_RAISE_LEVER:
+ sendMessage(_parentScene, NM_KLAYMEN_RAISE_LEVER, 0);
+ stStopProjecting();
+ break;
+ case 0x480B:
+ if (param.asInteger() != 1) {
+ if ((int8)getGlobalVar(V_PROJECTOR_SLOT) < _asProjectorItem->maxSlotCount)
+ incGlobalVar(V_PROJECTOR_SLOT, 1);
+ } else if (getGlobalVar(V_PROJECTOR_SLOT) > 0)
+ incGlobalVar(V_PROJECTOR_SLOT, -1);
+ stTurnToFront();
+ break;
+ case 0x480C:
+ // Check if the projector can be moved
+ if (param.asInteger() != 1)
+ messageResult = (int8)getGlobalVar(V_PROJECTOR_SLOT) < _asProjectorItem->maxSlotCount ? 1 : 0;
+ else
+ messageResult = getGlobalVar(V_PROJECTOR_SLOT) > 0 ? 1 : 0;
+ break;
+ case NM_KLAYMEN_LOWER_LEVER:
+ stStartProjecting();
+ break;
+ case NM_MOVE_TO_BACK:
+ sendMessage(_parentScene, NM_PRIORITY_CHANGE, 990);
+ break;
+ case NM_MOVE_TO_FRONT:
+ sendMessage(_parentScene, NM_PRIORITY_CHANGE, 1010);
+ break;
+ }
+ return messageResult;
+}
+
+uint32 AsCommonProjector::hmAnimation(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case NM_ANIMATION_STOP:
+ gotoNextState();
+ break;
+ }
+ return messageResult;
+}
+
+void AsCommonProjector::suMoving() {
+ if (_x <= _klaymen->getX())
+ _x = _klaymen->getX() - 100;
+ else
+ _x = _klaymen->getX() + 100;
+ moveProjector();
+ if (_beforeMoveX == _x) {
+ if (getGlobalVar(V_PROJECTOR_SLOT) == 0 && _asProjectorItem->leftBorderLeaves != 0) {
+ sendMessage(_parentScene, NM_SCENE_LEAVE, 0);
+ incGlobalVar(V_PROJECTOR_LOCATION, -1);
+ setGlobalVar(V_PROJECTOR_SLOT, kAsCommonProjectorItems[getGlobalVar(V_PROJECTOR_LOCATION)].maxSlotCount);
+ } else if ((int8)getGlobalVar(V_PROJECTOR_SLOT) == _asProjectorItem->maxSlotCount && _asProjectorItem->rightBorderLeaves != 0) {
+ sendMessage(_parentScene, NM_SCENE_LEAVE, 1);
+ incGlobalVar(V_PROJECTOR_LOCATION, +1);
+ setGlobalVar(V_PROJECTOR_SLOT, 0);
+ }
+ }
+ Sprite::updateBounds();
+}
+
+void AsCommonProjector::moveProjector() {
+
+ bool nowLockedInSlot = false;
+
+ _y = _asProjectorItem->point.y;
+
+ if (_asProjectorItem->index1 != -1) {
+ int16 elX = _asProjectorItem->index1 * 108 + _asProjectorItem->point.x;
+ if (elX - 20 < _x && elX + 20 > _x) {
+ nowLockedInSlot = true;
+ _y = _asProjectorItem->point.y + 10;
+ }
+ }
+
+ if (_asProjectorItem->lockSlotIndex != -1) {
+ int16 elX = _asProjectorItem->lockSlotIndex * 108 + _asProjectorItem->point.x;
+ if (elX - 20 < _x && elX + 20 > _x) {
+ nowLockedInSlot = true;
+ _y = _asProjectorItem->point.y + 10;
+ }
+ }
+
+ if (_lockedInSlot && !nowLockedInSlot)
+ _lockedInSlot = false;
+ else if (!_lockedInSlot && nowLockedInSlot) {
+ playSound(1, 0x5440E474);
+ _lockedInSlot = true;
+ }
+
+}
+
+void AsCommonProjector::stSuckedIn() {
+ AnimatedSprite::updateDeltaXY();
+ if (_collisionBounds.y1 <= 150) {
+ sendMessage(_asPipe, 0x483A, 0);
+ stopAnimation();
+ setVisible(false);
+ SetMessageHandler(&Sprite::handleMessage);
+ SetSpriteUpdate(NULL);
+ }
+}
+
+void AsCommonProjector::stIdle() {
+ startAnimation(0x10E3042B, 0, -1);
+ SetMessageHandler(&AsCommonProjector::handleMessage);
+ SetSpriteUpdate(NULL);
+}
+
+void AsCommonProjector::stMoving() {
+ _beforeMoveX = getGlobalVar(V_PROJECTOR_SLOT) * 108 + _asProjectorItem->point.x;
+ startAnimation(0x14A10137, 0, -1);
+ playSound(1, 0xEC008474);
+ SetMessageHandler(&AsCommonProjector::handleMessage);
+ SetSpriteUpdate(&AsCommonProjector::suMoving);
+}
+
+void AsCommonProjector::stStartLockedInSlot() {
+ startAnimation(0x80C32213, 0, -1);
+ SetMessageHandler(&AsCommonProjector::hmAnimation);
+ SetSpriteUpdate(NULL);
+ NextState(&AsCommonProjector::stStayLockedInSlot);
+}
+
+void AsCommonProjector::stStayLockedInSlot() {
+ startAnimation(0xD23B207F, 0, -1);
+ SetMessageHandler(&AsCommonProjector::hmLockedInSlot);
+ SetSpriteUpdate(NULL);
+}
+
+void AsCommonProjector::stStartProjecting() {
+ startAnimation(0x50A80517, 0, -1);
+ setGlobalVar(V_PROJECTOR_ACTIVE, 1);
+ playSound(0, 0xCC4A8456);
+ _vm->_soundMan->addSound(0x05331081, 0xCE428854);
+ _vm->_soundMan->playSoundLooping(0xCE428854);
+ SetMessageHandler(&AsCommonProjector::hmAnimation);
+ SetSpriteUpdate(NULL);
+ NextState(&AsCommonProjector::stLockedInSlot);
+}
+
+void AsCommonProjector::stLockedInSlot() {
+ sendMessage(_parentScene, NM_KLAYMEN_LOWER_LEVER, 0);
+ startAnimation(0xD833207F, 0, -1);
+ SetMessageHandler(&AsCommonProjector::hmLockedInSlot);
+ SetSpriteUpdate(NULL);
+}
+
+void AsCommonProjector::stStopProjecting() {
+ startAnimation(0x50A94417, 0, -1);
+ setGlobalVar(V_PROJECTOR_ACTIVE, 0);
+ playSound(0, 0xCC4A8456);
+ _vm->_soundMan->deleteSound(0xCE428854);
+ SetMessageHandler(&AsCommonProjector::hmAnimation);
+ SetSpriteUpdate(NULL);
+ NextState(&AsCommonProjector::stStayLockedInSlot);
+}
+
+void AsCommonProjector::stTurnToFront() {
+ _beforeMoveX = getGlobalVar(V_PROJECTOR_SLOT) * 108 + _asProjectorItem->point.x;
+ startAnimation(0x22CB4A33, 0, -1);
+ SetMessageHandler(&AsCommonProjector::hmAnimation);
+ SetSpriteUpdate(&AsCommonProjector::suMoving);
+ NextState(&AsCommonProjector::stMoving);
+}
+
+void AsCommonProjector::stStartSuckedIn() {
+ setGlobalVar(V_PROJECTOR_LOCATION, 4);
+ setGlobalVar(V_PROJECTOR_SLOT, 0);
+ startAnimation(0x708D4712, 0, -1);
+ playSound(2);
+ SetMessageHandler(&Sprite::handleMessage);
+ SetSpriteUpdate(&AsCommonProjector::stSuckedIn);
+}
+
+SsScene1402BridgePart::SsScene1402BridgePart(NeverhoodEngine *vm, uint32 fileHash, int surfacePriority)
+ : StaticSprite(vm, fileHash, surfacePriority) {
+
+ SetFilterY(&Sprite::defFilterY);
+ SetUpdateHandler(&StaticSprite::updatePosition);
+}
+
+AsScene1402PuzzleBox::AsScene1402PuzzleBox(NeverhoodEngine *vm, Scene *parentScene, int status)
+ : AnimatedSprite(vm, 1100), _parentScene(parentScene) {
+
+ createSurface(900, 347, 230);
+
+ SetFilterY(&Sprite::defFilterY);
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsScene1402PuzzleBox::handleMessage);
+ _x = 279;
+ _y = 270;
+ if (status == 2) {
+ // Puzzle box after the puzzle was solved
+ startAnimation(0x20060259, 0, -1);
+ playSound(0, 0x419014AC);
+ loadSound(1, 0x61901C29);
+ NextState(&AsScene1402PuzzleBox::stMoveDownSolvedDone);
+ } else if (status == 1) {
+ // Puzzle box appears
+ startAnimation(0x210A0213, 0, -1);
+ playSound(0, 0x41809C6C);
+ NextState(&AsScene1402PuzzleBox::stMoveUpDone);
+ } else {
+ // Puzzle box is here
+ startAnimation(0x20060259, -1, -1);
+ loadSound(1, 0x61901C29);
+ _newStickFrameIndex = STICK_LAST_FRAME;
+ }
+}
+
+uint32 AsScene1402PuzzleBox::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case NM_POSITION_CHANGE:
+ playSound(1);
+ startAnimation(0x20060259, -1, -1);
+ _playBackwards = true;
+ NextState(&AsScene1402PuzzleBox::stMoveDownDone);
+ break;
+ case NM_ANIMATION_STOP:
+ gotoNextState();
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene1402PuzzleBox::stMoveUpDone() {
+ sendMessage(_parentScene, 0x2000, 0);
+ stopAnimation();
+ setVisible(false);
+}
+
+void AsScene1402PuzzleBox::stMoveDownDone() {
+ sendMessage(_parentScene, 0x2001, 0);
+ stopAnimation();
+ setVisible(false);
+}
+
+void AsScene1402PuzzleBox::stMoveDownSolvedDone() {
+ sendMessage(_parentScene, 0x2003, 0);
+ stopAnimation();
+}
+
+static const int16 kScene1407MouseFloorY[] = {
+ 106, 150, 191, 230, 267, 308, 350, 395
+};
+
+static const struct {
+ int16 x;
+ int16 floorIndex;
+ int16 sectionIndex;
+ int16 nextHoleIndex;
+} kScene1407MouseHoles[] = {
+ {125, 0, 0, 7},
+ {452, 7, 21, 0},
+ {337, 4, 11, 4},
+ {286, 6, 17, 6},
+ {348, 6, 17, 39},
+ {536, 6, 18, 42},
+ {111, 1, 3, 18},
+ {203, 1, 3, 38},
+ {270, 1, 3, 9},
+ {197, 5, 14, 3},
+ {252, 5, 14, 35},
+ {297, 5, 14, 7},
+ {359, 5, 14, 8},
+ {422, 4, 12, 26},
+ {467, 4, 12, 2},
+ {539, 4, 12, 40},
+ {111, 5, 13, 17},
+ {211, 0, 1, 20},
+ {258, 0, 1, 11},
+ {322, 0, 1, 16},
+ { 99, 6, 16, 31},
+ {142, 6, 16, 27},
+ {194, 6, 16, 12},
+ {205, 2, 6, 45},
+ {264, 2, 6, 10},
+ { 98, 4, 10, 2},
+ {152, 4, 10, 37},
+ {199, 4, 10, 13},
+ {258, 4, 10, 16},
+ {100, 7, 19, 43},
+ {168, 7, 19, 23},
+ {123, 3, 8, 14},
+ {181, 3, 8, 39},
+ {230, 3, 8, 28},
+ {292, 3, 8, 22},
+ {358, 3, 8, 36},
+ {505, 3, 9, 44},
+ {400, 2, 7, 34},
+ {454, 2, 7, 32},
+ {532, 2, 7, 46},
+ {484, 5, 15, 25},
+ {529, 5, 15, 30},
+ {251, 7, 20, 48},
+ {303, 7, 20, 21},
+ {360, 7, 20, 33},
+ {503, 0, 2, 5},
+ {459, 1, 4, 19},
+ {530, 1, 4, 42},
+ {111, 2, 5, 47},
+ {442, 6, 18, 1}
+};
+
+static const struct {
+ int16 x1, x2;
+ int16 goodHoleIndex;
+} kScene1407MouseSections[] = {
+ {100, 149, 0},
+ {182, 351, 17},
+ {430, 524, 45},
+ { 89, 293, 7},
+ {407, 555, 47},
+ { 89, 132, 48},
+ {178, 303, 23},
+ {367, 551, 38},
+ {105, 398, 31},
+ {480, 537, 36},
+ { 84, 275, 27},
+ {318, 359, 2},
+ {402, 560, 15},
+ { 91, 132, 16},
+ {179, 400, 10},
+ {461, 552, 41},
+ { 86, 218, 21},
+ {267, 376, 4},
+ {420, 560, 49},
+ { 77, 188, 30},
+ {237, 394, 44},
+ {438, 515, 5}
+};
+
+AsScene1407Mouse::AsScene1407Mouse(NeverhoodEngine *vm, Scene *parentScene)
+ : AnimatedSprite(vm, 1100), _parentScene(parentScene), _currSectionIndex(0) {
+
+ createSurface(100, 117, 45);
+ _x = 108;
+ _y = 106;
+ stIdleLookAtGoodHole();
+ SetUpdateHandler(&AnimatedSprite::update);
+}
+
+void AsScene1407Mouse::suWalkTo() {
+ int16 xdelta = _walkDestX - _x;
+ if (xdelta > _deltaX)
+ xdelta = _deltaX;
+ else if (xdelta < -_deltaX)
+ xdelta = -_deltaX;
+ _deltaX = 0;
+ if (_walkDestX == _x)
+ sendMessage(this, NM_SCENE_LEAVE, 0);
+ else {
+ _x += xdelta;
+ updateBounds();
+ }
+}
+
+void AsScene1407Mouse::upGoThroughHole() {
+ if (_countdown != 0 && (--_countdown == 0)) {
+ SetUpdateHandler(&AnimatedSprite::update);
+ gotoNextState();
+ }
+ AnimatedSprite::update();
+}
+
+uint32 AsScene1407Mouse::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case NM_MOUSE_CLICK:
+ {
+ int16 mouseX = param.asPoint().x;
+ int16 mouseY = param.asPoint().y;
+ int holeIndex;
+ for (holeIndex = 0; holeIndex < 50; holeIndex++) {
+ int16 holeX = kScene1407MouseHoles[holeIndex].x;
+ int16 holeY = kScene1407MouseFloorY[kScene1407MouseHoles[holeIndex].floorIndex];
+ if (mouseX >= holeX - 14 && mouseX <= holeX + 14 && mouseY >= holeY - 36 && mouseY <= holeY)
+ break;
+ }
+ if (holeIndex < 50 && kScene1407MouseHoles[holeIndex].sectionIndex == _currSectionIndex) {
+ _nextHoleIndex = kScene1407MouseHoles[holeIndex].nextHoleIndex;
+ _walkDestX = kScene1407MouseHoles[holeIndex].x;
+ stWalkToHole();
+ } else {
+ if (mouseX < kScene1407MouseSections[_currSectionIndex].x1)
+ _walkDestX = kScene1407MouseSections[_currSectionIndex].x1;
+ else if (mouseX > kScene1407MouseSections[_currSectionIndex].x2)
+ _walkDestX = kScene1407MouseSections[_currSectionIndex].x2;
+ else
+ _walkDestX = mouseX;
+ stWalkToDest();
+ }
+ }
+ break;
+ case NM_SCENE_LEAVE:
+ gotoNextState();
+ break;
+ case 0x2001:
+ {
+ // Reset the position
+ // Find the nearest hole and go through it, and exit at the first hole
+ int16 distance = 640;
+ int matchIndex = 50;
+ for (int index = 0; index < 50; index++)
+ if (kScene1407MouseHoles[index].sectionIndex == _currSectionIndex &&
+ ABS(kScene1407MouseHoles[index].x - _x) < distance) {
+ matchIndex = index;
+ distance = ABS(kScene1407MouseHoles[index].x - _x);
+ }
+ if (matchIndex < 50) {
+ _nextHoleIndex = 0;
+ _walkDestX = kScene1407MouseHoles[matchIndex].x;
+ stWalkToHole();
+ }
+ }
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene1407Mouse::stIdleLookAtGoodHole() {
+ setDoDeltaX(kScene1407MouseHoles[kScene1407MouseSections[_currSectionIndex].goodHoleIndex].x < _x ? 1 : 0);
+ startAnimation(0x72215194, 0, -1);
+ SetMessageHandler(&AsScene1407Mouse::handleMessage);
+ SetSpriteUpdate(NULL);
+}
+
+void AsScene1407Mouse::stWalkToDest() {
+ if (_walkDestX != _x) {
+ setDoDeltaX(_walkDestX < _x ? 1 : 0);
+ startAnimation(0x22291510, 0, -1);
+ SetMessageHandler(&AsScene1407Mouse::handleMessage);
+ SetSpriteUpdate(&AsScene1407Mouse::suWalkTo);
+ NextState(&AsScene1407Mouse::stIdleLookAtGoodHole);
+ }
+}
+
+void AsScene1407Mouse::stWalkToHole() {
+ setDoDeltaX(_walkDestX < _x ? 1 : 0);
+ startAnimation(0x22291510, 0, -1);
+ SetMessageHandler(&AsScene1407Mouse::handleMessage);
+ SetSpriteUpdate(&AsScene1407Mouse::suWalkTo);
+ NextState(&AsScene1407Mouse::stGoThroughHole);
+}
+
+void AsScene1407Mouse::stGoThroughHole() {
+ startAnimation(0x72215194, 0, -1);
+ setVisible(false);
+ _countdown = 12;
+ SetUpdateHandler(&AsScene1407Mouse::upGoThroughHole);
+ SetMessageHandler(NULL);
+ SetSpriteUpdate(NULL);
+ NextState(&AsScene1407Mouse::stArriveAtHole);
+}
+
+void AsScene1407Mouse::stArriveAtHole() {
+ _currSectionIndex = kScene1407MouseHoles[_nextHoleIndex].sectionIndex;
+ _x = kScene1407MouseHoles[_nextHoleIndex].x;
+ _y = kScene1407MouseFloorY[kScene1407MouseHoles[_nextHoleIndex].floorIndex];
+ if (_nextHoleIndex == 1) {
+ sendMessage(_parentScene, 0x2000, 0);
+ _walkDestX = 512;
+ stWalkToDest();
+ setVisible(true);
+ } else {
+ _walkDestX = _x + 14;
+ stWalkToDest();
+ setVisible(true);
+ }
+}
+
+static const NPoint kAsScene1405TileItemPositions[] = {
+ {100, 80}, {162, 78}, {222, 76}, {292, 76},
+ {356, 82}, {422, 84}, {488, 86}, {550, 90},
+ {102, 134}, {164, 132}, {224, 136}, {294, 136},
+ {360, 136}, {422, 138}, {484, 144}, {548, 146},
+ { 98, 196}, {160, 200}, {228, 200}, {294, 202},
+ {360, 198}, {424, 200}, {482, 202}, {548, 206},
+ { 98, 260}, {160, 264}, {226, 260}, {296, 262},
+ {358, 260}, {424, 262}, {486, 264}, {550, 266},
+ { 94, 322}, {160, 316}, {226, 316}, {296, 320},
+ {358, 322}, {422, 324}, {488, 322}, {550, 322},
+ { 98, 380}, {160, 376}, {226, 376}, {294, 378},
+ {356, 380}, {420, 380}, {490, 378}, {552, 376}
+};
+
+AsScene1405Tile::AsScene1405Tile(NeverhoodEngine *vm, Scene1405 *parentScene, uint32 tileIndex)
+ : AnimatedSprite(vm, 1100), _parentScene(parentScene), _tileIndex(tileIndex), _countdown(0), _isShowing(false) {
+
+ loadSound(0, 0x05308101);
+ setSoundPan(0, (tileIndex % 8 * 4 + 4) * 25 / 8);
+ _x = kAsScene1405TileItemPositions[_tileIndex].x;
+ _y = kAsScene1405TileItemPositions[_tileIndex].y;
+ createSurface1(0x844B805C, 1100);
+ setVisible(false);
+ if (getSubVar(VA_IS_TILE_MATCH, _tileIndex))
+ _countdown = _vm->_rnd->getRandomNumber(36 - 1) + 1;
+ startAnimation(0x844B805C, getSubVar(VA_TILE_SYMBOLS, _tileIndex), -1);
+ _newStickFrameIndex = (int16)getSubVar(VA_TILE_SYMBOLS, _tileIndex);
+ SetUpdateHandler(&AsScene1405Tile::update);
+ SetMessageHandler(&AsScene1405Tile::handleMessage);
+}
+
+void AsScene1405Tile::update() {
+ updateAnim();
+ updatePosition();
+ if (_countdown != 0 && (--_countdown == 0))
+ show();
+}
+
+uint32 AsScene1405Tile::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x1011:
+ if (getSubVar(VA_IS_TILE_MATCH, _tileIndex) == 0 && _parentScene->getCountdown() == 0) {
+ show();
+ sendMessage(_parentScene, 0x2000, _tileIndex);
+ }
+ messageResult = 1;
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene1405Tile::show() {
+ if (!_isShowing) {
+ _isShowing = true;
+ playSound(0);
+ setVisible(true);
+ }
+}
+
+void AsScene1405Tile::hide() {
+ if (_isShowing) {
+ _isShowing = false;
+ playSound(0);
+ setVisible(false);
+ }
+}
+
+KmScene1401::KmScene1401(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
+ : Klaymen(vm, parentScene, x, y) {
+
+ // Empty
+}
+
+uint32 KmScene1401::xHandleMessage(int messageNum, const MessageParam &param) {
+ switch (messageNum) {
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case NM_KLAYMEN_STAND_IDLE:
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case NM_KLAYMEN_MOVE_OBJECT:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stMoveObjectSkipTurnFaceObject);
+ else
+ GotoState(&Klaymen::stMoveObjectFaceObject);
+ break;
+ case NM_KLAYMEN_PRESS_BUTTON:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stPressButton);
+ else if (param.asInteger() == 2)
+ GotoState(&Klaymen::stPressFloorButton);
+ else
+ GotoState(&Klaymen::stPressButtonSide);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ gotoNextStateExt();
+ break;
+ case 0x481B:
+ if (param.asPoint().y != 0)
+ startWalkToXDistance(param.asPoint().y, param.asPoint().x);
+ else
+ startWalkToAttachedSpriteXDistance(param.asPoint().x);
+ break;
+ case 0x481F:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stTurnAwayFromUse);
+ else if (param.asInteger() == 0)
+ GotoState(&Klaymen::stTurnToUseHalf);
+ else
+ GotoState(&Klaymen::stWonderAbout);
+ break;
+ case 0x482D:
+ setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
+ gotoNextStateExt();
+ break;
+ case 0x482E:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stWalkToFrontNoStep);
+ else
+ GotoState(&Klaymen::stWalkToFront);
+ break;
+ case 0x482F:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stTurnToFront);
+ else
+ GotoState(&Klaymen::stTurnToBack);
+ break;
+ }
+ return 0;
+}
+
+KmScene1402::KmScene1402(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
+ : Klaymen(vm, parentScene, x, y) {
+
+ SetFilterY(&Sprite::defFilterY);
+}
+
+uint32 KmScene1402::xHandleMessage(int messageNum, const MessageParam &param) {
+ switch (messageNum) {
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case NM_KLAYMEN_STAND_IDLE:
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case NM_KLAYMEN_MOVE_OBJECT:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stMoveObjectSkipTurnFaceObject);
+ else
+ GotoState(&Klaymen::stMoveObjectFaceObject);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ gotoNextStateExt();
+ break;
+ case 0x481B:
+ if (param.asPoint().y != 0)
+ startWalkToXDistance(param.asPoint().y, param.asPoint().x);
+ else
+ startWalkToAttachedSpriteXDistance(param.asPoint().x);
+ break;
+ case NM_KLAYMEN_TURN_TO_USE:
+ GotoState(&Klaymen::stTurnToUse);
+ break;
+ case NM_KLAYMEN_RETURN_FROM_USE:
+ GotoState(&Klaymen::stReturnFromUse);
+ break;
+ }
+ return 0;
+}
+
+static const KlaymenIdleTableItem klaymenIdleTable1403[] = {
+ {1, kIdleSpinHead},
+ {1, kIdleChest},
+ {1, kIdleHeadOff},
+};
+
+KmScene1403::KmScene1403(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
+ : Klaymen(vm, parentScene, x, y) {
+
+ setKlaymenIdleTable(klaymenIdleTable1403, ARRAYSIZE(klaymenIdleTable1403));
+}
+
+uint32 KmScene1403::xHandleMessage(int messageNum, const MessageParam &param) {
+ switch (messageNum) {
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case NM_KLAYMEN_STAND_IDLE:
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case NM_KLAYMEN_MOVE_OBJECT:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stMoveObjectSkipTurnFaceObject);
+ else
+ GotoState(&Klaymen::stMoveObjectFaceObject);
+ break;
+ case 0x480D:
+ GotoState(&Klaymen::stUseLever);
+ break;
+ case NM_KLAYMEN_PICKUP:
+ if (param.asInteger() == 2)
+ GotoState(&Klaymen::stPickUpNeedle);
+ else if (param.asInteger() == 1)
+ GotoState(&Klaymen::stPickUpTube);
+ else
+ GotoState(&Klaymen::stPickUpGeneric);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ gotoNextStateExt();
+ break;
+ case 0x481B:
+ if (param.asPoint().y != 0)
+ startWalkToXDistance(param.asPoint().y, param.asPoint().x);
+ else
+ startWalkToAttachedSpriteXDistance(param.asPoint().x);
+ break;
+ case NM_KLAYMEN_RELEASE_LEVER:
+ GotoState(&Klaymen::stReleaseLever);
+ break;
+ case 0x483F:
+ startSpecialWalkRight(param.asInteger());
+ break;
+ case 0x4840:
+ startSpecialWalkLeft(param.asInteger());
+ break;
+ }
+ return 0;
+}
+
+// KmScene1404
+
+KmScene1404::KmScene1404(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
+ : Klaymen(vm, parentScene, x, y) {
+
+ // Empty
+}
+
+uint32 KmScene1404::xHandleMessage(int messageNum, const MessageParam &param) {
+ switch (messageNum) {
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case NM_KLAYMEN_STAND_IDLE:
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case NM_KLAYMEN_MOVE_OBJECT:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stMoveObjectSkipTurnFaceObject);
+ else
+ GotoState(&Klaymen::stMoveObjectFaceObject);
+ break;
+ case NM_KLAYMEN_PICKUP:
+ if (param.asInteger() == 2)
+ GotoState(&Klaymen::stPickUpNeedle);
+ else if (param.asInteger() == 1)
+ GotoState(&Klaymen::stPickUpTube);
+ else
+ GotoState(&Klaymen::stPickUpGeneric);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ gotoNextStateExt();
+ break;
+ case NM_KLAYMEN_INSERT_DISK:
+ GotoState(&Klaymen::stInsertDisk);
+ break;
+ case 0x481B:
+ if (param.asPoint().y != 0)
+ startWalkToXDistance(param.asPoint().y, param.asPoint().x);
+ else
+ startWalkToAttachedSpriteXDistance(param.asPoint().x);
+ break;
+ case NM_KLAYMEN_TURN_TO_USE:
+ GotoState(&Klaymen::stTurnToUse);
+ break;
+ case NM_KLAYMEN_RETURN_FROM_USE:
+ GotoState(&Klaymen::stReturnFromUse);
+ break;
+ case 0x481F:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stWonderAboutAfter);
+ else if (param.asInteger() == 0)
+ GotoState(&Klaymen::stWonderAboutHalf);
+ else if (param.asInteger() == 4)
+ GotoState(&Klaymen::stTurnAwayFromUse);
+ else if (param.asInteger() == 3)
+ GotoState(&Klaymen::stTurnToUseHalf);
+ else
+ GotoState(&Klaymen::stWonderAbout);
+ break;
+ case 0x482D:
+ setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
+ gotoNextStateExt();
+ break;
+ case 0x483F:
+ startSpecialWalkRight(param.asInteger());
+ break;
+ case 0x4840:
+ startSpecialWalkLeft(param.asInteger());
+ break;
+ }
+ return 0;
+}
+
+} // End of namespace Neverhood
diff --git a/engines/neverhood/modules/module1400_sprites.h b/engines/neverhood/modules/module1400_sprites.h
new file mode 100644
index 0000000000..49b91fe0cf
--- /dev/null
+++ b/engines/neverhood/modules/module1400_sprites.h
@@ -0,0 +1,198 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public 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 NEVERHOOD_MODULES_MODULE1400_SPRITES_H
+#define NEVERHOOD_MODULES_MODULE1400_SPRITES_H
+
+#include "neverhood/neverhood.h"
+#include "neverhood/module.h"
+#include "neverhood/scene.h"
+
+namespace Neverhood {
+
+class AsScene1401Pipe : public AnimatedSprite {
+public:
+ AsScene1401Pipe(NeverhoodEngine *vm);
+ virtual ~AsScene1401Pipe();
+protected:
+ int _countdown1;
+ int _countdown2;
+ void update();
+ void upSuckInProjector();
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 hmSuckInProjector(int messageNum, const MessageParam &param, Entity *sender);
+ void stStartSucking();
+ void stDoneSucking();
+ void stSuckInProjector();
+};
+
+class AsScene1401Mouse : public AnimatedSprite {
+public:
+ AsScene1401Mouse(NeverhoodEngine *vm);
+protected:
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ void suSuckedIn();
+ void stSuckedIn();
+};
+
+class AsScene1401Cheese : public AnimatedSprite {
+public:
+ AsScene1401Cheese(NeverhoodEngine *vm);
+protected:
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ void suSuckedIn();
+ void stSuckedIn();
+};
+
+class AsScene1401BackDoor : public AnimatedSprite {
+public:
+ AsScene1401BackDoor(NeverhoodEngine *vm, Sprite *klaymen, bool isOpen);
+protected:
+ Sprite *_klaymen;
+ int _countdown;
+ bool _isOpen;
+ void update();
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ void stOpenDoor();
+ void stCloseDoor();
+ void stCloseDoorDone();
+};
+
+struct AsCommonProjectorItem {
+ NPoint point;
+ int8 maxSlotCount;
+ int8 lockSlotIndex;
+ int8 index1;
+ int8 leftBorderLeaves;
+ int8 rightBorderLeaves;
+};
+
+class AsCommonProjector : public AnimatedSprite {
+public:
+ AsCommonProjector(NeverhoodEngine *vm, Scene *parentScene, Sprite *klaymen, Sprite *asPipe);
+ virtual ~AsCommonProjector();
+protected:
+ Scene *_parentScene;
+ Sprite *_klaymen;
+ Sprite *_asPipe;
+ const AsCommonProjectorItem *_asProjectorItem;
+ int16 _beforeMoveX;
+ bool _lockedInSlot;
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 hmLockedInSlot(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 hmAnimation(int messageNum, const MessageParam &param, Entity *sender);
+ void suMoving();
+ void moveProjector();
+ void stSuckedIn();
+ void stIdle();
+ void stMoving();
+ void stStartLockedInSlot();
+ void stStayLockedInSlot();
+ void stStartProjecting();
+ void stLockedInSlot();
+ void stStopProjecting();
+ void stTurnToFront();
+ void stStartSuckedIn();
+};
+
+class SsScene1402BridgePart : public StaticSprite {
+public:
+ SsScene1402BridgePart(NeverhoodEngine *vm, uint32 fileHash, int surfacePriority);
+};
+
+class AsScene1402PuzzleBox : public AnimatedSprite {
+public:
+ AsScene1402PuzzleBox(NeverhoodEngine *vm, Scene *parentScene, int status);
+protected:
+ Scene *_parentScene;
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ void stMoveUpDone();
+ void stMoveDownDone();
+ void stMoveDownSolvedDone();
+};
+
+class AsScene1407Mouse : public AnimatedSprite {
+public:
+ AsScene1407Mouse(NeverhoodEngine *vm, Scene *parentScene);
+protected:
+ Scene *_parentScene;
+ int16 _walkDestX;
+ int16 _currSectionIndex;
+ int16 _nextHoleIndex;
+ int _countdown;
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ void suWalkTo();
+ void upGoThroughHole();
+ void stIdleLookAtGoodHole();
+ void stWalkToDest();
+ void stWalkToHole();
+ void stGoThroughHole();
+ void stArriveAtHole();
+};
+
+class Scene1405;
+
+class AsScene1405Tile : public AnimatedSprite {
+public:
+ AsScene1405Tile(NeverhoodEngine *vm, Scene1405 *parentScene, uint32 tileIndex);
+ void show();
+ void hide();
+protected:
+ Scene1405 *_parentScene;
+ bool _isShowing;
+ uint32 _tileIndex;
+ int _countdown;
+ void update();
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class KmScene1401 : public Klaymen {
+public:
+ KmScene1401(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
+protected:
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+};
+
+class KmScene1402 : public Klaymen {
+public:
+ KmScene1402(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
+protected:
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+};
+
+class KmScene1403 : public Klaymen {
+public:
+ KmScene1403(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
+protected:
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+};
+
+class KmScene1404 : public Klaymen {
+public:
+ KmScene1404(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
+protected:
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+};
+
+} // End of namespace Neverhood
+
+#endif /* NEVERHOOD_MODULES_MODULE1400_SPRITES_H */
diff --git a/engines/neverhood/modules/module1500.cpp b/engines/neverhood/modules/module1500.cpp
index 3ce9783b69..eaa23e586b 100644
--- a/engines/neverhood/modules/module1500.cpp
+++ b/engines/neverhood/modules/module1500.cpp
@@ -102,11 +102,11 @@ void Scene1501::update() {
Scene::update();
if (_countdown1 != 0) {
_countdown1--;
- if (_countdown1 == 0) {
+ if (_countdown1 == 0 || _skip) {
_vm->_screen->clear();
leaveScene(0);
}
- } else if ((_countdown2 != 0 && (--_countdown2 == 0)) || (_countdown2 == 0 && !isSoundPlaying(0))) {
+ } else if ((_countdown2 != 0 && (--_countdown2 == 0)) || (_countdown2 == 0 && !isSoundPlaying(0)) || _skip) {
_countdown1 = 12;
_palette->startFadeToBlack(11);
}
@@ -124,7 +124,7 @@ void Scene1501::update() {
uint32 Scene1501::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x0009:
+ case NM_KEYPRESS_SPACE:
_skip = true;
break;
}
diff --git a/engines/neverhood/modules/module1600.cpp b/engines/neverhood/modules/module1600.cpp
index a5a785e130..76c5ca93d2 100644
--- a/engines/neverhood/modules/module1600.cpp
+++ b/engines/neverhood/modules/module1600.cpp
@@ -20,10 +20,12 @@
*
*/
-#include "neverhood/modules/module1600.h"
#include "neverhood/gamemodule.h"
-#include "neverhood/modules/module1200.h"
-#include "neverhood/modules/module2200.h"
+#include "neverhood/modules/module1200_sprites.h"
+#include "neverhood/modules/module1600.h"
+#include "neverhood/modules/module1600_sprites.h"
+#include "neverhood/modules/module2200_sprites.h"
+#include "neverhood/modules/module3000_sprites.h"
namespace Neverhood {
@@ -183,825 +185,6 @@ void Module1600::updateScene() {
}
}
-AsCommonCar::AsCommonCar(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
- : AnimatedSprite(vm, 1000), _parentScene(parentScene) {
-
- createSurface(200, 556, 328);
- _x = x;
- _y = y;
-
- _inMainArea = false;
- _exitDirection = 0;
- _currPointIndex = 0;
- _hasAgainDestPoint = false;
- _stepError = 0;
- _hasAgainDestPointIndex = false;
- _steps = 0;
- _isBraking = false;
- _yMoveTotalSteps = 0;
- _isBusy = false;
- _isIdle = false;
- _isMoving = true;
- _rectFlag = false;
- _newDeltaXType = -1;
- _soundCounter = 0;
- _pathPoints = NULL;
- _currMoveDirection = 0;
-
- startAnimation(0xD4220027, 0, -1);
- setDoDeltaX(getGlobalVar(V_CAR_DELTA_X));
-
- SetUpdateHandler(&AsCommonCar::update);
- SetMessageHandler(&AsCommonCar::handleMessage);
- SetSpriteUpdate(NULL);
-}
-
-AsCommonCar::~AsCommonCar() {
- if (_finalizeStateCb == AnimationCallback(&AsCommonCar::evTurnCarDone))
- setGlobalVar(V_CAR_DELTA_X, !getGlobalVar(V_CAR_DELTA_X));
-}
-
-void AsCommonCar::setPathPoints(NPointArray *pathPoints) {
- _pathPoints = pathPoints;
-}
-
-void AsCommonCar::update() {
- if (_newDeltaXType >= 0) {
- setDoDeltaX(_newDeltaXType);
- _newDeltaXType = -1;
- }
- AnimatedSprite::update();
- if (_hasAgainDestPoint && _yMoveTotalSteps == 0 && !_isBusy) {
- _hasAgainDestPoint = false;
- _hasAgainDestPointIndex = false;
- sendPointMessage(this, 0x2004, _againDestPoint);
- } else if (_hasAgainDestPointIndex && _yMoveTotalSteps == 0 && !_isBusy) {
- _hasAgainDestPointIndex = false;
- sendMessage(this, 0x2003, _againDestPointIndex);
- }
- updateMovement();
- updateSound();
-}
-
-void AsCommonCar::upIdle() {
- update();
- if (++_idleCounter >= _idleCounterMax)
- stIdleBlink();
- updateSound();
-}
-
-uint32 AsCommonCar::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x1019:
- SetSpriteUpdate(NULL);
- break;
- case 0x2002:
- // Set the current position without moving
- _currPointIndex = param.asInteger();
- _stepError = 0;
- _x = pathPoint(_currPointIndex).x;
- _y = pathPoint(_currPointIndex).y;
- break;
- case 0x2003:
- // Move to a point by its index
- {
- int newPointIndex = param.asInteger();
- if (_yMoveTotalSteps <= 0 && !_isBusy) {
- _destX = pathPoint(newPointIndex).x;
- _destY = pathPoint(newPointIndex).y;
- if (_currPointIndex < newPointIndex) {
- moveToNextPoint();
- } else if (_currPointIndex == newPointIndex && _stepError == 0) {
- if (_currPointIndex == 0) {
- _yMoveTotalSteps = 0;
- sendMessage(_parentScene, 0x2005, 0);
- } else if (_currPointIndex == (int)_pathPoints->size()) {
- _yMoveTotalSteps = 0;
- sendMessage(_parentScene, 0x2006, 0);
- }
- } else {
- moveToPrevPoint();
- }
- } else {
- _hasAgainDestPointIndex = true;
- _againDestPointIndex = newPointIndex;
- }
- }
- break;
- case 0x2004:
- // Move to the point closest to the parameter point
- {
- int minMatchIndex = -1;
- int minMatchDistance, distance;
- NPoint pt = param.asPoint();
- if (_yMoveTotalSteps <= 0 && !_isBusy) {
- // Check if we're already exiting (or something)
- if ((pt.x <= 20 && _exitDirection == 1) ||
- (pt.x >= 620 && _exitDirection == 3) ||
- (pt.y <= 20 && _exitDirection == 2) ||
- (pt.y >= 460 && _exitDirection == 4))
- break;
- _destX = pt.x;
- _destY = pt.y;
- minMatchDistance = calcDistance(_destX, _destY, _x, _y) + 1;
- for (int i = _currPointIndex + 1; i < (int)_pathPoints->size(); i++) {
- distance = calcDistance(_destX, _destY, pathPoint(i).x, pathPoint(i).y);
- if (distance >= minMatchDistance)
- break;
- minMatchDistance = distance;
- minMatchIndex = i;
- }
- for (int i = _currPointIndex; i >= 0; i--) {
- distance = calcDistance(_destX, _destY, pathPoint(i).x, pathPoint(i).y);
- if (distance >= minMatchDistance)
- break;
- minMatchDistance = distance;
- minMatchIndex = i;
- }
- if (minMatchIndex == -1) {
- if (_currPointIndex == 0)
- moveToPrevPoint();
- else
- SetSpriteUpdate(NULL);
- } else {
- if (minMatchIndex > _currPointIndex)
- moveToNextPoint();
- else
- moveToPrevPoint();
- }
- } else {
- _hasAgainDestPoint = true;
- _againDestPoint = pt;
- }
- }
- break;
- case 0x2007:
- _yMoveTotalSteps = param.asInteger();
- _steps = 0;
- _isBraking = false;
- _lastDistance = 640;
- SetSpriteUpdate(&AsCommonCar::suMoveToPrevPoint);
- break;
- case 0x2008:
- _yMoveTotalSteps = param.asInteger();
- _steps = 0;
- _isBraking = false;
- _lastDistance = 640;
- SetSpriteUpdate(&AsCommonCar::suMoveToNextPoint);
- break;
- case 0x2009:
- stEnterCar();
- break;
- case 0x200A:
- stLeaveCar();
- break;
- case 0x200E:
- stTurnCar();
- break;
- case 0x200F:
- stCarAtHome();
- _newDeltaXType = param.asInteger();
- break;
- }
- return messageResult;
-}
-
-uint32 AsCommonCar::hmAnimation(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = AsCommonCar::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x100D:
- if (_isBusy && param.asInteger() == 0x025424A2)
- gotoNextState();
- break;
- case 0x3002:
- gotoNextState();
- break;
- }
- return messageResult;
-}
-
-uint32 AsCommonCar::hmLeaveCar(int messageNum, const MessageParam &param, Entity *sender) {
- switch (messageNum) {
- case 0x2009:
- stEnterCar();
- break;
- case 0x3002:
- sendMessage(_parentScene, 0x200A, 0);
- SetMessageHandler(&AsCommonCar::handleMessage);
- break;
- }
- return 0;
-}
-
-void AsCommonCar::stCarAtHome() {
- bool doDeltaX = _doDeltaX;
- SetSpriteUpdate(NULL);
- _hasAgainDestPoint = false;
- _hasAgainDestPointIndex = false;
- _isBraking = false;
- _isBusy = false;
- _isIdle = false;
- _isMoving = false;
- _rectFlag = false;
- NextState(&AsCommonCar::stLeanForwardIdle);
- startAnimation(0x35698F78, 0, -1);
- setDoDeltaX(doDeltaX ? 1 : 0);
- _currMoveDirection = 0;
- _newMoveDirection = 0;
- _steps = 0;
- _idleCounter = 0;
- _idleCounterMax = _vm->_rnd->getRandomNumber(64 - 1) + 24;
- SetUpdateHandler(&AsCommonCar::upIdle);
- SetMessageHandler(&AsCommonCar::handleMessage);
- FinalizeState(&AsCommonCar::evIdleDone);
-}
-
-void AsCommonCar::updateTurnMovement() {
- if (_turnMoveStatus == 1) {
- _lastDistance = 640;
- _isIdle = false;
- _isBraking = false;
- SetSpriteUpdate(&AsCommonCar::suMoveToNextPoint);
- } else if (_turnMoveStatus == 2) {
- _lastDistance = 640;
- _isIdle = false;
- _isBraking = false;
- SetSpriteUpdate(&AsCommonCar::suMoveToPrevPoint);
- }
-}
-
-void AsCommonCar::updateMovement() {
- if (_isBraking && !_isIdle && !_isBusy) {
- gotoNextState();
- _isMoving = false;
- _isIdle = true;
- startAnimation(0x192ADD30, 0, -1);
- SetUpdateHandler(&AsCommonCar::update);
- SetMessageHandler(&AsCommonCar::hmAnimation);
- NextState(&AsCommonCar::stLeanForwardIdle);
- } else if (!_isBraking && _steps && _isIdle) {
- gotoNextState();
- _isIdle = false;
- startAnimation(0x9966B138, 0, -1);
- SetUpdateHandler(&AsCommonCar::update);
- SetMessageHandler(&AsCommonCar::hmAnimation);
- NextState(&AsCommonCar::stUpdateMoveDirection);
- } else if (_newMoveDirection != _currMoveDirection && _isMoving && !_isBusy) {
- gotoNextState();
- _currMoveDirection = _newMoveDirection;
- stUpdateMoveDirection();
- }
-}
-
-void AsCommonCar::stEnterCar() {
- startAnimation(0xA86A9538, 0, -1);
- SetUpdateHandler(&AsCommonCar::update);
- SetMessageHandler(&AsCommonCar::hmAnimation);
- NextState(&AsCommonCar::stLeanForwardIdle);
-}
-
-void AsCommonCar::stLeaveCar() {
- startAnimation(0xA86A9538, -1, -1);
- _playBackwards = true;
- SetUpdateHandler(&AsCommonCar::update);
- SetMessageHandler(&AsCommonCar::hmLeaveCar);
-}
-
-void AsCommonCar::stLeanForwardIdle() {
- startAnimation(0x35698F78, 0, -1);
- _currMoveDirection = 0;
- _newMoveDirection = 0;
- _steps = 0;
- _idleCounter = 0;
- _idleCounterMax = _vm->_rnd->getRandomNumber(64 - 1) + 24;
- SetUpdateHandler(&AsCommonCar::upIdle);
- SetMessageHandler(&AsCommonCar::handleMessage);
- FinalizeState(&AsCommonCar::evIdleDone);
-}
-
-void AsCommonCar::evIdleDone() {
- SetUpdateHandler(&AsCommonCar::update);
-}
-
-void AsCommonCar::stIdleBlink() {
- startAnimation(0xB579A77C, 0, -1);
- _idleCounter = 0;
- _idleCounterMax = _vm->_rnd->getRandomNumber(64 - 1) + 24;
- SetUpdateHandler(&AsCommonCar::update);
- SetMessageHandler(&AsCommonCar::hmAnimation);
- NextState(&AsCommonCar::stLeanForwardIdle);
-}
-
-void AsCommonCar::stUpdateMoveDirection() {
- _isMoving = true;
- if (_currMoveDirection == 1)
- startAnimation(0xD4AA03A4, 0, -1);
- else if (_currMoveDirection == 3)
- startAnimation(0xD00A1364, 0, -1);
- else if ((_currMoveDirection == 2 && _doDeltaX) || (_currMoveDirection == 4 && !_doDeltaX))
- stTurnCar();
- else
- startAnimation(0xD4220027, 0, -1);
- setGlobalVar(V_CAR_DELTA_X, _doDeltaX ? 1 : 0);
-}
-
-void AsCommonCar::moveToNextPoint() {
- if (_currPointIndex >= (int)_pathPoints->size() - 1) {
- _yMoveTotalSteps = 0;
- sendMessage(this, 0x1019, 0);
- sendMessage(_parentScene, 0x2006, 0);
- } else {
- NPoint nextPt = pathPoint(_currPointIndex + 1);
- NPoint currPt = pathPoint(_currPointIndex);
- if (ABS(nextPt.y - currPt.y) <= ABS(nextPt.x - currPt.x) &&
- ((_currMoveDirection == 2 && nextPt.x < currPt.x) ||
- (_currMoveDirection == 4 && nextPt.x >= currPt.x))) {
- if (_currMoveDirection == 2)
- _currMoveDirection = 4;
- else if (_currMoveDirection == 4)
- _currMoveDirection = 2;
- if (_isIdle)
- stTurnCarMoveToNextPoint();
- else
- stBrakeMoveToNextPoint();
- } else {
- if (_steps == 0) {
- gotoNextState();
- _isIdle = false;
- startAnimation(0x9966B138, 0, -1);
- SetMessageHandler(&AsCommonCar::hmAnimation);
- SetUpdateHandler(&AsCommonCar::update);
- NextState(&AsCommonCar::stUpdateMoveDirection);
- }
- _isBraking = false;
- SetSpriteUpdate(&AsCommonCar::suMoveToNextPoint);
- _lastDistance = 640;
- }
- }
-}
-
-void AsCommonCar::stBrakeMoveToNextPoint() {
- gotoNextState();
- _isBusy = true;
- _isBraking = true;
- startAnimation(0x192ADD30, 0, -1);
- SetUpdateHandler(&AsCommonCar::update);
- SetMessageHandler(&AsCommonCar::hmAnimation);
- NextState(&AsCommonCar::stTurnCarMoveToNextPoint);
-}
-
-void AsCommonCar::stTurnCar() {
- // Turn to left/right #1
- gotoNextState();
- _isBusy = true;
- startAnimation(0xF46A0324, 0, -1);
- SetUpdateHandler(&AsCommonCar::update);
- SetMessageHandler(&AsCommonCar::hmAnimation);
- FinalizeState(&AsCommonCar::evTurnCarDone);
- _turnMoveStatus = 0;
- updateTurnMovement();
-}
-
-void AsCommonCar::stTurnCarMoveToNextPoint() {
- // Turn to left/right #2
- gotoNextState();
- _isBusy = true;
- startAnimation(0xF46A0324, 0, -1);
- SetUpdateHandler(&AsCommonCar::update);
- SetMessageHandler(&AsCommonCar::hmAnimation);
- FinalizeState(&AsCommonCar::evTurnCarDone);
- _turnMoveStatus = 1;
- updateTurnMovement();
-}
-
-void AsCommonCar::stTurnCarMoveToPrevPoint() {
- // Turn to left/right #3
- FinalizeState(NULL);
- _isBusy = true;
- startAnimation(0xF46A0324, 0, -1);
- SetUpdateHandler(&AsCommonCar::update);
- SetMessageHandler(&AsCommonCar::hmAnimation);
- FinalizeState(&AsCommonCar::evTurnCarDone);
- _turnMoveStatus = 2;
- updateTurnMovement();
-}
-
-void AsCommonCar::moveToPrevPoint() {
- if (_currPointIndex == 0 && _stepError == 0) {
- _yMoveTotalSteps = 0;
- sendMessage(this, 0x1019, 0);
- sendMessage(_parentScene, 0x2005, 0);
- } else {
- NPoint prevPt;
- NPoint currPt;
- if (_stepError == 0) {
- prevPt = pathPoint(_currPointIndex - 1);
- currPt = pathPoint(_currPointIndex);
- } else {
- prevPt = pathPoint(_currPointIndex);
- currPt = pathPoint(_currPointIndex + 1);
- }
- if (ABS(prevPt.y - currPt.y) <= ABS(prevPt.x - currPt.x) &&
- ((_currMoveDirection == 2 && prevPt.x < currPt.x) ||
- (_currMoveDirection == 4 && prevPt.x >= currPt.x))) {
- if (_currMoveDirection == 2)
- _currMoveDirection = 4;
- else if (_currMoveDirection == 4)
- _currMoveDirection = 2;
- if (_isIdle)
- stTurnCarMoveToPrevPoint();
- else
- stBrakeMoveToPrevPoint();
- } else {
- if (_steps == 0) {
- gotoNextState();
- _isIdle = false;
- startAnimation(0x9966B138, 0, -1);
- SetMessageHandler(&AsCommonCar::hmAnimation);
- SetUpdateHandler(&AsCommonCar::update);
- NextState(&AsCommonCar::stUpdateMoveDirection);
- }
- _isBraking = false;
- SetSpriteUpdate(&AsCommonCar::suMoveToPrevPoint);
- _lastDistance = 640;
- }
- }
-}
-
-void AsCommonCar::stBrakeMoveToPrevPoint() {
- FinalizeState(NULL);
- _isBusy = true;
- _isBraking = true;
- startAnimation(0x192ADD30, 0, -1);
- SetUpdateHandler(&AsCommonCar::update);
- SetMessageHandler(&AsCommonCar::hmAnimation);
- NextState(&AsCommonCar::stTurnCarMoveToPrevPoint);
-}
-
-void AsCommonCar::evTurnCarDone() {
- _isBusy = false;
- setDoDeltaX(2);
- _newMoveDirection = 0;
- stUpdateMoveDirection();
-}
-
-void AsCommonCar::suMoveToNextPoint() {
- int16 newX = _x, newY = _y;
-
- if (_currPointIndex >= (int)_pathPoints->size()) {
- _yMoveTotalSteps = 0;
- sendMessage(this, 0x1019, 0);
- sendMessage(_parentScene, 0x2006, 0);
- return;
- }
-
- if (_isBraking) {
- if (_steps <= 0) {
- sendMessage(this, 0x1019, 0);
- return;
- } else
- _steps--;
- } else if (_steps < 11)
- _steps++;
-
- bool firstTime = true;
- _ySteps = _steps;
- int stepsCtr = _steps;
-
- while (stepsCtr > 0) {
- NPoint pt1;
- NPoint pt2 = pathPoint(_currPointIndex);
- if (_currPointIndex + 1 >= (int)_pathPoints->size())
- pt1 = pathPoint(0);
- else
- pt1 = pathPoint(_currPointIndex + 1);
- int16 deltaX = ABS(pt1.x - pt2.x);
- int16 deltaY = ABS(pt1.y - pt2.y);
- if (deltaX >= deltaY) {
- _newMoveDirection = 2;
- if (pt1.x < pt2.x)
- _newMoveDirection = 4;
- if (stepsCtr + _stepError >= deltaX) {
- stepsCtr -= deltaX;
- stepsCtr += _stepError;
- _stepError = 0;
- _currPointIndex++;
- if (_currPointIndex == (int)_pathPoints->size() - 1)
- stepsCtr = 0;
- newX = pathPoint(_currPointIndex).x;
- newY = pathPoint(_currPointIndex).y;
- } else {
- _stepError += stepsCtr;
- if (pt1.x >= pt2.x)
- newX += stepsCtr;
- else
- newX -= stepsCtr;
- if (pt1.y >= pt2.y)
- newY = pt2.y + (deltaY * _stepError) / deltaX;
- else
- newY = pt2.y - (deltaY * _stepError) / deltaX;
- stepsCtr = 0;
- }
- } else {
- _newMoveDirection = 3;
- if (pt1.y < pt2.y)
- _newMoveDirection = 1;
- if (firstTime) {
- if (pt1.y >= pt2.y)
- stepsCtr += 7;
- else {
- stepsCtr -= 4;
- if (stepsCtr < 0)
- stepsCtr = 0;
- }
- _ySteps = stepsCtr;
- }
- if (stepsCtr + _stepError >= deltaY) {
- stepsCtr -= deltaY;
- stepsCtr += _stepError;
- _stepError = 0;
- _currPointIndex++;
- if (_currPointIndex == (int)_pathPoints->size() - 1)
- stepsCtr = 0;
- newX = pathPoint(_currPointIndex).x;
- newY = pathPoint(_currPointIndex).y;
- } else {
- _stepError += stepsCtr;
- if (pt1.x >= pt2.x)
- newX = pt2.x + (deltaX * _stepError) / deltaY;
- else
- newX = pt2.x - (deltaX * _stepError) / deltaY;
- if (pt1.y >= pt2.y)
- newY += stepsCtr;
- else
- newY -= stepsCtr;
- stepsCtr = 0;
- }
- }
- firstTime = false;
- }
-
- if (_yMoveTotalSteps != 0) {
- _x = newX;
- _y = newY;
- _yMoveTotalSteps -= _ySteps;
- if (_yMoveTotalSteps <= 0) {
- _isBraking = true;
- _yMoveTotalSteps = 0;
- }
- } else {
- int distance = calcDistance(_destX, _destY, _x, _y);
- _x = newX;
- _y = newY;
- if (newX > 20 && newX < 620 && newY > 20 && newY < 460) {
- _exitDirection = 0;
- _inMainArea = true;
- } else if (_inMainArea) {
- _destX = pathPoint(_pathPoints->size() - 1).x;
- _destY = pathPoint(_pathPoints->size() - 1).y;
- _inMainArea = false;
- if (_x <= 20)
- _exitDirection = 1;
- else if (_x >= 620)
- _exitDirection = 3;
- else if (_y <= 20)
- _exitDirection = 2;
- else if (_y >= 460)
- _exitDirection = 4;
- if (_exitDirection != 0 && _isBraking) {
- _isBraking = false;
- _steps = 11;
- }
- }
- if ((distance < 20 && _exitDirection == 0 && _lastDistance < distance) ||
- (_exitDirection == 0 && _lastDistance + 20 < distance))
- _isBraking = true;
- if (distance < _lastDistance)
- _lastDistance = distance;
- if (_currPointIndex == (int)_pathPoints->size() - 1) {
- _isBraking = true;
- _yMoveTotalSteps = 0;
- sendMessage(this, 0x1019, 0);
- sendMessage(_parentScene, 0x2006, 0);
- }
- }
-
-}
-
-void AsCommonCar::suMoveToPrevPoint() {
- int16 newX = _x, newY = _y;
-
- if (_currPointIndex == 0 && _stepError == 0) {
- _yMoveTotalSteps = 0;
- sendMessage(this, 0x1019, 0);
- sendMessage(_parentScene, 0x2005, 0);
- return;
- }
-
- if (_isBraking) {
- if (_steps <= 0) {
- sendMessage(this, 0x1019, 0);
- return;
- } else
- _steps--;
- } else if (_steps < 11)
- _steps++;
-
- bool firstTime = true;
- _ySteps = _steps;
- int stepsCtr = _steps;
-
- while (stepsCtr > 0) {
- if (_stepError == 0)
- _currPointIndex--;
- NPoint pt1;
- NPoint pt2 = pathPoint(_currPointIndex);
- if (_currPointIndex + 1 >= (int)_pathPoints->size())
- pt1 = pathPoint(0);
- else
- pt1 = pathPoint(_currPointIndex + 1);
- int16 deltaX = ABS(pt1.x - pt2.x);
- int16 deltaY = ABS(pt1.y - pt2.y);
- if (deltaX >= deltaY) {
- _newMoveDirection = 4;
- if (pt1.x < pt2.x)
- _newMoveDirection = 2;
- if (_stepError == 0)
- _stepError = deltaX;
- if (stepsCtr > _stepError) {
- stepsCtr -= _stepError;
- _stepError = 0;
- if (_currPointIndex == 0)
- stepsCtr = 0;
- newX = pathPoint(_currPointIndex).x;
- newY = pathPoint(_currPointIndex).y;
- } else {
- _stepError -= stepsCtr;
- if (pt1.x >= pt2.x)
- newX -= stepsCtr;
- else
- newX += stepsCtr;
- if (pt1.y >= pt2.y)
- newY = pt2.y + (deltaY * _stepError) / deltaX;
- else
- newY = pt2.y - (deltaY * _stepError) / deltaX;
- stepsCtr = 0;
- }
- } else {
- _newMoveDirection = 1;
- if (pt1.y < pt2.y)
- _newMoveDirection = 3;
- if (firstTime) {
- if (pt1.y >= pt2.y) {
- stepsCtr -= 4;
- if (stepsCtr < 0)
- stepsCtr = 0;
- } else {
- stepsCtr += 7;
- }
- _ySteps = stepsCtr;
- }
- if (_stepError == 0)
- _stepError = deltaY;
- if (stepsCtr > _stepError) {
- stepsCtr -= _stepError;
- _stepError = 0;
- if (_currPointIndex == 0)
- stepsCtr = 0;
- newX = pathPoint(_currPointIndex).x;
- newY = pathPoint(_currPointIndex).y;
- } else {
- _stepError -= stepsCtr;
- if (pt1.x >= pt2.x)
- newX = pt2.x + (deltaX * _stepError) / deltaY;
- else
- newX = pt2.x - (deltaX * _stepError) / deltaY;
- if (pt1.y >= pt2.y)
- newY -= stepsCtr;
- else
- newY += stepsCtr;
- stepsCtr = 0;
- }
- }
- firstTime = false;
- }
-
- if (_yMoveTotalSteps != 0) {
- _x = newX;
- _y = newY;
- _yMoveTotalSteps -= _ySteps;
- if (_yMoveTotalSteps <= 0) {
- _isBraking = true;
- _yMoveTotalSteps = 0;
- }
- } else {
- int distance = calcDistance(_destX, _destY, _x, _y);
- _x = newX;
- _y = newY;
- if (newX > 20 && newX < 620 && newY > 20 && newY < 460) {
- _exitDirection = 0;
- _inMainArea = true;
- } else if (_inMainArea) {
- _destX = pathPoint(0).x;
- _destY = pathPoint(0).y;
- _inMainArea = false;
- if (_x <= 20)
- _exitDirection = 1;
- else if (_x >= 620)
- _exitDirection = 3;
- else if (_y <= 20)
- _exitDirection = 2;
- else if (_y >= 460)
- _exitDirection = 4;
- if (_exitDirection != 0 && _isBraking) {
- _isBraking = false;
- _steps = 11;
- }
- }
- if ((distance < 20 && _exitDirection == 0 && _lastDistance < distance) ||
- (_exitDirection == 0 && _lastDistance + 20 < distance))
- _isBraking = true;
- if (distance < _lastDistance)
- _lastDistance = distance;
- if (_currPointIndex == 0 && _stepError == 0) {
- _isBraking = true;
- _yMoveTotalSteps = 0;
- sendMessage(this, 0x1019, 0);
- sendMessage(_parentScene, 0x2005, 0);
- }
- }
-
-}
-
-void AsCommonCar::updateSound() {
- int maxSoundCounter = 0;
- _soundCounter++;
- if (_steps != 0 && !_isIdle) {
- if (_currMoveDirection == 1)
- maxSoundCounter = 18 - _steps;
- else if (_currMoveDirection == 3) {
- maxSoundCounter = 5 - _steps;
- if (maxSoundCounter < 1)
- maxSoundCounter = 1;
- } else
- maxSoundCounter = 14 - _steps;
- } else
- maxSoundCounter = 21;
- if (_soundCounter >= maxSoundCounter) {
- sendMessage(_parentScene, 0x200D, 0);
- _soundCounter = 0;
- }
-}
-
-AsCommonIdleCarLower::AsCommonIdleCarLower(NeverhoodEngine *vm, int16 x, int16 y)
- : AnimatedSprite(vm, 0x1209E09F, 1100, x, y) {
-
- setDoDeltaX(1);
- startAnimation(0x1209E09F, 1, -1);
- _newStickFrameIndex = 1;
-}
-
-AsCommonIdleCarFull::AsCommonIdleCarFull(NeverhoodEngine *vm, int16 x, int16 y)
- : AnimatedSprite(vm, 0x1209E09F, 100, x, y) {
-
- setDoDeltaX(1);
- _newStickFrameIndex = 0;
-}
-
-AsCommonCarConnector::AsCommonCarConnector(NeverhoodEngine *vm, AsCommonCar *asCar)
- : AnimatedSprite(vm, 1100), _asCar(asCar) {
-
- createSurface1(0x60281C10, 150);
- startAnimation(0x60281C10, -1, -1);
- _newStickFrameIndex = STICK_LAST_FRAME;
- SetUpdateHandler(&AsCommonCarConnector::update);
-}
-
-void AsCommonCarConnector::update() {
- _x = _asCar->getX();
- _y = _asCar->getY();
- AnimatedSprite::update();
-}
-
-void Tracks::findTrackPoint(NPoint pt, int &minMatchTrackIndex, int &minMatchDistance,
- DataResource &dataResource) {
- const uint trackCount = size();
- minMatchTrackIndex = -1;
- minMatchDistance = 640;
- for (uint trackIndex = 0; trackIndex < trackCount; trackIndex++) {
- NPointArray *pointList = dataResource.getPointArray((*this)[trackIndex]->trackPointsName);
- for (uint pointIndex = 0; pointIndex < pointList->size(); pointIndex++) {
- NPoint testPt = (*pointList)[pointIndex];
- int distance = calcDistance(testPt.x, testPt.y, pt.x, pt.y);
- if (distance < minMatchDistance) {
- minMatchTrackIndex = trackIndex;
- minMatchDistance = distance;
- }
- }
- }
-}
-
Scene1608::Scene1608(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule), _asCar(NULL), _countdown1(0) {
@@ -1075,7 +258,7 @@ Scene1608::Scene1608(NeverhoodEngine *vm, Module *parentModule, int which)
SetMessageHandler(&Scene1608::hmUpperFloor);
SetUpdateHandler(&Scene1608::upUpperFloor);
_asCar->setPathPoints(_roomPathPoints);
- sendMessage(_asCar, 0x2002, _roomPathPoints->size() - 1);
+ sendMessage(_asCar, NM_POSITION_CHANGE, _roomPathPoints->size() - 1);
_sprite3 = insertStaticSprite(0xB47026B0, 1100);
_clipRect1.set(_sprite3->getDrawRect().x, _sprite3->getDrawRect().y, 640, _sprite2->getDrawRect().y2());
_clipRect3.set(_sprite2->getDrawRect().x, _sprite3->getDrawRect().y, 640, _sprite2->getDrawRect().y2());
@@ -1116,15 +299,15 @@ Scene1608::Scene1608(NeverhoodEngine *vm, Module *parentModule, int which)
_asIdleCarLower->setVisible(false);
_asIdleCarFull->setVisible(false);
_asCar->setPathPoints(_roomPathPoints);
- sendMessage(_asCar, 0x2002, 0);
- sendMessage(_asCar, 0x2008, 90);
+ sendMessage(_asCar, NM_POSITION_CHANGE, 0);
+ sendMessage(_asCar, NM_CAR_MOVE_TO_NEXT_POINT, 90);
_sprite3 = insertStaticSprite(0xB47026B0, 1100);
_clipRect1.set(_sprite3->getDrawRect().x, _sprite3->getDrawRect().y, 640, _sprite2->getDrawRect().y2());
_clipRect3.set(_sprite2->getDrawRect().x, _sprite3->getDrawRect().y, 640, _sprite2->getDrawRect().y2());
_clipRect2 = _clipRect1;
_clipRect2.y2 = 215;
_kmScene1608->setClipRect(_clipRect1);
- _asCar->setClipRect(_clipRect1);
+ _asCar->setClipRect(_clipRect3);
_asIdleCarLower->setClipRect(_clipRect1);
_asIdleCarFull->setClipRect(_clipRect1);
_asTape = insertSprite<AsScene1201Tape>(this, 13, 1100, 412, 443, 0x9148A011);
@@ -1166,7 +349,7 @@ void Scene1608::upUpperFloor() {
_asIdleCarLower->setVisible(false);
_asIdleCarFull->setVisible(false);
_asCar->setVisible(true);
- sendMessage(_asCar, 0x2009, 0);
+ sendMessage(_asCar, NM_CAR_ENTER, 0);
_asCar->handleUpdate();
_klaymen = NULL;
_carStatus = 0;
@@ -1178,7 +361,7 @@ void Scene1608::upCarAtHome() {
Scene::update();
if (_mouseClicked) {
if (_mouseClickPos.x <= 329 && _asCar->getX() == 375 && _asCar->getY() == 227) {
- sendMessage(_asCar, 0x200A, 0);
+ sendMessage(_asCar, NM_CAR_LEAVE, 0);
SetUpdateHandler(&Scene1608::upGettingOutOfCar);
} else {
sendPointMessage(_asCar, 0x2004, _mouseClickPos);
@@ -1218,12 +401,12 @@ void Scene1608::upRidingCar() {
sendPointMessage(_asCar, 0x2004, _mouseClickPos);
_mouseClicked = false;
}
- if (_asCar->getX() < 300) {
+ if (_asCar->getY() < 330) {
if (_carClipFlag) {
_carClipFlag = false;
_asCar->setClipRect(_clipRect1);
if (!_asCar->isDoDeltaX())
- sendMessage(_asCar, 0x200E, 0);
+ sendMessage(_asCar, NM_CAR_TURN, 0);
}
} else if (!_carClipFlag) {
_carClipFlag = true;
@@ -1234,13 +417,13 @@ void Scene1608::upRidingCar() {
uint32 Scene1608::hmLowerFloor(int messageNum, const MessageParam &param, Entity *sender) {
Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0x20250B1A) {
clearRectList();
_klaymen->setVisible(false);
showMouse(false);
_sprite1->setVisible(false);
- //sendMessage(_asDoor, 0x4809, 0); // Play sound?
+ //sendMessage(_asDoor, NM_KLAYMEN_CLOSE_DOOR, 0); // Play sound?
_countdown1 = 28;
}
break;
@@ -1261,7 +444,7 @@ uint32 Scene1608::hmLowerFloor(int messageNum, const MessageParam &param, Entity
uint32 Scene1608::hmUpperFloor(int messageNum, const MessageParam &param, Entity *sender) {
Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0x60842040)
_carStatus = 1;
break;
@@ -1281,13 +464,13 @@ uint32 Scene1608::hmUpperFloor(int messageNum, const MessageParam &param, Entity
uint32 Scene1608::hmRidingCar(int messageNum, const MessageParam &param, Entity *sender) {
Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x2005:
+ case NM_KLAYMEN_CLIMB_LADDER:
leaveScene(1);
break;
- case 0x2006:
+ case NM_KLAYMEN_STOP_CLIMBING:
SetMessageHandler(&Scene1608::hmCarAtHome);
SetUpdateHandler(&Scene1608::upCarAtHome);
- sendMessage(_asCar, 0x200F, 1);
+ sendMessage(_asCar, NM_CAR_AT_HOME, 1);
break;
case 0x200D:
sendMessage(_parentModule, 0x200D, 0);
@@ -1299,7 +482,7 @@ uint32 Scene1608::hmRidingCar(int messageNum, const MessageParam &param, Entity
uint32 Scene1608::hmCarAtHome(int messageNum, const MessageParam &param, Entity *sender) {
Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x200A:
+ case NM_CAR_LEAVE:
_carStatus = 2;
break;
case 0x200D:
@@ -1361,11 +544,11 @@ void Scene1609::update() {
uint32 Scene1609::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x0001:
+ case NM_MOUSE_CLICK:
if (param.asPoint().x <= 20 || param.asPoint().x >= 620)
leaveScene(0);
break;
- case 0x2000:
+ case NM_ANIMATION_UPDATE:
if (!_isSolved) {
if (_changeCurrentSymbol)
_asSymbols[_symbolPosition]->change(_currentSymbolIndex + 12, false);
diff --git a/engines/neverhood/modules/module1600.h b/engines/neverhood/modules/module1600.h
index 5f0da528ab..f08eaad8fc 100644
--- a/engines/neverhood/modules/module1600.h
+++ b/engines/neverhood/modules/module1600.h
@@ -26,13 +26,9 @@
#include "neverhood/neverhood.h"
#include "neverhood/module.h"
#include "neverhood/scene.h"
-#include "neverhood/console.h"
-#include "neverhood/modules/module3000.h"
namespace Neverhood {
-// Module1600
-
class Module1600 : public Module {
public:
Module1600(NeverhoodEngine *vm, Module *parentModule, int which);
@@ -43,90 +39,7 @@ protected:
void updateScene();
};
-class AsCommonCar : public AnimatedSprite {
-public:
- AsCommonCar(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
- ~AsCommonCar();
- void setPathPoints(NPointArray *pathPoints);
-protected:
- Scene *_parentScene;
- NPointArray *_pathPoints;
- int _newMoveDirection;
- int _currMoveDirection;
- int _exitDirection;
- int _currPointIndex;
- bool _hasAgainDestPoint;
- NPoint _againDestPoint;
- bool _hasAgainDestPointIndex;
- int _againDestPointIndex;
- bool _inMainArea;
- bool _isBraking;
- bool _isBusy;
- bool _isIdle;
- bool _isMoving;
- bool _rectFlag;
- int _idleCounter;
- int _idleCounterMax;
- int _steps;
- int _stepError;
- int _lastDistance;
- int _yMoveTotalSteps;
- int _ySteps;
- int _newDeltaXType;
- int _soundCounter;
- int _turnMoveStatus;
- int16 _destX, _destY;
- NPoint pathPoint(uint index) { return (*_pathPoints)[index]; }
- void update();
- void upIdle();
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- uint32 hmAnimation(int messageNum, const MessageParam &param, Entity *sender);
- uint32 hmLeaveCar(int messageNum, const MessageParam &param, Entity *sender);
- void stCarAtHome();
- void updateTurnMovement();
- void updateMovement();
- void stEnterCar();
- void stLeaveCar();
- void stLeanForwardIdle();
- void evIdleDone();
- void stIdleBlink();
- void stUpdateMoveDirection();
- void stTurnCar();
- void moveToNextPoint();
- void stBrakeMoveToNextPoint();
- void stTurnCarMoveToNextPoint();
- void moveToPrevPoint();
- void stBrakeMoveToPrevPoint();
- void stTurnCarMoveToPrevPoint();
- void evTurnCarDone();
- void suMoveToNextPoint();
- void suMoveToPrevPoint();
- void updateSound();
-};
-
-class AsCommonIdleCarLower : public AnimatedSprite {
-public:
- AsCommonIdleCarLower(NeverhoodEngine *vm, int16 x, int16 y);
-};
-
-class AsCommonIdleCarFull : public AnimatedSprite {
-public:
- AsCommonIdleCarFull(NeverhoodEngine *vm, int16 x, int16 y);
-};
-
-class AsCommonCarConnector : public AnimatedSprite {
-public:
- AsCommonCarConnector(NeverhoodEngine *vm, AsCommonCar *asCar);
-protected:
- AsCommonCar *_asCar;
- void update();
-};
-
-class Tracks : public Common::Array<TrackInfo*> {
-public:
- void findTrackPoint(NPoint pt, int &minMatchTrackIndex, int &minMatchDistance,
- DataResource &dataResource);
-};
+class AsCommonCar;
class Scene1608 : public Scene {
public:
@@ -162,6 +75,8 @@ protected:
void updateKlaymenCliprect();
};
+class AsScene3011Symbol;
+
class Scene1609 : public Scene {
friend class Console;
public:
diff --git a/engines/neverhood/modules/module1600_sprites.cpp b/engines/neverhood/modules/module1600_sprites.cpp
new file mode 100644
index 0000000000..b7b3658c5e
--- /dev/null
+++ b/engines/neverhood/modules/module1600_sprites.cpp
@@ -0,0 +1,934 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public 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 "neverhood/modules/module1600_sprites.h"
+
+namespace Neverhood {
+
+AsCommonCar::AsCommonCar(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
+ : AnimatedSprite(vm, 1000), _parentScene(parentScene) {
+
+ createSurface(200, 556, 328);
+ _x = x;
+ _y = y;
+
+ _inMainArea = false;
+ _exitDirection = 0;
+ _currPointIndex = 0;
+ _hasAgainDestPoint = false;
+ _stepError = 0;
+ _hasAgainDestPointIndex = false;
+ _steps = 0;
+ _isBraking = false;
+ _yMoveTotalSteps = 0;
+ _isBusy = false;
+ _isIdle = false;
+ _isMoving = true;
+ _rectFlag = false;
+ _newDeltaXType = -1;
+ _soundCounter = 0;
+ _pathPoints = NULL;
+ _currMoveDirection = 0;
+
+ startAnimation(0xD4220027, 0, -1);
+ setDoDeltaX(getGlobalVar(V_CAR_DELTA_X));
+
+ SetUpdateHandler(&AsCommonCar::update);
+ SetMessageHandler(&AsCommonCar::handleMessage);
+ SetSpriteUpdate(NULL);
+}
+
+AsCommonCar::~AsCommonCar() {
+ if (_finalizeStateCb == AnimationCallback(&AsCommonCar::evTurnCarDone))
+ setGlobalVar(V_CAR_DELTA_X, !getGlobalVar(V_CAR_DELTA_X));
+}
+
+void AsCommonCar::setPathPoints(NPointArray *pathPoints) {
+ _pathPoints = pathPoints;
+}
+
+void AsCommonCar::update() {
+ if (_newDeltaXType >= 0) {
+ setDoDeltaX(_newDeltaXType);
+ _newDeltaXType = -1;
+ }
+ AnimatedSprite::update();
+ if (_hasAgainDestPoint && _yMoveTotalSteps == 0 && !_isBusy) {
+ _hasAgainDestPoint = false;
+ _hasAgainDestPointIndex = false;
+ sendPointMessage(this, 0x2004, _againDestPoint);
+ } else if (_hasAgainDestPointIndex && _yMoveTotalSteps == 0 && !_isBusy) {
+ _hasAgainDestPointIndex = false;
+ sendMessage(this, 0x2003, _againDestPointIndex);
+ }
+ updateMovement();
+ updateSound();
+}
+
+void AsCommonCar::upIdle() {
+ update();
+ if (++_idleCounter >= _idleCounterMax)
+ stIdleBlink();
+ updateSound();
+}
+
+uint32 AsCommonCar::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case NM_SCENE_LEAVE:
+ SetSpriteUpdate(NULL);
+ break;
+ case NM_POSITION_CHANGE:
+ // Set the current position without moving
+ _currPointIndex = param.asInteger();
+ _stepError = 0;
+ _x = pathPoint(_currPointIndex).x;
+ _y = pathPoint(_currPointIndex).y;
+ break;
+ case 0x2003:
+ // Move to a point by its index
+ {
+ int newPointIndex = param.asInteger();
+ if (_yMoveTotalSteps <= 0 && !_isBusy) {
+ _destX = pathPoint(newPointIndex).x;
+ _destY = pathPoint(newPointIndex).y;
+ if (_currPointIndex < newPointIndex) {
+ moveToNextPoint();
+ } else if (_currPointIndex == newPointIndex && _stepError == 0) {
+ if (_currPointIndex == 0) {
+ _yMoveTotalSteps = 0;
+ sendMessage(_parentScene, NM_KLAYMEN_CLIMB_LADDER, 0);
+ } else if (_currPointIndex == (int)_pathPoints->size()) {
+ _yMoveTotalSteps = 0;
+ sendMessage(_parentScene, NM_KLAYMEN_STOP_CLIMBING, 0);
+ }
+ } else {
+ moveToPrevPoint();
+ }
+ } else {
+ _hasAgainDestPointIndex = true;
+ _againDestPointIndex = newPointIndex;
+ }
+ }
+ break;
+ case 0x2004:
+ // Move to the point closest to the parameter point
+ {
+ int minMatchIndex = -1;
+ int minMatchDistance, distance;
+ NPoint pt = param.asPoint();
+ if (_yMoveTotalSteps <= 0 && !_isBusy) {
+ // Check if we're already exiting (or something)
+ if ((pt.x <= 20 && _exitDirection == 1) ||
+ (pt.x >= 620 && _exitDirection == 3) ||
+ (pt.y <= 20 && _exitDirection == 2) ||
+ (pt.y >= 460 && _exitDirection == 4))
+ break;
+ _destX = pt.x;
+ _destY = pt.y;
+ minMatchDistance = calcDistance(_destX, _destY, _x, _y) + 1;
+ for (int i = _currPointIndex + 1; i < (int)_pathPoints->size(); i++) {
+ distance = calcDistance(_destX, _destY, pathPoint(i).x, pathPoint(i).y);
+ if (distance >= minMatchDistance)
+ break;
+ minMatchDistance = distance;
+ minMatchIndex = i;
+ }
+ for (int i = _currPointIndex; i >= 0; i--) {
+ distance = calcDistance(_destX, _destY, pathPoint(i).x, pathPoint(i).y);
+ if (distance >= minMatchDistance)
+ break;
+ minMatchDistance = distance;
+ minMatchIndex = i;
+ }
+ if (minMatchIndex == -1) {
+ if (_currPointIndex == 0)
+ moveToPrevPoint();
+ else
+ SetSpriteUpdate(NULL);
+ } else {
+ if (minMatchIndex > _currPointIndex)
+ moveToNextPoint();
+ else
+ moveToPrevPoint();
+ }
+ } else {
+ _hasAgainDestPoint = true;
+ _againDestPoint = pt;
+ }
+ }
+ break;
+ case NM_CAR_MOVE_TO_PREV_POINT:
+ _yMoveTotalSteps = param.asInteger();
+ _steps = 0;
+ _isBraking = false;
+ _lastDistance = 640;
+ SetSpriteUpdate(&AsCommonCar::suMoveToPrevPoint);
+ break;
+ case NM_CAR_MOVE_TO_NEXT_POINT:
+ _yMoveTotalSteps = param.asInteger();
+ _steps = 0;
+ _isBraking = false;
+ _lastDistance = 640;
+ SetSpriteUpdate(&AsCommonCar::suMoveToNextPoint);
+ break;
+ case NM_CAR_ENTER:
+ stEnterCar();
+ break;
+ case NM_CAR_LEAVE:
+ stLeaveCar();
+ break;
+ case NM_CAR_TURN:
+ stTurnCar();
+ break;
+ case NM_CAR_AT_HOME:
+ stCarAtHome();
+ _newDeltaXType = param.asInteger();
+ break;
+ }
+ return messageResult;
+}
+
+uint32 AsCommonCar::hmAnimation(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = AsCommonCar::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case NM_ANIMATION_START:
+ if (_isBusy && param.asInteger() == 0x025424A2)
+ gotoNextState();
+ break;
+ case NM_ANIMATION_STOP:
+ gotoNextState();
+ break;
+ }
+ return messageResult;
+}
+
+uint32 AsCommonCar::hmLeaveCar(int messageNum, const MessageParam &param, Entity *sender) {
+ switch (messageNum) {
+ case NM_CAR_ENTER:
+ stEnterCar();
+ break;
+ case NM_ANIMATION_STOP:
+ sendMessage(_parentScene, NM_CAR_LEAVE, 0);
+ SetMessageHandler(&AsCommonCar::handleMessage);
+ break;
+ }
+ return 0;
+}
+
+void AsCommonCar::stCarAtHome() {
+ bool doDeltaX = _doDeltaX;
+ SetSpriteUpdate(NULL);
+ _hasAgainDestPoint = false;
+ _hasAgainDestPointIndex = false;
+ _isBraking = false;
+ _isBusy = false;
+ _isIdle = false;
+ _isMoving = false;
+ _rectFlag = false;
+ NextState(&AsCommonCar::stLeanForwardIdle);
+ startAnimation(0x35698F78, 0, -1);
+ setDoDeltaX(doDeltaX ? 1 : 0);
+ _currMoveDirection = 0;
+ _newMoveDirection = 0;
+ _steps = 0;
+ _idleCounter = 0;
+ _idleCounterMax = _vm->_rnd->getRandomNumber(64 - 1) + 24;
+ SetUpdateHandler(&AsCommonCar::upIdle);
+ SetMessageHandler(&AsCommonCar::handleMessage);
+ FinalizeState(&AsCommonCar::evIdleDone);
+}
+
+void AsCommonCar::updateTurnMovement() {
+ if (_turnMoveStatus == 1) {
+ _lastDistance = 640;
+ _isIdle = false;
+ _isBraking = false;
+ SetSpriteUpdate(&AsCommonCar::suMoveToNextPoint);
+ } else if (_turnMoveStatus == 2) {
+ _lastDistance = 640;
+ _isIdle = false;
+ _isBraking = false;
+ SetSpriteUpdate(&AsCommonCar::suMoveToPrevPoint);
+ }
+}
+
+void AsCommonCar::updateMovement() {
+ if (_isBraking && !_isIdle && !_isBusy) {
+ gotoNextState();
+ _isMoving = false;
+ _isIdle = true;
+ startAnimation(0x192ADD30, 0, -1);
+ SetUpdateHandler(&AsCommonCar::update);
+ SetMessageHandler(&AsCommonCar::hmAnimation);
+ NextState(&AsCommonCar::stLeanForwardIdle);
+ } else if (!_isBraking && _steps && _isIdle) {
+ gotoNextState();
+ _isIdle = false;
+ startAnimation(0x9966B138, 0, -1);
+ SetUpdateHandler(&AsCommonCar::update);
+ SetMessageHandler(&AsCommonCar::hmAnimation);
+ NextState(&AsCommonCar::stUpdateMoveDirection);
+ } else if (_newMoveDirection != _currMoveDirection && _isMoving && !_isBusy) {
+ gotoNextState();
+ _currMoveDirection = _newMoveDirection;
+ stUpdateMoveDirection();
+ }
+}
+
+void AsCommonCar::stEnterCar() {
+ startAnimation(0xA86A9538, 0, -1);
+ SetUpdateHandler(&AsCommonCar::update);
+ SetMessageHandler(&AsCommonCar::hmAnimation);
+ NextState(&AsCommonCar::stLeanForwardIdle);
+}
+
+void AsCommonCar::stLeaveCar() {
+ startAnimation(0xA86A9538, -1, -1);
+ _playBackwards = true;
+ SetUpdateHandler(&AsCommonCar::update);
+ SetMessageHandler(&AsCommonCar::hmLeaveCar);
+}
+
+void AsCommonCar::stLeanForwardIdle() {
+ startAnimation(0x35698F78, 0, -1);
+ _currMoveDirection = 0;
+ _newMoveDirection = 0;
+ _steps = 0;
+ _idleCounter = 0;
+ _idleCounterMax = _vm->_rnd->getRandomNumber(64 - 1) + 24;
+ SetUpdateHandler(&AsCommonCar::upIdle);
+ SetMessageHandler(&AsCommonCar::handleMessage);
+ FinalizeState(&AsCommonCar::evIdleDone);
+}
+
+void AsCommonCar::evIdleDone() {
+ SetUpdateHandler(&AsCommonCar::update);
+}
+
+void AsCommonCar::stIdleBlink() {
+ startAnimation(0xB579A77C, 0, -1);
+ _idleCounter = 0;
+ _idleCounterMax = _vm->_rnd->getRandomNumber(64 - 1) + 24;
+ SetUpdateHandler(&AsCommonCar::update);
+ SetMessageHandler(&AsCommonCar::hmAnimation);
+ NextState(&AsCommonCar::stLeanForwardIdle);
+}
+
+void AsCommonCar::stUpdateMoveDirection() {
+ _isMoving = true;
+ if (_currMoveDirection == 1)
+ startAnimation(0xD4AA03A4, 0, -1);
+ else if (_currMoveDirection == 3)
+ startAnimation(0xD00A1364, 0, -1);
+ else if ((_currMoveDirection == 2 && _doDeltaX) || (_currMoveDirection == 4 && !_doDeltaX))
+ stTurnCar();
+ else
+ startAnimation(0xD4220027, 0, -1);
+ setGlobalVar(V_CAR_DELTA_X, _doDeltaX ? 1 : 0);
+}
+
+void AsCommonCar::moveToNextPoint() {
+ if (_currPointIndex >= (int)_pathPoints->size() - 1) {
+ _yMoveTotalSteps = 0;
+ sendMessage(this, NM_SCENE_LEAVE, 0);
+ sendMessage(_parentScene, NM_KLAYMEN_STOP_CLIMBING, 0);
+ } else {
+ NPoint nextPt = pathPoint(_currPointIndex + 1);
+ NPoint currPt = pathPoint(_currPointIndex);
+ if (ABS(nextPt.y - currPt.y) <= ABS(nextPt.x - currPt.x) &&
+ ((_currMoveDirection == 2 && nextPt.x < currPt.x) ||
+ (_currMoveDirection == 4 && nextPt.x >= currPt.x))) {
+ if (_currMoveDirection == 2)
+ _currMoveDirection = 4;
+ else if (_currMoveDirection == 4)
+ _currMoveDirection = 2;
+ if (_isIdle)
+ stTurnCarMoveToNextPoint();
+ else
+ stBrakeMoveToNextPoint();
+ } else {
+ if (_steps == 0) {
+ gotoNextState();
+ _isIdle = false;
+ startAnimation(0x9966B138, 0, -1);
+ SetMessageHandler(&AsCommonCar::hmAnimation);
+ SetUpdateHandler(&AsCommonCar::update);
+ NextState(&AsCommonCar::stUpdateMoveDirection);
+ }
+ _isBraking = false;
+ SetSpriteUpdate(&AsCommonCar::suMoveToNextPoint);
+ _lastDistance = 640;
+ }
+ }
+}
+
+void AsCommonCar::stBrakeMoveToNextPoint() {
+ gotoNextState();
+ _isBusy = true;
+ _isBraking = true;
+ startAnimation(0x192ADD30, 0, -1);
+ SetUpdateHandler(&AsCommonCar::update);
+ SetMessageHandler(&AsCommonCar::hmAnimation);
+ NextState(&AsCommonCar::stTurnCarMoveToNextPoint);
+}
+
+void AsCommonCar::stTurnCar() {
+ // Turn to left/right #1
+ gotoNextState();
+ _isBusy = true;
+ startAnimation(0xF46A0324, 0, -1);
+ SetUpdateHandler(&AsCommonCar::update);
+ SetMessageHandler(&AsCommonCar::hmAnimation);
+ FinalizeState(&AsCommonCar::evTurnCarDone);
+ _turnMoveStatus = 0;
+ updateTurnMovement();
+}
+
+void AsCommonCar::stTurnCarMoveToNextPoint() {
+ // Turn to left/right #2
+ gotoNextState();
+ _isBusy = true;
+ startAnimation(0xF46A0324, 0, -1);
+ SetUpdateHandler(&AsCommonCar::update);
+ SetMessageHandler(&AsCommonCar::hmAnimation);
+ FinalizeState(&AsCommonCar::evTurnCarDone);
+ _turnMoveStatus = 1;
+ updateTurnMovement();
+}
+
+void AsCommonCar::stTurnCarMoveToPrevPoint() {
+ // Turn to left/right #3
+ FinalizeState(NULL);
+ _isBusy = true;
+ startAnimation(0xF46A0324, 0, -1);
+ SetUpdateHandler(&AsCommonCar::update);
+ SetMessageHandler(&AsCommonCar::hmAnimation);
+ FinalizeState(&AsCommonCar::evTurnCarDone);
+ _turnMoveStatus = 2;
+ updateTurnMovement();
+}
+
+void AsCommonCar::moveToPrevPoint() {
+ if (_currPointIndex == 0 && _stepError == 0) {
+ _yMoveTotalSteps = 0;
+ sendMessage(this, NM_SCENE_LEAVE, 0);
+ sendMessage(_parentScene, NM_KLAYMEN_CLIMB_LADDER, 0);
+ } else {
+ NPoint prevPt;
+ NPoint currPt;
+ if (_stepError == 0) {
+ prevPt = pathPoint(_currPointIndex - 1);
+ currPt = pathPoint(_currPointIndex);
+ } else {
+ prevPt = pathPoint(_currPointIndex);
+ currPt = pathPoint(_currPointIndex + 1);
+ }
+ if (ABS(prevPt.y - currPt.y) <= ABS(prevPt.x - currPt.x) &&
+ ((_currMoveDirection == 2 && prevPt.x < currPt.x) ||
+ (_currMoveDirection == 4 && prevPt.x >= currPt.x))) {
+ if (_currMoveDirection == 2)
+ _currMoveDirection = 4;
+ else if (_currMoveDirection == 4)
+ _currMoveDirection = 2;
+ if (_isIdle)
+ stTurnCarMoveToPrevPoint();
+ else
+ stBrakeMoveToPrevPoint();
+ } else {
+ if (_steps == 0) {
+ gotoNextState();
+ _isIdle = false;
+ startAnimation(0x9966B138, 0, -1);
+ SetMessageHandler(&AsCommonCar::hmAnimation);
+ SetUpdateHandler(&AsCommonCar::update);
+ NextState(&AsCommonCar::stUpdateMoveDirection);
+ }
+ _isBraking = false;
+ SetSpriteUpdate(&AsCommonCar::suMoveToPrevPoint);
+ _lastDistance = 640;
+ }
+ }
+}
+
+void AsCommonCar::stBrakeMoveToPrevPoint() {
+ FinalizeState(NULL);
+ _isBusy = true;
+ _isBraking = true;
+ startAnimation(0x192ADD30, 0, -1);
+ SetUpdateHandler(&AsCommonCar::update);
+ SetMessageHandler(&AsCommonCar::hmAnimation);
+ NextState(&AsCommonCar::stTurnCarMoveToPrevPoint);
+}
+
+void AsCommonCar::evTurnCarDone() {
+ _isBusy = false;
+ setDoDeltaX(2);
+ _newMoveDirection = 0;
+ stUpdateMoveDirection();
+}
+
+void AsCommonCar::suMoveToNextPoint() {
+ int16 newX = _x, newY = _y;
+
+ if (_currPointIndex >= (int)_pathPoints->size()) {
+ _yMoveTotalSteps = 0;
+ sendMessage(this, NM_SCENE_LEAVE, 0);
+ sendMessage(_parentScene, NM_KLAYMEN_STOP_CLIMBING, 0);
+ return;
+ }
+
+ if (_isBraking) {
+ if (_steps <= 0) {
+ sendMessage(this, NM_SCENE_LEAVE, 0);
+ return;
+ } else
+ _steps--;
+ } else if (_steps < 11)
+ _steps++;
+
+ bool firstTime = true;
+ _ySteps = _steps;
+ int stepsCtr = _steps;
+
+ while (stepsCtr > 0) {
+ NPoint pt1;
+ NPoint pt2 = pathPoint(_currPointIndex);
+ if (_currPointIndex + 1 >= (int)_pathPoints->size())
+ pt1 = pathPoint(0);
+ else
+ pt1 = pathPoint(_currPointIndex + 1);
+ int16 deltaX = ABS(pt1.x - pt2.x);
+ int16 deltaY = ABS(pt1.y - pt2.y);
+ if (deltaX >= deltaY) {
+ _newMoveDirection = 2;
+ if (pt1.x < pt2.x)
+ _newMoveDirection = 4;
+ if (stepsCtr + _stepError >= deltaX) {
+ stepsCtr -= deltaX;
+ stepsCtr += _stepError;
+ _stepError = 0;
+ _currPointIndex++;
+ if (_currPointIndex == (int)_pathPoints->size() - 1)
+ stepsCtr = 0;
+ newX = pathPoint(_currPointIndex).x;
+ newY = pathPoint(_currPointIndex).y;
+ } else {
+ _stepError += stepsCtr;
+ if (pt1.x >= pt2.x)
+ newX += stepsCtr;
+ else
+ newX -= stepsCtr;
+ if (pt1.y >= pt2.y)
+ newY = pt2.y + (deltaY * _stepError) / deltaX;
+ else
+ newY = pt2.y - (deltaY * _stepError) / deltaX;
+ stepsCtr = 0;
+ }
+ } else {
+ _newMoveDirection = 3;
+ if (pt1.y < pt2.y)
+ _newMoveDirection = 1;
+ if (firstTime) {
+ if (pt1.y >= pt2.y)
+ stepsCtr += 7;
+ else {
+ stepsCtr -= 4;
+ if (stepsCtr < 0)
+ stepsCtr = 0;
+ }
+ _ySteps = stepsCtr;
+ }
+ if (stepsCtr + _stepError >= deltaY) {
+ stepsCtr -= deltaY;
+ stepsCtr += _stepError;
+ _stepError = 0;
+ _currPointIndex++;
+ if (_currPointIndex == (int)_pathPoints->size() - 1)
+ stepsCtr = 0;
+ newX = pathPoint(_currPointIndex).x;
+ newY = pathPoint(_currPointIndex).y;
+ } else {
+ _stepError += stepsCtr;
+ if (pt1.x >= pt2.x)
+ newX = pt2.x + (deltaX * _stepError) / deltaY;
+ else
+ newX = pt2.x - (deltaX * _stepError) / deltaY;
+ if (pt1.y >= pt2.y)
+ newY += stepsCtr;
+ else
+ newY -= stepsCtr;
+ stepsCtr = 0;
+ }
+ }
+ firstTime = false;
+ }
+
+ if (_yMoveTotalSteps != 0) {
+ _x = newX;
+ _y = newY;
+ _yMoveTotalSteps -= _ySteps;
+ if (_yMoveTotalSteps <= 0) {
+ _isBraking = true;
+ _yMoveTotalSteps = 0;
+ }
+ } else {
+ int distance = calcDistance(_destX, _destY, _x, _y);
+ _x = newX;
+ _y = newY;
+ if (newX > 20 && newX < 620 && newY > 20 && newY < 460) {
+ _exitDirection = 0;
+ _inMainArea = true;
+ } else if (_inMainArea) {
+ _destX = pathPoint(_pathPoints->size() - 1).x;
+ _destY = pathPoint(_pathPoints->size() - 1).y;
+ _inMainArea = false;
+ if (_x <= 20)
+ _exitDirection = 1;
+ else if (_x >= 620)
+ _exitDirection = 3;
+ else if (_y <= 20)
+ _exitDirection = 2;
+ else if (_y >= 460)
+ _exitDirection = 4;
+ if (_exitDirection != 0 && _isBraking) {
+ _isBraking = false;
+ _steps = 11;
+ }
+ }
+ if ((distance < 20 && _exitDirection == 0 && _lastDistance < distance) ||
+ (_exitDirection == 0 && _lastDistance + 20 < distance))
+ _isBraking = true;
+ if (distance < _lastDistance)
+ _lastDistance = distance;
+ if (_currPointIndex == (int)_pathPoints->size() - 1) {
+ _isBraking = true;
+ _yMoveTotalSteps = 0;
+ sendMessage(this, NM_SCENE_LEAVE, 0);
+ sendMessage(_parentScene, NM_KLAYMEN_STOP_CLIMBING, 0);
+ }
+ }
+
+}
+
+void AsCommonCar::suMoveToPrevPoint() {
+ int16 newX = _x, newY = _y;
+
+ if (_currPointIndex == 0 && _stepError == 0) {
+ _yMoveTotalSteps = 0;
+ sendMessage(this, NM_SCENE_LEAVE, 0);
+ sendMessage(_parentScene, NM_KLAYMEN_CLIMB_LADDER, 0);
+ return;
+ }
+
+ if (_isBraking) {
+ if (_steps <= 0) {
+ sendMessage(this, NM_SCENE_LEAVE, 0);
+ return;
+ } else
+ _steps--;
+ } else if (_steps < 11)
+ _steps++;
+
+ bool firstTime = true;
+ _ySteps = _steps;
+ int stepsCtr = _steps;
+
+ while (stepsCtr > 0) {
+ if (_stepError == 0)
+ _currPointIndex--;
+ NPoint pt1;
+ NPoint pt2 = pathPoint(_currPointIndex);
+ if (_currPointIndex + 1 >= (int)_pathPoints->size())
+ pt1 = pathPoint(0);
+ else
+ pt1 = pathPoint(_currPointIndex + 1);
+ int16 deltaX = ABS(pt1.x - pt2.x);
+ int16 deltaY = ABS(pt1.y - pt2.y);
+ if (deltaX >= deltaY) {
+ _newMoveDirection = 4;
+ if (pt1.x < pt2.x)
+ _newMoveDirection = 2;
+ if (_stepError == 0)
+ _stepError = deltaX;
+ if (stepsCtr > _stepError) {
+ stepsCtr -= _stepError;
+ _stepError = 0;
+ if (_currPointIndex == 0)
+ stepsCtr = 0;
+ newX = pathPoint(_currPointIndex).x;
+ newY = pathPoint(_currPointIndex).y;
+ } else {
+ _stepError -= stepsCtr;
+ if (pt1.x >= pt2.x)
+ newX -= stepsCtr;
+ else
+ newX += stepsCtr;
+ if (pt1.y >= pt2.y)
+ newY = pt2.y + (deltaY * _stepError) / deltaX;
+ else
+ newY = pt2.y - (deltaY * _stepError) / deltaX;
+ stepsCtr = 0;
+ }
+ } else {
+ _newMoveDirection = 1;
+ if (pt1.y < pt2.y)
+ _newMoveDirection = 3;
+ if (firstTime) {
+ if (pt1.y >= pt2.y) {
+ stepsCtr -= 4;
+ if (stepsCtr < 0)
+ stepsCtr = 0;
+ } else {
+ stepsCtr += 7;
+ }
+ _ySteps = stepsCtr;
+ }
+ if (_stepError == 0)
+ _stepError = deltaY;
+ if (stepsCtr > _stepError) {
+ stepsCtr -= _stepError;
+ _stepError = 0;
+ if (_currPointIndex == 0)
+ stepsCtr = 0;
+ newX = pathPoint(_currPointIndex).x;
+ newY = pathPoint(_currPointIndex).y;
+ } else {
+ _stepError -= stepsCtr;
+ if (pt1.x >= pt2.x)
+ newX = pt2.x + (deltaX * _stepError) / deltaY;
+ else
+ newX = pt2.x - (deltaX * _stepError) / deltaY;
+ if (pt1.y >= pt2.y)
+ newY -= stepsCtr;
+ else
+ newY += stepsCtr;
+ stepsCtr = 0;
+ }
+ }
+ firstTime = false;
+ }
+
+ if (_yMoveTotalSteps != 0) {
+ _x = newX;
+ _y = newY;
+ _yMoveTotalSteps -= _ySteps;
+ if (_yMoveTotalSteps <= 0) {
+ _isBraking = true;
+ _yMoveTotalSteps = 0;
+ }
+ } else {
+ int distance = calcDistance(_destX, _destY, _x, _y);
+ _x = newX;
+ _y = newY;
+ if (newX > 20 && newX < 620 && newY > 20 && newY < 460) {
+ _exitDirection = 0;
+ _inMainArea = true;
+ } else if (_inMainArea) {
+ _destX = pathPoint(0).x;
+ _destY = pathPoint(0).y;
+ _inMainArea = false;
+ if (_x <= 20)
+ _exitDirection = 1;
+ else if (_x >= 620)
+ _exitDirection = 3;
+ else if (_y <= 20)
+ _exitDirection = 2;
+ else if (_y >= 460)
+ _exitDirection = 4;
+ if (_exitDirection != 0 && _isBraking) {
+ _isBraking = false;
+ _steps = 11;
+ }
+ }
+ if ((distance < 20 && _exitDirection == 0 && _lastDistance < distance) ||
+ (_exitDirection == 0 && _lastDistance + 20 < distance))
+ _isBraking = true;
+ if (distance < _lastDistance)
+ _lastDistance = distance;
+ if (_currPointIndex == 0 && _stepError == 0) {
+ _isBraking = true;
+ _yMoveTotalSteps = 0;
+ sendMessage(this, NM_SCENE_LEAVE, 0);
+ sendMessage(_parentScene, NM_KLAYMEN_CLIMB_LADDER, 0);
+ }
+ }
+
+}
+
+void AsCommonCar::updateSound() {
+ int maxSoundCounter = 0;
+ _soundCounter++;
+ if (_steps != 0 && !_isIdle) {
+ if (_currMoveDirection == 1)
+ maxSoundCounter = 18 - _steps;
+ else if (_currMoveDirection == 3) {
+ maxSoundCounter = 5 - _steps;
+ if (maxSoundCounter < 1)
+ maxSoundCounter = 1;
+ } else
+ maxSoundCounter = 14 - _steps;
+ } else
+ maxSoundCounter = 21;
+ if (_soundCounter >= maxSoundCounter) {
+ sendMessage(_parentScene, 0x200D, 0);
+ _soundCounter = 0;
+ }
+}
+
+AsCommonIdleCarLower::AsCommonIdleCarLower(NeverhoodEngine *vm, int16 x, int16 y)
+ : AnimatedSprite(vm, 0x1209E09F, 1100, x, y) {
+
+ setDoDeltaX(1);
+ startAnimation(0x1209E09F, 1, -1);
+ _newStickFrameIndex = 1;
+}
+
+AsCommonIdleCarFull::AsCommonIdleCarFull(NeverhoodEngine *vm, int16 x, int16 y)
+ : AnimatedSprite(vm, 0x1209E09F, 100, x, y) {
+
+ setDoDeltaX(1);
+ _newStickFrameIndex = 0;
+}
+
+AsCommonCarConnector::AsCommonCarConnector(NeverhoodEngine *vm, AsCommonCar *asCar)
+ : AnimatedSprite(vm, 1100), _asCar(asCar) {
+
+ createSurface1(0x60281C10, 150);
+ startAnimation(0x60281C10, -1, -1);
+ _newStickFrameIndex = STICK_LAST_FRAME;
+ SetUpdateHandler(&AsCommonCarConnector::update);
+}
+
+void AsCommonCarConnector::update() {
+ _x = _asCar->getX();
+ _y = _asCar->getY();
+ AnimatedSprite::update();
+}
+
+void Tracks::findTrackPoint(NPoint pt, int &minMatchTrackIndex, int &minMatchDistance,
+ DataResource &dataResource) {
+ const uint trackCount = size();
+ minMatchTrackIndex = -1;
+ minMatchDistance = 640;
+ for (uint trackIndex = 0; trackIndex < trackCount; trackIndex++) {
+ NPointArray *pointList = dataResource.getPointArray((*this)[trackIndex]->trackPointsName);
+ for (uint pointIndex = 0; pointIndex < pointList->size(); pointIndex++) {
+ NPoint testPt = (*pointList)[pointIndex];
+ int distance = calcDistance(testPt.x, testPt.y, pt.x, pt.y);
+ if (distance < minMatchDistance) {
+ minMatchTrackIndex = trackIndex;
+ minMatchDistance = distance;
+ }
+ }
+ }
+}
+
+KmScene1608::KmScene1608(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
+ : Klaymen(vm, parentScene, x, y) {
+
+ // Empty
+}
+
+uint32 KmScene1608::xHandleMessage(int messageNum, const MessageParam &param) {
+ uint32 messageResult = 0;
+ switch (messageNum) {
+ case 0x2032:
+ _isSittingInTeleporter = param.asInteger() != 0;
+ messageResult = 1;
+ break;
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case NM_KLAYMEN_STAND_IDLE:
+ if (_isSittingInTeleporter)
+ GotoState(&Klaymen::stSitIdleTeleporter);
+ else
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case NM_KLAYMEN_PICKUP:
+ if (param.asInteger() == 2)
+ GotoState(&Klaymen::stPickUpNeedle);
+ else if (param.asInteger() == 1)
+ GotoState(&Klaymen::stPickUpTube);
+ else
+ GotoState(&Klaymen::stPickUpGeneric);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ gotoNextStateExt();
+ break;
+ case 0x481B:
+ if (param.asPoint().y != 0)
+ startWalkToXDistance(param.asPoint().y, param.asPoint().x);
+ else
+ startWalkToAttachedSpriteXDistance(param.asPoint().x);
+ break;
+ case NM_KLAYMEN_TURN_TO_USE:
+ if (_isSittingInTeleporter)
+ GotoState(&Klaymen::stTurnToUseInTeleporter);
+ break;
+ case NM_KLAYMEN_RETURN_FROM_USE:
+ if (_isSittingInTeleporter)
+ GotoState(&Klaymen::stReturnFromUseInTeleporter);
+ break;
+ case 0x481F:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stWonderAboutAfter);
+ else if (param.asInteger() == 0)
+ GotoState(&Klaymen::stWonderAboutHalf);
+ else if (param.asInteger() == 4)
+ GotoState(&Klaymen::stTurnAwayFromUse);
+ else if (param.asInteger() == 3)
+ GotoState(&Klaymen::stTurnToUseHalf);
+ else
+ GotoState(&Klaymen::stWonderAbout);
+ break;
+ case 0x482D:
+ setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
+ gotoNextStateExt();
+ break;
+ case 0x4834:
+ GotoState(&Klaymen::stStepOver);
+ break;
+ case 0x4835:
+ sendMessage(_parentScene, 0x2032, 1);
+ _isSittingInTeleporter = true;
+ GotoState(&Klaymen::stSitInTeleporter);
+ break;
+ case 0x4836:
+ sendMessage(_parentScene, 0x2032, 0);
+ _isSittingInTeleporter = false;
+ GotoState(&Klaymen::stGetUpFromTeleporter);
+ break;
+ case 0x483F:
+ startSpecialWalkRight(param.asInteger());
+ break;
+ case 0x4840:
+ startSpecialWalkLeft(param.asInteger());
+ break;
+ }
+ return messageResult;
+}
+
+} // End of namespace Neverhood
diff --git a/engines/neverhood/modules/module1600_sprites.h b/engines/neverhood/modules/module1600_sprites.h
new file mode 100644
index 0000000000..fa59475dad
--- /dev/null
+++ b/engines/neverhood/modules/module1600_sprites.h
@@ -0,0 +1,126 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public 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 NEVERHOOD_MODULES_MODULE1600_SPRITES_H
+#define NEVERHOOD_MODULES_MODULE1600_SPRITES_H
+
+#include "neverhood/neverhood.h"
+#include "neverhood/module.h"
+#include "neverhood/scene.h"
+
+namespace Neverhood {
+
+class AsCommonCar : public AnimatedSprite {
+public:
+ AsCommonCar(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
+ ~AsCommonCar();
+ void setPathPoints(NPointArray *pathPoints);
+protected:
+ Scene *_parentScene;
+ NPointArray *_pathPoints;
+ int _newMoveDirection;
+ int _currMoveDirection;
+ int _exitDirection;
+ int _currPointIndex;
+ bool _hasAgainDestPoint;
+ NPoint _againDestPoint;
+ bool _hasAgainDestPointIndex;
+ int _againDestPointIndex;
+ bool _inMainArea;
+ bool _isBraking;
+ bool _isBusy;
+ bool _isIdle;
+ bool _isMoving;
+ bool _rectFlag;
+ int _idleCounter;
+ int _idleCounterMax;
+ int _steps;
+ int _stepError;
+ int _lastDistance;
+ int _yMoveTotalSteps;
+ int _ySteps;
+ int _newDeltaXType;
+ int _soundCounter;
+ int _turnMoveStatus;
+ int16 _destX, _destY;
+ NPoint pathPoint(uint index) { return (*_pathPoints)[index]; }
+ void update();
+ void upIdle();
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 hmAnimation(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 hmLeaveCar(int messageNum, const MessageParam &param, Entity *sender);
+ void stCarAtHome();
+ void updateTurnMovement();
+ void updateMovement();
+ void stEnterCar();
+ void stLeaveCar();
+ void stLeanForwardIdle();
+ void evIdleDone();
+ void stIdleBlink();
+ void stUpdateMoveDirection();
+ void stTurnCar();
+ void moveToNextPoint();
+ void stBrakeMoveToNextPoint();
+ void stTurnCarMoveToNextPoint();
+ void moveToPrevPoint();
+ void stBrakeMoveToPrevPoint();
+ void stTurnCarMoveToPrevPoint();
+ void evTurnCarDone();
+ void suMoveToNextPoint();
+ void suMoveToPrevPoint();
+ void updateSound();
+};
+
+class AsCommonIdleCarLower : public AnimatedSprite {
+public:
+ AsCommonIdleCarLower(NeverhoodEngine *vm, int16 x, int16 y);
+};
+
+class AsCommonIdleCarFull : public AnimatedSprite {
+public:
+ AsCommonIdleCarFull(NeverhoodEngine *vm, int16 x, int16 y);
+};
+
+class AsCommonCarConnector : public AnimatedSprite {
+public:
+ AsCommonCarConnector(NeverhoodEngine *vm, AsCommonCar *asCar);
+protected:
+ AsCommonCar *_asCar;
+ void update();
+};
+
+class Tracks : public Common::Array<TrackInfo*> {
+public:
+ void findTrackPoint(NPoint pt, int &minMatchTrackIndex, int &minMatchDistance,
+ DataResource &dataResource);
+};
+
+class KmScene1608 : public Klaymen {
+public:
+ KmScene1608(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
+protected:
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+};
+
+} // End of namespace Neverhood
+
+#endif /* NEVERHOOD_MODULES_MODULE1600_SPRITES_H */
diff --git a/engines/neverhood/modules/module1700.cpp b/engines/neverhood/modules/module1700.cpp
index 2aeae466ff..1062691cd2 100644
--- a/engines/neverhood/modules/module1700.cpp
+++ b/engines/neverhood/modules/module1700.cpp
@@ -20,8 +20,9 @@
*
*/
-#include "neverhood/modules/module1700.h"
#include "neverhood/gamemodule.h"
+#include "neverhood/modules/module1700.h"
+#include "neverhood/modules/module1700_sprites.h"
namespace Neverhood {
@@ -126,8 +127,6 @@ void Module1700::updateScene() {
}
}
-// Scene1705
-
static const uint32 kScene1705FileHashes[] = {
0x910EA801, 0x920EA801, 0x940EA801,
0x980EA801, 0x800EA801, 0xB00EA801,
@@ -135,47 +134,6 @@ static const uint32 kScene1705FileHashes[] = {
0xD10EA801, 0x110EA801, 0x910EA800
};
-SsScene1705WallSymbol::SsScene1705WallSymbol(NeverhoodEngine *vm, uint32 fileHash, int symbolIndex)
- : StaticSprite(vm, fileHash, 100) {
-
- _x = _spriteResource.getPosition().x + symbolIndex * 30;
- _y = _spriteResource.getPosition().y + 160;
- updatePosition();
-}
-
-SsScene1705Tape::SsScene1705Tape(NeverhoodEngine *vm, Scene *parentScene, uint32 tapeIndex, int surfacePriority, int16 x, int16 y, uint32 fileHash)
- : StaticSprite(vm, fileHash, surfacePriority, x - 24, y - 4), _parentScene(parentScene), _tapeIndex(tapeIndex) {
-
- if (!getSubVar(VA_HAS_TAPE, _tapeIndex) && !getSubVar(VA_IS_TAPE_INSERTED, _tapeIndex)) {
- SetMessageHandler(&SsScene1705Tape::handleMessage);
- } else {
- setVisible(false);
- SetMessageHandler(NULL);
- }
- _collisionBoundsOffset = _drawOffset;
- _collisionBoundsOffset.x -= 4;
- _collisionBoundsOffset.y -= 8;
- _collisionBoundsOffset.width += 8;
- _collisionBoundsOffset.height += 16;
- Sprite::updateBounds();
-}
-
-uint32 SsScene1705Tape::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x1011:
- sendMessage(_parentScene, 0x4826, 0);
- messageResult = 1;
- break;
- case 0x4806:
- setSubVar(VA_HAS_TAPE, _tapeIndex, 1);
- setVisible(false);
- SetMessageHandler(NULL);
- break;
- }
- return messageResult;
-}
-
Scene1705::Scene1705(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule), _paletteArea(1) {
@@ -257,7 +215,7 @@ void Scene1705::update() {
uint32 Scene1705::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x2000:
+ case NM_ANIMATION_UPDATE:
if (param.asInteger()) {
setRectList(0x004B6B40);
_klaymen->setKlaymenIdleTable3();
diff --git a/engines/neverhood/modules/module1700.h b/engines/neverhood/modules/module1700.h
index deb5573f2b..09daff2acf 100644
--- a/engines/neverhood/modules/module1700.h
+++ b/engines/neverhood/modules/module1700.h
@@ -26,7 +26,6 @@
#include "neverhood/neverhood.h"
#include "neverhood/module.h"
#include "neverhood/scene.h"
-#include "neverhood/smackerscene.h"
namespace Neverhood {
@@ -40,22 +39,6 @@ protected:
void updateScene();
};
-// Scene1705
-
-class SsScene1705WallSymbol : public StaticSprite {
-public:
- SsScene1705WallSymbol(NeverhoodEngine *vm, uint32 fileHash, int symbolIndex);
-};
-
-class SsScene1705Tape : public StaticSprite {
-public:
- SsScene1705Tape(NeverhoodEngine *vm, Scene *parentScene, uint32 tapeIndex, int surfacePriority, int16 x, int16 y, uint32 fileHash);
-protected:
- Scene *_parentScene;
- uint32 _tapeIndex;
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
-
class Scene1705 : public Scene {
public:
Scene1705(NeverhoodEngine *vm, Module *parentModule, int which);
diff --git a/engines/neverhood/modules/module1700_sprites.cpp b/engines/neverhood/modules/module1700_sprites.cpp
new file mode 100644
index 0000000000..d6e00c95f3
--- /dev/null
+++ b/engines/neverhood/modules/module1700_sprites.cpp
@@ -0,0 +1,156 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public 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 "neverhood/modules/module1700_sprites.h"
+
+namespace Neverhood {
+
+SsScene1705WallSymbol::SsScene1705WallSymbol(NeverhoodEngine *vm, uint32 fileHash, int symbolIndex)
+ : StaticSprite(vm, fileHash, 100) {
+
+ _x = _spriteResource.getPosition().x + symbolIndex * 30;
+ _y = _spriteResource.getPosition().y + 160;
+ updatePosition();
+}
+
+SsScene1705Tape::SsScene1705Tape(NeverhoodEngine *vm, Scene *parentScene, uint32 tapeIndex, int surfacePriority, int16 x, int16 y, uint32 fileHash)
+ : StaticSprite(vm, fileHash, surfacePriority, x - 24, y - 4), _parentScene(parentScene), _tapeIndex(tapeIndex) {
+
+ if (!getSubVar(VA_HAS_TAPE, _tapeIndex) && !getSubVar(VA_IS_TAPE_INSERTED, _tapeIndex)) {
+ SetMessageHandler(&SsScene1705Tape::handleMessage);
+ } else {
+ setVisible(false);
+ SetMessageHandler(NULL);
+ }
+ _collisionBoundsOffset = _drawOffset;
+ _collisionBoundsOffset.x -= 4;
+ _collisionBoundsOffset.y -= 8;
+ _collisionBoundsOffset.width += 8;
+ _collisionBoundsOffset.height += 16;
+ Sprite::updateBounds();
+}
+
+uint32 SsScene1705Tape::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x1011:
+ sendMessage(_parentScene, 0x4826, 0);
+ messageResult = 1;
+ break;
+ case NM_KLAYMEN_USE_OBJECT:
+ setSubVar(VA_HAS_TAPE, _tapeIndex, 1);
+ setVisible(false);
+ SetMessageHandler(NULL);
+ break;
+ }
+ return messageResult;
+}
+
+KmScene1705::KmScene1705(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
+ : Klaymen(vm, parentScene, x, y) {
+
+ // Empty
+}
+
+uint32 KmScene1705::xHandleMessage(int messageNum, const MessageParam &param) {
+ uint32 messageResult = 0;
+ switch (messageNum) {
+ case NM_ANIMATION_UPDATE:
+ _isSittingInTeleporter = param.asInteger() != 0;
+ messageResult = 1;
+ break;
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case NM_KLAYMEN_STAND_IDLE:
+ if (_isSittingInTeleporter)
+ GotoState(&Klaymen::stSitIdleTeleporter);
+ else
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x4803:
+ GotoState(&Klaymen::stFallSkipJump);
+ break;
+ case NM_KLAYMEN_PICKUP:
+ if (param.asInteger() == 2)
+ GotoState(&Klaymen::stPickUpNeedle);
+ else if (param.asInteger() == 1)
+ GotoState(&Klaymen::stPickUpTube);
+ else
+ GotoState(&Klaymen::stPickUpGeneric);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ gotoNextStateExt();
+ break;
+ case 0x481B:
+ if (param.asPoint().y != 0)
+ startWalkToXDistance(param.asPoint().y, param.asPoint().x);
+ else
+ startWalkToAttachedSpriteXDistance(param.asPoint().x);
+ break;
+ case NM_KLAYMEN_TURN_TO_USE:
+ if (_isSittingInTeleporter) {
+ GotoState(&Klaymen::stTurnToUseInTeleporter);
+ }
+ break;
+ case NM_KLAYMEN_RETURN_FROM_USE:
+ if (_isSittingInTeleporter)
+ GotoState(&Klaymen::stReturnFromUseInTeleporter);
+ break;
+ case 0x481F:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stWonderAboutAfter);
+ else if (param.asInteger() == 0)
+ GotoState(&Klaymen::stWonderAboutHalf);
+ else if (param.asInteger() == 4)
+ GotoState(&Klaymen::stTurnAwayFromUse);
+ else if (param.asInteger() == 3)
+ GotoState(&Klaymen::stTurnToUseHalf);
+ else
+ GotoState(&Klaymen::stWonderAbout);
+ break;
+ case 0x4834:
+ GotoState(&Klaymen::stStepOver);
+ break;
+ case 0x4835:
+ sendMessage(_parentScene, 0x2000, 1);
+ _isSittingInTeleporter = true;
+ GotoState(&Klaymen::stSitInTeleporter);
+ break;
+ case 0x4836:
+ sendMessage(_parentScene, 0x2000, 0);
+ _isSittingInTeleporter = false;
+ GotoState(&Klaymen::stGetUpFromTeleporter);
+ break;
+ case 0x483D:
+ teleporterAppear(0x5E0A4905);
+ break;
+ case 0x483E:
+ teleporterDisappear(0xD86E4477);
+ break;
+ }
+ return messageResult;
+}
+
+} // End of namespace Neverhood
diff --git a/engines/neverhood/modules/module1700_sprites.h b/engines/neverhood/modules/module1700_sprites.h
new file mode 100644
index 0000000000..4117de01d9
--- /dev/null
+++ b/engines/neverhood/modules/module1700_sprites.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 NEVERHOOD_MODULES_MODULE1700_SPRITES_H
+#define NEVERHOOD_MODULES_MODULE1700_SPRITES_H
+
+#include "neverhood/neverhood.h"
+#include "neverhood/module.h"
+#include "neverhood/scene.h"
+
+namespace Neverhood {
+
+class SsScene1705WallSymbol : public StaticSprite {
+public:
+ SsScene1705WallSymbol(NeverhoodEngine *vm, uint32 fileHash, int symbolIndex);
+};
+
+class SsScene1705Tape : public StaticSprite {
+public:
+ SsScene1705Tape(NeverhoodEngine *vm, Scene *parentScene, uint32 tapeIndex, int surfacePriority, int16 x, int16 y, uint32 fileHash);
+protected:
+ Scene *_parentScene;
+ uint32 _tapeIndex;
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class KmScene1705 : public Klaymen {
+public:
+ KmScene1705(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
+protected:
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+};
+
+} // End of namespace Neverhood
+
+#endif /* NEVERHOOD_MODULES_MODULE1700_SPRITES_H */
diff --git a/engines/neverhood/modules/module1800.cpp b/engines/neverhood/modules/module1800.cpp
index b312678467..282292a516 100644
--- a/engines/neverhood/modules/module1800.cpp
+++ b/engines/neverhood/modules/module1800.cpp
@@ -20,9 +20,10 @@
*
*/
-#include "neverhood/modules/module1800.h"
-#include "neverhood/navigationscene.h"
+#include "neverhood/diskplayerscene.h"
#include "neverhood/menumodule.h"
+#include "neverhood/navigationscene.h"
+#include "neverhood/modules/module1800.h"
namespace Neverhood {
diff --git a/engines/neverhood/modules/module1900.cpp b/engines/neverhood/modules/module1900.cpp
index 29c20083f9..5fdc6091dc 100644
--- a/engines/neverhood/modules/module1900.cpp
+++ b/engines/neverhood/modules/module1900.cpp
@@ -21,7 +21,7 @@
*/
#include "neverhood/modules/module1900.h"
-#include "neverhood/gamemodule.h"
+#include "neverhood/modules/module1900_sprites.h"
namespace Neverhood {
@@ -84,8 +84,6 @@ void Module1900::updateScene() {
}
}
-// Scene1901
-
Scene1901::Scene1901(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule) {
@@ -126,395 +124,6 @@ Scene1901::Scene1901(NeverhoodEngine *vm, Module *parentModule, int which)
}
-static const NPoint kAsScene1907SymbolGroundPositions[] = {
- {160, 310}, { 90, 340}, {210, 335},
- {210, 380}, {310, 340}, {290, 400},
- {400, 375}, {370, 435}, {475, 415}
-};
-
-static const NPoint kAsScene1907SymbolPluggedInPositions[] = {
- {275, 125}, {244, 125}, {238, 131},
- {221, 135}, {199, 136}, {168, 149},
- {145, 152}, {123, 154}, {103, 157}
-};
-
-static const NPoint kAsScene1907SymbolGroundHitPositions[] = {
- {275, 299}, {244, 299}, {238, 305},
- {221, 309}, {199, 310}, {168, 323},
- {145, 326}, {123, 328}, {103, 331}
-};
-
-static const NPoint kAsScene1907SymbolPluggedInDownPositions[] = {
- {275, 136}, {244, 156}, {238, 183},
- {221, 207}, {199, 228}, {168, 262},
- {145, 285}, {123, 307}, {103, 331}
-};
-
-static const uint32 kAsScene1907SymbolFileHashes[] = {
- 0x006A1034, 0x006A1010, 0x006A1814,
- 0x006A1016, 0x006A0014, 0x002A1014,
- 0x00EA1014, 0x206A1014, 0x046A1414
-};
-
-bool AsScene1907Symbol::_plugInFailed = false;
-int AsScene1907Symbol::_plugInTryCount = 0;
-
-AsScene1907Symbol::AsScene1907Symbol(NeverhoodEngine *vm, Scene1907 *parentScene, int elementIndex, int positionIndex)
- : AnimatedSprite(vm, 1000 - positionIndex), _parentScene(parentScene), _elementIndex(elementIndex), _isMoving(false) {
-
- _plugInFailed = false;
- _plugInTryCount = 0;
-
- if (getGlobalVar(V_STAIRS_PUZZLE_SOLVED)) {
- _isPluggedIn = true;
- _currPositionIndex = elementIndex;
- if (!getGlobalVar(V_STAIRS_DOWN)) {
- _x = kAsScene1907SymbolPluggedInPositions[_currPositionIndex].x;
- _y = kAsScene1907SymbolPluggedInPositions[_currPositionIndex].y;
- } else {
- _x = kAsScene1907SymbolPluggedInDownPositions[_currPositionIndex].x;
- _y = kAsScene1907SymbolPluggedInDownPositions[_currPositionIndex].y;
- }
- createSurface1(kAsScene1907SymbolFileHashes[_elementIndex], 1000 + _currPositionIndex);
- startAnimation(kAsScene1907SymbolFileHashes[_elementIndex], -1, -1);
- _newStickFrameIndex = STICK_LAST_FRAME;
- } else {
- _isPluggedIn = false;
- _currPositionIndex = positionIndex;
- loadSound(0, 0x74231924);
- loadSound(1, 0x36691914);
- loadSound(2, 0x5421D806);
- _parentScene->setPositionFree(_currPositionIndex, false);
- _x = kAsScene1907SymbolGroundPositions[_currPositionIndex].x;
- _y = kAsScene1907SymbolGroundPositions[_currPositionIndex].y;
- createSurface1(kAsScene1907SymbolFileHashes[_elementIndex], 1000 + _currPositionIndex);
- startAnimation(kAsScene1907SymbolFileHashes[_elementIndex], 0, -1);
- _newStickFrameIndex = 0;
- }
- _collisionBoundsOffset.set(0, 0, 80, 80);
- Sprite::updateBounds();
- SetUpdateHandler(&AnimatedSprite::update);
- SetMessageHandler(&AsScene1907Symbol::handleMessage);
-
-}
-
-void AsScene1907Symbol::update() {
- updateAnim();
- handleSpriteUpdate();
- updatePosition();
- if (_plugInFailed && _plugInTryCount == 0)
- _plugInFailed = false;
-}
-
-uint32 AsScene1907Symbol::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x1011:
- if (!_isPluggedIn && !_plugInFailed) {
- tryToPlugIn();
- messageResult = 1;
- } else
- messageResult = 0;
- break;
- }
- return messageResult;
-}
-
-uint32 AsScene1907Symbol::hmTryToPlugIn(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x3002:
- gotoNextState();
- break;
- }
- return messageResult;
-}
-
-void AsScene1907Symbol::suTryToPlugIn() {
- _currStep++;
- _x -= _deltaX;
- _y -= _deltaY;
- if (_currStep == 16) {
- _x -= _smallDeltaX;
- _y -= _smallDeltaY;
- SetSpriteUpdate(NULL);
- }
-}
-
-void AsScene1907Symbol::suFallOff() {
- if (_fallOffDelay != 0) {
- _fallOffDelay--;
- } else {
- _y += _yAccel;
- _yAccel += 8;
- if (_y >= kAsScene1907SymbolGroundHitPositions[_currPositionIndex].y) {
- _y = kAsScene1907SymbolGroundHitPositions[_currPositionIndex].y;
- stFallOffHitGround();
- }
- }
-}
-
-void AsScene1907Symbol::suFallOffHitGround() {
-
- if (_x == _someX - _xBreak)
- _x -= _smallDeltaX;
- else
- _x -= _deltaX;
-
- if (_y == kAsScene1907SymbolGroundHitPositions[_currPositionIndex].y) {
- _y -= _someY;
- }
-
- if (_currStep < 8) {
- _y -= _yAccel;
- _yAccel -= 4;
- if (_yAccel < 0)
- _yAccel = 0;
- } else if (_currStep < 15) {
- _y += _yAccel;
- _yAccel += 4;
- } else {
- _y = kAsScene1907SymbolGroundPositions[_newPositionIndex].y;
- cbFallOffHitGroundEvent();
- }
-
- _currStep++;
-}
-
-void AsScene1907Symbol::suMoveDown() {
- _y += _yIncr;
- if (_yIncr < 11)
- _yIncr++;
- if (_y >= kAsScene1907SymbolPluggedInDownPositions[_elementIndex].y) {
- _y = kAsScene1907SymbolPluggedInDownPositions[_elementIndex].y;
- _isMoving = false;
- SetSpriteUpdate(NULL);
- }
-}
-
-void AsScene1907Symbol::suMoveUp() {
- _y -= _yIncr;
- if (getGlobalVar(V_WALL_BROKEN)) {
- if (_y - (9 + (_elementIndex > 5 ? 31 : 0)) < kAsScene1907SymbolPluggedInPositions[_elementIndex].y)
- _yIncr--;
- else
- _yIncr++;
- } else
- _yIncr = 2;
- if (_yIncr > 9)
- _yIncr = 9;
- else if (_yIncr < 1)
- _yIncr = 1;
- if (_y < kAsScene1907SymbolPluggedInPositions[_elementIndex].y) {
- _y = kAsScene1907SymbolPluggedInPositions[_elementIndex].y;
- _isMoving = false;
- SetSpriteUpdate(NULL);
- }
-}
-
-void AsScene1907Symbol::tryToPlugIn() {
- _isPluggedIn = true;
- _plugInTryCount++;
- _newPositionIndex = _parentScene->getNextPosition();
- _parentScene->setPositionFree(_currPositionIndex, true);
- sendMessage(_parentScene, 0x1022, 1100 + _newPositionIndex);
- startAnimation(kAsScene1907SymbolFileHashes[_elementIndex], 0, -1);
- SetUpdateHandler(&AsScene1907Symbol::update);
- SetMessageHandler(&AsScene1907Symbol::hmTryToPlugIn);
- SetSpriteUpdate(&AsScene1907Symbol::suTryToPlugIn);
- _currStep = 0;
- _deltaX = (_x - kAsScene1907SymbolPluggedInPositions[_newPositionIndex].x) / 16;
- _smallDeltaX = _x - _deltaX * 16 - kAsScene1907SymbolPluggedInPositions[_newPositionIndex].x;
- _deltaY = (_y - kAsScene1907SymbolPluggedInPositions[_newPositionIndex].y) / 16;
- _smallDeltaY = _y - _deltaY * 16 - kAsScene1907SymbolPluggedInPositions[_newPositionIndex].y;
- if (_elementIndex == _newPositionIndex) {
- NextState(&AsScene1907Symbol::stPlugIn);
- } else {
- _plugInFailed = true;
- NextState(&AsScene1907Symbol::stPlugInFail);
- }
-}
-
-void AsScene1907Symbol::fallOff(int newPositionIndex, int fallOffDelay) {
- _isPluggedIn = false;
- _newPositionIndex = newPositionIndex;
- _fallOffDelay = fallOffDelay;
- _parentScene->setPositionFree(_newPositionIndex, false);
- _x = kAsScene1907SymbolPluggedInPositions[_currPositionIndex].x;
- _y = kAsScene1907SymbolPluggedInPositions[_currPositionIndex].y;
- _someX = _x;
- _someY = _y;
- startAnimation(kAsScene1907SymbolFileHashes[_elementIndex], -1, 0);
- _playBackwards = true;
- _newStickFrameIndex = STICK_LAST_FRAME;
- _currStep = 0;
- _yAccel = 1;
- SetUpdateHandler(&AsScene1907Symbol::update);
- SetMessageHandler(&AsScene1907Symbol::handleMessage);
- SetSpriteUpdate(&AsScene1907Symbol::suFallOff);
-}
-
-void AsScene1907Symbol::stFallOffHitGround() {
- playSound(1);
- sendMessage(_parentScene, 0x1022, 1000 + _newPositionIndex);
- Entity::_priority = 1000 - _newPositionIndex;
- _parentScene->removeCollisionSprite(this);
- _parentScene->addCollisionSprite(this);
- SetSpriteUpdate(&AsScene1907Symbol::suFallOffHitGround);
- NextState(&AsScene1907Symbol::cbFallOffHitGroundEvent);
- _newStickFrameIndex = 0;
- _currStep = 0;
- _yAccel = 30;
- _deltaX = (_x - kAsScene1907SymbolGroundPositions[_newPositionIndex].x) / 15;
- _xBreak = _deltaX * 15;
- _smallDeltaX = _x - kAsScene1907SymbolGroundPositions[_newPositionIndex].x - _xBreak;
- _someY = 0;
- if (kAsScene1907SymbolGroundHitPositions[_currPositionIndex].y > kAsScene1907SymbolGroundPositions[_newPositionIndex].y)
- _someY = kAsScene1907SymbolGroundHitPositions[_currPositionIndex].y - kAsScene1907SymbolGroundPositions[_newPositionIndex].y;
-}
-
-void AsScene1907Symbol::cbFallOffHitGroundEvent() {
- _currPositionIndex = _newPositionIndex;
- if (_plugInTryCount > 0)
- _plugInTryCount--;
- startAnimation(kAsScene1907SymbolFileHashes[_elementIndex], 0, -1);
- _newStickFrameIndex = 0;
- SetUpdateHandler(&AnimatedSprite::update);
- SetMessageHandler(&AsScene1907Symbol::handleMessage);
- SetSpriteUpdate(NULL);
- updateBounds();
- playSound(2);
-}
-
-void AsScene1907Symbol::stPlugIn() {
- playSound(0);
- _currPositionIndex = _newPositionIndex;
- stopAnimation();
- SetMessageHandler(&AsScene1907Symbol::handleMessage);
- SetSpriteUpdate(NULL);
- if (_elementIndex == 8)
- sendMessage(_parentScene, 0x2001, 0);
-}
-
-void AsScene1907Symbol::stPlugInFail() {
- _currPositionIndex = _newPositionIndex;
- stopAnimation();
- _parentScene->plugInFailed();
-}
-
-void AsScene1907Symbol::moveUp() {
- startAnimation(kAsScene1907SymbolFileHashes[_elementIndex], -1, -1);
- stopAnimation();
- SetMessageHandler(&AsScene1907Symbol::handleMessage);
- SetSpriteUpdate(&AsScene1907Symbol::suMoveUp);
- _yIncr = 1;
- _isMoving = true;
-}
-
-void AsScene1907Symbol::moveDown() {
- startAnimation(kAsScene1907SymbolFileHashes[_elementIndex], -1, -1);
- stopAnimation();
- SetMessageHandler(&AsScene1907Symbol::handleMessage);
- SetSpriteUpdate(&AsScene1907Symbol::suMoveDown);
- _yIncr = 4;
- _isMoving = true;
-}
-
-SsScene1907UpDownButton::SsScene1907UpDownButton(NeverhoodEngine *vm, Scene1907 *parentScene, AsScene1907Symbol *asScene1907Symbol)
- : StaticSprite(vm, 1400), _parentScene(parentScene), _asScene1907Symbol(asScene1907Symbol),
- _countdown1(0) {
-
- loadSprite(0x64516424, kSLFDefDrawOffset | kSLFDefPosition | kSLFDefCollisionBoundsOffset, 1400);
- setVisible(false);
- loadSound(0, 0x44061000);
- SetUpdateHandler(&SsScene1907UpDownButton::update);
- SetMessageHandler(&SsScene1907UpDownButton::handleMessage);
- if (getGlobalVar(V_STAIRS_PUZZLE_SOLVED)) {
- if (getGlobalVar(V_STAIRS_DOWN))
- setToDownPosition();
- else
- setToUpPosition();
- }
-}
-
-void SsScene1907UpDownButton::update() {
- updatePosition();
- if (_countdown1 != 0 && (--_countdown1 == 0)) {
- setVisible(false);
- sendMessage(_parentScene, 0x2000, 0);
- }
-}
-
-uint32 SsScene1907UpDownButton::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x1011:
- if (_countdown1 == 0 && !_asScene1907Symbol->isMoving() && getGlobalVar(V_STAIRS_PUZZLE_SOLVED)) {
- setVisible(true);
- _countdown1 = 4;
- updatePosition();
- playSound(0);
- }
- messageResult = 1;
- }
- return messageResult;
-}
-
-void SsScene1907UpDownButton::setToUpPosition() {
- _y = _spriteResource.getPosition().y;
- updateBounds();
- updatePosition();
-}
-
-void SsScene1907UpDownButton::setToDownPosition() {
- _y = _spriteResource.getPosition().y + 174;
- updateBounds();
- updatePosition();
-}
-
-AsScene1907WaterHint::AsScene1907WaterHint(NeverhoodEngine *vm)
- : AnimatedSprite(vm, 1400) {
-
- createSurface1(0x110A1061, 1500);
- _x = 320;
- _y = 240;
- startAnimation(0x110A1061, 0, -1);
- _newStickFrameIndex = 0;
- setVisible(false);
- _needRefresh = true;
- AnimatedSprite::updatePosition();
- SetUpdateHandler(&AsScene1907WaterHint::update);
- SetMessageHandler(&Sprite::handleMessage);
-}
-
-void AsScene1907WaterHint::update() {
- updateAnim();
- updatePosition();
-}
-
-uint32 AsScene1907WaterHint::hmShowing(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x3002:
- gotoNextState();
- break;
- }
- return messageResult;
-}
-
-void AsScene1907WaterHint::show() {
- setVisible(true);
- startAnimation(0x110A1061, 0, -1);
- SetMessageHandler(&AsScene1907WaterHint::hmShowing);
- NextState(&AsScene1907WaterHint::hide);
-}
-
-void AsScene1907WaterHint::hide() {
- stopAnimation();
- setVisible(false);
- SetMessageHandler(&Sprite::handleMessage);
-}
-
Scene1907::Scene1907(NeverhoodEngine *vm, Module *parentModule)
: Scene(vm, parentModule), _currMovingSymbolIndex(0), _pluggedInCount(0),
_moveDownCountdown(0), _moveUpCountdown(0), _countdown3(0), _hasPlugInFailed(false) {
@@ -589,13 +198,13 @@ void Scene1907::update() {
uint32 Scene1907::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x0001:
+ case NM_MOUSE_CLICK:
if ((param.asPoint().x <= 20 || param.asPoint().x >= 620) &&
!_hasPlugInFailed && _moveDownCountdown == 0 && _moveUpCountdown == 0 && _countdown3 == 0) {
leaveScene(0);
}
break;
- case 0x2000:
+ case NM_ANIMATION_UPDATE:
if (getGlobalVar(V_STAIRS_DOWN)) {
playSound(0);
for (int i = 0; i < 9; i++)
diff --git a/engines/neverhood/modules/module1900.h b/engines/neverhood/modules/module1900.h
index abb5eb1d87..d785c6f506 100644
--- a/engines/neverhood/modules/module1900.h
+++ b/engines/neverhood/modules/module1900.h
@@ -26,7 +26,6 @@
#include "neverhood/neverhood.h"
#include "neverhood/module.h"
#include "neverhood/scene.h"
-#include "neverhood/modules/module1200.h"
namespace Neverhood {
@@ -41,80 +40,14 @@ protected:
void updateScene();
};
-// Scene1901
-
class Scene1901 : public Scene {
public:
Scene1901(NeverhoodEngine *vm, Module *parentModule, int which);
};
-// Scene1907
-
-class Scene1907;
-
-class AsScene1907Symbol : public AnimatedSprite {
-public:
- AsScene1907Symbol(NeverhoodEngine *vm, Scene1907 *parentScene, int elementIndex, int positionIndex);
- void moveUp();
- void moveDown();
- void fallOff(int newPositionIndex, int fallOffDelay);
- bool isPluggedIn() { return _isPluggedIn; }
- bool isMoving() { return _isMoving; }
-protected:
- Scene1907 *_parentScene;
- int _elementIndex;
- int _currPositionIndex;
- int _newPositionIndex;
- bool _isPluggedIn;
- bool _isMoving;
- int _someX, _someY;
- int _xBreak;
- int _currStep;
- int _yAccel;
- int _yIncr;
- int _fallOffDelay;
- int _deltaX, _smallDeltaX;
- int _deltaY, _smallDeltaY;
- // Dumb, change if possible
- static bool _plugInFailed;
- static int _plugInTryCount;
- void update();
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- uint32 hmTryToPlugIn(int messageNum, const MessageParam &param, Entity *sender);
- void suTryToPlugIn();
- void suFallOff();
- void suFallOffHitGround();
- void suMoveDown();
- void suMoveUp();
- void tryToPlugIn();
- void stFallOffHitGround();
- void cbFallOffHitGroundEvent();
- void stPlugIn();
- void stPlugInFail();
-};
-
-class AsScene1907WaterHint : public AnimatedSprite {
-public:
- AsScene1907WaterHint(NeverhoodEngine *vm);
- void show();
-protected:
- void update();
- uint32 hmShowing(int messageNum, const MessageParam &param, Entity *sender);
- void hide();
-};
-
-class SsScene1907UpDownButton : public StaticSprite {
-public:
- SsScene1907UpDownButton(NeverhoodEngine *vm, Scene1907 *parentScene, AsScene1907Symbol *asScene1907Symbol);
- void setToUpPosition();
- void setToDownPosition();
-protected:
- Scene1907 *_parentScene;
- AsScene1907Symbol *_asScene1907Symbol;
- int _countdown1;
- void update();
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
+class AsScene1907Symbol;
+class SsScene1907UpDownButton;
+class AsScene1907WaterHint;
class Scene1907 : public Scene {
public:
diff --git a/engines/neverhood/modules/module1900_sprites.cpp b/engines/neverhood/modules/module1900_sprites.cpp
new file mode 100644
index 0000000000..9e43203def
--- /dev/null
+++ b/engines/neverhood/modules/module1900_sprites.cpp
@@ -0,0 +1,456 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public 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 "neverhood/modules/module1900.h"
+#include "neverhood/modules/module1900_sprites.h"
+
+namespace Neverhood {
+
+static const NPoint kAsScene1907SymbolGroundPositions[] = {
+ {160, 310}, { 90, 340}, {210, 335},
+ {210, 380}, {310, 340}, {290, 400},
+ {400, 375}, {370, 435}, {475, 415}
+};
+
+static const NPoint kAsScene1907SymbolPluggedInPositions[] = {
+ {275, 125}, {244, 125}, {238, 131},
+ {221, 135}, {199, 136}, {168, 149},
+ {145, 152}, {123, 154}, {103, 157}
+};
+
+static const NPoint kAsScene1907SymbolGroundHitPositions[] = {
+ {275, 299}, {244, 299}, {238, 305},
+ {221, 309}, {199, 310}, {168, 323},
+ {145, 326}, {123, 328}, {103, 331}
+};
+
+static const NPoint kAsScene1907SymbolPluggedInDownPositions[] = {
+ {275, 136}, {244, 156}, {238, 183},
+ {221, 207}, {199, 228}, {168, 262},
+ {145, 285}, {123, 307}, {103, 331}
+};
+
+static const uint32 kAsScene1907SymbolFileHashes[] = {
+ 0x006A1034, 0x006A1010, 0x006A1814,
+ 0x006A1016, 0x006A0014, 0x002A1014,
+ 0x00EA1014, 0x206A1014, 0x046A1414
+};
+
+bool AsScene1907Symbol::_plugInFailed = false;
+int AsScene1907Symbol::_plugInTryCount = 0;
+
+AsScene1907Symbol::AsScene1907Symbol(NeverhoodEngine *vm, Scene1907 *parentScene, int elementIndex, int positionIndex)
+ : AnimatedSprite(vm, 1000 - positionIndex), _parentScene(parentScene), _elementIndex(elementIndex), _isMoving(false) {
+
+ _plugInFailed = false;
+ _plugInTryCount = 0;
+
+ if (getGlobalVar(V_STAIRS_PUZZLE_SOLVED)) {
+ _isPluggedIn = true;
+ _currPositionIndex = elementIndex;
+ if (!getGlobalVar(V_STAIRS_DOWN)) {
+ _x = kAsScene1907SymbolPluggedInPositions[_currPositionIndex].x;
+ _y = kAsScene1907SymbolPluggedInPositions[_currPositionIndex].y;
+ } else {
+ _x = kAsScene1907SymbolPluggedInDownPositions[_currPositionIndex].x;
+ _y = kAsScene1907SymbolPluggedInDownPositions[_currPositionIndex].y;
+ }
+ createSurface1(kAsScene1907SymbolFileHashes[_elementIndex], 1000 + _currPositionIndex);
+ startAnimation(kAsScene1907SymbolFileHashes[_elementIndex], -1, -1);
+ _newStickFrameIndex = STICK_LAST_FRAME;
+ } else {
+ _isPluggedIn = false;
+ _currPositionIndex = positionIndex;
+ loadSound(0, 0x74231924);
+ loadSound(1, 0x36691914);
+ loadSound(2, 0x5421D806);
+ _parentScene->setPositionFree(_currPositionIndex, false);
+ _x = kAsScene1907SymbolGroundPositions[_currPositionIndex].x;
+ _y = kAsScene1907SymbolGroundPositions[_currPositionIndex].y;
+ createSurface1(kAsScene1907SymbolFileHashes[_elementIndex], 1000 + _currPositionIndex);
+ startAnimation(kAsScene1907SymbolFileHashes[_elementIndex], 0, -1);
+ _newStickFrameIndex = 0;
+ }
+ _collisionBoundsOffset.set(0, 0, 80, 80);
+ Sprite::updateBounds();
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsScene1907Symbol::handleMessage);
+
+}
+
+void AsScene1907Symbol::update() {
+ updateAnim();
+ handleSpriteUpdate();
+ updatePosition();
+ if (_plugInFailed && _plugInTryCount == 0)
+ _plugInFailed = false;
+}
+
+uint32 AsScene1907Symbol::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x1011:
+ if (!_isPluggedIn && !_plugInFailed) {
+ tryToPlugIn();
+ messageResult = 1;
+ } else
+ messageResult = 0;
+ break;
+ }
+ return messageResult;
+}
+
+uint32 AsScene1907Symbol::hmTryToPlugIn(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case NM_ANIMATION_STOP:
+ gotoNextState();
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene1907Symbol::suTryToPlugIn() {
+ _currStep++;
+ _x -= _deltaX;
+ _y -= _deltaY;
+ if (_currStep == 16) {
+ _x -= _smallDeltaX;
+ _y -= _smallDeltaY;
+ SetSpriteUpdate(NULL);
+ }
+}
+
+void AsScene1907Symbol::suFallOff() {
+ if (_fallOffDelay != 0) {
+ _fallOffDelay--;
+ } else {
+ _y += _yAccel;
+ _yAccel += 8;
+ if (_y >= kAsScene1907SymbolGroundHitPositions[_currPositionIndex].y) {
+ _y = kAsScene1907SymbolGroundHitPositions[_currPositionIndex].y;
+ stFallOffHitGround();
+ }
+ }
+}
+
+void AsScene1907Symbol::suFallOffHitGround() {
+
+ if (_x == _someX - _xBreak)
+ _x -= _smallDeltaX;
+ else
+ _x -= _deltaX;
+
+ if (_y == kAsScene1907SymbolGroundHitPositions[_currPositionIndex].y) {
+ _y -= _someY;
+ }
+
+ if (_currStep < 8) {
+ _y -= _yAccel;
+ _yAccel -= 4;
+ if (_yAccel < 0)
+ _yAccel = 0;
+ } else if (_currStep < 15) {
+ _y += _yAccel;
+ _yAccel += 4;
+ } else {
+ _y = kAsScene1907SymbolGroundPositions[_newPositionIndex].y;
+ cbFallOffHitGroundEvent();
+ }
+
+ _currStep++;
+}
+
+void AsScene1907Symbol::suMoveDown() {
+ _y += _yIncr;
+ if (_yIncr < 11)
+ _yIncr++;
+ if (_y >= kAsScene1907SymbolPluggedInDownPositions[_elementIndex].y) {
+ _y = kAsScene1907SymbolPluggedInDownPositions[_elementIndex].y;
+ _isMoving = false;
+ SetSpriteUpdate(NULL);
+ }
+}
+
+void AsScene1907Symbol::suMoveUp() {
+ _y -= _yIncr;
+ if (getGlobalVar(V_WALL_BROKEN)) {
+ if (_y - (9 + (_elementIndex > 5 ? 31 : 0)) < kAsScene1907SymbolPluggedInPositions[_elementIndex].y)
+ _yIncr--;
+ else
+ _yIncr++;
+ } else
+ _yIncr = 2;
+ if (_yIncr > 9)
+ _yIncr = 9;
+ else if (_yIncr < 1)
+ _yIncr = 1;
+ if (_y < kAsScene1907SymbolPluggedInPositions[_elementIndex].y) {
+ _y = kAsScene1907SymbolPluggedInPositions[_elementIndex].y;
+ _isMoving = false;
+ SetSpriteUpdate(NULL);
+ }
+}
+
+void AsScene1907Symbol::tryToPlugIn() {
+ _isPluggedIn = true;
+ _plugInTryCount++;
+ _newPositionIndex = _parentScene->getNextPosition();
+ _parentScene->setPositionFree(_currPositionIndex, true);
+ sendMessage(_parentScene, NM_PRIORITY_CHANGE, 1100 + _newPositionIndex);
+ startAnimation(kAsScene1907SymbolFileHashes[_elementIndex], 0, -1);
+ SetUpdateHandler(&AsScene1907Symbol::update);
+ SetMessageHandler(&AsScene1907Symbol::hmTryToPlugIn);
+ SetSpriteUpdate(&AsScene1907Symbol::suTryToPlugIn);
+ _currStep = 0;
+ _deltaX = (_x - kAsScene1907SymbolPluggedInPositions[_newPositionIndex].x) / 16;
+ _smallDeltaX = _x - _deltaX * 16 - kAsScene1907SymbolPluggedInPositions[_newPositionIndex].x;
+ _deltaY = (_y - kAsScene1907SymbolPluggedInPositions[_newPositionIndex].y) / 16;
+ _smallDeltaY = _y - _deltaY * 16 - kAsScene1907SymbolPluggedInPositions[_newPositionIndex].y;
+ if (_elementIndex == _newPositionIndex) {
+ NextState(&AsScene1907Symbol::stPlugIn);
+ } else {
+ _plugInFailed = true;
+ NextState(&AsScene1907Symbol::stPlugInFail);
+ }
+}
+
+void AsScene1907Symbol::fallOff(int newPositionIndex, int fallOffDelay) {
+ _isPluggedIn = false;
+ _newPositionIndex = newPositionIndex;
+ _fallOffDelay = fallOffDelay;
+ _parentScene->setPositionFree(_newPositionIndex, false);
+ _x = kAsScene1907SymbolPluggedInPositions[_currPositionIndex].x;
+ _y = kAsScene1907SymbolPluggedInPositions[_currPositionIndex].y;
+ _someX = _x;
+ _someY = _y;
+ startAnimation(kAsScene1907SymbolFileHashes[_elementIndex], -1, 0);
+ _playBackwards = true;
+ _newStickFrameIndex = STICK_LAST_FRAME;
+ _currStep = 0;
+ _yAccel = 1;
+ SetUpdateHandler(&AsScene1907Symbol::update);
+ SetMessageHandler(&AsScene1907Symbol::handleMessage);
+ SetSpriteUpdate(&AsScene1907Symbol::suFallOff);
+}
+
+void AsScene1907Symbol::stFallOffHitGround() {
+ playSound(1);
+ sendMessage(_parentScene, NM_PRIORITY_CHANGE, 1000 + _newPositionIndex);
+ Entity::_priority = 1000 - _newPositionIndex;
+ _parentScene->removeCollisionSprite(this);
+ _parentScene->addCollisionSprite(this);
+ SetSpriteUpdate(&AsScene1907Symbol::suFallOffHitGround);
+ NextState(&AsScene1907Symbol::cbFallOffHitGroundEvent);
+ _newStickFrameIndex = 0;
+ _currStep = 0;
+ _yAccel = 30;
+ _deltaX = (_x - kAsScene1907SymbolGroundPositions[_newPositionIndex].x) / 15;
+ _xBreak = _deltaX * 15;
+ _smallDeltaX = _x - kAsScene1907SymbolGroundPositions[_newPositionIndex].x - _xBreak;
+ _someY = 0;
+ if (kAsScene1907SymbolGroundHitPositions[_currPositionIndex].y > kAsScene1907SymbolGroundPositions[_newPositionIndex].y)
+ _someY = kAsScene1907SymbolGroundHitPositions[_currPositionIndex].y - kAsScene1907SymbolGroundPositions[_newPositionIndex].y;
+}
+
+void AsScene1907Symbol::cbFallOffHitGroundEvent() {
+ _currPositionIndex = _newPositionIndex;
+ if (_plugInTryCount > 0)
+ _plugInTryCount--;
+ startAnimation(kAsScene1907SymbolFileHashes[_elementIndex], 0, -1);
+ _newStickFrameIndex = 0;
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsScene1907Symbol::handleMessage);
+ SetSpriteUpdate(NULL);
+ updateBounds();
+ playSound(2);
+}
+
+void AsScene1907Symbol::stPlugIn() {
+ playSound(0);
+ _currPositionIndex = _newPositionIndex;
+ stopAnimation();
+ SetMessageHandler(&AsScene1907Symbol::handleMessage);
+ SetSpriteUpdate(NULL);
+ if (_elementIndex == 8)
+ sendMessage(_parentScene, 0x2001, 0);
+}
+
+void AsScene1907Symbol::stPlugInFail() {
+ _currPositionIndex = _newPositionIndex;
+ stopAnimation();
+ _parentScene->plugInFailed();
+}
+
+void AsScene1907Symbol::moveUp() {
+ startAnimation(kAsScene1907SymbolFileHashes[_elementIndex], -1, -1);
+ stopAnimation();
+ SetMessageHandler(&AsScene1907Symbol::handleMessage);
+ SetSpriteUpdate(&AsScene1907Symbol::suMoveUp);
+ _yIncr = 1;
+ _isMoving = true;
+}
+
+void AsScene1907Symbol::moveDown() {
+ startAnimation(kAsScene1907SymbolFileHashes[_elementIndex], -1, -1);
+ stopAnimation();
+ SetMessageHandler(&AsScene1907Symbol::handleMessage);
+ SetSpriteUpdate(&AsScene1907Symbol::suMoveDown);
+ _yIncr = 4;
+ _isMoving = true;
+}
+
+SsScene1907UpDownButton::SsScene1907UpDownButton(NeverhoodEngine *vm, Scene1907 *parentScene, AsScene1907Symbol *asScene1907Symbol)
+ : StaticSprite(vm, 1400), _parentScene(parentScene), _asScene1907Symbol(asScene1907Symbol),
+ _countdown1(0) {
+
+ loadSprite(0x64516424, kSLFDefDrawOffset | kSLFDefPosition | kSLFDefCollisionBoundsOffset, 1400);
+ setVisible(false);
+ loadSound(0, 0x44061000);
+ SetUpdateHandler(&SsScene1907UpDownButton::update);
+ SetMessageHandler(&SsScene1907UpDownButton::handleMessage);
+ if (getGlobalVar(V_STAIRS_PUZZLE_SOLVED)) {
+ if (getGlobalVar(V_STAIRS_DOWN))
+ setToDownPosition();
+ else
+ setToUpPosition();
+ }
+}
+
+void SsScene1907UpDownButton::update() {
+ updatePosition();
+ if (_countdown1 != 0 && (--_countdown1 == 0)) {
+ setVisible(false);
+ sendMessage(_parentScene, 0x2000, 0);
+ }
+}
+
+uint32 SsScene1907UpDownButton::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x1011:
+ if (_countdown1 == 0 && !_asScene1907Symbol->isMoving() && getGlobalVar(V_STAIRS_PUZZLE_SOLVED)) {
+ setVisible(true);
+ _countdown1 = 4;
+ updatePosition();
+ playSound(0);
+ }
+ messageResult = 1;
+ }
+ return messageResult;
+}
+
+void SsScene1907UpDownButton::setToUpPosition() {
+ _y = _spriteResource.getPosition().y;
+ updateBounds();
+ updatePosition();
+}
+
+void SsScene1907UpDownButton::setToDownPosition() {
+ _y = _spriteResource.getPosition().y + 174;
+ updateBounds();
+ updatePosition();
+}
+
+AsScene1907WaterHint::AsScene1907WaterHint(NeverhoodEngine *vm)
+ : AnimatedSprite(vm, 1400) {
+
+ createSurface1(0x110A1061, 1500);
+ _x = 320;
+ _y = 240;
+ startAnimation(0x110A1061, 0, -1);
+ _newStickFrameIndex = 0;
+ setVisible(false);
+ _needRefresh = true;
+ AnimatedSprite::updatePosition();
+ SetUpdateHandler(&AsScene1907WaterHint::update);
+ SetMessageHandler(&Sprite::handleMessage);
+}
+
+void AsScene1907WaterHint::update() {
+ updateAnim();
+ updatePosition();
+}
+
+uint32 AsScene1907WaterHint::hmShowing(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case NM_ANIMATION_STOP:
+ gotoNextState();
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene1907WaterHint::show() {
+ setVisible(true);
+ startAnimation(0x110A1061, 0, -1);
+ SetMessageHandler(&AsScene1907WaterHint::hmShowing);
+ NextState(&AsScene1907WaterHint::hide);
+}
+
+void AsScene1907WaterHint::hide() {
+ stopAnimation();
+ setVisible(false);
+ SetMessageHandler(&Sprite::handleMessage);
+}
+
+KmScene1901::KmScene1901(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
+ : Klaymen(vm, parentScene, x, y) {
+
+ // Empty
+}
+
+uint32 KmScene1901::xHandleMessage(int messageNum, const MessageParam &param) {
+ switch (messageNum) {
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case NM_KLAYMEN_STAND_IDLE:
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ gotoNextStateExt();
+ break;
+ case NM_KLAYMEN_TURN_TO_USE:
+ GotoState(&Klaymen::stTurnToUse);
+ break;
+ case NM_KLAYMEN_RETURN_FROM_USE:
+ GotoState(&Klaymen::stReturnFromUse);
+ break;
+ case 0x482D:
+ setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
+ gotoNextStateExt();
+ break;
+ case 0x483F:
+ startSpecialWalkRight(param.asInteger());
+ break;
+ case 0x4840:
+ startSpecialWalkLeft(param.asInteger());
+ break;
+ }
+ return 0;
+}
+
+} // End of namespace Neverhood
diff --git a/engines/neverhood/modules/module1900_sprites.h b/engines/neverhood/modules/module1900_sprites.h
new file mode 100644
index 0000000000..7e57b11618
--- /dev/null
+++ b/engines/neverhood/modules/module1900_sprites.h
@@ -0,0 +1,107 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef NEVERHOOD_MODULES_MODULE1900_SPRITES_H
+#define NEVERHOOD_MODULES_MODULE1900_SPRITES_H
+
+#include "neverhood/neverhood.h"
+#include "neverhood/module.h"
+#include "neverhood/scene.h"
+
+namespace Neverhood {
+
+class Scene1907;
+
+class AsScene1907Symbol : public AnimatedSprite {
+public:
+ AsScene1907Symbol(NeverhoodEngine *vm, Scene1907 *parentScene, int elementIndex, int positionIndex);
+ void moveUp();
+ void moveDown();
+ void fallOff(int newPositionIndex, int fallOffDelay);
+ bool isPluggedIn() { return _isPluggedIn; }
+ bool isMoving() { return _isMoving; }
+protected:
+ Scene1907 *_parentScene;
+ int _elementIndex;
+ int _currPositionIndex;
+ int _newPositionIndex;
+ bool _isPluggedIn;
+ bool _isMoving;
+ int _someX, _someY;
+ int _xBreak;
+ int _currStep;
+ int _yAccel;
+ int _yIncr;
+ int _fallOffDelay;
+ int _deltaX, _smallDeltaX;
+ int _deltaY, _smallDeltaY;
+ // Dumb, change if possible
+ static bool _plugInFailed;
+ static int _plugInTryCount;
+ void update();
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 hmTryToPlugIn(int messageNum, const MessageParam &param, Entity *sender);
+ void suTryToPlugIn();
+ void suFallOff();
+ void suFallOffHitGround();
+ void suMoveDown();
+ void suMoveUp();
+ void tryToPlugIn();
+ void stFallOffHitGround();
+ void cbFallOffHitGroundEvent();
+ void stPlugIn();
+ void stPlugInFail();
+};
+
+class AsScene1907WaterHint : public AnimatedSprite {
+public:
+ AsScene1907WaterHint(NeverhoodEngine *vm);
+ void show();
+protected:
+ void update();
+ uint32 hmShowing(int messageNum, const MessageParam &param, Entity *sender);
+ void hide();
+};
+
+class SsScene1907UpDownButton : public StaticSprite {
+public:
+ SsScene1907UpDownButton(NeverhoodEngine *vm, Scene1907 *parentScene, AsScene1907Symbol *asScene1907Symbol);
+ void setToUpPosition();
+ void setToDownPosition();
+protected:
+ Scene1907 *_parentScene;
+ AsScene1907Symbol *_asScene1907Symbol;
+ int _countdown1;
+ void update();
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class KmScene1901 : public Klaymen {
+public:
+ KmScene1901(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
+protected:
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+};
+
+} // End of namespace Neverhood
+
+#endif /* NEVERHOOD_MODULES_MODULE1900_SPRITES_H */
diff --git a/engines/neverhood/modules/module2000.cpp b/engines/neverhood/modules/module2000.cpp
index fcccdefbdd..ad18e65cdd 100644
--- a/engines/neverhood/modules/module2000.cpp
+++ b/engines/neverhood/modules/module2000.cpp
@@ -21,8 +21,7 @@
*/
#include "neverhood/modules/module2000.h"
-#include "neverhood/gamemodule.h"
-#include "neverhood/navigationscene.h"
+#include "neverhood/modules/module2000_sprites.h"
namespace Neverhood {
@@ -145,7 +144,7 @@ Scene2001::Scene2001(NeverhoodEngine *vm, Module *parentModule, int which)
uint32 Scene2001::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x2000:
+ case NM_ANIMATION_UPDATE:
if (param.asInteger()) {
setRectList(0x004B3680);
_klaymen->setKlaymenIdleTable3();
diff --git a/engines/neverhood/modules/module2000.h b/engines/neverhood/modules/module2000.h
index fa62f9a70e..8dc72c57dc 100644
--- a/engines/neverhood/modules/module2000.h
+++ b/engines/neverhood/modules/module2000.h
@@ -26,7 +26,6 @@
#include "neverhood/neverhood.h"
#include "neverhood/module.h"
#include "neverhood/scene.h"
-#include "neverhood/modules/module1200.h"
namespace Neverhood {
@@ -41,8 +40,6 @@ protected:
void updateScene();
};
-// Scene2001
-
class Scene2001 : public Scene {
public:
Scene2001(NeverhoodEngine *vm, Module *parentModule, int which);
diff --git a/engines/neverhood/modules/module2000_sprites.cpp b/engines/neverhood/modules/module2000_sprites.cpp
new file mode 100644
index 0000000000..35edd8e73f
--- /dev/null
+++ b/engines/neverhood/modules/module2000_sprites.cpp
@@ -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.
+ *
+ */
+
+#include "neverhood/modules/module2000_sprites.h"
+
+namespace Neverhood {
+
+KmScene2001::KmScene2001(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
+ : Klaymen(vm, parentScene, x, y) {
+
+ // Empty
+}
+
+uint32 KmScene2001::xHandleMessage(int messageNum, const MessageParam &param) {
+ uint32 messageResult = 0;
+ switch (messageNum) {
+ case NM_ANIMATION_UPDATE:
+ _isSittingInTeleporter = param.asInteger() != 0;
+ messageResult = 1;
+ break;
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case NM_KLAYMEN_STAND_IDLE:
+ if (_isSittingInTeleporter)
+ GotoState(&Klaymen::stSitIdleTeleporter);
+ else
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x4804:
+ if (param.asInteger() != 0) {
+ _destX = param.asInteger();
+ GotoState(&Klaymen::stWalkingFirst);
+ } else
+ GotoState(&Klaymen::stPeekWall);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ gotoNextStateExt();
+ break;
+ case NM_KLAYMEN_TURN_TO_USE:
+ if (_isSittingInTeleporter)
+ GotoState(&Klaymen::stTurnToUseInTeleporter);
+ break;
+ case NM_KLAYMEN_RETURN_FROM_USE:
+ if (_isSittingInTeleporter)
+ GotoState(&Klaymen::stReturnFromUseInTeleporter);
+ break;
+ case 0x4834:
+ GotoState(&Klaymen::stStepOver);
+ break;
+ case 0x4835:
+ sendMessage(_parentScene, 0x2000, 1);
+ _isSittingInTeleporter = true;
+ GotoState(&Klaymen::stSitInTeleporter);
+ break;
+ case 0x4836:
+ sendMessage(_parentScene, 0x2000, 0);
+ _isSittingInTeleporter = false;
+ GotoState(&Klaymen::stGetUpFromTeleporter);
+ break;
+ case 0x483D:
+ teleporterAppear(0xBE68CC54);
+ break;
+ case 0x483E:
+ teleporterDisappear(0x18AB4ED4);
+ break;
+ }
+ return messageResult;
+}
+
+} // End of namespace Neverhood
diff --git a/engines/neverhood/modules/module2000_sprites.h b/engines/neverhood/modules/module2000_sprites.h
new file mode 100644
index 0000000000..ca84aa73ca
--- /dev/null
+++ b/engines/neverhood/modules/module2000_sprites.h
@@ -0,0 +1,41 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef NEVERHOOD_MODULES_MODULE2000_SPRITES_H
+#define NEVERHOOD_MODULES_MODULE2000_SPRITES_H
+
+#include "neverhood/neverhood.h"
+#include "neverhood/module.h"
+#include "neverhood/scene.h"
+
+namespace Neverhood {
+
+class KmScene2001 : public Klaymen {
+public:
+ KmScene2001(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
+protected:
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+};
+
+} // End of namespace Neverhood
+
+#endif /* NEVERHOOD_MODULES_MODULE2000_SPRITES_H */
diff --git a/engines/neverhood/modules/module2100.cpp b/engines/neverhood/modules/module2100.cpp
index bcff9d9d1b..e95eb58420 100644
--- a/engines/neverhood/modules/module2100.cpp
+++ b/engines/neverhood/modules/module2100.cpp
@@ -20,9 +20,9 @@
*
*/
+#include "neverhood/modules/module1200_sprites.h"
#include "neverhood/modules/module2100.h"
-#include "neverhood/gamemodule.h"
-#include "neverhood/modules/module1200.h"
+#include "neverhood/modules/module2100_sprites.h"
namespace Neverhood {
@@ -74,125 +74,6 @@ void Module2100::updateScene() {
}
}
-// Scene2101
-
-AsScene2101Door::AsScene2101Door(NeverhoodEngine *vm, bool isOpen)
- : AnimatedSprite(vm, 1100) {
-
- createSurface(100, 328, 347);
- _x = 320;
- _y = 240;
- SetUpdateHandler(&AnimatedSprite::update);
- SetMessageHandler(&AsScene2101Door::handleMessage);
- if (isOpen) {
- startAnimation(0x0C202B9C, -1, -1);
- _newStickFrameIndex = STICK_LAST_FRAME;
- } else
- setVisible(false);
-}
-
-uint32 AsScene2101Door::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x3002:
- gotoNextState();
- break;
- case 0x4808:
- stOpenDoor();
- break;
- case 0x4809:
- stCloseDoor();
- break;
- }
- return messageResult;
-}
-
-void AsScene2101Door::stOpenDoor() {
- startAnimation(0x0C202B9C, 0, -1);
- _newStickFrameIndex = STICK_LAST_FRAME;
- setVisible(true);
- playSound(0, calcHash("fxDoorOpen32"));
-}
-
-void AsScene2101Door::stCloseDoor() {
- startAnimation(0xC222A8D4, 0, -1);
- _newStickFrameIndex = STICK_LAST_FRAME;
- setVisible(true);
- playSound(0, calcHash("fxDoorClose32"));
- NextState(&AsScene2101Door::stCloseDoorDone);
-}
-
-void AsScene2101Door::stCloseDoorDone() {
- stopAnimation();
- setVisible(false);
-}
-
-AsScene2101HitByDoorEffect::AsScene2101HitByDoorEffect(NeverhoodEngine *vm, Sprite *klaymen)
- : AnimatedSprite(vm, 1400), _klaymen(klaymen) {
-
- SetUpdateHandler(&AnimatedSprite::update);
- SetMessageHandler(&AsScene2101HitByDoorEffect::handleMessage);
- createSurface(1200, 88, 165);
- setVisible(false);
-}
-
-uint32 AsScene2101HitByDoorEffect::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x2001:
- _x = _klaymen->getX();
- _y = _klaymen->getY() - 132;
- startAnimation(0x0422255A, 0, -1);
- setVisible(true);
- break;
- case 0x3002:
- stopAnimation();
- setVisible(false);
- break;
- }
- return messageResult;
-}
-
-SsCommonFloorButton::SsCommonFloorButton(NeverhoodEngine *vm, Scene *parentScene, uint32 fileHash1, uint32 fileHash2, int surfacePriority, uint32 soundFileHash)
- : StaticSprite(vm, 1100), _parentScene(parentScene), _countdown(0),
- _fileHash1(fileHash1), _fileHash2(fileHash2), _soundFileHash(soundFileHash) {
-
- SetUpdateHandler(&SsCommonFloorButton::update);
- SetMessageHandler(&SsCommonFloorButton::handleMessage);
- if (_soundFileHash == 0)
- _soundFileHash = 0x44141000;
- createSurface(1010, 61, 30);
- if (_fileHash1)
- loadSprite(_fileHash1, kSLFDefDrawOffset | kSLFDefPosition);
- else
- setVisible(false);
-}
-
-void SsCommonFloorButton::update() {
- if (_countdown != 0 && (--_countdown == 0)) {
- sendMessage(_parentScene, 0x1022, 1010);
- if (_fileHash1)
- loadSprite(_fileHash1, kSLFDefDrawOffset | kSLFDefPosition);
- else
- setVisible(false);
- }
-}
-
-uint32 SsCommonFloorButton::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x480B:
- sendMessage(_parentScene, 0x480B, 0);
- setVisible(true);
- sendMessage(_parentScene, 0x1022, 990);
- loadSprite(_fileHash2, kSLFDefDrawOffset | kSLFDefPosition);
- _countdown = 16;
- playSound(0, _soundFileHash);
- break;
- }
- return messageResult;
-}
-
Scene2101::Scene2101(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule) {
@@ -266,7 +147,7 @@ void Scene2101::update() {
if (_countdown1 != 0) {
if (_doorStatus == 2) {
if (--_countdown1 == 0) {
- sendMessage(_asDoor, 0x4809, 0);
+ sendMessage(_asDoor, NM_KLAYMEN_CLOSE_DOOR, 0);
_doorStatus = 1;
}
} else {
@@ -274,12 +155,12 @@ void Scene2101::update() {
_canAcceptInput = false;
if (--_countdown1 == 0) {
if (_klaymen->getX() < 480) {
- sendMessage(_asDoor, 0x4809, 0);
+ sendMessage(_asDoor, NM_KLAYMEN_CLOSE_DOOR, 0);
_doorStatus = 1;
} else if (_klaymen->getX() >= 480 && _klaymen->getX() <= 575) {
_klaymen->setDoDeltaX(0);
setMessageList2(0x004B8F48);
- sendMessage(_asDoor, 0x4809, 0);
+ sendMessage(_asDoor, NM_KLAYMEN_CLOSE_DOOR, 0);
sendMessage(_asHitByDoorEffect, 0x2001, 0);
_doorStatus = 1;
}
@@ -293,7 +174,7 @@ void Scene2101::update() {
uint32 Scene2101::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0x02144CB1)
sendEntityMessage(_klaymen, 0x1014, _ssFloorButton);
else if (param.asInteger() == 0x21E64A00) {
@@ -304,7 +185,7 @@ uint32 Scene2101::handleMessage(int messageNum, const MessageParam &param, Entit
} else if (param.asInteger() == 0x41442820)
cancelMessageList();
break;
- case 0x2000:
+ case NM_ANIMATION_UPDATE:
if (param.asInteger() != 0) {
setRectList(0x004B9008);
_klaymen->setKlaymenIdleTable3();
@@ -315,7 +196,7 @@ uint32 Scene2101::handleMessage(int messageNum, const MessageParam &param, Entit
break;
case 0x480B:
if (sender == _ssFloorButton && _doorStatus == 1) {
- sendMessage(_asDoor, 0x4808, 0);
+ sendMessage(_asDoor, NM_KLAYMEN_OPEN_DOOR, 0);
_doorStatus = 0;
_countdown1 = 90;
}
diff --git a/engines/neverhood/modules/module2100.h b/engines/neverhood/modules/module2100.h
index d76bed0780..c5256434d9 100644
--- a/engines/neverhood/modules/module2100.h
+++ b/engines/neverhood/modules/module2100.h
@@ -40,38 +40,6 @@ protected:
void updateScene();
};
-// Scene1901
-
-class AsScene2101Door : public AnimatedSprite {
-public:
- AsScene2101Door(NeverhoodEngine *vm, bool isOpen);
-protected:
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- void stOpenDoor();
- void stCloseDoor();
- void stCloseDoorDone();
-};
-
-class AsScene2101HitByDoorEffect : public AnimatedSprite {
-public:
- AsScene2101HitByDoorEffect(NeverhoodEngine *vm, Sprite *klaymen);
-protected:
- Sprite *_klaymen;
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
-
-class SsCommonFloorButton : public StaticSprite {
-public:
- SsCommonFloorButton(NeverhoodEngine *vm, Scene *parentScene, uint32 fileHash1, uint32 fileHash2, int surfacePriority, uint32 soundFileHash);
-protected:
- Scene *_parentScene;
- uint32 _soundFileHash;
- uint32 _fileHash1, _fileHash2;
- int16 _countdown;
- void update();
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
-
class Scene2101 : public Scene {
public:
Scene2101(NeverhoodEngine *vm, Module *parentModule, int which);
diff --git a/engines/neverhood/modules/module2100_sprites.cpp b/engines/neverhood/modules/module2100_sprites.cpp
new file mode 100644
index 0000000000..f43c0afed5
--- /dev/null
+++ b/engines/neverhood/modules/module2100_sprites.cpp
@@ -0,0 +1,260 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public 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 "neverhood/modules/module2100_sprites.h"
+
+namespace Neverhood {
+
+AsScene2101Door::AsScene2101Door(NeverhoodEngine *vm, bool isOpen)
+ : AnimatedSprite(vm, 1100) {
+
+ createSurface(100, 328, 347);
+ _x = 320;
+ _y = 240;
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsScene2101Door::handleMessage);
+ if (isOpen) {
+ startAnimation(0x0C202B9C, -1, -1);
+ _newStickFrameIndex = STICK_LAST_FRAME;
+ } else
+ setVisible(false);
+}
+
+uint32 AsScene2101Door::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case NM_ANIMATION_STOP:
+ gotoNextState();
+ break;
+ case NM_KLAYMEN_OPEN_DOOR:
+ stOpenDoor();
+ break;
+ case NM_KLAYMEN_CLOSE_DOOR:
+ stCloseDoor();
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene2101Door::stOpenDoor() {
+ startAnimation(0x0C202B9C, 0, -1);
+ _newStickFrameIndex = STICK_LAST_FRAME;
+ setVisible(true);
+ playSound(0, calcHash("fxDoorOpen32"));
+}
+
+void AsScene2101Door::stCloseDoor() {
+ startAnimation(0xC222A8D4, 0, -1);
+ _newStickFrameIndex = STICK_LAST_FRAME;
+ setVisible(true);
+ playSound(0, calcHash("fxDoorClose32"));
+ NextState(&AsScene2101Door::stCloseDoorDone);
+}
+
+void AsScene2101Door::stCloseDoorDone() {
+ stopAnimation();
+ setVisible(false);
+}
+
+AsScene2101HitByDoorEffect::AsScene2101HitByDoorEffect(NeverhoodEngine *vm, Sprite *klaymen)
+ : AnimatedSprite(vm, 1400), _klaymen(klaymen) {
+
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsScene2101HitByDoorEffect::handleMessage);
+ createSurface(1200, 88, 165);
+ setVisible(false);
+}
+
+uint32 AsScene2101HitByDoorEffect::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x2001:
+ _x = _klaymen->getX();
+ _y = _klaymen->getY() - 132;
+ startAnimation(0x0422255A, 0, -1);
+ setVisible(true);
+ break;
+ case NM_ANIMATION_STOP:
+ stopAnimation();
+ setVisible(false);
+ break;
+ }
+ return messageResult;
+}
+
+SsCommonFloorButton::SsCommonFloorButton(NeverhoodEngine *vm, Scene *parentScene, uint32 fileHash1, uint32 fileHash2, int surfacePriority, uint32 soundFileHash)
+ : StaticSprite(vm, 1100), _parentScene(parentScene), _countdown(0),
+ _fileHash1(fileHash1), _fileHash2(fileHash2), _soundFileHash(soundFileHash) {
+
+ SetUpdateHandler(&SsCommonFloorButton::update);
+ SetMessageHandler(&SsCommonFloorButton::handleMessage);
+ if (_soundFileHash == 0)
+ _soundFileHash = 0x44141000;
+ createSurface(1010, 61, 30);
+ if (_fileHash1)
+ loadSprite(_fileHash1, kSLFDefDrawOffset | kSLFDefPosition);
+ else
+ setVisible(false);
+}
+
+void SsCommonFloorButton::update() {
+ if (_countdown != 0 && (--_countdown == 0)) {
+ sendMessage(_parentScene, NM_PRIORITY_CHANGE, 1010);
+ if (_fileHash1)
+ loadSprite(_fileHash1, kSLFDefDrawOffset | kSLFDefPosition);
+ else
+ setVisible(false);
+ }
+}
+
+uint32 SsCommonFloorButton::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x480B:
+ sendMessage(_parentScene, 0x480B, 0);
+ setVisible(true);
+ sendMessage(_parentScene, NM_PRIORITY_CHANGE, 990);
+ loadSprite(_fileHash2, kSLFDefDrawOffset | kSLFDefPosition);
+ _countdown = 16;
+ playSound(0, _soundFileHash);
+ break;
+ }
+ return messageResult;
+}
+
+KmScene2101::KmScene2101(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
+ : Klaymen(vm, parentScene, x, y) {
+
+ // Empty
+}
+
+uint32 KmScene2101::xHandleMessage(int messageNum, const MessageParam &param) {
+ uint32 messageResult = 0;
+ switch (messageNum) {
+ case NM_ANIMATION_UPDATE:
+ _isSittingInTeleporter = param.asInteger() != 0;
+ messageResult = 1;
+ break;
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case NM_KLAYMEN_STAND_IDLE:
+ if (_isSittingInTeleporter)
+ GotoState(&Klaymen::stSitIdleTeleporter);
+ else
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x4811:
+ GotoState(&KmScene2101::stHitByDoor);
+ break;
+ case NM_KLAYMEN_PICKUP:
+ if (param.asInteger() == 2)
+ GotoState(&Klaymen::stPickUpNeedle);
+ else if (param.asInteger() == 1)
+ GotoState(&Klaymen::stPickUpTube);
+ else
+ GotoState(&Klaymen::stPickUpGeneric);
+ break;
+ case NM_KLAYMEN_PRESS_BUTTON:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stPressButton);
+ else if (param.asInteger() == 2)
+ GotoState(&Klaymen::stPressFloorButton);
+ else
+ GotoState(&Klaymen::stPressButtonSide);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ gotoNextStateExt();
+ break;
+ case 0x481B:
+ if (param.asPoint().y != 0)
+ startWalkToXDistance(param.asPoint().y, param.asPoint().x);
+ else
+ startWalkToAttachedSpriteXDistance(param.asPoint().x);
+ break;
+ case NM_KLAYMEN_TURN_TO_USE:
+ if (_isSittingInTeleporter)
+ GotoState(&Klaymen::stTurnToUseInTeleporter);
+ break;
+ case NM_KLAYMEN_RETURN_FROM_USE:
+ if (_isSittingInTeleporter)
+ GotoState(&Klaymen::stReturnFromUseInTeleporter);
+ break;
+ case 0x4834:
+ GotoState(&Klaymen::stStepOver);
+ break;
+ case 0x4835:
+ sendMessage(_parentScene, 0x2000, 1);
+ _isSittingInTeleporter = true;
+ GotoState(&Klaymen::stSitInTeleporter);
+ break;
+ case 0x4836:
+ sendMessage(_parentScene, 0x2000, 0);
+ _isSittingInTeleporter = false;
+ GotoState(&Klaymen::stGetUpFromTeleporter);
+ break;
+ case 0x483D:
+ teleporterAppear(0xFF290E30);
+ break;
+ case 0x483E:
+ teleporterDisappear(0x9A28CA1C);
+ break;
+ }
+ return messageResult;
+}
+
+uint32 KmScene2101::hmHitByDoor(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = hmLowLevelAnimation(messageNum, param, sender);
+ int16 speedUpFrameIndex;
+ switch (messageNum) {
+ case 0x1008:
+ speedUpFrameIndex = getFrameIndex(kKlaymenSpeedUpHash);
+ if (_currFrameIndex < speedUpFrameIndex) {
+ startAnimation(0x35AA8059, speedUpFrameIndex, -1);
+ _y = 438;
+ }
+ messageResult = 0;
+ break;
+ case NM_ANIMATION_START:
+ if (param.asInteger() == 0x1A1A0785) {
+ playSound(0, 0x40F0A342);
+ } else if (param.asInteger() == 0x60428026) {
+ playSound(0, 0x40608A59);
+ }
+ break;
+ }
+ return messageResult;
+}
+
+void KmScene2101::stHitByDoor() {
+ _busyStatus = 1;
+ _acceptInput = false;
+ startAnimation(0x35AA8059, 0, -1);
+ SetUpdateHandler(&Klaymen::update);
+ SetMessageHandler(&KmScene2101::hmHitByDoor);
+ SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
+ playSound(0, 0x402E82D4);
+}
+
+} // End of namespace Neverhood
diff --git a/engines/neverhood/modules/module2100_sprites.h b/engines/neverhood/modules/module2100_sprites.h
new file mode 100644
index 0000000000..85a6b9f27d
--- /dev/null
+++ b/engines/neverhood/modules/module2100_sprites.h
@@ -0,0 +1,75 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public 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 NEVERHOOD_MODULES_MODULE2100_SPRITES_H
+#define NEVERHOOD_MODULES_MODULE2100_SPRITES_H
+
+#include "neverhood/neverhood.h"
+#include "neverhood/module.h"
+#include "neverhood/scene.h"
+
+namespace Neverhood {
+
+class AsScene2101Door : public AnimatedSprite {
+public:
+ AsScene2101Door(NeverhoodEngine *vm, bool isOpen);
+protected:
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ void stOpenDoor();
+ void stCloseDoor();
+ void stCloseDoorDone();
+};
+
+class AsScene2101HitByDoorEffect : public AnimatedSprite {
+public:
+ AsScene2101HitByDoorEffect(NeverhoodEngine *vm, Sprite *klaymen);
+protected:
+ Sprite *_klaymen;
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class SsCommonFloorButton : public StaticSprite {
+public:
+ SsCommonFloorButton(NeverhoodEngine *vm, Scene *parentScene, uint32 fileHash1, uint32 fileHash2, int surfacePriority, uint32 soundFileHash);
+protected:
+ Scene *_parentScene;
+ uint32 _soundFileHash;
+ uint32 _fileHash1, _fileHash2;
+ int16 _countdown;
+ void update();
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class KmScene2101 : public Klaymen {
+public:
+ KmScene2101(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
+
+ void stHitByDoor();
+ uint32 hmHitByDoor(int messageNum, const MessageParam &param, Entity *sender);
+
+protected:
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+};
+
+} // End of namespace Neverhood
+
+#endif /* NEVERHOOD_MODULES_MODULE2100_SPRITES_H */
diff --git a/engines/neverhood/modules/module2200.cpp b/engines/neverhood/modules/module2200.cpp
index 99f21cad74..f1d5d2854d 100644
--- a/engines/neverhood/modules/module2200.cpp
+++ b/engines/neverhood/modules/module2200.cpp
@@ -20,11 +20,14 @@
*
*/
-#include "neverhood/modules/module2200.h"
-#include "neverhood/modules/module1000.h"
-#include "neverhood/modules/module1200.h"
-#include "neverhood/gamemodule.h"
+#include "common/config-manager.h"
+
#include "neverhood/diskplayerscene.h"
+#include "neverhood/gamemodule.h"
+#include "neverhood/modules/module1000_sprites.h"
+#include "neverhood/modules/module1200_sprites.h"
+#include "neverhood/modules/module2200.h"
+#include "neverhood/modules/module2200_sprites.h"
namespace Neverhood {
@@ -45,6 +48,18 @@ Module2200::~Module2200() {
}
void Module2200::createScene(int sceneNum, int which) {
+ if (sceneNum == 46 && ConfMan.getBool("skiphallofrecordsscenes")) {
+ // Skip the whole Hall of Records storyboard scenes,
+ // and teleport to the last scene
+ sceneNum = 41;
+ }
+
+ if (sceneNum == 40 && ConfMan.getBool("skiphallofrecordsscenes")) {
+ // Skip the whole Hall of Records storyboard scenes,
+ // and teleport back to the first scene
+ sceneNum = 5;
+ }
+
debug(1, "Module2200::createScene(%d, %d)", sceneNum, which);
_sceneNum = sceneNum;
switch (_sceneNum) {
@@ -445,95 +460,6 @@ void Module2200::createHallOfRecordsScene(int which, uint32 hallOfRecordsInfoId)
_childObject = new HallOfRecordsScene(_vm, this, which, hallOfRecordsInfoId);
}
-// Scene2201
-
-AsScene2201CeilingFan::AsScene2201CeilingFan(NeverhoodEngine *vm)
- : AnimatedSprite(vm, 1100) {
-
- _x = 403;
- _y = 259;
- createSurface(100, 233, 96);
- startAnimation(0x8600866, 0, -1);
- SetUpdateHandler(&AnimatedSprite::update);
-}
-
-AsScene2201Door::AsScene2201Door(NeverhoodEngine *vm, Klaymen *klaymen, Sprite *ssDoorLight, bool isOpen)
- : AnimatedSprite(vm, 1100), _klaymen(klaymen), _ssDoorLight(ssDoorLight), _countdown(0), _isOpen(isOpen) {
-
- _x = 408;
- _y = 290;
- createSurface(900, 63, 266);
- SetUpdateHandler(&AsScene2201Door::update);
- SetMessageHandler(&AsScene2201Door::handleMessage);
- if (_isOpen) {
- startAnimation(0xE2CB0412, -1, -1);
- _countdown = 48;
- _newStickFrameIndex = STICK_LAST_FRAME;
- } else {
- startAnimation(0xE2CB0412, 0, -1);
- _newStickFrameIndex = 0;
- _ssDoorLight->setVisible(false);
- }
-}
-
-void AsScene2201Door::update() {
- if (_countdown != 0 && _isOpen && (--_countdown == 0))
- stCloseDoor();
- AnimatedSprite::update();
-}
-
-uint32 AsScene2201Door::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x100D:
- if (param.asInteger() == 0x11001090) {
- if (_isOpen)
- _ssDoorLight->setVisible(true);
- } else if (param.asInteger() == 0x11283090) {
- if (!_isOpen)
- _ssDoorLight->setVisible(false);
- }
- break;
- case 0x2000:
- if (_isOpen)
- _countdown = 144;
- messageResult = _isOpen ? 1 : 0;
- break;
- case 0x3002:
- gotoNextState();
- break;
- case 0x4808:
- _countdown = 144;
- if (!_isOpen)
- stOpenDoor();
- break;
- }
- return messageResult;
-}
-
-void AsScene2201Door::stOpenDoor() {
- _isOpen = true;
- startAnimation(0xE2CB0412, 0, -1);
- _newStickFrameIndex = STICK_LAST_FRAME;
- playSound(0, calcHash("fxDoorOpen33"));
-}
-
-void AsScene2201Door::stCloseDoor() {
- _isOpen = false;
- startAnimation(0xE2CB0412, -1, -1);
- _playBackwards = true;
- _newStickFrameIndex = 0;
- playSound(0, calcHash("fxDoorClose33"));
-}
-
-SsScene2201PuzzleCube::SsScene2201PuzzleCube(NeverhoodEngine *vm, uint32 positionIndex, uint32 cubeIndex)
- : StaticSprite(vm, 900) {
-
- createSurface(100, 16, 16);
- loadSprite(kSsScene2201PuzzleCubeFileHashes[cubeIndex], kSLFCenteredDrawOffset | kSLFSetPosition, 0,
- kSsScene2201PuzzleCubePoints[positionIndex].x, kSsScene2201PuzzleCubePoints[positionIndex].y);
-}
-
Scene2201::Scene2201(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule), _isSoundPlaying(false) {
@@ -625,7 +551,7 @@ void Scene2201::update() {
uint32 Scene2201::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0x402064D8)
sendEntityMessage(_klaymen, 0x1014, _ssDoorButton);
else if (param.asInteger() == 0x35803198) {
@@ -649,7 +575,7 @@ uint32 Scene2201::handleMessage(int messageNum, const MessageParam &param, Entit
break;
case 0x480B:
if (sender == _ssDoorButton)
- sendMessage(_asDoor, 0x4808, 0);
+ sendMessage(_asDoor, NM_KLAYMEN_OPEN_DOOR, 0);
break;
case 0x4826:
if (sender == _asTape) {
@@ -661,215 +587,6 @@ uint32 Scene2201::handleMessage(int messageNum, const MessageParam &param, Entit
return 0;
}
-static const NPoint kSsScene2202PuzzleCubePoints[] = {
- {196, 105}, {323, 102}, {445, 106},
- {192, 216}, {319, 220}, {446, 216},
- {188, 320}, {319, 319}, {443, 322}
-};
-
-static const uint32 kSsScene2202PuzzleCubeFileHashes1[] = {
- 0xA500800C, 0x2182910C, 0x2323980C,
- 0x23049084, 0x21008080, 0x2303900C,
- 0x6120980C, 0x2504D808
-};
-
-static const uint32 kSsScene2202PuzzleCubeFileHashes2[] = {
- 0x0AAD8080, 0x0A290291, 0x0A2BA398,
- 0x822B8490, 0x86298080, 0x0A2B8390,
- 0x0A69A098, 0x0E2D84D8
-};
-
-SsScene2202PuzzleCube::SsScene2202PuzzleCube(NeverhoodEngine *vm, Scene *parentScene, int16 cubePosition, int16 cubeSymbol)
- : StaticSprite(vm, 900), _parentScene(parentScene), _cubeSymbol(cubeSymbol), _cubePosition(cubePosition), _isMoving(false) {
-
- int surfacePriority;
-
- SetUpdateHandler(&SsScene2202PuzzleCube::update);
- SetMessageHandler(&SsScene2202PuzzleCube::handleMessage);
- if (_cubePosition >= 0 && _cubePosition <= 2)
- surfacePriority = 100;
- else if (_cubePosition >= 3 && _cubePosition <= 5)
- surfacePriority = 300;
- else
- surfacePriority = 500;
- debug(1, "TODO: Unused SurfacePriority: %d", surfacePriority);
- loadSprite(kSsScene2202PuzzleCubeFileHashes2[_cubeSymbol], kSLFCenteredDrawOffset | kSLFSetPosition | kSLFDefCollisionBoundsOffset, 0,
- kSsScene2202PuzzleCubePoints[_cubePosition].x, kSsScene2202PuzzleCubePoints[_cubePosition].y);
- loadSound(0, 0x40958621);
- loadSound(1, 0x51108241);
-}
-
-void SsScene2202PuzzleCube::update() {
- handleSpriteUpdate();
- updatePosition();
-}
-
-uint32 SsScene2202PuzzleCube::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x1011:
- if (!_isMoving && !getGlobalVar(V_TILE_PUZZLE_SOLVED))
- sendMessage(_parentScene, 0x2000, _cubePosition);
- messageResult = 1;
- break;
- case 0x2001:
- _isMoving = true;
- moveCube(param.asInteger());
- break;
- }
- return messageResult;
-}
-
-void SsScene2202PuzzleCube::suMoveCubeX() {
-
- bool done = false;
-
- if (_counterDirection) {
- if (_counter > 2)
- _counter -= 2;
- } else {
- if (_counter < 20)
- _counter += 2;
- }
-
- for (int16 i = 0; i < _counter; i++) {
- _x += _xIncr;
- _errValue += _yDelta;
- if (_errValue >= _xDelta) {
- _errValue -= _xDelta;
- _y += _yIncr;
- }
- if (_x == _newX && _y == _newY) {
- done = true;
- break;
- }
- if (_x == _xFlagPos)
- _counterDirection = true;
- }
-
- if (done)
- stopMoving();
-
- updateBounds();
-
-}
-
-void SsScene2202PuzzleCube::suMoveCubeY() {
-
- bool done = false;
-
- if (_counterDirection) {
- if (_counter > 2)
- _counter -= 2;
- } else {
- if (_counter < 20)
- _counter += 2;
- }
-
- for (int16 i = 0; i < _counter; i++) {
- _y += _yIncr;
- _errValue += _xDelta;
- if (_errValue >= _yDelta) {
- _errValue -= _yDelta;
- _x += _xIncr;
- }
- if (_x == _newX && _y == _newY) {
- done = true;
- break;
- }
- if (_x == _xFlagPos)
- _counterDirection = true;
- }
-
- if (done)
- stopMoving();
-
- updateBounds();
-
-}
-
-void SsScene2202PuzzleCube::moveCube(int16 newCubePosition) {
-
- loadSprite(kSsScene2202PuzzleCubeFileHashes1[_cubeSymbol], kSLFCenteredDrawOffset);
-
- setSubVar(VA_CUBE_POSITIONS, _cubePosition, (uint32)-1);
- setSubVar(VA_CUBE_POSITIONS, newCubePosition, (uint32)_cubeSymbol);
-
- _cubePosition = newCubePosition;
- _errValue = 0;
- _counterDirection = false;
- _counter = 0;
- _newX = kSsScene2202PuzzleCubePoints[newCubePosition].x;
- _newY = kSsScene2202PuzzleCubePoints[newCubePosition].y;
-
- if (_x == _newX && _y == _newY)
- return;
-
- if (_x <= _newX) {
- if (_y <= _newY) {
- _xDelta = _newX - _x;
- _yDelta = _newY - _y;
- _xIncr = 1;
- _yIncr = 1;
- } else {
- _xDelta = _newX - _x;
- _yDelta = _y - _newY;
- _xIncr = 1;
- _yIncr = -1;
- }
- } else {
- if (_y <= _newY) {
- _xDelta = _x - _newX;
- _yDelta = _newY - _y;
- _xIncr = -1;
- _yIncr = 1;
- } else {
- _xDelta = _x - _newX;
- _yDelta = _y - _newY;
- _xIncr = -1;
- _yIncr = -1;
- }
- }
-
- if (_xDelta > _yDelta) {
- SetSpriteUpdate(&SsScene2202PuzzleCube::suMoveCubeX);
- if (_xIncr > 0) {
- if (_newX - _x >= 180)
- _xFlagPos = _newX - 90;
- else
- _xFlagPos = _x + _newX / 2;
- } else {
- if (_x - _newX >= 180)
- _xFlagPos = _x + 90;
- else
- _xFlagPos = _x / 2 + _newX;
- }
- playSound(0);
- } else {
- SetSpriteUpdate(&SsScene2202PuzzleCube::suMoveCubeY);
- if (_yIncr > 0) {
- if (_newY - _y >= 180)
- _xFlagPos = _newY - 90;
- else
- _xFlagPos = _y + _newY / 2;
- } else {
- if (_y - _newY >= 180)
- _xFlagPos = _y + 90;
- else
- _xFlagPos = _y / 2 + _newY;
- }
- playSound(1);
- }
-
-}
-
-void SsScene2202PuzzleCube::stopMoving() {
- loadSprite(kSsScene2202PuzzleCubeFileHashes2[_cubeSymbol], kSLFCenteredDrawOffset);
- SetSpriteUpdate(NULL);
- _isMoving = false;
- sendMessage(_parentScene, 0x2002, _cubePosition);
-}
-
Scene2202::Scene2202(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule), _isSolved(false), _leaveScene(false), _isCubeMoving(false),
_ssMovingCube(NULL), _ssDoneMovingCube(NULL) {
@@ -945,15 +662,15 @@ void Scene2202::update() {
uint32 Scene2202::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x0001:
+ case NM_MOUSE_CLICK:
if (param.asPoint().x <= 20 || param.asPoint().x >= 620)
leaveScene(0);
break;
- case 0x2000:
+ case NM_ANIMATION_UPDATE:
_movingCubePosition = (int16)param.asInteger();
_ssMovingCube = (Sprite*)sender;
break;
- case 0x2002:
+ case NM_POSITION_CHANGE:
_isCubeMoving = false;
_ssDoneMovingCube = (Sprite*)sender;
if (param.asInteger() <= 2)
@@ -991,100 +708,6 @@ bool Scene2202::testIsSolved() {
getSubVar(VA_CUBE_POSITIONS, 8) == 7;
}
-static const uint32 kAsCommonKeyFileHashes[] = {
- 0x2450D850, 0x0C9CE8D0, 0x2C58A152
-};
-
-AsCommonKey::AsCommonKey(NeverhoodEngine *vm, Scene *parentScene, int keyIndex, int surfacePriority, int16 x, int16 y)
- : AnimatedSprite(vm, kAsCommonKeyFileHashes[keyIndex], surfacePriority, x, y), _parentScene(parentScene), _keyIndex(keyIndex) {
-
- if (!getSubVar(VA_HAS_KEY, _keyIndex) && !getSubVar(VA_IS_KEY_INSERTED, _keyIndex)) {
- SetMessageHandler(&AsCommonKey::handleMessage);
- } else {
- // If Klaymen already has the key or it's already inserted then don't show it
- setVisible(false);
- SetMessageHandler(NULL);
- }
-}
-
-uint32 AsCommonKey::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x1011:
- sendMessage(_parentScene, 0x4826, 0);
- messageResult = 1;
- break;
- case 0x4806:
- setSubVar(VA_HAS_KEY, _keyIndex, 1);
- setVisible(false);
- SetMessageHandler(NULL);
- }
- return messageResult;
-}
-
-static const uint32 kAsScene2203DoorFileHashes[] = {
- 0x7868AE10, 0x1A488110
-};
-
-AsScene2203Door::AsScene2203Door(NeverhoodEngine *vm, Scene *parentScene, uint doorIndex)
- : AnimatedSprite(vm, 1100), _parentScene(parentScene), _doorIndex(doorIndex) {
-
- SetUpdateHandler(&AnimatedSprite::update);
- SetMessageHandler(&AsScene2203Door::handleMessage);
- _x = 320;
- _y = 240;
- createSurface1(kAsScene2203DoorFileHashes[_doorIndex], 900);
- if (getGlobalVar(V_LARGE_DOOR_NUMBER) == _doorIndex) {
- startAnimation(kAsScene2203DoorFileHashes[_doorIndex], -1, -1);
- _newStickFrameIndex = STICK_LAST_FRAME;
- } else {
- startAnimation(kAsScene2203DoorFileHashes[_doorIndex], 0, -1);
- _newStickFrameIndex = 0;
- }
-}
-
-uint32 AsScene2203Door::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x1011:
- if (_doorIndex == getGlobalVar(V_LARGE_DOOR_NUMBER))
- sendMessage(_parentScene, 0x2002, 0);
- else
- sendMessage(_parentScene, 0x2001, 0);
- messageResult = 1;
- break;
- case 0x2000:
- _otherDoor = (Sprite*)param.asEntity();
- break;
- case 0x3002:
- if (_doorIndex == getGlobalVar(V_LARGE_DOOR_NUMBER))
- sendMessage(_parentScene, 0x4808, 0);
- stopAnimation();
- break;
- case 0x4808:
- setGlobalVar(V_LARGE_DOOR_NUMBER, _doorIndex);
- sendMessage(_otherDoor, 0x4809, 0);
- openDoor();
- break;
- case 0x4809:
- closeDoor();
- sendMessage(_parentScene, 0x2003, 0);
- break;
- }
- return messageResult;
-}
-
-void AsScene2203Door::openDoor() {
- playSound(0, 0x341014C4);
- startAnimation(kAsScene2203DoorFileHashes[_doorIndex], 1, -1);
-}
-
-void AsScene2203Door::closeDoor() {
- startAnimation(kAsScene2203DoorFileHashes[_doorIndex], -1, -1);
- _playBackwards = true;
- _newStickFrameIndex = 0;
-}
-
Scene2203::Scene2203(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule) {
@@ -1163,7 +786,7 @@ uint32 Scene2203::handleMessage(int messageNum, const MessageParam &param, Entit
else
setMessageList2(0x004B83C8);
break;
- case 0x2002:
+ case NM_POSITION_CHANGE:
if (sender == _asLeftDoor)
setMessageList2(0x004B8370);
else
@@ -1175,7 +798,7 @@ uint32 Scene2203::handleMessage(int messageNum, const MessageParam &param, Entit
else
_ssSmallRightDoor->setVisible(false);
break;
- case 0x4808:
+ case NM_KLAYMEN_OPEN_DOOR:
if (sender == _asLeftDoor) {
_ssSmallLeftDoor->setVisible(true);
_klaymen->setClipRect(_leftDoorClipRect);
@@ -1197,24 +820,6 @@ uint32 Scene2203::handleMessage(int messageNum, const MessageParam &param, Entit
return messageResult;
}
-SsScene2205DoorFrame::SsScene2205DoorFrame(NeverhoodEngine *vm)
- : StaticSprite(vm, 900) {
-
- SetMessageHandler(&SsScene2205DoorFrame::handleMessage);
- createSurface(1100, 45, 206);
- loadSprite(getGlobalVar(V_LIGHTS_ON) ? 0x24306227 : 0xD90032A0, kSLFDefDrawOffset | kSLFDefPosition);
-}
-
-uint32 SsScene2205DoorFrame::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x2000:
- loadSprite(getGlobalVar(V_LIGHTS_ON) ? 0x24306227 : 0xD90032A0, kSLFDefDrawOffset | kSLFDefPosition);
- break;
- }
- return messageResult;
-}
-
Scene2205::Scene2205(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule) {
@@ -1306,7 +911,7 @@ void Scene2205::update() {
uint32 Scene2205::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0x6449569A)
setMessageList(0x004B0690);
else if (param.asInteger() == 0x2841369C)
@@ -1325,134 +930,6 @@ static const int16 kScene2206XPositions[] = {
384, 480, 572
};
-static const uint32 kScene2206MessageIds1[] = {
- 0x004B8998, 0x004B89B8, 0x004B89D8
-};
-
-static const uint32 kScene2206MessageIds2[] = {
- 0x004B89F8, 0x004B8A20, 0x004B8A48
-};
-
-static const int16 kAsScene2206DoorSpikesXDeltasOpen[] = {
- -24, -28, -18, 6, 9, -8
-};
-
-static const int16 kAsScene2206DoorSpikesXDeltasClose[] = {
- -8, 7, 11, 26, 13, 14
-};
-
-AsScene2206DoorSpikes::AsScene2206DoorSpikes(NeverhoodEngine *vm, uint32 fileHash)
- : StaticSprite(vm, fileHash, 200) {
-
- if (getGlobalVar(V_SPIKES_RETRACTED))
- _x -= 63;
- SetUpdateHandler(&AsScene2206DoorSpikes::update);
- SetMessageHandler(&AsScene2206DoorSpikes::handleMessage);
- SetSpriteUpdate(NULL);
-}
-
-void AsScene2206DoorSpikes::update() {
- handleSpriteUpdate();
- updatePosition();
-}
-
-uint32 AsScene2206DoorSpikes::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x4808:
- _deltaIndex = 0;
- playSound(0, 0x032746E0);
- SetMessageHandler(NULL);
- SetSpriteUpdate(&AsScene2206DoorSpikes::suOpen);
- break;
- case 0x4809:
- _deltaIndex = 0;
- playSound(0, 0x002642C0);
- SetMessageHandler(NULL);
- SetSpriteUpdate(&AsScene2206DoorSpikes::suClose);
- break;
- }
- return messageResult;
-}
-
-void AsScene2206DoorSpikes::suOpen() {
- if (_deltaIndex < 6) {
- _x += kAsScene2206DoorSpikesXDeltasOpen[_deltaIndex];
- _deltaIndex++;
- } else {
- SetMessageHandler(&AsScene2206DoorSpikes::handleMessage);
- SetSpriteUpdate(NULL);
- }
-}
-
-void AsScene2206DoorSpikes::suClose() {
- if (_deltaIndex < 6) {
- _x += kAsScene2206DoorSpikesXDeltasClose[_deltaIndex];
- _deltaIndex++;
- } else {
- SetMessageHandler(&AsScene2206DoorSpikes::handleMessage);
- SetSpriteUpdate(NULL);
- }
-}
-
-AsScene2206Platform::AsScene2206Platform(NeverhoodEngine *vm, uint32 fileHash)
- : StaticSprite(vm, fileHash, 50) {
-
- SetUpdateHandler(&AsScene2206Platform::update);
- SetMessageHandler(&AsScene2206Platform::handleMessage);
- SetSpriteUpdate(NULL);
-}
-
-void AsScene2206Platform::update() {
- handleSpriteUpdate();
- updatePosition();
-}
-
-uint32 AsScene2206Platform::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x4803:
- _yDelta = 0;
- SetMessageHandler(NULL);
- SetSpriteUpdate(&AsScene2206Platform::suMoveDown);
- break;
- }
- return messageResult;
-}
-
-void AsScene2206Platform::suMoveDown() {
- _yDelta++;
- _y += _yDelta;
-}
-
-SsScene2206TestTube::SsScene2206TestTube(NeverhoodEngine *vm, Scene *parentScene, int surfacePriority, uint32 fileHash)
- : StaticSprite(vm, fileHash, surfacePriority), _parentScene(parentScene) {
-
- if (getGlobalVar(V_HAS_TEST_TUBE)) {
- setVisible(false);
- SetMessageHandler(NULL);
- } else
- SetMessageHandler(&SsScene2206TestTube::handleMessage);
- _collisionBoundsOffset = _drawOffset;
- updateBounds();
-}
-
-uint32 SsScene2206TestTube::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x1011:
- sendMessage(_parentScene, 0x4826, 0);
- messageResult = 1;
- break;
- case 0x4806:
- setGlobalVar(V_HAS_TEST_TUBE, 1);
- setVisible(false);
- SetMessageHandler(NULL);
- break;
- }
- return messageResult;
-}
-
Scene2206::Scene2206(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule) {
@@ -1535,7 +1012,7 @@ Scene2206::~Scene2206() {
uint32 Scene2206::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0x800C6694)
readClickedColumn();
else if (param.asInteger() == 0x402064D8)
@@ -1554,19 +1031,19 @@ uint32 Scene2206::handleMessage(int messageNum, const MessageParam &param, Entit
if (sender == _ssButton) {
setGlobalVar(V_SPIKES_RETRACTED, getGlobalVar(V_SPIKES_RETRACTED) ? 0 : 1);
if (getGlobalVar(V_SPIKES_RETRACTED))
- sendMessage(_asDoorSpikes, 0x4808, 0);
+ sendMessage(_asDoorSpikes, NM_KLAYMEN_OPEN_DOOR, 0);
else
- sendMessage(_asDoorSpikes, 0x4809, 0);
+ sendMessage(_asDoorSpikes, NM_KLAYMEN_CLOSE_DOOR, 0);
}
break;
case 0x4826:
sendEntityMessage(_klaymen, 0x1014, _ssTestTube);
setMessageList(0x004B8988);
break;
- case 0x482A:
+ case NM_MOVE_TO_BACK:
klaymenBehindSpikes();
break;
- case 0x482B:
+ case NM_MOVE_TO_FRONT:
klaymenInFrontSpikes();
break;
}
@@ -1597,6 +1074,14 @@ void Scene2206::klaymenBehindSpikes() {
_klaymen->setClipRect(_sprite2->getDrawRect().x, 0, _sprite3->getDrawRect().x2(), _sprite1->getDrawRect().y2());
}
+static const uint32 kScene2206MessageIds1[] = {
+ 0x004B8998, 0x004B89B8, 0x004B89D8
+};
+
+static const uint32 kScene2206MessageIds2[] = {
+ 0x004B89F8, 0x004B8A20, 0x004B8A48
+};
+
void Scene2206::readClickedColumn() {
setGlobalVar(V_CLICKED_COLUMN_INDEX, (_mouseClickPos.x - 354) / 96);
if (getGlobalVar(V_CLICKED_COLUMN_INDEX) > 2)
@@ -1617,317 +1102,6 @@ static const uint32 kScene2207FileHashes[] = {
0x3BB1E12E, 0x23B1E12E, 0x13B1E12E
};
-AsScene2207Elevator::AsScene2207Elevator(NeverhoodEngine *vm, Scene *parentScene)
- : AnimatedSprite(vm, 900), _parentScene(parentScene), _pointIndex(0), _destPointIndex(0), _destPointIndexDelta(0) {
-
- NPoint pt;
-
- _dataResource.load(0x00524846);
- _pointArray = _dataResource.getPointArray(0x005B02B7);
- pt = _dataResource.getPoint(0x403A82B1);
- _x = pt.x;
- _y = pt.y;
- createSurface(1100, 129, 103);
- startAnimation(getGlobalVar(V_LIGHTS_ON) ? 0xC858CC19 : 0x294B3377, 0, 0);
- _newStickFrameIndex = 0;
- SetUpdateHandler(&AsScene2207Elevator::update);
- SetMessageHandler(&AsScene2207Elevator::handleMessage);
- SetSpriteUpdate(&AsScene2207Elevator::suSetPosition);
-}
-
-AsScene2207Elevator::~AsScene2207Elevator() {
- _vm->_soundMan->deleteSoundGroup(0x02700413);
-}
-
-void AsScene2207Elevator::update() {
-
- if (_destPointIndex + _destPointIndexDelta > _pointIndex) {
- _pointIndex++;
- startAnimation(getGlobalVar(V_LIGHTS_ON) ? 0xC858CC19 : 0x294B3377, _pointIndex, _pointIndex);
- _newStickFrameIndex = _pointIndex;
- if (_destPointIndex + _destPointIndexDelta == _pointIndex) {
- if (_destPointIndexDelta != 0)
- _destPointIndexDelta = 0;
- else {
- _vm->_soundMan->deleteSound(0xD3B02847);
- playSound(0, 0x53B8284A);
- }
- }
- }
-
- if (_destPointIndex + _destPointIndexDelta < _pointIndex) {
- _pointIndex--;
- if (_pointIndex == 0)
- sendMessage(_parentScene, 0x2003, 0);
- startAnimation(getGlobalVar(V_LIGHTS_ON) ? 0xC858CC19 : 0x294B3377, _pointIndex, _pointIndex);
- _newStickFrameIndex = _pointIndex;
- if (_destPointIndex + _destPointIndexDelta == _pointIndex) {
- if (_destPointIndexDelta != 0)
- _destPointIndexDelta = 0;
- else {
- _vm->_soundMan->deleteSound(0xD3B02847);
- playSound(0, 0x53B8284A);
- }
- }
- }
-
- if (_pointIndex > 20 && _surface->getPriority() != 900)
- sendMessage(_parentScene, 0x2002, 900);
- else if (_pointIndex < 20 && _surface->getPriority() != 1100)
- sendMessage(_parentScene, 0x2002, 1100);
-
- AnimatedSprite::update();
-
- if (_destPointIndex + _destPointIndexDelta == _pointIndex && _isMoving) {
- sendMessage(_parentScene, 0x2004, 0);
- _isMoving = false;
- }
-
-}
-
-void AsScene2207Elevator::suSetPosition() {
- _x = (*_pointArray)[_pointIndex].x;
- _y = (*_pointArray)[_pointIndex].y - 60;
- updateBounds();
-}
-
-uint32 AsScene2207Elevator::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x2000:
- moveToY(param.asInteger());
- break;
- }
- return messageResult;
-}
-
-void AsScene2207Elevator::moveToY(int16 y) {
- int16 minDistance = 480;
-
- if (!_pointArray || _pointArray->size() == 0)
- return;
-
- for (uint i = 0; i < _pointArray->size(); i++) {
- int16 distance = ABS(y - (*_pointArray)[i].y);
- if (distance < minDistance) {
- minDistance = distance;
- _destPointIndex = i;
- }
- }
-
- if (_destPointIndex != _pointIndex) {
- if (_destPointIndex == 0 || _destPointIndex == (int)_pointArray->size() - 1)
- _destPointIndexDelta = 0;
- else if (_destPointIndex < _pointIndex)
- _destPointIndexDelta = -2;
- else
- _destPointIndexDelta = 2;
- _vm->_soundMan->addSound(0x02700413, 0xD3B02847);
- _vm->_soundMan->playSoundLooping(0xD3B02847);
- }
-
- _isMoving = true;
-
-}
-
-AsScene2207Lever::AsScene2207Lever(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y, int doDeltaX)
- : AnimatedSprite(vm, 1100), _parentScene(parentScene) {
-
- _x = x;
- _y = y;
- createSurface(1010, 71, 73);
- setDoDeltaX(doDeltaX);
- startAnimation(0x80880090, 0, -1);
- _newStickFrameIndex = 0;
- SetUpdateHandler(&AnimatedSprite::update);
- SetMessageHandler(&AsScene2207Lever::handleMessage);
-}
-
-uint32 AsScene2207Lever::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x1011:
- sendMessage(_parentScene, 0x4826, 0);
- messageResult = 1;
- break;
- case 0x3002:
- gotoNextState();
- stopAnimation();
- break;
- case 0x4807:
- stLeverUp();
- break;
- case 0x480F:
- stLeverDown();
- break;
- case 0x482A:
- sendMessage(_parentScene, 0x1022, 990);
- break;
- case 0x482B:
- sendMessage(_parentScene, 0x1022, 1010);
- break;
- }
- return messageResult;
-}
-
-void AsScene2207Lever::stLeverDown() {
- startAnimation(0x80880090, 1, -1);
- playSound(0, 0x40581882);
- FinalizeState(&AsScene2207Lever::stLeverDownEvent);
-}
-
-void AsScene2207Lever::stLeverDownEvent() {
- sendMessage(_parentScene, 0x480F, 0);
-}
-
-void AsScene2207Lever::stLeverUp() {
- startAnimation(0x80880090, 6, -1);
- _playBackwards = true;
- playSound(0, 0x40581882);
- FinalizeState(&AsScene2207Lever::stLeverUpEvent);
-}
-
-void AsScene2207Lever::stLeverUpEvent() {
- sendMessage(_parentScene, 0x4807, 0);
-}
-
-AsScene2207WallRobotAnimation::AsScene2207WallRobotAnimation(NeverhoodEngine *vm, Scene *parentScene)
- : AnimatedSprite(vm, 1200), _idle(true) {
-
- _x = 309;
- _y = 320;
- createSurface1(0xCCFD6090, 100);
- startAnimation(0xCCFD6090, 0, -1);
- _newStickFrameIndex = 0;
- loadSound(1, 0x40330872);
- loadSound(2, 0x72A2914A);
- loadSound(3, 0xD4226080);
- SetUpdateHandler(&AnimatedSprite::update);
- SetMessageHandler(&AsScene2207WallRobotAnimation::handleMessage);
-}
-
-AsScene2207WallRobotAnimation::~AsScene2207WallRobotAnimation() {
- _vm->_soundMan->deleteSoundGroup(0x80D00820);
-}
-
-uint32 AsScene2207WallRobotAnimation::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x100D:
- if (!_idle) {
- if (param.asInteger() == 0x3423093) {
- _vm->_soundMan->addSound(0x80D00820, 0x12121943);
- _vm->_soundMan->playSoundLooping(0x12121943);
- } else if (param.asInteger() == 0x834AB011) {
- stopSound(0);
- stopSound(1);
- stopSound(2);
- stopSound(3);
- _vm->_soundMan->deleteSound(0x12121943);
- } else if (param.asInteger() == 0x3A980501)
- playSound(1);
- else if (param.asInteger() == 0x2A2AD498)
- playSound(2);
- else if (param.asInteger() == 0xC4980008)
- playSound(3);
- else if (param.asInteger() == 0x06B84228)
- playSound(0, 0xE0702146);
- }
- break;
- case 0x2006:
- stStartAnimation();
- break;
- case 0x2007:
- stStopAnimation();
- break;
- case 0x3002:
- gotoNextState();
- break;
- }
- return messageResult;
-}
-
-void AsScene2207WallRobotAnimation::stStartAnimation() {
- if (!_idle) {
- NextState(NULL);
- } else {
- startAnimation(0xCCFD6090, 0, -1);
- _idle = false;
- setVisible(true);
- }
-}
-
-void AsScene2207WallRobotAnimation::stStopAnimation() {
- NextState(&AsScene2207WallRobotAnimation::cbStopAnimation);
-}
-
-void AsScene2207WallRobotAnimation::cbStopAnimation() {
- stopAnimation();
- stopSound(0);
- stopSound(1);
- stopSound(2);
- stopSound(3);
- _vm->_soundMan->deleteSound(0x12121943);
- _idle = true;
- setVisible(false);
-}
-
-AsScene2207WallCannonAnimation::AsScene2207WallCannonAnimation(NeverhoodEngine *vm)
- : AnimatedSprite(vm, 1200), _idle(true) {
-
- _x = 309;
- _y = 320;
- createSurface1(0x8CAA0099, 100);
- startAnimation(0x8CAA0099, 0, -1);
- _newStickFrameIndex = 0;
- SetUpdateHandler(&AnimatedSprite::update);
- SetMessageHandler(&AsScene2207WallCannonAnimation::handleMessage);
-}
-
-uint32 AsScene2207WallCannonAnimation::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x2006:
- stStartAnimation();
- break;
- case 0x2007:
- stStopAnimation();
- break;
- case 0x3002:
- gotoNextState();
- break;
- }
- return messageResult;
-}
-
-void AsScene2207WallCannonAnimation::stStartAnimation() {
- if (!_idle) {
- NextState(NULL);
- } else {
- setVisible(true);
- startAnimation(0x8CAA0099, 0, -1);
- _idle = false;
- }
-}
-
-void AsScene2207WallCannonAnimation::stStopAnimation() {
- NextState(&AsScene2207WallCannonAnimation::cbStopAnimation);
-}
-
-void AsScene2207WallCannonAnimation::cbStopAnimation() {
- stopAnimation();
- setVisible(false);
- _idle = true;
-}
-
-SsScene2207Symbol::SsScene2207Symbol(NeverhoodEngine *vm, uint32 fileHash, int index)
- : StaticSprite(vm, fileHash, 100) {
-
- _x = 330;
- _y = 246 + index * 50;
- updatePosition();
-}
-
Scene2207::Scene2207(NeverhoodEngine *vm, Module *parentModule)
: Scene(vm, parentModule), _klaymenAtElevator(true), _elevatorSurfacePriority(0) {
@@ -2005,7 +1179,7 @@ void Scene2207::update() {
uint32 Scene2207::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0x0014F275) {
if (_klaymenAtElevator) {
sendMessage(_asElevator, 0x2000, _mouseClickPos.y);
@@ -2041,15 +1215,15 @@ uint32 Scene2207::handleMessage(int messageNum, const MessageParam &param, Entit
setMessageList(0x004B37D8);
}
break;
- case 0x2002:
+ case NM_POSITION_CHANGE:
_elevatorSurfacePriority = param.asInteger();
break;
case 0x2003:
_isKlaymenBusy = false;
break;
- case 0x4807:
- sendMessage(_asWallRobotAnimation, 0x2007, 0);
- sendMessage(_asWallCannonAnimation, 0x2007, 0);
+ case NM_KLAYMEN_RAISE_LEVER:
+ sendMessage(_asWallRobotAnimation, NM_CAR_MOVE_TO_PREV_POINT, 0);
+ sendMessage(_asWallCannonAnimation, NM_CAR_MOVE_TO_PREV_POINT, 0);
break;
case 0x480B:
if (sender == _ssButton) {
@@ -2062,9 +1236,9 @@ uint32 Scene2207::handleMessage(int messageNum, const MessageParam &param, Entit
}
}
break;
- case 0x480F:
- sendMessage(_asWallRobotAnimation, 0x2006, 0);
- sendMessage(_asWallCannonAnimation, 0x2006, 0);
+ case NM_KLAYMEN_LOWER_LEVER:
+ sendMessage(_asWallRobotAnimation, NM_KLAYMEN_STOP_CLIMBING, 0);
+ sendMessage(_asWallCannonAnimation, NM_KLAYMEN_STOP_CLIMBING, 0);
_asWallRobotAnimation->setVisible(true);
_asWallCannonAnimation->setVisible(true);
break;
@@ -2088,12 +1262,12 @@ uint32 Scene2207::handleMessage(int messageNum, const MessageParam &param, Entit
uint32 Scene2207::handleMessage2(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x2002:
+ case NM_POSITION_CHANGE:
_elevatorSurfacePriority = param.asInteger();
break;
case 0x2004:
SetMessageHandler(&Scene2207::handleMessage);
- sendMessage(_klaymen, 0x2005, 0);
+ sendMessage(_klaymen, NM_KLAYMEN_CLIMB_LADDER, 0);
sendEntityMessage(_klaymen, 0x1014, _asLever);
setMessageList(0x004B3920);
setRectList(0x004B3948);
@@ -2226,7 +1400,7 @@ void Scene2208::update() {
uint32 Scene2208::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x0001:
+ case NM_MOUSE_CLICK:
if (param.asPoint().x <= 40 || param.asPoint().x >= 600)
leaveScene(0);
break;
@@ -2345,7 +1519,7 @@ void Scene2242::update() {
uint32 Scene2242::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0x800C6694)
readClickedColumn();
break;
@@ -2446,7 +1620,7 @@ HallOfRecordsScene::~HallOfRecordsScene() {
uint32 HallOfRecordsScene::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0x800C6694)
readClickedColumn();
break;
@@ -2534,7 +1708,7 @@ Scene2247::~Scene2247() {
uint32 Scene2247::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0x800C6694)
readClickedColumn();
break;
diff --git a/engines/neverhood/modules/module2200.h b/engines/neverhood/modules/module2200.h
index 5c19f2a818..6b414304ae 100644
--- a/engines/neverhood/modules/module2200.h
+++ b/engines/neverhood/modules/module2200.h
@@ -31,8 +31,6 @@
namespace Neverhood {
-// Module2200
-
class Module2200 : public Module {
public:
Module2200(NeverhoodEngine *vm, Module *parentModule, int which);
@@ -44,43 +42,6 @@ protected:
void createHallOfRecordsScene(int which, uint32 hallOfRecordsInfoId);
};
-// Scene2201
-
-static const NPoint kSsScene2201PuzzleCubePoints[] = {
- {305, 305}, {321, 305}, {336, 305}, {305, 319},
- {321, 319}, {336, 319}, {305, 332}, {321, 332},
- {336, 333}
-};
-
-static const uint32 kSsScene2201PuzzleCubeFileHashes[] = {
- 0x88134A44, 0xAA124340, 0xB8124602, 0xA902464C,
- 0x890A4244, 0xA8124642, 0xB812C204, 0x381A4A4C
-};
-
-class AsScene2201CeilingFan : public AnimatedSprite {
-public:
- AsScene2201CeilingFan(NeverhoodEngine *vm);
-};
-
-class AsScene2201Door : public AnimatedSprite {
-public:
- AsScene2201Door(NeverhoodEngine *vm, Klaymen *klaymen, Sprite *ssDoorLight, bool isOpen);
-protected:
- Klaymen *_klaymen;
- Sprite *_ssDoorLight;
- bool _isOpen;
- int _countdown;
- void update();
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- void stOpenDoor();
- void stCloseDoor();
-};
-
-class SsScene2201PuzzleCube : public StaticSprite {
-public:
- SsScene2201PuzzleCube(NeverhoodEngine *vm, uint32 positionIndex, uint32 cubeIndex);
-};
-
class Scene2201 : public Scene {
public:
Scene2201(NeverhoodEngine *vm, Module *parentModule, int which);
@@ -96,30 +57,6 @@ protected:
uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
};
-class SsScene2202PuzzleCube : public StaticSprite {
-public:
- SsScene2202PuzzleCube(NeverhoodEngine *vm, Scene *parentScene, int16 cubePosition, int16 cubeSymbol);
-protected:
- Scene *_parentScene;
- int16 _cubeSymbol;
- int16 _cubePosition;
- int16 _newX, _newY;
- int16 _xDelta, _yDelta;
- int16 _xIncr;
- int16 _yIncr;
- int16 _errValue;
- int16 _counter;
- int16 _xFlagPos;
- bool _counterDirection;
- bool _isMoving;
- void update();
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- void suMoveCubeX();
- void suMoveCubeY();
- void moveCube(int16 newCubePosition);
- void stopMoving();
-};
-
class Scene2202 : public Scene {
public:
Scene2202(NeverhoodEngine *vm, Module *parentModule, int which);
@@ -138,27 +75,6 @@ protected:
bool testIsSolved();
};
-class AsCommonKey : public AnimatedSprite {
-public:
- AsCommonKey(NeverhoodEngine *vm, Scene *parentScene, int keyIndex, int surfacePriority, int16 x, int16 y);
-protected:
- Scene *_parentScene;
- int _keyIndex;
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
-
-class AsScene2203Door : public AnimatedSprite {
-public:
- AsScene2203Door(NeverhoodEngine *vm, Scene *parentScene, uint doorIndex);
-protected:
- Scene *_parentScene;
- Sprite *_otherDoor;
- uint _doorIndex;
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- void openDoor();
- void closeDoor();
-};
-
class Scene2203 : public Scene {
public:
Scene2203(NeverhoodEngine *vm, Module *parentModule, int which);
@@ -175,12 +91,7 @@ protected:
uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
};
-class SsScene2205DoorFrame : public StaticSprite {
-public:
- SsScene2205DoorFrame(NeverhoodEngine *vm);
-protected:
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
+class SsCommonPressButton;
class Scene2205 : public Scene {
public:
@@ -194,35 +105,6 @@ protected:
uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
};
-class AsScene2206DoorSpikes : public StaticSprite {
-public:
- AsScene2206DoorSpikes(NeverhoodEngine *vm, uint32 fileHash);
-protected:
- int _deltaIndex;
- void update();
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- void suOpen();
- void suClose();
-};
-
-class AsScene2206Platform : public StaticSprite {
-public:
- AsScene2206Platform(NeverhoodEngine *vm, uint32 fileHash);
-protected:
- int16 _yDelta;
- void update();
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- void suMoveDown();
-};
-
-class SsScene2206TestTube : public StaticSprite {
-public:
- SsScene2206TestTube(NeverhoodEngine *vm, Scene *parentScene, int surfacePriority, uint32 fileHash);
-protected:
- Scene *_parentScene;
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
-
class Scene2206 : public Scene {
public:
Scene2206(NeverhoodEngine *vm, Module *parentModule, int which);
@@ -241,62 +123,6 @@ protected:
void readClickedColumn();
};
-class AsScene2207Elevator : public AnimatedSprite {
-public:
- AsScene2207Elevator(NeverhoodEngine *vm, Scene *parentScene);
- ~AsScene2207Elevator();
-protected:
- Scene *_parentScene;
- NPointArray *_pointArray;
- int16 _pointIndex;
- int16 _destPointIndex, _destPointIndexDelta;
- bool _isMoving;
- void update();
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- void suSetPosition();
- void moveToY(int16 y);
-};
-
-class AsScene2207Lever : public AnimatedSprite {
-public:
- AsScene2207Lever(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y, int doDeltaX);
-protected:
- Scene *_parentScene;
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- void stLeverDown();
- void stLeverDownEvent();
- void stLeverUp();
- void stLeverUpEvent();
-};
-
-class AsScene2207WallRobotAnimation : public AnimatedSprite {
-public:
- AsScene2207WallRobotAnimation(NeverhoodEngine *vm, Scene *parentScene);
- ~AsScene2207WallRobotAnimation();
-protected:
- bool _idle;
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- void stStartAnimation();
- void stStopAnimation();
- void cbStopAnimation();
-};
-
-class AsScene2207WallCannonAnimation : public AnimatedSprite {
-public:
- AsScene2207WallCannonAnimation(NeverhoodEngine *vm);
-protected:
- bool _idle;
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- void stStartAnimation();
- void stStopAnimation();
- void cbStopAnimation();
-};
-
-class SsScene2207Symbol : public StaticSprite {
-public:
- SsScene2207Symbol(NeverhoodEngine *vm, uint32 fileHash, int index);
-};
-
class Scene2207 : public Scene {
public:
Scene2207(NeverhoodEngine *vm, Module *parentModule);
diff --git a/engines/neverhood/modules/module2200_sprites.cpp b/engines/neverhood/modules/module2200_sprites.cpp
new file mode 100644
index 0000000000..ddf31f7920
--- /dev/null
+++ b/engines/neverhood/modules/module2200_sprites.cpp
@@ -0,0 +1,1429 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public 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 "neverhood/modules/module2200_sprites.h"
+
+namespace Neverhood {
+
+AsScene2201CeilingFan::AsScene2201CeilingFan(NeverhoodEngine *vm)
+ : AnimatedSprite(vm, 1100) {
+
+ _x = 403;
+ _y = 259;
+ createSurface(100, 233, 96);
+ startAnimation(0x8600866, 0, -1);
+ SetUpdateHandler(&AnimatedSprite::update);
+}
+
+AsScene2201Door::AsScene2201Door(NeverhoodEngine *vm, Klaymen *klaymen, Sprite *ssDoorLight, bool isOpen)
+ : AnimatedSprite(vm, 1100), _klaymen(klaymen), _ssDoorLight(ssDoorLight), _countdown(0), _isOpen(isOpen) {
+
+ _x = 408;
+ _y = 290;
+ createSurface(900, 63, 266);
+ SetUpdateHandler(&AsScene2201Door::update);
+ SetMessageHandler(&AsScene2201Door::handleMessage);
+ if (_isOpen) {
+ startAnimation(0xE2CB0412, -1, -1);
+ _countdown = 48;
+ _newStickFrameIndex = STICK_LAST_FRAME;
+ } else {
+ startAnimation(0xE2CB0412, 0, -1);
+ _newStickFrameIndex = 0;
+ _ssDoorLight->setVisible(false);
+ }
+}
+
+void AsScene2201Door::update() {
+ if (_countdown != 0 && _isOpen && (--_countdown == 0))
+ stCloseDoor();
+ AnimatedSprite::update();
+}
+
+uint32 AsScene2201Door::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case NM_ANIMATION_START:
+ if (param.asInteger() == 0x11001090) {
+ if (_isOpen)
+ _ssDoorLight->setVisible(true);
+ } else if (param.asInteger() == 0x11283090) {
+ if (!_isOpen)
+ _ssDoorLight->setVisible(false);
+ }
+ break;
+ case NM_ANIMATION_UPDATE:
+ if (_isOpen)
+ _countdown = 144;
+ messageResult = _isOpen ? 1 : 0;
+ break;
+ case NM_ANIMATION_STOP:
+ gotoNextState();
+ break;
+ case NM_KLAYMEN_OPEN_DOOR:
+ _countdown = 144;
+ if (!_isOpen)
+ stOpenDoor();
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene2201Door::stOpenDoor() {
+ _isOpen = true;
+ startAnimation(0xE2CB0412, 0, -1);
+ _newStickFrameIndex = STICK_LAST_FRAME;
+ playSound(0, calcHash("fxDoorOpen33"));
+}
+
+void AsScene2201Door::stCloseDoor() {
+ _isOpen = false;
+ startAnimation(0xE2CB0412, -1, -1);
+ _playBackwards = true;
+ _newStickFrameIndex = 0;
+ playSound(0, calcHash("fxDoorClose33"));
+}
+
+SsScene2201PuzzleCube::SsScene2201PuzzleCube(NeverhoodEngine *vm, uint32 positionIndex, uint32 cubeIndex)
+ : StaticSprite(vm, 900) {
+
+ createSurface(100, 16, 16);
+ loadSprite(kSsScene2201PuzzleCubeFileHashes[cubeIndex], kSLFCenteredDrawOffset | kSLFSetPosition, 0,
+ kSsScene2201PuzzleCubePoints[positionIndex].x, kSsScene2201PuzzleCubePoints[positionIndex].y);
+}
+
+static const NPoint kSsScene2202PuzzleCubePoints[] = {
+ {196, 105}, {323, 102}, {445, 106},
+ {192, 216}, {319, 220}, {446, 216},
+ {188, 320}, {319, 319}, {443, 322}
+};
+
+static const uint32 kSsScene2202PuzzleCubeFileHashes1[] = {
+ 0xA500800C, 0x2182910C, 0x2323980C,
+ 0x23049084, 0x21008080, 0x2303900C,
+ 0x6120980C, 0x2504D808
+};
+
+static const uint32 kSsScene2202PuzzleCubeFileHashes2[] = {
+ 0x0AAD8080, 0x0A290291, 0x0A2BA398,
+ 0x822B8490, 0x86298080, 0x0A2B8390,
+ 0x0A69A098, 0x0E2D84D8
+};
+
+SsScene2202PuzzleCube::SsScene2202PuzzleCube(NeverhoodEngine *vm, Scene *parentScene, int16 cubePosition, int16 cubeSymbol)
+ : StaticSprite(vm, 900), _parentScene(parentScene), _cubeSymbol(cubeSymbol), _cubePosition(cubePosition), _isMoving(false) {
+
+ int surfacePriority;
+
+ SetUpdateHandler(&SsScene2202PuzzleCube::update);
+ SetMessageHandler(&SsScene2202PuzzleCube::handleMessage);
+ if (_cubePosition >= 0 && _cubePosition <= 2)
+ surfacePriority = 100;
+ else if (_cubePosition >= 3 && _cubePosition <= 5)
+ surfacePriority = 300;
+ else
+ surfacePriority = 500;
+ debug(1, "TODO: Unused SurfacePriority: %d", surfacePriority);
+ loadSprite(kSsScene2202PuzzleCubeFileHashes2[_cubeSymbol], kSLFCenteredDrawOffset | kSLFSetPosition | kSLFDefCollisionBoundsOffset, 0,
+ kSsScene2202PuzzleCubePoints[_cubePosition].x, kSsScene2202PuzzleCubePoints[_cubePosition].y);
+ loadSound(0, 0x40958621);
+ loadSound(1, 0x51108241);
+}
+
+void SsScene2202PuzzleCube::update() {
+ handleSpriteUpdate();
+ updatePosition();
+}
+
+uint32 SsScene2202PuzzleCube::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x1011:
+ if (!_isMoving && !getGlobalVar(V_TILE_PUZZLE_SOLVED))
+ sendMessage(_parentScene, 0x2000, _cubePosition);
+ messageResult = 1;
+ break;
+ case 0x2001:
+ _isMoving = true;
+ moveCube(param.asInteger());
+ break;
+ }
+ return messageResult;
+}
+
+void SsScene2202PuzzleCube::suMoveCubeX() {
+
+ bool done = false;
+
+ if (_counterDirection) {
+ if (_counter > 2)
+ _counter -= 2;
+ } else {
+ if (_counter < 20)
+ _counter += 2;
+ }
+
+ for (int16 i = 0; i < _counter; i++) {
+ _x += _xIncr;
+ _errValue += _yDelta;
+ if (_errValue >= _xDelta) {
+ _errValue -= _xDelta;
+ _y += _yIncr;
+ }
+ if (_x == _newX && _y == _newY) {
+ done = true;
+ break;
+ }
+ if (_x == _xFlagPos)
+ _counterDirection = true;
+ }
+
+ if (done)
+ stopMoving();
+
+ updateBounds();
+
+}
+
+void SsScene2202PuzzleCube::suMoveCubeY() {
+
+ bool done = false;
+
+ if (_counterDirection) {
+ if (_counter > 2)
+ _counter -= 2;
+ } else {
+ if (_counter < 20)
+ _counter += 2;
+ }
+
+ for (int16 i = 0; i < _counter; i++) {
+ _y += _yIncr;
+ _errValue += _xDelta;
+ if (_errValue >= _yDelta) {
+ _errValue -= _yDelta;
+ _x += _xIncr;
+ }
+ if (_x == _newX && _y == _newY) {
+ done = true;
+ break;
+ }
+ if (_x == _xFlagPos)
+ _counterDirection = true;
+ }
+
+ if (done)
+ stopMoving();
+
+ updateBounds();
+
+}
+
+void SsScene2202PuzzleCube::moveCube(int16 newCubePosition) {
+
+ loadSprite(kSsScene2202PuzzleCubeFileHashes1[_cubeSymbol], kSLFCenteredDrawOffset);
+
+ setSubVar(VA_CUBE_POSITIONS, _cubePosition, (uint32)-1);
+ setSubVar(VA_CUBE_POSITIONS, newCubePosition, (uint32)_cubeSymbol);
+
+ _cubePosition = newCubePosition;
+ _errValue = 0;
+ _counterDirection = false;
+ _counter = 0;
+ _newX = kSsScene2202PuzzleCubePoints[newCubePosition].x;
+ _newY = kSsScene2202PuzzleCubePoints[newCubePosition].y;
+
+ if (_x == _newX && _y == _newY)
+ return;
+
+ if (_x <= _newX) {
+ if (_y <= _newY) {
+ _xDelta = _newX - _x;
+ _yDelta = _newY - _y;
+ _xIncr = 1;
+ _yIncr = 1;
+ } else {
+ _xDelta = _newX - _x;
+ _yDelta = _y - _newY;
+ _xIncr = 1;
+ _yIncr = -1;
+ }
+ } else {
+ if (_y <= _newY) {
+ _xDelta = _x - _newX;
+ _yDelta = _newY - _y;
+ _xIncr = -1;
+ _yIncr = 1;
+ } else {
+ _xDelta = _x - _newX;
+ _yDelta = _y - _newY;
+ _xIncr = -1;
+ _yIncr = -1;
+ }
+ }
+
+ if (_xDelta > _yDelta) {
+ SetSpriteUpdate(&SsScene2202PuzzleCube::suMoveCubeX);
+ if (_xIncr > 0) {
+ if (_newX - _x >= 180)
+ _xFlagPos = _newX - 90;
+ else
+ _xFlagPos = _x + _newX / 2;
+ } else {
+ if (_x - _newX >= 180)
+ _xFlagPos = _x + 90;
+ else
+ _xFlagPos = _x / 2 + _newX;
+ }
+ playSound(0);
+ } else {
+ SetSpriteUpdate(&SsScene2202PuzzleCube::suMoveCubeY);
+ if (_yIncr > 0) {
+ if (_newY - _y >= 180)
+ _xFlagPos = _newY - 90;
+ else
+ _xFlagPos = _y + _newY / 2;
+ } else {
+ if (_y - _newY >= 180)
+ _xFlagPos = _y + 90;
+ else
+ _xFlagPos = _y / 2 + _newY;
+ }
+ playSound(1);
+ }
+
+}
+
+void SsScene2202PuzzleCube::stopMoving() {
+ loadSprite(kSsScene2202PuzzleCubeFileHashes2[_cubeSymbol], kSLFCenteredDrawOffset);
+ SetSpriteUpdate(NULL);
+ _isMoving = false;
+ sendMessage(_parentScene, NM_POSITION_CHANGE, _cubePosition);
+}
+
+static const uint32 kAsCommonKeyFileHashes[] = {
+ 0x2450D850, 0x0C9CE8D0, 0x2C58A152
+};
+
+AsCommonKey::AsCommonKey(NeverhoodEngine *vm, Scene *parentScene, int keyIndex, int surfacePriority, int16 x, int16 y)
+ : AnimatedSprite(vm, kAsCommonKeyFileHashes[keyIndex], surfacePriority, x, y), _parentScene(parentScene), _keyIndex(keyIndex) {
+
+ if (!getSubVar(VA_HAS_KEY, _keyIndex) && !getSubVar(VA_IS_KEY_INSERTED, _keyIndex)) {
+ SetMessageHandler(&AsCommonKey::handleMessage);
+ } else {
+ // If Klaymen already has the key or it's already inserted then don't show it
+ setVisible(false);
+ SetMessageHandler(NULL);
+ }
+}
+
+uint32 AsCommonKey::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x1011:
+ sendMessage(_parentScene, 0x4826, 0);
+ messageResult = 1;
+ break;
+ case NM_KLAYMEN_USE_OBJECT:
+ setSubVar(VA_HAS_KEY, _keyIndex, 1);
+ setVisible(false);
+ SetMessageHandler(NULL);
+ }
+ return messageResult;
+}
+
+static const uint32 kAsScene2203DoorFileHashes[] = {
+ 0x7868AE10, 0x1A488110
+};
+
+AsScene2203Door::AsScene2203Door(NeverhoodEngine *vm, Scene *parentScene, uint doorIndex)
+ : AnimatedSprite(vm, 1100), _parentScene(parentScene), _doorIndex(doorIndex) {
+
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsScene2203Door::handleMessage);
+ _x = 320;
+ _y = 240;
+ createSurface1(kAsScene2203DoorFileHashes[_doorIndex], 900);
+ if (getGlobalVar(V_LARGE_DOOR_NUMBER) == _doorIndex) {
+ startAnimation(kAsScene2203DoorFileHashes[_doorIndex], -1, -1);
+ _newStickFrameIndex = STICK_LAST_FRAME;
+ } else {
+ startAnimation(kAsScene2203DoorFileHashes[_doorIndex], 0, -1);
+ _newStickFrameIndex = 0;
+ }
+}
+
+uint32 AsScene2203Door::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x1011:
+ if (_doorIndex == getGlobalVar(V_LARGE_DOOR_NUMBER))
+ sendMessage(_parentScene, NM_POSITION_CHANGE, 0);
+ else
+ sendMessage(_parentScene, 0x2001, 0);
+ messageResult = 1;
+ break;
+ case NM_ANIMATION_UPDATE:
+ _otherDoor = (Sprite*)param.asEntity();
+ break;
+ case NM_ANIMATION_STOP:
+ if (_doorIndex == getGlobalVar(V_LARGE_DOOR_NUMBER))
+ sendMessage(_parentScene, NM_KLAYMEN_OPEN_DOOR, 0);
+ stopAnimation();
+ break;
+ case NM_KLAYMEN_OPEN_DOOR:
+ setGlobalVar(V_LARGE_DOOR_NUMBER, _doorIndex);
+ sendMessage(_otherDoor, NM_KLAYMEN_CLOSE_DOOR, 0);
+ openDoor();
+ break;
+ case NM_KLAYMEN_CLOSE_DOOR:
+ closeDoor();
+ sendMessage(_parentScene, 0x2003, 0);
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene2203Door::openDoor() {
+ playSound(0, 0x341014C4);
+ startAnimation(kAsScene2203DoorFileHashes[_doorIndex], 1, -1);
+}
+
+void AsScene2203Door::closeDoor() {
+ startAnimation(kAsScene2203DoorFileHashes[_doorIndex], -1, -1);
+ _playBackwards = true;
+ _newStickFrameIndex = 0;
+}
+
+SsScene2205DoorFrame::SsScene2205DoorFrame(NeverhoodEngine *vm)
+ : StaticSprite(vm, 900) {
+
+ SetMessageHandler(&SsScene2205DoorFrame::handleMessage);
+ createSurface(1100, 45, 206);
+ loadSprite(getGlobalVar(V_LIGHTS_ON) ? 0x24306227 : 0xD90032A0, kSLFDefDrawOffset | kSLFDefPosition);
+}
+
+uint32 SsScene2205DoorFrame::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case NM_ANIMATION_UPDATE:
+ loadSprite(getGlobalVar(V_LIGHTS_ON) ? 0x24306227 : 0xD90032A0, kSLFDefDrawOffset | kSLFDefPosition);
+ break;
+ }
+ return messageResult;
+}
+
+static const int16 kAsScene2206DoorSpikesXDeltasOpen[] = {
+ -24, -28, -18, 6, 9, -8
+};
+
+static const int16 kAsScene2206DoorSpikesXDeltasClose[] = {
+ -8, 7, 11, 26, 13, 14
+};
+
+AsScene2206DoorSpikes::AsScene2206DoorSpikes(NeverhoodEngine *vm, uint32 fileHash)
+ : StaticSprite(vm, fileHash, 200) {
+
+ if (getGlobalVar(V_SPIKES_RETRACTED))
+ _x -= 63;
+ SetUpdateHandler(&AsScene2206DoorSpikes::update);
+ SetMessageHandler(&AsScene2206DoorSpikes::handleMessage);
+ SetSpriteUpdate(NULL);
+}
+
+void AsScene2206DoorSpikes::update() {
+ handleSpriteUpdate();
+ updatePosition();
+}
+
+uint32 AsScene2206DoorSpikes::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case NM_KLAYMEN_OPEN_DOOR:
+ _deltaIndex = 0;
+ playSound(0, 0x032746E0);
+ SetMessageHandler(NULL);
+ SetSpriteUpdate(&AsScene2206DoorSpikes::suOpen);
+ break;
+ case NM_KLAYMEN_CLOSE_DOOR:
+ _deltaIndex = 0;
+ playSound(0, 0x002642C0);
+ SetMessageHandler(NULL);
+ SetSpriteUpdate(&AsScene2206DoorSpikes::suClose);
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene2206DoorSpikes::suOpen() {
+ if (_deltaIndex < 6) {
+ _x += kAsScene2206DoorSpikesXDeltasOpen[_deltaIndex];
+ _deltaIndex++;
+ } else {
+ SetMessageHandler(&AsScene2206DoorSpikes::handleMessage);
+ SetSpriteUpdate(NULL);
+ }
+}
+
+void AsScene2206DoorSpikes::suClose() {
+ if (_deltaIndex < 6) {
+ _x += kAsScene2206DoorSpikesXDeltasClose[_deltaIndex];
+ _deltaIndex++;
+ } else {
+ SetMessageHandler(&AsScene2206DoorSpikes::handleMessage);
+ SetSpriteUpdate(NULL);
+ }
+}
+
+AsScene2206Platform::AsScene2206Platform(NeverhoodEngine *vm, uint32 fileHash)
+ : StaticSprite(vm, fileHash, 50) {
+
+ SetUpdateHandler(&AsScene2206Platform::update);
+ SetMessageHandler(&AsScene2206Platform::handleMessage);
+ SetSpriteUpdate(NULL);
+}
+
+void AsScene2206Platform::update() {
+ handleSpriteUpdate();
+ updatePosition();
+}
+
+uint32 AsScene2206Platform::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x4803:
+ _yDelta = 0;
+ SetMessageHandler(NULL);
+ SetSpriteUpdate(&AsScene2206Platform::suMoveDown);
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene2206Platform::suMoveDown() {
+ _yDelta++;
+ _y += _yDelta;
+}
+
+SsScene2206TestTube::SsScene2206TestTube(NeverhoodEngine *vm, Scene *parentScene, int surfacePriority, uint32 fileHash)
+ : StaticSprite(vm, fileHash, surfacePriority), _parentScene(parentScene) {
+
+ if (getGlobalVar(V_HAS_TEST_TUBE)) {
+ setVisible(false);
+ SetMessageHandler(NULL);
+ } else
+ SetMessageHandler(&SsScene2206TestTube::handleMessage);
+ _collisionBoundsOffset = _drawOffset;
+ updateBounds();
+}
+
+uint32 SsScene2206TestTube::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x1011:
+ sendMessage(_parentScene, 0x4826, 0);
+ messageResult = 1;
+ break;
+ case NM_KLAYMEN_USE_OBJECT:
+ setGlobalVar(V_HAS_TEST_TUBE, 1);
+ setVisible(false);
+ SetMessageHandler(NULL);
+ break;
+ }
+ return messageResult;
+}
+
+AsScene2207Elevator::AsScene2207Elevator(NeverhoodEngine *vm, Scene *parentScene)
+ : AnimatedSprite(vm, 900), _parentScene(parentScene), _pointIndex(0), _destPointIndex(0), _destPointIndexDelta(0) {
+
+ NPoint pt;
+
+ _dataResource.load(0x00524846);
+ _pointArray = _dataResource.getPointArray(0x005B02B7);
+ pt = _dataResource.getPoint(0x403A82B1);
+ _x = pt.x;
+ _y = pt.y;
+ createSurface(1100, 129, 103);
+ startAnimation(getGlobalVar(V_LIGHTS_ON) ? 0xC858CC19 : 0x294B3377, 0, 0);
+ _newStickFrameIndex = 0;
+ SetUpdateHandler(&AsScene2207Elevator::update);
+ SetMessageHandler(&AsScene2207Elevator::handleMessage);
+ SetSpriteUpdate(&AsScene2207Elevator::suSetPosition);
+}
+
+AsScene2207Elevator::~AsScene2207Elevator() {
+ _vm->_soundMan->deleteSoundGroup(0x02700413);
+}
+
+void AsScene2207Elevator::update() {
+
+ if (_destPointIndex + _destPointIndexDelta > _pointIndex) {
+ _pointIndex++;
+ startAnimation(getGlobalVar(V_LIGHTS_ON) ? 0xC858CC19 : 0x294B3377, _pointIndex, _pointIndex);
+ _newStickFrameIndex = _pointIndex;
+ if (_destPointIndex + _destPointIndexDelta == _pointIndex) {
+ if (_destPointIndexDelta != 0)
+ _destPointIndexDelta = 0;
+ else {
+ _vm->_soundMan->deleteSound(0xD3B02847);
+ playSound(0, 0x53B8284A);
+ }
+ }
+ }
+
+ if (_destPointIndex + _destPointIndexDelta < _pointIndex) {
+ _pointIndex--;
+ if (_pointIndex == 0)
+ sendMessage(_parentScene, 0x2003, 0);
+ startAnimation(getGlobalVar(V_LIGHTS_ON) ? 0xC858CC19 : 0x294B3377, _pointIndex, _pointIndex);
+ _newStickFrameIndex = _pointIndex;
+ if (_destPointIndex + _destPointIndexDelta == _pointIndex) {
+ if (_destPointIndexDelta != 0)
+ _destPointIndexDelta = 0;
+ else {
+ _vm->_soundMan->deleteSound(0xD3B02847);
+ playSound(0, 0x53B8284A);
+ }
+ }
+ }
+
+ if (_pointIndex > 20 && _surface->getPriority() != 900)
+ sendMessage(_parentScene, NM_POSITION_CHANGE, 900);
+ else if (_pointIndex < 20 && _surface->getPriority() != 1100)
+ sendMessage(_parentScene, NM_POSITION_CHANGE, 1100);
+
+ AnimatedSprite::update();
+
+ if (_destPointIndex + _destPointIndexDelta == _pointIndex && _isMoving) {
+ sendMessage(_parentScene, 0x2004, 0);
+ _isMoving = false;
+ }
+
+}
+
+void AsScene2207Elevator::suSetPosition() {
+ _x = (*_pointArray)[_pointIndex].x;
+ _y = (*_pointArray)[_pointIndex].y - 60;
+ updateBounds();
+}
+
+uint32 AsScene2207Elevator::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case NM_ANIMATION_UPDATE:
+ moveToY(param.asInteger());
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene2207Elevator::moveToY(int16 y) {
+ int16 minDistance = 480;
+
+ if (!_pointArray || _pointArray->size() == 0)
+ return;
+
+ for (uint i = 0; i < _pointArray->size(); i++) {
+ int16 distance = ABS(y - (*_pointArray)[i].y);
+ if (distance < minDistance) {
+ minDistance = distance;
+ _destPointIndex = i;
+ }
+ }
+
+ if (_destPointIndex != _pointIndex) {
+ if (_destPointIndex == 0 || _destPointIndex == (int)_pointArray->size() - 1)
+ _destPointIndexDelta = 0;
+ else if (_destPointIndex < _pointIndex)
+ _destPointIndexDelta = -2;
+ else
+ _destPointIndexDelta = 2;
+ _vm->_soundMan->addSound(0x02700413, 0xD3B02847);
+ _vm->_soundMan->playSoundLooping(0xD3B02847);
+ }
+
+ _isMoving = true;
+
+}
+
+AsScene2207Lever::AsScene2207Lever(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y, int doDeltaX)
+ : AnimatedSprite(vm, 1100), _parentScene(parentScene) {
+
+ _x = x;
+ _y = y;
+ createSurface(1010, 71, 73);
+ setDoDeltaX(doDeltaX);
+ startAnimation(0x80880090, 0, -1);
+ _newStickFrameIndex = 0;
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsScene2207Lever::handleMessage);
+}
+
+uint32 AsScene2207Lever::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x1011:
+ sendMessage(_parentScene, 0x4826, 0);
+ messageResult = 1;
+ break;
+ case NM_ANIMATION_STOP:
+ gotoNextState();
+ stopAnimation();
+ break;
+ case NM_KLAYMEN_RAISE_LEVER:
+ stLeverUp();
+ break;
+ case NM_KLAYMEN_LOWER_LEVER:
+ stLeverDown();
+ break;
+ case NM_MOVE_TO_BACK:
+ sendMessage(_parentScene, NM_PRIORITY_CHANGE, 990);
+ break;
+ case NM_MOVE_TO_FRONT:
+ sendMessage(_parentScene, NM_PRIORITY_CHANGE, 1010);
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene2207Lever::stLeverDown() {
+ startAnimation(0x80880090, 1, -1);
+ playSound(0, 0x40581882);
+ FinalizeState(&AsScene2207Lever::stLeverDownEvent);
+}
+
+void AsScene2207Lever::stLeverDownEvent() {
+ sendMessage(_parentScene, NM_KLAYMEN_LOWER_LEVER, 0);
+}
+
+void AsScene2207Lever::stLeverUp() {
+ startAnimation(0x80880090, 6, -1);
+ _playBackwards = true;
+ playSound(0, 0x40581882);
+ FinalizeState(&AsScene2207Lever::stLeverUpEvent);
+}
+
+void AsScene2207Lever::stLeverUpEvent() {
+ sendMessage(_parentScene, NM_KLAYMEN_RAISE_LEVER, 0);
+}
+
+AsScene2207WallRobotAnimation::AsScene2207WallRobotAnimation(NeverhoodEngine *vm, Scene *parentScene)
+ : AnimatedSprite(vm, 1200), _idle(true) {
+
+ _x = 309;
+ _y = 320;
+ createSurface1(0xCCFD6090, 100);
+ startAnimation(0xCCFD6090, 0, -1);
+ _newStickFrameIndex = 0;
+ loadSound(1, 0x40330872);
+ loadSound(2, 0x72A2914A);
+ loadSound(3, 0xD4226080);
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsScene2207WallRobotAnimation::handleMessage);
+}
+
+AsScene2207WallRobotAnimation::~AsScene2207WallRobotAnimation() {
+ _vm->_soundMan->deleteSoundGroup(0x80D00820);
+}
+
+uint32 AsScene2207WallRobotAnimation::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case NM_ANIMATION_START:
+ if (!_idle) {
+ if (param.asInteger() == 0x3423093) {
+ _vm->_soundMan->addSound(0x80D00820, 0x12121943);
+ _vm->_soundMan->playSoundLooping(0x12121943);
+ } else if (param.asInteger() == 0x834AB011) {
+ stopSound(0);
+ stopSound(1);
+ stopSound(2);
+ stopSound(3);
+ _vm->_soundMan->deleteSound(0x12121943);
+ } else if (param.asInteger() == 0x3A980501)
+ playSound(1);
+ else if (param.asInteger() == 0x2A2AD498)
+ playSound(2);
+ else if (param.asInteger() == 0xC4980008)
+ playSound(3);
+ else if (param.asInteger() == 0x06B84228)
+ playSound(0, 0xE0702146);
+ }
+ break;
+ case NM_KLAYMEN_STOP_CLIMBING:
+ stStartAnimation();
+ break;
+ case NM_CAR_MOVE_TO_PREV_POINT:
+ stStopAnimation();
+ break;
+ case NM_ANIMATION_STOP:
+ gotoNextState();
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene2207WallRobotAnimation::stStartAnimation() {
+ if (!_idle) {
+ NextState(NULL);
+ } else {
+ startAnimation(0xCCFD6090, 0, -1);
+ _idle = false;
+ setVisible(true);
+ }
+}
+
+void AsScene2207WallRobotAnimation::stStopAnimation() {
+ NextState(&AsScene2207WallRobotAnimation::cbStopAnimation);
+}
+
+void AsScene2207WallRobotAnimation::cbStopAnimation() {
+ stopAnimation();
+ stopSound(0);
+ stopSound(1);
+ stopSound(2);
+ stopSound(3);
+ _vm->_soundMan->deleteSound(0x12121943);
+ _idle = true;
+ setVisible(false);
+}
+
+AsScene2207WallCannonAnimation::AsScene2207WallCannonAnimation(NeverhoodEngine *vm)
+ : AnimatedSprite(vm, 1200), _idle(true) {
+
+ _x = 309;
+ _y = 320;
+ createSurface1(0x8CAA0099, 100);
+ startAnimation(0x8CAA0099, 0, -1);
+ _newStickFrameIndex = 0;
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsScene2207WallCannonAnimation::handleMessage);
+}
+
+uint32 AsScene2207WallCannonAnimation::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case NM_KLAYMEN_STOP_CLIMBING:
+ stStartAnimation();
+ break;
+ case NM_CAR_MOVE_TO_PREV_POINT:
+ stStopAnimation();
+ break;
+ case NM_ANIMATION_STOP:
+ gotoNextState();
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene2207WallCannonAnimation::stStartAnimation() {
+ if (!_idle) {
+ NextState(NULL);
+ } else {
+ setVisible(true);
+ startAnimation(0x8CAA0099, 0, -1);
+ _idle = false;
+ }
+}
+
+void AsScene2207WallCannonAnimation::stStopAnimation() {
+ NextState(&AsScene2207WallCannonAnimation::cbStopAnimation);
+}
+
+void AsScene2207WallCannonAnimation::cbStopAnimation() {
+ stopAnimation();
+ setVisible(false);
+ _idle = true;
+}
+
+SsScene2207Symbol::SsScene2207Symbol(NeverhoodEngine *vm, uint32 fileHash, int index)
+ : StaticSprite(vm, fileHash, 100) {
+
+ _x = 330;
+ _y = 246 + index * 50;
+ updatePosition();
+}
+
+KmScene2201::KmScene2201(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y, NRect *clipRects, int clipRectsCount)
+ : Klaymen(vm, parentScene, x, y) {
+
+ _surface->setClipRects(clipRects, clipRectsCount);
+ _dataResource.load(0x04104242);
+}
+
+uint32 KmScene2201::xHandleMessage(int messageNum, const MessageParam &param) {
+ switch (messageNum) {
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case NM_KLAYMEN_STAND_IDLE:
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case NM_KLAYMEN_PICKUP:
+ GotoState(&Klaymen::stPickUpGeneric);
+ break;
+ case NM_KLAYMEN_PRESS_BUTTON:
+ if (param.asInteger() == 0)
+ GotoState(&Klaymen::stPressButtonSide);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger() ? 1 : 0);
+ gotoNextStateExt();
+ break;
+ case 0x4818:
+ startWalkToX(_dataResource.getPoint(param.asInteger()).x, false);
+ break;
+ case 0x481B:
+ if (param.asPoint().y != 0)
+ startWalkToXDistance(param.asPoint().y, param.asPoint().x);
+ else
+ startWalkToAttachedSpriteXDistance(param.asPoint().x);
+ break;
+ case NM_KLAYMEN_TURN_TO_USE:
+ GotoState(&Klaymen::stTurnToUse);
+ break;
+ case NM_KLAYMEN_RETURN_FROM_USE:
+ GotoState(&Klaymen::stReturnFromUse);
+ break;
+ case 0x482D:
+ setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
+ gotoNextStateExt();
+ break;
+ case 0x482E:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stWalkToFrontNoStep);
+ else
+ GotoState(&Klaymen::stWalkToFront);
+ break;
+ case 0x482F:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stTurnToFront);
+ else
+ GotoState(&Klaymen::stTurnToBack);
+ break;
+ case 0x483F:
+ startSpecialWalkRight(param.asInteger());
+ break;
+ case 0x4840:
+ startSpecialWalkLeft(param.asInteger());
+ break;
+ }
+ return 0;
+}
+
+KmScene2203::KmScene2203(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
+ : Klaymen(vm, parentScene, x, y) {
+
+ // Empty
+}
+
+uint32 KmScene2203::xHandleMessage(int messageNum, const MessageParam &param) {
+ switch (messageNum) {
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case NM_KLAYMEN_STAND_IDLE:
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case NM_KLAYMEN_PICKUP:
+ if (param.asInteger() == 2)
+ GotoState(&Klaymen::stPickUpNeedle);
+ else if (param.asInteger() == 1)
+ GotoState(&Klaymen::stPickUpTube);
+ else
+ GotoState(&Klaymen::stPickUpGeneric);
+ break;
+ case NM_KLAYMEN_PRESS_BUTTON:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stPressButton);
+ else if (param.asInteger() == 2)
+ GotoState(&Klaymen::stPressFloorButton);
+ else
+ GotoState(&Klaymen::stPressButtonSide);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ gotoNextStateExt();
+ break;
+ case 0x4818:
+ startWalkToX(_dataResource.getPoint(param.asInteger()).x, false);
+ break;
+ case 0x4819:
+ GotoState(&KmScene2203::stClayDoorOpen);
+ break;
+ case NM_KLAYMEN_INSERT_DISK:
+ GotoState(&Klaymen::stInsertDisk);
+ break;
+ case 0x481B:
+ if (param.asPoint().y != 0)
+ startWalkToXDistance(param.asPoint().y, param.asPoint().x);
+ else
+ startWalkToAttachedSpriteXDistance(param.asPoint().x);
+ break;
+ case NM_KLAYMEN_TURN_TO_USE:
+ GotoState(&Klaymen::stTurnToUse);
+ break;
+ case NM_KLAYMEN_RETURN_FROM_USE:
+ GotoState(&Klaymen::stReturnFromUse);
+ break;
+ case 0x482D:
+ setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
+ gotoNextStateExt();
+ break;
+ case 0x483F:
+ startSpecialWalkRight(param.asInteger());
+ break;
+ case 0x4840:
+ startSpecialWalkLeft(param.asInteger());
+ break;
+ }
+ return 0;
+}
+
+void KmScene2203::stClayDoorOpen() {
+ if (!stStartAction(AnimationCallback(&KmScene2203::stClayDoorOpen))) {
+ _busyStatus = 2;
+ _acceptInput = false;
+ startAnimation(0x5CCCB330, 0, -1);
+ SetUpdateHandler(&Klaymen::update);
+ SetMessageHandler(&KmScene2203::hmClayDoorOpen);
+ SetSpriteUpdate(&Klaymen::suUpdateDestX);
+ }
+}
+
+uint32 KmScene2203::hmClayDoorOpen(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = hmLowLevelAnimation(messageNum, param, sender);
+ switch (messageNum) {
+ case NM_ANIMATION_START:
+ if (param.asInteger() == 0x040D4186) {
+ sendMessage(_attachedSprite, NM_KLAYMEN_OPEN_DOOR, 0);
+ }
+ break;
+ }
+ return messageResult;
+}
+
+KmScene2205::KmScene2205(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
+ : Klaymen(vm, parentScene, x, y) {
+
+ // Empty
+}
+
+void KmScene2205::xUpdate() {
+ setGlobalVar(V_KLAYMEN_FRAMEINDEX, _currFrameIndex);
+}
+
+uint32 KmScene2205::xHandleMessage(int messageNum, const MessageParam &param) {
+ switch (messageNum) {
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case NM_KLAYMEN_STAND_IDLE:
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x4804:
+ if (param.asInteger() != 0) {
+ _destX = param.asInteger();
+ GotoState(&Klaymen::stStartWalkingResume);
+ } else
+ GotoState(&Klaymen::stPeekWall);
+ break;
+ case NM_KLAYMEN_PRESS_BUTTON:
+ if (param.asInteger() == 0)
+ GotoState(&Klaymen::stPressButtonSide);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ gotoNextStateExt();
+ break;
+ case 0x4818:
+ startWalkToX(_dataResource.getPoint(param.asInteger()).x, false);
+ break;
+ case 0x483F:
+ startSpecialWalkRight(param.asInteger());
+ break;
+ case 0x4840:
+ startSpecialWalkLeft(param.asInteger());
+ break;
+ }
+ return 0;
+}
+
+KmScene2206::KmScene2206(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
+ : Klaymen(vm, parentScene, x, y) {
+
+ _walkResumeFrameIncr = 1;
+ _vm->_soundMan->addSound(0x80101800, 0xD3B02847);
+}
+
+KmScene2206::~KmScene2206() {
+ _vm->_soundMan->deleteSoundGroup(0x80101800);
+}
+
+void KmScene2206::xUpdate() {
+ setGlobalVar(V_KLAYMEN_FRAMEINDEX, _currFrameIndex);
+}
+
+uint32 KmScene2206::xHandleMessage(int messageNum, const MessageParam &param) {
+ switch (messageNum) {
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case NM_KLAYMEN_STAND_IDLE:
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x4803:
+ GotoState(&KmScene2206::stRidePlatformDown);
+ break;
+ case 0x4804:
+ if (param.asInteger() != 0) {
+ _destX = param.asInteger();
+ GotoState(&Klaymen::stStartWalkingResume);
+ } else
+ GotoState(&Klaymen::stPeekWall);
+ break;
+ case NM_KLAYMEN_PICKUP:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stPickUpTube);
+ else
+ GotoState(&Klaymen::stPickUpGeneric);
+ break;
+ case NM_KLAYMEN_PRESS_BUTTON:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stPressButton);
+ else if (param.asInteger() == 2)
+ GotoState(&Klaymen::stPressFloorButton);
+ else
+ GotoState(&Klaymen::stPressButtonSide);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ gotoNextStateExt();
+ break;
+ case 0x481B:
+ if (param.asPoint().y != 0)
+ startWalkToXDistance(param.asPoint().y, param.asPoint().x);
+ else
+ startWalkToAttachedSpriteXDistance(param.asPoint().x);
+ break;
+ case 0x481F:
+ if (param.asInteger() == 0)
+ GotoState(&Klaymen::stWonderAboutHalf);
+ else if (param.asInteger() == 1)
+ GotoState(&Klaymen::stWonderAboutAfter);
+ else if (param.asInteger() == 3)
+ GotoState(&Klaymen::stTurnToUseHalf);
+ else if (param.asInteger() == 4)
+ GotoState(&Klaymen::stTurnAwayFromUse);
+ else
+ GotoState(&Klaymen::stWonderAbout);
+ break;
+ case 0x482D:
+ setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
+ gotoNextStateExt();
+ break;
+ case 0x482E:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stWalkToFrontNoStep);
+ else
+ GotoState(&Klaymen::stWalkToFront);
+ break;
+ case 0x482F:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stTurnToFront);
+ else
+ GotoState(&Klaymen::stTurnToBack);
+ break;
+ case 0x4837:
+ stopWalking();
+ break;
+ case 0x483F:
+ startSpecialWalkRight(param.asInteger());
+ break;
+ case 0x4840:
+ startSpecialWalkLeft(param.asInteger());
+ break;
+ }
+ return 0;
+}
+
+void KmScene2206::suRidePlatformDown() {
+ _platformDeltaY++;
+ _y += _platformDeltaY;
+ if (_y > 600)
+ sendMessage(this, NM_SCENE_LEAVE, 0);
+}
+
+void KmScene2206::stRidePlatformDown() {
+ if (!stStartActionFromIdle(AnimationCallback(&KmScene2206::stRidePlatformDown))) {
+ _busyStatus = 1;
+ sendMessage(_parentScene, 0x4803, 0);
+ _acceptInput = false;
+ _platformDeltaY = 0;
+ startAnimation(0x5420E254, 0, -1);
+ SetUpdateHandler(&Klaymen::update);
+ SetMessageHandler(&Klaymen::hmLowLevel);
+ SetSpriteUpdate(&KmScene2206::suRidePlatformDown);
+ _vm->_soundMan->playSoundLooping(0xD3B02847);
+ }
+}
+
+KmScene2207::KmScene2207(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
+ : Klaymen(vm, parentScene, x, y) {
+
+ // Empty
+}
+
+uint32 KmScene2207::xHandleMessage(int messageNum, const MessageParam &param) {
+ switch (messageNum) {
+ case 0x2001:
+ GotoState(&Klaymen::stRidePlatform);
+ break;
+ case NM_KLAYMEN_CLIMB_LADDER:
+ suRidePlatform();
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case NM_KLAYMEN_STAND_IDLE:
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x480D:
+ GotoState(&Klaymen::stInteractLever);
+ break;
+ case NM_KLAYMEN_PICKUP:
+ GotoState(&Klaymen::stPickUpGeneric);
+ break;
+ case NM_KLAYMEN_PRESS_BUTTON:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stPressButton);
+ else if (param.asInteger() == 2)
+ GotoState(&Klaymen::stPressFloorButton);
+ else
+ GotoState(&Klaymen::stPressButtonSide);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ gotoNextStateExt();
+ break;
+ case 0x481B:
+ if (param.asPoint().y != 0)
+ startWalkToXDistance(param.asPoint().y, param.asPoint().x);
+ else
+ startWalkToAttachedSpriteXDistance(param.asPoint().x);
+ break;
+ case NM_KLAYMEN_RELEASE_LEVER:
+ GotoState(&Klaymen::stReleaseLever);
+ break;
+ case 0x482D:
+ setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
+ gotoNextStateExt();
+ break;
+ case 0x483F:
+ startSpecialWalkRight(param.asInteger());
+ break;
+ case 0x4840:
+ startSpecialWalkLeft(param.asInteger());
+ break;
+ }
+ return 0;
+}
+
+KmScene2242::KmScene2242(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
+ : Klaymen(vm, parentScene, x, y) {
+
+ // Empty
+}
+
+void KmScene2242::xUpdate() {
+ setGlobalVar(V_KLAYMEN_FRAMEINDEX, _currFrameIndex);
+}
+
+uint32 KmScene2242::xHandleMessage(int messageNum, const MessageParam &param) {
+ switch (messageNum) {
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case NM_KLAYMEN_STAND_IDLE:
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x4804:
+ if (param.asInteger() != 0) {
+ _destX = param.asInteger();
+ GotoState(&Klaymen::stStartWalkingResume);
+ } else
+ GotoState(&Klaymen::stPeekWall);
+ break;
+ case NM_KLAYMEN_PICKUP:
+ if (param.asInteger() == 2)
+ GotoState(&Klaymen::stPickUpNeedle);
+ else if (param.asInteger() == 1)
+ GotoState(&Klaymen::stPickUpTube);
+ else
+ GotoState(&Klaymen::stPickUpGeneric);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ gotoNextStateExt();
+ break;
+ case 0x481B:
+ if (param.asPoint().y != 0)
+ startWalkToXDistance(param.asPoint().y, param.asPoint().x);
+ else
+ startWalkToAttachedSpriteXDistance(param.asPoint().x);
+ break;
+ case 0x481F:
+ if (param.asInteger() == 0)
+ GotoState(&Klaymen::stWonderAboutHalf);
+ else if (param.asInteger() == 1)
+ GotoState(&Klaymen::stWonderAboutAfter);
+ else if (param.asInteger() == 3)
+ GotoState(&Klaymen::stTurnToUseHalf);
+ else if (param.asInteger() == 4)
+ GotoState(&Klaymen::stTurnAwayFromUse);
+ else
+ GotoState(&Klaymen::stWonderAbout);
+ break;
+ case 0x482D:
+ setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
+ gotoNextStateExt();
+ break;
+ case 0x4837:
+ stopWalking();
+ break;
+ }
+ return 0;
+}
+
+KmHallOfRecords::KmHallOfRecords(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
+ : Klaymen(vm, parentScene, x, y) {
+ // Empty
+}
+
+void KmHallOfRecords::xUpdate() {
+ setGlobalVar(V_KLAYMEN_FRAMEINDEX, _currFrameIndex);
+}
+
+uint32 KmHallOfRecords::xHandleMessage(int messageNum, const MessageParam &param) {
+ switch (messageNum) {
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case NM_KLAYMEN_STAND_IDLE:
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x4804:
+ if (param.asInteger() != 0) {
+ _destX = param.asInteger();
+ GotoState(&Klaymen::stStartWalkingResume);
+ } else
+ GotoState(&Klaymen::stPeekWall);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ gotoNextStateExt();
+ break;
+ case 0x481F:
+ if (param.asInteger() == 0)
+ GotoState(&Klaymen::stWonderAboutHalf);
+ else if (param.asInteger() == 1)
+ GotoState(&Klaymen::stWonderAboutAfter);
+ else if (param.asInteger() == 3)
+ GotoState(&Klaymen::stTurnToUseHalf);
+ else if (param.asInteger() == 4)
+ GotoState(&Klaymen::stTurnAwayFromUse);
+ else
+ GotoState(&Klaymen::stWonderAbout);
+ break;
+ case 0x482D:
+ setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
+ gotoNextStateExt();
+ break;
+ case 0x4837:
+ stopWalking();
+ break;
+ }
+ return 0;
+}
+
+KmScene2247::KmScene2247(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
+ : Klaymen(vm, parentScene, x, y) {
+
+ // Empty
+}
+
+void KmScene2247::xUpdate() {
+ setGlobalVar(V_KLAYMEN_FRAMEINDEX, _currFrameIndex);
+}
+
+uint32 KmScene2247::xHandleMessage(int messageNum, const MessageParam &param) {
+ switch (messageNum) {
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case NM_KLAYMEN_STAND_IDLE:
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x4804:
+ if (param.asInteger() != 0) {
+ _destX = param.asInteger();
+ GotoState(&Klaymen::stStartWalkingResume);
+ } else
+ GotoState(&Klaymen::stPeekWall);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ gotoNextStateExt();
+ break;
+ case 0x481F:
+ if (param.asInteger() == 0)
+ GotoState(&Klaymen::stWonderAboutHalf);
+ else if (param.asInteger() == 1)
+ GotoState(&Klaymen::stWonderAboutAfter);
+ else if (param.asInteger() == 3)
+ GotoState(&Klaymen::stTurnToUseHalf);
+ else if (param.asInteger() == 4)
+ GotoState(&Klaymen::stTurnAwayFromUse);
+ else
+ GotoState(&Klaymen::stWonderAbout);
+ break;
+ case 0x482D:
+ setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
+ gotoNextStateExt();
+ break;
+ case 0x4837:
+ stopWalking();
+ break;
+ }
+ return 0;
+}
+
+} // End of namespace Neverhood
diff --git a/engines/neverhood/modules/module2200_sprites.h b/engines/neverhood/modules/module2200_sprites.h
new file mode 100644
index 0000000000..9aaf3b6aae
--- /dev/null
+++ b/engines/neverhood/modules/module2200_sprites.h
@@ -0,0 +1,275 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public 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 NEVERHOOD_MODULES_MODULE2200_SPRITES_H
+#define NEVERHOOD_MODULES_MODULE2200_SPRITES_H
+
+#include "neverhood/neverhood.h"
+#include "neverhood/module.h"
+#include "neverhood/scene.h"
+#include "neverhood/graphics.h"
+
+namespace Neverhood {
+
+static const NPoint kSsScene2201PuzzleCubePoints[] = {
+ {305, 305}, {321, 305}, {336, 305}, {305, 319},
+ {321, 319}, {336, 319}, {305, 332}, {321, 332},
+ {336, 333}
+};
+
+static const uint32 kSsScene2201PuzzleCubeFileHashes[] = {
+ 0x88134A44, 0xAA124340, 0xB8124602, 0xA902464C,
+ 0x890A4244, 0xA8124642, 0xB812C204, 0x381A4A4C
+};
+
+class AsScene2201CeilingFan : public AnimatedSprite {
+public:
+ AsScene2201CeilingFan(NeverhoodEngine *vm);
+};
+
+class AsScene2201Door : public AnimatedSprite {
+public:
+ AsScene2201Door(NeverhoodEngine *vm, Klaymen *klaymen, Sprite *ssDoorLight, bool isOpen);
+protected:
+ Klaymen *_klaymen;
+ Sprite *_ssDoorLight;
+ bool _isOpen;
+ int _countdown;
+ void update();
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ void stOpenDoor();
+ void stCloseDoor();
+};
+
+class SsScene2201PuzzleCube : public StaticSprite {
+public:
+ SsScene2201PuzzleCube(NeverhoodEngine *vm, uint32 positionIndex, uint32 cubeIndex);
+};
+
+class SsScene2202PuzzleCube : public StaticSprite {
+public:
+ SsScene2202PuzzleCube(NeverhoodEngine *vm, Scene *parentScene, int16 cubePosition, int16 cubeSymbol);
+protected:
+ Scene *_parentScene;
+ int16 _cubeSymbol;
+ int16 _cubePosition;
+ int16 _newX, _newY;
+ int16 _xDelta, _yDelta;
+ int16 _xIncr;
+ int16 _yIncr;
+ int16 _errValue;
+ int16 _counter;
+ int16 _xFlagPos;
+ bool _counterDirection;
+ bool _isMoving;
+ void update();
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ void suMoveCubeX();
+ void suMoveCubeY();
+ void moveCube(int16 newCubePosition);
+ void stopMoving();
+};
+
+class AsCommonKey : public AnimatedSprite {
+public:
+ AsCommonKey(NeverhoodEngine *vm, Scene *parentScene, int keyIndex, int surfacePriority, int16 x, int16 y);
+protected:
+ Scene *_parentScene;
+ int _keyIndex;
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class AsScene2203Door : public AnimatedSprite {
+public:
+ AsScene2203Door(NeverhoodEngine *vm, Scene *parentScene, uint doorIndex);
+protected:
+ Scene *_parentScene;
+ Sprite *_otherDoor;
+ uint _doorIndex;
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ void openDoor();
+ void closeDoor();
+};
+
+class SsScene2205DoorFrame : public StaticSprite {
+public:
+ SsScene2205DoorFrame(NeverhoodEngine *vm);
+protected:
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class AsScene2206DoorSpikes : public StaticSprite {
+public:
+ AsScene2206DoorSpikes(NeverhoodEngine *vm, uint32 fileHash);
+protected:
+ int _deltaIndex;
+ void update();
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ void suOpen();
+ void suClose();
+};
+
+class AsScene2206Platform : public StaticSprite {
+public:
+ AsScene2206Platform(NeverhoodEngine *vm, uint32 fileHash);
+protected:
+ int16 _yDelta;
+ void update();
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ void suMoveDown();
+};
+
+class SsScene2206TestTube : public StaticSprite {
+public:
+ SsScene2206TestTube(NeverhoodEngine *vm, Scene *parentScene, int surfacePriority, uint32 fileHash);
+protected:
+ Scene *_parentScene;
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class AsScene2207Elevator : public AnimatedSprite {
+public:
+ AsScene2207Elevator(NeverhoodEngine *vm, Scene *parentScene);
+ ~AsScene2207Elevator();
+protected:
+ Scene *_parentScene;
+ NPointArray *_pointArray;
+ int16 _pointIndex;
+ int16 _destPointIndex, _destPointIndexDelta;
+ bool _isMoving;
+ void update();
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ void suSetPosition();
+ void moveToY(int16 y);
+};
+
+class AsScene2207Lever : public AnimatedSprite {
+public:
+ AsScene2207Lever(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y, int doDeltaX);
+protected:
+ Scene *_parentScene;
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ void stLeverDown();
+ void stLeverDownEvent();
+ void stLeverUp();
+ void stLeverUpEvent();
+};
+
+class AsScene2207WallRobotAnimation : public AnimatedSprite {
+public:
+ AsScene2207WallRobotAnimation(NeverhoodEngine *vm, Scene *parentScene);
+ ~AsScene2207WallRobotAnimation();
+protected:
+ bool _idle;
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ void stStartAnimation();
+ void stStopAnimation();
+ void cbStopAnimation();
+};
+
+class AsScene2207WallCannonAnimation : public AnimatedSprite {
+public:
+ AsScene2207WallCannonAnimation(NeverhoodEngine *vm);
+protected:
+ bool _idle;
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ void stStartAnimation();
+ void stStopAnimation();
+ void cbStopAnimation();
+};
+
+class SsScene2207Symbol : public StaticSprite {
+public:
+ SsScene2207Symbol(NeverhoodEngine *vm, uint32 fileHash, int index);
+};
+
+class KmScene2201 : public Klaymen {
+public:
+ KmScene2201(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y, NRect *clipRects, int clipRectsCount);
+protected:
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+};
+
+class KmScene2203 : public Klaymen {
+public:
+ KmScene2203(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
+protected:
+ void stClayDoorOpen();
+ uint32 hmClayDoorOpen(int messageNum, const MessageParam &param, Entity *sender);
+
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+};
+
+class KmScene2205 : public Klaymen {
+public:
+ KmScene2205(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
+protected:
+ void xUpdate();
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+};
+
+class KmScene2206 : public Klaymen {
+public:
+ KmScene2206(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
+ ~KmScene2206();
+protected:
+ void stRidePlatformDown();
+ void suRidePlatformDown();
+
+ void xUpdate();
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+};
+
+class KmScene2207 : public Klaymen {
+public:
+ KmScene2207(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
+protected:
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+};
+
+class KmScene2242 : public Klaymen {
+public:
+ KmScene2242(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
+protected:
+ void xUpdate();
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+};
+
+class KmHallOfRecords : public Klaymen {
+public:
+ KmHallOfRecords(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
+protected:
+ void xUpdate();
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+};
+
+class KmScene2247 : public Klaymen {
+public:
+ KmScene2247(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
+protected:
+ void xUpdate();
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+};
+
+} // End of namespace Neverhood
+
+#endif /* NEVERHOOD_MODULES_MODULE2200_SPRITES_H */
diff --git a/engines/neverhood/modules/module2300.cpp b/engines/neverhood/modules/module2300.cpp
index 2a46df1ee2..689d53570f 100644
--- a/engines/neverhood/modules/module2300.cpp
+++ b/engines/neverhood/modules/module2300.cpp
@@ -20,8 +20,8 @@
*
*/
-#include "neverhood/modules/module2300.h"
#include "neverhood/navigationscene.h"
+#include "neverhood/modules/module2300.h"
namespace Neverhood {
diff --git a/engines/neverhood/modules/module2400.cpp b/engines/neverhood/modules/module2400.cpp
index 21ea390ba2..867fb692f2 100644
--- a/engines/neverhood/modules/module2400.cpp
+++ b/engines/neverhood/modules/module2400.cpp
@@ -20,7 +20,13 @@
*
*/
+#include "neverhood/modules/module1000_sprites.h"
+#include "neverhood/modules/module1200_sprites.h"
#include "neverhood/modules/module2400.h"
+#include "neverhood/modules/module2100_sprites.h"
+#include "neverhood/modules/module2200_sprites.h"
+#include "neverhood/modules/module2400_sprites.h"
+#include "neverhood/modules/module2800_sprites.h"
namespace Neverhood {
@@ -175,198 +181,6 @@ static const NRect kScene2401Rects[] = {
{ 465, 331, 491, 389 }
};
-static const uint32 kAsScene2401WaterSpitFileHashes2[] = {
- 0x5C044690, 0x5C644690, 0x5CA44690,
- 0x5D244690, 0x5E244690
-};
-
-static const uint32 kAsScene2401WaterSpitFileHashes1[] = {
- 0xF4418408, 0xF4418808, 0xF4419008,
- 0xF441A008, 0xCD4F8411
-};
-
-AsScene2401WaterSpit::AsScene2401WaterSpit(NeverhoodEngine *vm)
- : AnimatedSprite(vm, 1200) {
-
- _x = 240;
- _y = 447;
- createSurface(100, 146, 74);
- setVisible(false);
- SetUpdateHandler(&AnimatedSprite::update);
- SetMessageHandler(&AsScene2401WaterSpit::handleMessage);
- SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
-}
-
-uint32 AsScene2401WaterSpit::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x100D:
- if (param.asInteger() == 0x120A0013)
- playSound(0, kAsScene2401WaterSpitFileHashes1[_soundIndex]);
- break;
- case 0x2000:
- _x = 240;
- _y = 447;
- _soundIndex = getSubVar(VA_CURR_WATER_PIPES_LEVEL, param.asInteger());
- startAnimation(kAsScene2401WaterSpitFileHashes2[param.asInteger()], 0, -1);
- setVisible(true);
- playSound(0, 0x48640244);
- break;
- case 0x3002:
- stopAnimation();
- setVisible(false);
- break;
- }
- return messageResult;
-}
-
-AsScene2401FlowingWater::AsScene2401FlowingWater(NeverhoodEngine *vm)
- : AnimatedSprite(vm, 1200), _isWaterFlowing(false) {
-
- _x = 88;
- _y = 421;
- createSurface1(0x10203116, 100);
- setVisible(false);
- SetUpdateHandler(&AnimatedSprite::update);
- SetMessageHandler(&AsScene2401FlowingWater::handleMessage);
-}
-
-AsScene2401FlowingWater::~AsScene2401FlowingWater() {
- _vm->_soundMan->deleteSoundGroup(0x40F11C09);
-}
-
-uint32 AsScene2401FlowingWater::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x100D:
- if (_isWaterFlowing && param.asInteger() == 0x02421405)
- startAnimationByHash(0x10203116, 0x01084280, 0);
- break;
- case 0x2002:
- if (!_isWaterFlowing) {
- _vm->_soundMan->addSound(0x40F11C09, 0x980C1420);
- _vm->_soundMan->playSoundLooping(0x980C1420);
- startAnimation(0x10203116, 0, -1);
- setVisible(true);
- _isWaterFlowing = true;
- }
- break;
- case 0x2003:
- _vm->_soundMan->deleteSound(0x980C1420);
- _isWaterFlowing = false;
- break;
- case 0x3002:
- stopAnimation();
- setVisible(false);
- break;
- }
- return messageResult;
-}
-
-AsScene2401WaterFlushing::AsScene2401WaterFlushing(NeverhoodEngine *vm, int16 x, int16 y)
- : AnimatedSprite(vm, 1200), _countdown(0), _flushLoopCount(0) {
-
- _x = x;
- _y = y;
- createSurface1(0xB8596884, 100);
- setVisible(false);
- SetUpdateHandler(&AsScene2401WaterFlushing::update);
- SetMessageHandler(&AsScene2401WaterFlushing::handleMessage);
-}
-
-void AsScene2401WaterFlushing::update() {
- if (_countdown != 0 && (--_countdown) == 0) {
- setDoDeltaX(_vm->_rnd->getRandomNumber(1));
- startAnimation(0xB8596884, 0, -1);
- setVisible(true);
- }
- AnimatedSprite::update();
-}
-
-uint32 AsScene2401WaterFlushing::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x100D:
- if (_flushLoopCount > 0 && param.asInteger() == 0x02421405) {
- startAnimationByHash(0xB8596884, 0x01084280, 0);
- _flushLoopCount--;
- }
- break;
- case 0x2002:
- if (param.asInteger() > 0) {
- _flushLoopCount = param.asInteger() - 1;
- _countdown = _vm->_rnd->getRandomNumber(3) + 1;
- }
- break;
- case 0x3002:
- stopAnimation();
- setVisible(false);
- break;
- }
- return messageResult;
-}
-
-AsScene2401Door::AsScene2401Door(NeverhoodEngine *vm, bool isOpen)
- : AnimatedSprite(vm, 1100), _countdown(0), _isOpen(isOpen) {
-
- _x = 320;
- _y = 240;
- createSurface1(0x44687810, 100);
- _newStickFrameIndex = STICK_LAST_FRAME;
- if (_isOpen) {
- stopAnimation();
- setVisible(false);
- _countdown = 48;
- } else {
- startAnimation(0x44687810, 0, -1);
- _newStickFrameIndex = 0;
- }
- SetUpdateHandler(&AsScene2401Door::update);
- SetMessageHandler(&AsScene2401Door::handleMessage);
-}
-
-void AsScene2401Door::update() {
- if (_isOpen && _countdown != 0 && (--_countdown) == 0) {
- _isOpen = false;
- setVisible(true);
- startAnimation(0x44687810, -1, -1);
- _newStickFrameIndex = 0;
- _playBackwards = true;
- playSound(0, calcHash("fxDoorClose38"));
- }
- AnimatedSprite::update();
-}
-
-uint32 AsScene2401Door::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x2004:
- if (_isOpen)
- _countdown = 168;
- messageResult = _isOpen ? 1 : 0;
- break;
- case 0x3002:
- gotoNextState();
- break;
- case 0x4808:
- if (!_isOpen) {
- _countdown = 168;
- _isOpen = true;
- setVisible(true);
- startAnimation(0x44687810, 0, -1);
- playSound(0, calcHash("fxDoorOpen38"));
- NextState(&AsScene2401Door::stDoorOpenFinished);
- }
- break;
- }
- return messageResult;
-}
-
-void AsScene2401Door::stDoorOpenFinished() {
- stopAnimation();
- setVisible(false);
-}
-
Scene2401::Scene2401(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule), _countdown1(0), _countdown2(0), _unkFlag(false),
_soundToggle(false), _asWaterSpitIndex(0) {
@@ -439,11 +253,11 @@ void Scene2401::update() {
if (puzzleSolved) {
setGlobalVar(V_NOTES_DOOR_UNLOCKED, 1);
setGlobalVar(V_NOTES_PUZZLE_SOLVED, 1);
- sendMessage(_asDoor, 0x4808, 0);
+ sendMessage(_asDoor, NM_KLAYMEN_OPEN_DOOR, 0);
} else if (waterInside) {
playPipeSound(0xD0431020);
for (uint i = 0; i < 5; i++) {
- sendMessage(_asWaterFlushing[i], 0x2002, getSubVar(VA_CURR_WATER_PIPES_LEVEL, i));
+ sendMessage(_asWaterFlushing[i], NM_POSITION_CHANGE, getSubVar(VA_CURR_WATER_PIPES_LEVEL, i));
setSubVar(VA_CURR_WATER_PIPES_LEVEL, i, 0);
}
}
@@ -469,7 +283,7 @@ void Scene2401::update() {
uint32 Scene2401::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0x402064D8)
sendEntityMessage(_klaymen, 0x1014, _ssButton);
else if (param.asInteger() == 0x02144CB1)
@@ -499,7 +313,7 @@ uint32 Scene2401::handleMessage(int messageNum, const MessageParam &param, Entit
} else if (param.asInteger() == 0x09C4B40A && _countdown2 > 12)
_countdown2 = 12;
break;
- case 0x2000:
+ case NM_ANIMATION_UPDATE:
messageResult = 0;
for (uint32 i = 0; i < 5; i++)
if (kScene2401Rects[i].contains(_mouseClickPos.x, _mouseClickPos.y)) {
@@ -520,15 +334,15 @@ uint32 Scene2401::handleMessage(int messageNum, const MessageParam &param, Entit
_countdown1 = 8;
} else if (sender == _ssFloorButton && getGlobalVar(V_WATER_RUNNING)) {
_countdown2 = 144;
- sendMessage(_asFlowingWater, 0x2002, 0);
+ sendMessage(_asFlowingWater, NM_POSITION_CHANGE, 0);
playSound(0, 0xE1130324);
}
break;
- case 0x482A:
+ case NM_MOVE_TO_BACK:
_palette->addBasePalette(0xB103B604, 0, 65, 0);
_palette->startFadeToPalette(12);
break;
- case 0x482B:
+ case NM_MOVE_TO_FRONT:
_palette->addBasePalette(0x91D3A391, 0, 65, 0);
_palette->startFadeToPalette(12);
break;
@@ -546,143 +360,6 @@ static const uint32 kScene2402FileHashes[] = {
0xD0910068, 0xD09100A8
};
-AsScene2402Door::AsScene2402Door(NeverhoodEngine *vm, Scene *parentScene, bool isOpen)
- : AnimatedSprite(vm, 1100), _parentScene(parentScene), _isOpen(isOpen), _countdown(0) {
-
- _x = 320;
- _y = 240;
- createSurface1(0x80495831, 100);
- if (_isOpen) {
- startAnimation(0x80495831, -1, -1);
- _newStickFrameIndex = STICK_LAST_FRAME;
- _countdown = 48;
- } else {
- stopAnimation();
- setVisible(false);
- }
- SetUpdateHandler(&AsScene2402Door::update);
- SetMessageHandler(&AsScene2402Door::handleMessage);
-}
-
-void AsScene2402Door::update() {
- if (_isOpen && _countdown != 0 && (--_countdown) == 0) {
- _isOpen = false;
- setVisible(true);
- startAnimation(0x80495831, -1, -1);
- _playBackwards = true;
- playSound(0, calcHash("fxDoorClose38"));
- NextState(&AsScene2402Door::stDoorClosingFinished);
- }
- AnimatedSprite::update();
-}
-
-uint32 AsScene2402Door::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x2000:
- if (_isOpen)
- _countdown = 144;
- messageResult = _isOpen ? 1 : 0;
- break;
- case 0x3002:
- gotoNextState();
- break;
- case 0x4808:
- _countdown = 144;
- _isOpen = true;
- setVisible(true);
- startAnimation(0x80495831, 0, -1);
- _newStickFrameIndex = STICK_LAST_FRAME;
- playSound(0, calcHash("fxDoorOpen38"));
- break;
- }
- return messageResult;
-}
-
-void AsScene2402Door::stDoorClosingFinished() {
- sendMessage(_parentScene, 0x2001, 0);
- setVisible(false);
-}
-
-AsScene2402TV::AsScene2402TV(NeverhoodEngine *vm, Klaymen *klaymen)
- : AnimatedSprite(vm, 1100), _klaymen(klaymen), _countdown1(0), _countdown2(0) {
-
- _x = 260;
- _y = 210;
- createSurface(100, 127, 90);
- setDoDeltaX(1);
- SetMessageHandler(&Sprite::handleMessage);
- if (!getGlobalVar(V_TV_JOKE_TOLD)) {
- loadSound(0, 0x58208810);
- _countdown1 = 48;
- startAnimation(0x4919397A, 0, -1);
- _newStickFrameIndex = 0;
- SetUpdateHandler(&AsScene2402TV::upWait);
- } else {
- int16 frameIndex;
- if (_klaymen->getX() > 320)
- _currFrameIndex = 29;
- frameIndex = CLIP<int16>((_klaymen->getX() - _x + 150) / 10, 0, 29);
- startAnimation(0x050A0103, frameIndex, -1);
- _newStickFrameIndex = frameIndex;
- _countdown1 = 0;
- SetUpdateHandler(&AsScene2402TV::upFocusKlaymen);
- }
-}
-
-AsScene2402TV::~AsScene2402TV() {
- _vm->_soundMan->deleteSoundGroup(0x01520123);
-}
-
-void AsScene2402TV::upWait() {
- if (_countdown1 != 0 && (--_countdown1) == 0) {
- startAnimation(0x4919397A, 0, -1);
- SetMessageHandler(&AsScene2402TV::hmJoke);
- NextState(&AsScene2402TV::stJokeFinished);
- }
- AnimatedSprite::update();
-}
-
-void AsScene2402TV::upFocusKlaymen() {
- int16 frameIndex = CLIP<int16>((_klaymen->getX() - _x + 150) / 10, 0, 29);
- if (frameIndex != _currFrameIndex) {
- if (frameIndex > _currFrameIndex)
- _currFrameIndex++;
- else if (frameIndex < _currFrameIndex)
- _currFrameIndex--;
- startAnimation(0x050A0103, _currFrameIndex, -1);
- _newStickFrameIndex = _currFrameIndex;
- if (_countdown2 == 0) {
- _vm->_soundMan->addSound(0x01520123, 0xC42D4528);
- _vm->_soundMan->playSoundLooping(0xC42D4528);
- }
- _countdown2 = 5;
- } else if (_countdown2 != 0 && (--_countdown2 == 0))
- _vm->_soundMan->deleteSound(0xC42D4528);
- AnimatedSprite::update();
-}
-
-void AsScene2402TV::stJokeFinished() {
- setGlobalVar(V_TV_JOKE_TOLD, 1);
- startAnimation(0x050A0103, 0, -1);
- _newStickFrameIndex = 0;
- SetUpdateHandler(&AsScene2402TV::upFocusKlaymen);
-}
-
-uint32 AsScene2402TV::hmJoke(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x100D:
- if (param.asInteger() == 0x431EA0B0)
- playSound(0);
- break;
- case 0x3002:
- gotoNextState();
- break;
- }
- return messageResult;
-}
-
Scene2402::Scene2402(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule), _countdown(0), _soundToggle(false) {
@@ -734,7 +411,7 @@ Scene2402::~Scene2402() {
void Scene2402::update() {
if (_countdown != 0 && (--_countdown) == 0) {
if (_pipeStatus >= 10) {
- sendMessage(_asDoor, 0x4808, 0);
+ sendMessage(_asDoor, NM_KLAYMEN_OPEN_DOOR, 0);
_ssDoorFrame->loadSprite(0x00B415E0, kSLFDefDrawOffset | kSLFDefPosition);
} else if (_pipeStatus >= 5) {
_countdown = 8;
@@ -751,7 +428,7 @@ void Scene2402::update() {
uint32 Scene2402::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0x402064D8)
sendEntityMessage(_klaymen, 0x1014, _ssButton);
else if (param.asInteger() == 0x01C66840) {
@@ -839,13 +516,13 @@ Scene2403::Scene2403(NeverhoodEngine *vm, Module *parentModule, int which)
uint32 Scene2403::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0x040424D0)
sendEntityMessage(_klaymen, 0x1014, _ssButton);
else if (param.asInteger() == 0x180CE614)
sendEntityMessage(_klaymen, 0x1014, _asLightCord);
break;
- case 0x2000:
+ case NM_ANIMATION_UPDATE:
_isClimbingLadder = true;
setRectList(0x004B5E28);
break;
@@ -864,7 +541,7 @@ uint32 Scene2403::handleMessage(int messageNum, const MessageParam &param, Entit
}
}
break;
- case 0x480F:
+ case NM_KLAYMEN_LOWER_LEVER:
if (sender == _asLightCord)
leaveScene(2);
break;
@@ -960,7 +637,7 @@ Scene2406::Scene2406(NeverhoodEngine *vm, Module *parentModule, int which)
uint32 Scene2406::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0x41062804) {
if (getGlobalVar(V_SPIKES_RETRACTED))
setMessageList(0x004B7758);
@@ -968,7 +645,7 @@ uint32 Scene2406::handleMessage(int messageNum, const MessageParam &param, Entit
setMessageList(0x004B7738);
}
break;
- case 0x2000:
+ case NM_ANIMATION_UPDATE:
_isClimbingLadder = true;
setRectList(0x004B78D8);
break;
diff --git a/engines/neverhood/modules/module2400.h b/engines/neverhood/modules/module2400.h
index 3802c747f1..61603f3e00 100644
--- a/engines/neverhood/modules/module2400.h
+++ b/engines/neverhood/modules/module2400.h
@@ -27,13 +27,6 @@
#include "neverhood/module.h"
#include "neverhood/scene.h"
#include "neverhood/gamemodule.h"
-#include "neverhood/modules/module1000.h"
-#include "neverhood/modules/module1100.h"
-#include "neverhood/modules/module1200.h"
-#include "neverhood/modules/module2100.h"
-#include "neverhood/modules/module2200.h"
-#include "neverhood/modules/module2800.h"
-#include "neverhood/modules/module2800_sprites.h"
#include "neverhood/diskplayerscene.h"
namespace Neverhood {
@@ -51,44 +44,6 @@ protected:
uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
};
-class AsScene2401WaterSpit : public AnimatedSprite {
-public:
- AsScene2401WaterSpit(NeverhoodEngine *vm);
-protected:
- int _soundIndex;
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
-
-class AsScene2401FlowingWater : public AnimatedSprite {
-public:
- AsScene2401FlowingWater(NeverhoodEngine *vm);
- virtual ~AsScene2401FlowingWater();
-protected:
- bool _isWaterFlowing;
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
-
-class AsScene2401WaterFlushing : public AnimatedSprite {
-public:
- AsScene2401WaterFlushing(NeverhoodEngine *vm, int16 x, int16 y);
-protected:
- int _countdown;
- int _flushLoopCount;
- void update();
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
-
-class AsScene2401Door : public AnimatedSprite {
-public:
- AsScene2401Door(NeverhoodEngine *vm, bool isOpen);
-protected:
- int _countdown;
- bool _isOpen;
- void update();
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- void stDoorOpenFinished();
-};
-
class Scene2401 : public Scene {
public:
Scene2401(NeverhoodEngine *vm, Module *parentModule, int which);
@@ -112,32 +67,6 @@ protected:
void playPipeSound(uint32 fileHash);
};
-class AsScene2402Door : public AnimatedSprite {
-public:
- AsScene2402Door(NeverhoodEngine *vm, Scene *parentScene, bool isOpen);
-protected:
- Scene *_parentScene;
- int _countdown;
- bool _isOpen;
- void update();
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- void stDoorClosingFinished();
-};
-
-class AsScene2402TV : public AnimatedSprite {
-public:
- AsScene2402TV(NeverhoodEngine *vm, Klaymen *klaymen);
- virtual ~AsScene2402TV();
-protected:
- Klaymen *_klaymen;
- int _countdown1;
- int _countdown2;
- void upWait();
- void upFocusKlaymen();
- void stJokeFinished();
- uint32 hmJoke(int messageNum, const MessageParam &param, Entity *sender);
-};
-
class Scene2402 : public Scene {
public:
Scene2402(NeverhoodEngine *vm, Module *parentModule, int which);
diff --git a/engines/neverhood/modules/module2400_sprites.cpp b/engines/neverhood/modules/module2400_sprites.cpp
new file mode 100644
index 0000000000..32c00cde27
--- /dev/null
+++ b/engines/neverhood/modules/module2400_sprites.cpp
@@ -0,0 +1,741 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public 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 "neverhood/modules/module2400_sprites.h"
+
+namespace Neverhood {
+
+static const uint32 kAsScene2401WaterSpitFileHashes2[] = {
+ 0x5C044690, 0x5C644690, 0x5CA44690,
+ 0x5D244690, 0x5E244690
+};
+
+static const uint32 kAsScene2401WaterSpitFileHashes1[] = {
+ 0xF4418408, 0xF4418808, 0xF4419008,
+ 0xF441A008, 0xCD4F8411
+};
+
+AsScene2401WaterSpit::AsScene2401WaterSpit(NeverhoodEngine *vm)
+ : AnimatedSprite(vm, 1200) {
+
+ _x = 240;
+ _y = 447;
+ createSurface(100, 146, 74);
+ setVisible(false);
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsScene2401WaterSpit::handleMessage);
+ SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
+}
+
+uint32 AsScene2401WaterSpit::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case NM_ANIMATION_START:
+ if (param.asInteger() == 0x120A0013)
+ playSound(0, kAsScene2401WaterSpitFileHashes1[_soundIndex]);
+ break;
+ case NM_ANIMATION_UPDATE:
+ _x = 240;
+ _y = 447;
+ _soundIndex = getSubVar(VA_CURR_WATER_PIPES_LEVEL, param.asInteger());
+ startAnimation(kAsScene2401WaterSpitFileHashes2[param.asInteger()], 0, -1);
+ setVisible(true);
+ playSound(0, 0x48640244);
+ break;
+ case NM_ANIMATION_STOP:
+ stopAnimation();
+ setVisible(false);
+ break;
+ }
+ return messageResult;
+}
+
+AsScene2401FlowingWater::AsScene2401FlowingWater(NeverhoodEngine *vm)
+ : AnimatedSprite(vm, 1200), _isWaterFlowing(false) {
+
+ _x = 88;
+ _y = 421;
+ createSurface1(0x10203116, 100);
+ setVisible(false);
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsScene2401FlowingWater::handleMessage);
+}
+
+AsScene2401FlowingWater::~AsScene2401FlowingWater() {
+ _vm->_soundMan->deleteSoundGroup(0x40F11C09);
+}
+
+uint32 AsScene2401FlowingWater::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case NM_ANIMATION_START:
+ if (_isWaterFlowing && param.asInteger() == 0x02421405)
+ startAnimationByHash(0x10203116, 0x01084280, 0);
+ break;
+ case NM_POSITION_CHANGE:
+ if (!_isWaterFlowing) {
+ _vm->_soundMan->addSound(0x40F11C09, 0x980C1420);
+ _vm->_soundMan->playSoundLooping(0x980C1420);
+ startAnimation(0x10203116, 0, -1);
+ setVisible(true);
+ _isWaterFlowing = true;
+ }
+ break;
+ case 0x2003:
+ _vm->_soundMan->deleteSound(0x980C1420);
+ _isWaterFlowing = false;
+ break;
+ case NM_ANIMATION_STOP:
+ stopAnimation();
+ setVisible(false);
+ break;
+ }
+ return messageResult;
+}
+
+AsScene2401WaterFlushing::AsScene2401WaterFlushing(NeverhoodEngine *vm, int16 x, int16 y)
+ : AnimatedSprite(vm, 1200), _countdown(0), _flushLoopCount(0) {
+
+ _x = x;
+ _y = y;
+ createSurface1(0xB8596884, 100);
+ setVisible(false);
+ SetUpdateHandler(&AsScene2401WaterFlushing::update);
+ SetMessageHandler(&AsScene2401WaterFlushing::handleMessage);
+}
+
+void AsScene2401WaterFlushing::update() {
+ if (_countdown != 0 && (--_countdown) == 0) {
+ setDoDeltaX(_vm->_rnd->getRandomNumber(1));
+ startAnimation(0xB8596884, 0, -1);
+ setVisible(true);
+ }
+ AnimatedSprite::update();
+}
+
+uint32 AsScene2401WaterFlushing::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case NM_ANIMATION_START:
+ if (_flushLoopCount > 0 && param.asInteger() == 0x02421405) {
+ startAnimationByHash(0xB8596884, 0x01084280, 0);
+ _flushLoopCount--;
+ }
+ break;
+ case NM_POSITION_CHANGE:
+ if (param.asInteger() > 0) {
+ _flushLoopCount = param.asInteger() - 1;
+ _countdown = _vm->_rnd->getRandomNumber(3) + 1;
+ }
+ break;
+ case NM_ANIMATION_STOP:
+ stopAnimation();
+ setVisible(false);
+ break;
+ }
+ return messageResult;
+}
+
+AsScene2401Door::AsScene2401Door(NeverhoodEngine *vm, bool isOpen)
+ : AnimatedSprite(vm, 1100), _countdown(0), _isOpen(isOpen) {
+
+ _x = 320;
+ _y = 240;
+ createSurface1(0x44687810, 100);
+ _newStickFrameIndex = STICK_LAST_FRAME;
+ if (_isOpen) {
+ stopAnimation();
+ setVisible(false);
+ _countdown = 48;
+ } else {
+ startAnimation(0x44687810, 0, -1);
+ _newStickFrameIndex = 0;
+ }
+ SetUpdateHandler(&AsScene2401Door::update);
+ SetMessageHandler(&AsScene2401Door::handleMessage);
+}
+
+void AsScene2401Door::update() {
+ if (_isOpen && _countdown != 0 && (--_countdown) == 0) {
+ _isOpen = false;
+ setVisible(true);
+ startAnimation(0x44687810, -1, -1);
+ _newStickFrameIndex = 0;
+ _playBackwards = true;
+ playSound(0, calcHash("fxDoorClose38"));
+ }
+ AnimatedSprite::update();
+}
+
+uint32 AsScene2401Door::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x2004:
+ if (_isOpen)
+ _countdown = 168;
+ messageResult = _isOpen ? 1 : 0;
+ break;
+ case NM_ANIMATION_STOP:
+ gotoNextState();
+ break;
+ case NM_KLAYMEN_OPEN_DOOR:
+ if (!_isOpen) {
+ _countdown = 168;
+ _isOpen = true;
+ setVisible(true);
+ startAnimation(0x44687810, 0, -1);
+ playSound(0, calcHash("fxDoorOpen38"));
+ NextState(&AsScene2401Door::stDoorOpenFinished);
+ }
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene2401Door::stDoorOpenFinished() {
+ stopAnimation();
+ setVisible(false);
+}
+
+AsScene2402Door::AsScene2402Door(NeverhoodEngine *vm, Scene *parentScene, bool isOpen)
+ : AnimatedSprite(vm, 1100), _parentScene(parentScene), _isOpen(isOpen), _countdown(0) {
+
+ _x = 320;
+ _y = 240;
+ createSurface1(0x80495831, 100);
+ if (_isOpen) {
+ startAnimation(0x80495831, -1, -1);
+ _newStickFrameIndex = STICK_LAST_FRAME;
+ _countdown = 48;
+ } else {
+ stopAnimation();
+ setVisible(false);
+ }
+ SetUpdateHandler(&AsScene2402Door::update);
+ SetMessageHandler(&AsScene2402Door::handleMessage);
+}
+
+void AsScene2402Door::update() {
+ if (_isOpen && _countdown != 0 && (--_countdown) == 0) {
+ _isOpen = false;
+ setVisible(true);
+ startAnimation(0x80495831, -1, -1);
+ _playBackwards = true;
+ playSound(0, calcHash("fxDoorClose38"));
+ NextState(&AsScene2402Door::stDoorClosingFinished);
+ }
+ AnimatedSprite::update();
+}
+
+uint32 AsScene2402Door::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case NM_ANIMATION_UPDATE:
+ if (_isOpen)
+ _countdown = 144;
+ messageResult = _isOpen ? 1 : 0;
+ break;
+ case NM_ANIMATION_STOP:
+ gotoNextState();
+ break;
+ case NM_KLAYMEN_OPEN_DOOR:
+ _countdown = 144;
+ _isOpen = true;
+ setVisible(true);
+ startAnimation(0x80495831, 0, -1);
+ _newStickFrameIndex = STICK_LAST_FRAME;
+ playSound(0, calcHash("fxDoorOpen38"));
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene2402Door::stDoorClosingFinished() {
+ sendMessage(_parentScene, 0x2001, 0);
+ setVisible(false);
+}
+
+AsScene2402TV::AsScene2402TV(NeverhoodEngine *vm, Klaymen *klaymen)
+ : AnimatedSprite(vm, 1100), _klaymen(klaymen), _countdown1(0), _countdown2(0) {
+
+ _x = 260;
+ _y = 210;
+ createSurface(100, 127, 90);
+ setDoDeltaX(1);
+ SetMessageHandler(&Sprite::handleMessage);
+ if (!getGlobalVar(V_TV_JOKE_TOLD)) {
+ loadSound(0, 0x58208810);
+ _countdown1 = 48;
+ startAnimation(0x4919397A, 0, -1);
+ _newStickFrameIndex = 0;
+ SetUpdateHandler(&AsScene2402TV::upWait);
+ } else {
+ int16 frameIndex;
+ if (_klaymen->getX() > 320)
+ _currFrameIndex = 29;
+ frameIndex = CLIP<int16>((_klaymen->getX() - _x + 150) / 10, 0, 29);
+ startAnimation(0x050A0103, frameIndex, -1);
+ _newStickFrameIndex = frameIndex;
+ _countdown1 = 0;
+ SetUpdateHandler(&AsScene2402TV::upFocusKlaymen);
+ }
+}
+
+AsScene2402TV::~AsScene2402TV() {
+ _vm->_soundMan->deleteSoundGroup(0x01520123);
+}
+
+void AsScene2402TV::upWait() {
+ if (_countdown1 != 0 && (--_countdown1) == 0) {
+ startAnimation(0x4919397A, 0, -1);
+ SetMessageHandler(&AsScene2402TV::hmJoke);
+ NextState(&AsScene2402TV::stJokeFinished);
+ }
+ AnimatedSprite::update();
+}
+
+void AsScene2402TV::upFocusKlaymen() {
+ int16 frameIndex = CLIP<int16>((_klaymen->getX() - _x + 150) / 10, 0, 29);
+ if (frameIndex != _currFrameIndex) {
+ if (frameIndex > _currFrameIndex)
+ _currFrameIndex++;
+ else if (frameIndex < _currFrameIndex)
+ _currFrameIndex--;
+ startAnimation(0x050A0103, _currFrameIndex, -1);
+ _newStickFrameIndex = _currFrameIndex;
+ if (_countdown2 == 0) {
+ _vm->_soundMan->addSound(0x01520123, 0xC42D4528);
+ _vm->_soundMan->playSoundLooping(0xC42D4528);
+ }
+ _countdown2 = 5;
+ } else if (_countdown2 != 0 && (--_countdown2 == 0))
+ _vm->_soundMan->deleteSound(0xC42D4528);
+ AnimatedSprite::update();
+}
+
+void AsScene2402TV::stJokeFinished() {
+ setGlobalVar(V_TV_JOKE_TOLD, 1);
+ startAnimation(0x050A0103, 0, -1);
+ _newStickFrameIndex = 0;
+ SetUpdateHandler(&AsScene2402TV::upFocusKlaymen);
+}
+
+uint32 AsScene2402TV::hmJoke(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case NM_ANIMATION_START:
+ if (param.asInteger() == 0x431EA0B0)
+ playSound(0);
+ break;
+ case NM_ANIMATION_STOP:
+ gotoNextState();
+ break;
+ }
+ return messageResult;
+}
+
+KmScene2401::KmScene2401(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
+ : Klaymen(vm, parentScene, x, y),
+ _canSpitPipe(false), _contSpitPipe(false), _readyToSpit(false),
+ _spitPipeIndex(0), _spitDestPipeIndex(0), _spitContDestPipeIndex(0) {
+
+ // Empty
+}
+
+uint32 KmScene2401::xHandleMessage(int messageNum, const MessageParam &param) {
+ uint32 messageResult = 0;
+ switch (messageNum) {
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case NM_KLAYMEN_STAND_IDLE:
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case NM_KLAYMEN_PRESS_BUTTON:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stPressButton);
+ else if (param.asInteger() == 2)
+ GotoState(&Klaymen::stPressFloorButton);
+ else
+ GotoState(&Klaymen::stPressButtonSide);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ gotoNextStateExt();
+ break;
+ case 0x481B:
+ if (param.asPoint().y != 0)
+ startWalkToXDistance(param.asPoint().y, param.asPoint().x);
+ else
+ startWalkToAttachedSpriteXDistance(param.asPoint().x);
+ break;
+ case 0x481F:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stTurnAwayFromUse);
+ else if (param.asInteger() == 0)
+ GotoState(&Klaymen::stTurnToUseHalf);
+ else
+ GotoState(&Klaymen::stWonderAbout);
+ break;
+ case 0x482D:
+ setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
+ gotoNextStateExt();
+ break;
+ case 0x482E:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stWalkToFrontNoStep);
+ else
+ GotoState(&Klaymen::stWalkToFront);
+ break;
+ case 0x482F:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stTurnToFront);
+ else
+ GotoState(&Klaymen::stTurnToBack);
+ break;
+ case 0x4832:
+ GotoState(&Klaymen::stUseTube);
+ break;
+ case 0x4833:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stWonderAbout);
+ else {
+ _spitPipeIndex = sendMessage(_parentScene, 0x2000, 0);
+ GotoState(&KmScene2401::stTrySpitIntoPipe);
+ }
+ break;
+ case 0x483F:
+ startSpecialWalkRight(param.asInteger());
+ break;
+ case 0x4840:
+ startSpecialWalkLeft(param.asInteger());
+ break;
+ }
+ return messageResult;
+}
+
+uint32 KmScene2401::hmSpit(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Klaymen::hmLowLevelAnimation(messageNum, param, sender);
+ switch (messageNum) {
+ case NM_ANIMATION_START:
+ if (param.asInteger() == 0x16401CA6) {
+ _canSpitPipe = true;
+ if (_contSpitPipe)
+ spitIntoPipe();
+ } else if (param.asInteger() == 0xC11C0008) {
+ _canSpitPipe = false;
+ _acceptInput = false;
+ _readyToSpit = false;
+ } else if (param.asInteger() == 0x018A0001) {
+ sendMessage(_parentScene, 0x2001, _spitDestPipeIndex);
+ }
+ break;
+ }
+ return messageResult;
+}
+
+void KmScene2401::stTrySpitIntoPipe() {
+ if (_readyToSpit) {
+ _contSpitPipe = true;
+ _spitContDestPipeIndex = _spitPipeIndex;
+ if (_canSpitPipe)
+ spitIntoPipe();
+ } else if (!stStartAction(AnimationCallback(&KmScene2401::stTrySpitIntoPipe))) {
+ _busyStatus = 2;
+ _acceptInput = true;
+ _spitDestPipeIndex = _spitPipeIndex;
+ _readyToSpit = true;
+ _canSpitPipe = false;
+ _contSpitPipe = false;
+ startAnimation(0x1808B150, 0, -1);
+ SetUpdateHandler(&Klaymen::update);
+ SetMessageHandler(&KmScene2401::hmSpit);
+ SetSpriteUpdate(NULL);
+ }
+}
+
+void KmScene2401::spitIntoPipe() {
+ _contSpitPipe = false;
+ _spitDestPipeIndex = _spitContDestPipeIndex;
+ _canSpitPipe = false;
+ _acceptInput = false;
+ startAnimation(0x1B08B553, 0, -1);
+ SetUpdateHandler(&Klaymen::update);
+ SetMessageHandler(&KmScene2401::hmSpit);
+ SetSpriteUpdate(NULL);
+ NextState(&KmScene2401::stContSpitIntoPipe);
+}
+
+void KmScene2401::stContSpitIntoPipe() {
+ _canSpitPipe = true;
+ _acceptInput = true;
+ startAnimationByHash(0x1808B150, 0x16401CA6, 0);
+ SetUpdateHandler(&Klaymen::update);
+ SetMessageHandler(&KmScene2401::hmSpit);
+ SetSpriteUpdate(NULL);
+}
+
+KmScene2402::KmScene2402(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
+ : Klaymen(vm, parentScene, x, y) {
+
+ // Empty
+}
+
+uint32 KmScene2402::xHandleMessage(int messageNum, const MessageParam &param) {
+ uint32 messageResult = 0;
+ switch (messageNum) {
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case NM_KLAYMEN_STAND_IDLE:
+ if (!getGlobalVar(V_TV_JOKE_TOLD))
+ GotoState(&Klaymen::stStandWonderAbout);
+ else
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x4804:
+ if (param.asInteger() != 0) {
+ _destX = param.asInteger();
+ GotoState(&Klaymen::stWalkingFirst);
+ } else
+ GotoState(&Klaymen::stPeekWall);
+ break;
+ case NM_KLAYMEN_PICKUP:
+ GotoState(&Klaymen::stPickUpGeneric);
+ break;
+ case NM_KLAYMEN_PRESS_BUTTON:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stPressButton);
+ else if (param.asInteger() == 2)
+ GotoState(&Klaymen::stPressFloorButton);
+ else
+ GotoState(&Klaymen::stPressButtonSide);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ gotoNextStateExt();
+ break;
+ case 0x481B:
+ if (param.asPoint().y != 0)
+ startWalkToXDistance(param.asPoint().y, param.asPoint().x);
+ else
+ startWalkToAttachedSpriteXDistance(param.asPoint().x);
+ break;
+ case 0x481F:
+ if (param.asInteger() == 0)
+ GotoState(&Klaymen::stWonderAboutHalf);
+ else if (param.asInteger() == 1)
+ GotoState(&Klaymen::stWonderAboutAfter);
+ else if (param.asInteger() == 3)
+ GotoState(&Klaymen::stTurnToUseHalf);
+ else if (param.asInteger() == 4)
+ GotoState(&Klaymen::stTurnAwayFromUse);
+ else
+ GotoState(&Klaymen::stWonderAbout);
+ break;
+ case 0x483F:
+ startSpecialWalkRight(param.asInteger());
+ break;
+ case 0x4840:
+ startSpecialWalkLeft(param.asInteger());
+ break;
+ }
+ return messageResult;
+}
+
+KmScene2403::KmScene2403(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
+ : Klaymen(vm, parentScene, x, y) {
+
+ // Empty
+}
+
+uint32 KmScene2403::xHandleMessage(int messageNum, const MessageParam &param) {
+ uint32 messageResult = 0;
+ switch (messageNum) {
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case NM_KLAYMEN_STAND_IDLE:
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x480D:
+ GotoState(&Klaymen::stPullCord);
+ break;
+ case NM_KLAYMEN_PICKUP:
+ GotoState(&Klaymen::stPickUpGeneric);
+ break;
+ case NM_KLAYMEN_PRESS_BUTTON:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stPressButton);
+ else if (param.asInteger() == 2)
+ GotoState(&Klaymen::stPressFloorButton);
+ else
+ GotoState(&Klaymen::stPressButtonSide);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ gotoNextStateExt();
+ break;
+ case 0x481B:
+ if (param.asPoint().y != 0)
+ startWalkToXDistance(param.asPoint().y, param.asPoint().x);
+ else
+ startWalkToAttachedSpriteXDistance(param.asPoint().x);
+ break;
+ case 0x481F:
+ if (param.asInteger() == 0)
+ GotoState(&Klaymen::stWonderAboutHalf);
+ else if (param.asInteger() == 1)
+ GotoState(&Klaymen::stWonderAboutAfter);
+ else if (param.asInteger() == 3)
+ GotoState(&Klaymen::stTurnToUseHalf);
+ else if (param.asInteger() == 4)
+ GotoState(&Klaymen::stTurnAwayFromUse);
+ else
+ GotoState(&Klaymen::stWonderAbout);
+ break;
+ case 0x4820:
+ sendMessage(_parentScene, 0x2000, 0);
+ GotoState(&Klaymen::stContinueClimbLadderUp);
+ break;
+ case 0x4821:
+ sendMessage(_parentScene, 0x2000, 0);
+ _destY = param.asInteger();
+ GotoState(&Klaymen::stStartClimbLadderDown);
+ break;
+ case 0x4822:
+ sendMessage(_parentScene, 0x2000, 0);
+ _destY = param.asInteger();
+ GotoState(&Klaymen::stStartClimbLadderUp);
+ break;
+ case 0x4823:
+ sendMessage(_parentScene, 0x2001, 0);
+ GotoState(&Klaymen::stClimbLadderHalf);
+ break;
+ case 0x482D:
+ setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
+ gotoNextStateExt();
+ break;
+ case 0x483F:
+ startSpecialWalkRight(param.asInteger());
+ break;
+ case 0x4840:
+ startSpecialWalkLeft(param.asInteger());
+ break;
+ }
+ return messageResult;
+}
+
+KmScene2406::KmScene2406(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y, NRect *clipRects, int clipRectsCount)
+ : Klaymen(vm, parentScene, x, y) {
+
+ _surface->setClipRects(clipRects, clipRectsCount);
+}
+
+uint32 KmScene2406::xHandleMessage(int messageNum, const MessageParam &param) {
+ uint32 messageResult = 0;
+ switch (messageNum) {
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case NM_KLAYMEN_STAND_IDLE:
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x4804:
+ if (param.asInteger() != 0) {
+ _destX = param.asInteger();
+ GotoState(&Klaymen::stWalkingFirst);
+ } else
+ GotoState(&Klaymen::stPeekWall);
+ break;
+ case NM_KLAYMEN_PICKUP:
+ if (param.asInteger() == 2)
+ GotoState(&Klaymen::stPickUpNeedle);
+ else if (param.asInteger() == 1)
+ GotoState(&Klaymen::stPickUpTube);
+ else
+ GotoState(&Klaymen::stPickUpGeneric);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ gotoNextStateExt();
+ break;
+ case NM_KLAYMEN_INSERT_DISK:
+ GotoState(&Klaymen::stInsertDisk);
+ break;
+ case 0x481B:
+ if (param.asPoint().y != 0)
+ startWalkToXDistance(param.asPoint().y, param.asPoint().x);
+ else
+ startWalkToAttachedSpriteXDistance(param.asPoint().x);
+ break;
+ case NM_KLAYMEN_TURN_TO_USE:
+ GotoState(&Klaymen::stTurnToUse);
+ break;
+ case NM_KLAYMEN_RETURN_FROM_USE:
+ GotoState(&Klaymen::stReturnFromUse);
+ break;
+ case 0x481F:
+ if (param.asInteger() == 0)
+ GotoState(&Klaymen::stWonderAboutHalf);
+ else if (param.asInteger() == 1)
+ GotoState(&Klaymen::stWonderAboutAfter);
+ else if (param.asInteger() == 3)
+ GotoState(&Klaymen::stTurnToUseHalf);
+ else if (param.asInteger() == 4)
+ GotoState(&Klaymen::stTurnAwayFromUse);
+ else
+ GotoState(&Klaymen::stWonderAbout);
+ break;
+ case 0x4820:
+ sendMessage(_parentScene, 0x2000, 0);
+ GotoState(&Klaymen::stContinueClimbLadderUp);
+ break;
+ case 0x4821:
+ sendMessage(_parentScene, 0x2000, 0);
+ _destY = param.asInteger();
+ GotoState(&Klaymen::stStartClimbLadderDown);
+ break;
+ case 0x4822:
+ sendMessage(_parentScene, 0x2000, 0);
+ _destY = param.asInteger();
+ GotoState(&Klaymen::stStartClimbLadderUp);
+ break;
+ case 0x4823:
+ sendMessage(_parentScene, 0x2001, 0);
+ GotoState(&Klaymen::stClimbLadderHalf);
+ break;
+ case 0x483F:
+ startSpecialWalkRight(param.asInteger());
+ break;
+ case 0x4840:
+ startSpecialWalkLeft(param.asInteger());
+ break;
+ }
+ return messageResult;
+}
+
+} // End of namespace Neverhood
diff --git a/engines/neverhood/modules/module2400_sprites.h b/engines/neverhood/modules/module2400_sprites.h
new file mode 100644
index 0000000000..a901eb101c
--- /dev/null
+++ b/engines/neverhood/modules/module2400_sprites.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 NEVERHOOD_MODULES_MODULE2400_SPRITES_H
+#define NEVERHOOD_MODULES_MODULE2400_SPRITES_H
+
+#include "neverhood/neverhood.h"
+#include "neverhood/module.h"
+#include "neverhood/scene.h"
+#include "neverhood/gamemodule.h"
+
+namespace Neverhood {
+
+class AsScene2401WaterSpit : public AnimatedSprite {
+public:
+ AsScene2401WaterSpit(NeverhoodEngine *vm);
+protected:
+ int _soundIndex;
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class AsScene2401FlowingWater : public AnimatedSprite {
+public:
+ AsScene2401FlowingWater(NeverhoodEngine *vm);
+ virtual ~AsScene2401FlowingWater();
+protected:
+ bool _isWaterFlowing;
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class AsScene2401WaterFlushing : public AnimatedSprite {
+public:
+ AsScene2401WaterFlushing(NeverhoodEngine *vm, int16 x, int16 y);
+protected:
+ int _countdown;
+ int _flushLoopCount;
+ void update();
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class AsScene2401Door : public AnimatedSprite {
+public:
+ AsScene2401Door(NeverhoodEngine *vm, bool isOpen);
+protected:
+ int _countdown;
+ bool _isOpen;
+ void update();
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ void stDoorOpenFinished();
+};
+
+class AsScene2402Door : public AnimatedSprite {
+public:
+ AsScene2402Door(NeverhoodEngine *vm, Scene *parentScene, bool isOpen);
+protected:
+ Scene *_parentScene;
+ int _countdown;
+ bool _isOpen;
+ void update();
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ void stDoorClosingFinished();
+};
+
+class AsScene2402TV : public AnimatedSprite {
+public:
+ AsScene2402TV(NeverhoodEngine *vm, Klaymen *klaymen);
+ virtual ~AsScene2402TV();
+protected:
+ Klaymen *_klaymen;
+ int _countdown1;
+ int _countdown2;
+ void upWait();
+ void upFocusKlaymen();
+ void stJokeFinished();
+ uint32 hmJoke(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class KmScene2401 : public Klaymen {
+public:
+ KmScene2401(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
+protected:
+ bool _canSpitPipe;
+ bool _contSpitPipe;
+ bool _readyToSpit;
+ uint32 _spitPipeIndex;
+ uint32 _spitDestPipeIndex;
+ uint32 _spitContDestPipeIndex;
+
+ void spitIntoPipe();
+ void stTrySpitIntoPipe();
+ void stContSpitIntoPipe();
+ uint32 hmSpit(int messageNum, const MessageParam &param, Entity *sender);
+
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+};
+
+class KmScene2402 : public Klaymen {
+public:
+ KmScene2402(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
+protected:
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+};
+
+class KmScene2403 : public Klaymen {
+public:
+ KmScene2403(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
+protected:
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+};
+
+class KmScene2406 : public Klaymen {
+public:
+ KmScene2406(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y, NRect *clipRects, int clipRectsCount);
+protected:
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+};
+
+} // End of namespace Neverhood
+
+#endif /* NEVERHOOD_MODULES_MODULE2400_SPRITES_H */
diff --git a/engines/neverhood/modules/module2500.cpp b/engines/neverhood/modules/module2500.cpp
index 46ce2ba4fc..eb1b65cd83 100644
--- a/engines/neverhood/modules/module2500.cpp
+++ b/engines/neverhood/modules/module2500.cpp
@@ -20,8 +20,12 @@
*
*/
+#include "neverhood/modules/module1600.h" // for Scene1608
+#include "neverhood/modules/module1600_sprites.h"
#include "neverhood/modules/module2500.h"
-#include "neverhood/modules/module1600.h"
+#include "neverhood/modules/module2500_sprites.h"
+#include "neverhood/modules/module2700.h" // for Scene2704
+#include "neverhood/modules/module2700_sprites.h"
namespace Neverhood {
@@ -248,7 +252,7 @@ Scene2501::Scene2501(NeverhoodEngine *vm, Module *parentModule, int which)
setRectList(0x004B2608);
SetMessageHandler(&Scene2501::handleMessage);
SetUpdateHandler(&Scene2501::update);
- sendMessage(_asCar, 0x2009, 0);
+ sendMessage(_asCar, NM_CAR_ENTER, 0);
_asCar->setVisible(false);
_currTrackIndex = 0;
} else if (which == 1 || which == 2) {
@@ -273,7 +277,7 @@ Scene2501::Scene2501(NeverhoodEngine *vm, Module *parentModule, int which)
setRectList(0x004B2608);
SetMessageHandler(&Scene2501::handleMessage);
SetUpdateHandler(&Scene2501::update);
- sendMessage(_asCar, 0x2009, 0);
+ sendMessage(_asCar, NM_CAR_ENTER, 0);
_asCar->setVisible(false);
_currTrackIndex = 0;
}
@@ -291,14 +295,14 @@ Scene2501::Scene2501(NeverhoodEngine *vm, Module *parentModule, int which)
if (which >= 0 && _tracks[_currTrackIndex]->which2 == which) {
NPoint testPoint = (*_trackPoints)[_trackPoints->size() - 1];
- sendMessage(_asCar, 0x2002, _trackPoints->size() - 1);
+ sendMessage(_asCar, NM_POSITION_CHANGE, _trackPoints->size() - 1);
if (testPoint.x < 0 || testPoint.x >= 640 || testPoint.y < 0 || testPoint.y >= 480)
- sendMessage(_asCar, 0x2007, 150);
+ sendMessage(_asCar, NM_CAR_MOVE_TO_PREV_POINT, 150);
} else {
NPoint testPoint = (*_trackPoints)[0];
- sendMessage(_asCar, 0x2002, 0);
+ sendMessage(_asCar, NM_POSITION_CHANGE, 0);
if (testPoint.x < 0 || testPoint.x >= 640 || testPoint.y < 0 || testPoint.y >= 480)
- sendMessage(_asCar, 0x2008, 150);
+ sendMessage(_asCar, NM_CAR_MOVE_TO_NEXT_POINT, 150);
}
_carStatus = 0;
@@ -325,7 +329,7 @@ void Scene2501::update() {
_asIdleCarLower->setVisible(false);
_asIdleCarFull->setVisible(false);
_asCar->setVisible(true);
- sendMessage(_asCar, 0x2009, 0);
+ sendMessage(_asCar, NM_CAR_ENTER, 0);
_asCar->handleUpdate();
_klaymen = NULL;
_carStatus = 0;
@@ -337,7 +341,7 @@ void Scene2501::upCarAtHome() {
Scene::update();
if (_mouseClicked) {
if (_mouseClickPos.x <= 210 && _asCar->getX() == 211 && _asCar->getY() == 400) {
- sendMessage(_asCar, 0x200A, 0);
+ sendMessage(_asCar, NM_CAR_LEAVE, 0);
SetUpdateHandler(&Scene2501::upGettingOutOfCar);
} else {
moveCarToPoint(_mouseClickPos);
@@ -381,7 +385,7 @@ void Scene2501::upRidingCar() {
uint32 Scene2501::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0x60842040)
_carStatus = 1;
break;
@@ -395,23 +399,23 @@ uint32 Scene2501::handleMessage(int messageNum, const MessageParam &param, Entit
uint32 Scene2501::hmRidingCar(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x2005:
+ case NM_KLAYMEN_CLIMB_LADDER:
if (_tracks[_currTrackIndex]->which1 < 0 && _newTrackIndex >= 0)
changeTrack();
else if (_tracks[_currTrackIndex]->which1 == 0) {
SetMessageHandler(&Scene2501::hmCarAtHome);
SetUpdateHandler(&Scene2501::upCarAtHome);
- sendMessage(_asCar, 0x200F, 1);
+ sendMessage(_asCar, NM_CAR_AT_HOME, 1);
} else if (_tracks[_currTrackIndex]->which1 > 0)
leaveScene(_tracks[_currTrackIndex]->which1);
break;
- case 0x2006:
+ case NM_KLAYMEN_STOP_CLIMBING:
if (_tracks[_currTrackIndex]->which2 < 0 && _newTrackIndex >= 0)
changeTrack();
else if (_tracks[_currTrackIndex]->which2 == 0) {
SetMessageHandler(&Scene2501::hmCarAtHome);
SetUpdateHandler(&Scene2501::upCarAtHome);
- sendMessage(_asCar, 0x200F, 1);
+ sendMessage(_asCar, NM_CAR_AT_HOME, 1);
} else if (_tracks[_currTrackIndex]->which2 > 0)
leaveScene(_tracks[_currTrackIndex]->which2);
break;
@@ -425,7 +429,7 @@ uint32 Scene2501::hmRidingCar(int messageNum, const MessageParam &param, Entity
uint32 Scene2501::hmCarAtHome(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x200A:
+ case NM_CAR_LEAVE:
_carStatus = 2;
break;
case 0x200D:
@@ -456,9 +460,9 @@ void Scene2501::changeTrack() {
_trackPoints = _dataResource.getPointArray(_tracks[_currTrackIndex]->trackPointsName);
_asCar->setPathPoints(_trackPoints);
if (_currTrackIndex == 0)
- sendMessage(_asCar, 0x2002, _trackPoints->size() - 1);
+ sendMessage(_asCar, NM_POSITION_CHANGE, _trackPoints->size() - 1);
else
- sendMessage(_asCar, 0x2002, 0);
+ sendMessage(_asCar, NM_POSITION_CHANGE, 0);
sendPointMessage(_asCar, 0x2004, _clickPoint);
_newTrackIndex = -1;
}
@@ -470,54 +474,6 @@ void Scene2501::updateKlaymenClipRect() {
_kmScene2501->setClipRect(0, 0, 640, 388);
}
-SsScene2504Button::SsScene2504Button(NeverhoodEngine *vm)
- : StaticSprite(vm, 1400), _countdown(0), _isSoundPlaying(false) {
-
- loadSprite(0x070220D9, kSLFDefDrawOffset | kSLFDefPosition | kSLFDefCollisionBoundsOffset, 400);
- setVisible(false);
- loadSound(0, 0x4600204C);
- loadSound(1, 0x408C0034);
- loadSound(2, 0x44043000);
- loadSound(3, 0x44045000);
- SetMessageHandler(&SsScene2504Button::handleMessage);
- SetUpdateHandler(&SsScene2504Button::update);
-}
-
-void SsScene2504Button::update() {
- updatePosition();
- if (_isSoundPlaying && !isSoundPlaying(0) && !isSoundPlaying(1)) {
- playSound(3);
- setVisible(false);
- _isSoundPlaying = false;
- }
- if (_countdown != 0 && (--_countdown) == 0) {
- if (getSubVar(VA_LOCKS_DISABLED, 0x01180951))
- playSound(0);
- else
- playSound(1);
- _isSoundPlaying = true;
- }
-}
-
-uint32 SsScene2504Button::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x1011:
- if (_countdown == 0 && !_isSoundPlaying) {
- setVisible(true);
- _countdown = 2;
- if (getSubVar(VA_LOCKS_DISABLED, 0x01180951))
- setSubVar(VA_LOCKS_DISABLED, 0x01180951, 0);
- else
- setSubVar(VA_LOCKS_DISABLED, 0x01180951, 1);
- playSound(2);
- }
- messageResult = 1;
- break;
- }
- return messageResult;
-}
-
Scene2504::Scene2504(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule) {
@@ -535,7 +491,7 @@ Scene2504::Scene2504(NeverhoodEngine *vm, Module *parentModule, int which)
uint32 Scene2504::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x0001:
+ case NM_MOUSE_CLICK:
if (param.asPoint().x <= 20 || param.asPoint().x >= 620)
leaveScene(0);
break;
diff --git a/engines/neverhood/modules/module2500.h b/engines/neverhood/modules/module2500.h
index 07db7907d5..de6226ef0c 100644
--- a/engines/neverhood/modules/module2500.h
+++ b/engines/neverhood/modules/module2500.h
@@ -26,14 +26,10 @@
#include "neverhood/neverhood.h"
#include "neverhood/module.h"
#include "neverhood/scene.h"
-#include "neverhood/modules/module1000.h"
-#include "neverhood/modules/module1600.h"
-#include "neverhood/modules/module2700.h"
+#include "neverhood/modules/module1600_sprites.h" // for Tracks
namespace Neverhood {
-// Module2500
-
class Module2500 : public Module {
public:
Module2500(NeverhoodEngine *vm, Module *parentModule, int which);
@@ -47,6 +43,8 @@ protected:
void createScene2704(int which, uint32 sceneInfoId, int16 value, const uint32 *staticSprites = NULL, const NRect *clipRect = NULL);
};
+class AsCommonCar;
+
class Scene2501 : public Scene {
public:
Scene2501(NeverhoodEngine *vm, Module *parentModule, int which);
@@ -79,16 +77,6 @@ protected:
void updateKlaymenClipRect();
};
-class SsScene2504Button : public StaticSprite {
-public:
- SsScene2504Button(NeverhoodEngine *vm);
-protected:
- int _countdown;
- bool _isSoundPlaying;
- void update();
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
-
class Scene2504 : public Scene {
public:
Scene2504(NeverhoodEngine *vm, Module *parentModule, int which);
diff --git a/engines/neverhood/modules/module2500_sprites.cpp b/engines/neverhood/modules/module2500_sprites.cpp
new file mode 100644
index 0000000000..1394a87db6
--- /dev/null
+++ b/engines/neverhood/modules/module2500_sprites.cpp
@@ -0,0 +1,127 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "neverhood/modules/module2500_sprites.h"
+
+namespace Neverhood {
+
+SsScene2504Button::SsScene2504Button(NeverhoodEngine *vm)
+ : StaticSprite(vm, 1400), _countdown(0), _isSoundPlaying(false) {
+
+ loadSprite(0x070220D9, kSLFDefDrawOffset | kSLFDefPosition | kSLFDefCollisionBoundsOffset, 400);
+ setVisible(false);
+ loadSound(0, 0x4600204C);
+ loadSound(1, 0x408C0034);
+ loadSound(2, 0x44043000);
+ loadSound(3, 0x44045000);
+ SetMessageHandler(&SsScene2504Button::handleMessage);
+ SetUpdateHandler(&SsScene2504Button::update);
+}
+
+void SsScene2504Button::update() {
+ updatePosition();
+ if (_isSoundPlaying && !isSoundPlaying(0) && !isSoundPlaying(1)) {
+ playSound(3);
+ setVisible(false);
+ _isSoundPlaying = false;
+ }
+ if (_countdown != 0 && (--_countdown) == 0) {
+ if (getSubVar(VA_LOCKS_DISABLED, 0x01180951))
+ playSound(0);
+ else
+ playSound(1);
+ _isSoundPlaying = true;
+ }
+}
+
+uint32 SsScene2504Button::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x1011:
+ if (_countdown == 0 && !_isSoundPlaying) {
+ setVisible(true);
+ _countdown = 2;
+ if (getSubVar(VA_LOCKS_DISABLED, 0x01180951))
+ setSubVar(VA_LOCKS_DISABLED, 0x01180951, 0);
+ else
+ setSubVar(VA_LOCKS_DISABLED, 0x01180951, 1);
+ playSound(2);
+ }
+ messageResult = 1;
+ break;
+ }
+ return messageResult;
+}
+
+KmScene2501::KmScene2501(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
+ : Klaymen(vm, parentScene, x, y) {
+
+ // Empty
+}
+
+uint32 KmScene2501::xHandleMessage(int messageNum, const MessageParam &param) {
+ uint32 messageResult = 0;
+ switch (messageNum) {
+ case NM_ANIMATION_UPDATE:
+ _isSittingInTeleporter = param.asInteger() != 0;
+ messageResult = 1;
+ break;
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case NM_KLAYMEN_STAND_IDLE:
+ if (_isSittingInTeleporter)
+ GotoState(&Klaymen::stSitIdleTeleporter);
+ else
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ gotoNextStateExt();
+ break;
+ case NM_KLAYMEN_TURN_TO_USE:
+ if (_isSittingInTeleporter)
+ GotoState(&Klaymen::stTurnToUseInTeleporter);
+ break;
+ case NM_KLAYMEN_RETURN_FROM_USE:
+ if (_isSittingInTeleporter)
+ GotoState(&Klaymen::stReturnFromUseInTeleporter);
+ break;
+ case 0x4834:
+ GotoState(&Klaymen::stStepOver);
+ break;
+ case 0x4835:
+ sendMessage(_parentScene, 0x2000, 1);
+ _isSittingInTeleporter = true;
+ GotoState(&Klaymen::stSitInTeleporter);
+ break;
+ case 0x4836:
+ sendMessage(_parentScene, 0x2000, 0);
+ _isSittingInTeleporter = false;
+ GotoState(&Klaymen::stGetUpFromTeleporter);
+ break;
+ }
+ return messageResult;
+}
+
+} // End of namespace Neverhood
diff --git a/engines/neverhood/modules/module2500_sprites.h b/engines/neverhood/modules/module2500_sprites.h
new file mode 100644
index 0000000000..e7f7b05702
--- /dev/null
+++ b/engines/neverhood/modules/module2500_sprites.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 NEVERHOOD_MODULES_MODULE2500_SPRITES_H
+#define NEVERHOOD_MODULES_MODULE2500_SPRITES_H
+
+#include "neverhood/neverhood.h"
+#include "neverhood/module.h"
+#include "neverhood/scene.h"
+
+namespace Neverhood {
+
+class SsScene2504Button : public StaticSprite {
+public:
+ SsScene2504Button(NeverhoodEngine *vm);
+protected:
+ int _countdown;
+ bool _isSoundPlaying;
+ void update();
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class KmScene2501 : public Klaymen {
+public:
+ KmScene2501(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
+protected:
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+};
+
+} // End of namespace Neverhood
+
+#endif /* NEVERHOOD_MODULES_MODULE2500_SPRITES_H */
diff --git a/engines/neverhood/modules/module2600.cpp b/engines/neverhood/modules/module2600.cpp
index 2fce82b777..3c3e733b3f 100644
--- a/engines/neverhood/modules/module2600.cpp
+++ b/engines/neverhood/modules/module2600.cpp
@@ -21,6 +21,7 @@
*/
#include "neverhood/modules/module2600.h"
+#include "neverhood/modules/module2600_sprites.h"
namespace Neverhood {
@@ -219,94 +220,6 @@ void Module2600::updateScene() {
}
}
-SsScene2609Button::SsScene2609Button(NeverhoodEngine *vm, Scene *parentScene)
- : StaticSprite(vm, 1400), _parentScene(parentScene), _countdown(0) {
-
- SetUpdateHandler(&SsScene2609Button::update);
- SetMessageHandler(&SsScene2609Button::handleMessage);
-
- loadSprite(0x825A6923, kSLFDefDrawOffset | kSLFDefPosition | kSLFDefCollisionBoundsOffset, 400);
- if (!getGlobalVar(V_WATER_RUNNING))
- setVisible(false);
- loadSound(0, 0x10267160);
- loadSound(1, 0x7027FD64);
- loadSound(2, 0x44043000);
- loadSound(3, 0x44045000);
-}
-
-void SsScene2609Button::update() {
- updatePosition();
- if (_countdown != 0 && (--_countdown == 0)) {
- if (getGlobalVar(V_WATER_RUNNING)) {
- setGlobalVar(V_WATER_RUNNING, 0);
- sendMessage(_parentScene, 0x2001, 0);
- } else {
- setGlobalVar(V_WATER_RUNNING, 1);
- sendMessage(_parentScene, 0x2002, 0);
- }
- }
-}
-
-uint32 SsScene2609Button::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x1011:
- if (_countdown == 0) {
- sendMessage(_parentScene, 0x2000, 0);
- if (getGlobalVar(V_WATER_RUNNING)) {
- setVisible(false);
- playSound(3);
- playSound(1);
- _countdown = 12;
- } else {
- setVisible(true);
- playSound(2);
- playSound(0);
- _countdown = 96;
- }
- }
- messageResult = 1;
- break;
- }
- return messageResult;
-}
-
-AsScene2609Water::AsScene2609Water(NeverhoodEngine *vm)
- : AnimatedSprite(vm, 1000) {
-
- _x = 240;
- _y = 420;
- setDoDeltaX(1);
- createSurface1(0x9C210C90, 1200);
- setClipRect(260, 260, 400, 368);
- _vm->_soundMan->addSound(0x08526C36, 0xDC2769B0);
- SetUpdateHandler(&AnimatedSprite::update);
- SetMessageHandler(&AsScene2609Water::handleMessage);
- if (getGlobalVar(V_WATER_RUNNING))
- sendMessage(this, 0x2002, 0);
-}
-
-AsScene2609Water::~AsScene2609Water() {
- _vm->_soundMan->deleteSoundGroup(0x08526C36);
-}
-
-uint32 AsScene2609Water::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x2001:
- stopAnimation();
- setVisible(false);
- _vm->_soundMan->stopSound(0xDC2769B0);
- break;
- case 0x2002:
- startAnimation(0x9C210C90, 0, -1);
- setVisible(true);
- _vm->_soundMan->playSoundLooping(0xDC2769B0);
- break;
- }
- return messageResult;
-}
-
Scene2609::Scene2609(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule), _isBusy(false) {
@@ -326,20 +239,20 @@ Scene2609::Scene2609(NeverhoodEngine *vm, Module *parentModule, int which)
uint32 Scene2609::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x0001:
+ case NM_MOUSE_CLICK:
if ((param.asPoint().x <= 20 || param.asPoint().x >= 620) && !_isBusy)
leaveScene(0);
break;
- case 0x2000:
+ case NM_ANIMATION_UPDATE:
_isBusy = true;
break;
case 0x2001:
_isBusy = false;
sendMessage(_asWater, 0x2001, 0);
break;
- case 0x2002:
+ case NM_POSITION_CHANGE:
_isBusy = false;
- sendMessage(_asWater, 0x2002, 0);
+ sendMessage(_asWater, NM_POSITION_CHANGE, 0);
break;
}
return 0;
diff --git a/engines/neverhood/modules/module2600.h b/engines/neverhood/modules/module2600.h
index d972e0fb0d..99ec3a34ca 100644
--- a/engines/neverhood/modules/module2600.h
+++ b/engines/neverhood/modules/module2600.h
@@ -41,24 +41,6 @@ protected:
void updateScene();
};
-class SsScene2609Button : public StaticSprite {
-public:
- SsScene2609Button(NeverhoodEngine *vm, Scene *parentScene);
-protected:
- Scene *_parentScene;
- int _countdown;
- void update();
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
-
-class AsScene2609Water : public AnimatedSprite {
-public:
- AsScene2609Water(NeverhoodEngine *vm);
- virtual ~AsScene2609Water();
-protected:
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
-
class Scene2609 : public Scene {
public:
Scene2609(NeverhoodEngine *vm, Module *parentModule, int which);
diff --git a/engines/neverhood/modules/module2600_sprites.cpp b/engines/neverhood/modules/module2600_sprites.cpp
new file mode 100644
index 0000000000..2506a6eb48
--- /dev/null
+++ b/engines/neverhood/modules/module2600_sprites.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 "neverhood/modules/module2600_sprites.h"
+
+namespace Neverhood {
+
+SsScene2609Button::SsScene2609Button(NeverhoodEngine *vm, Scene *parentScene)
+ : StaticSprite(vm, 1400), _parentScene(parentScene), _countdown(0) {
+
+ SetUpdateHandler(&SsScene2609Button::update);
+ SetMessageHandler(&SsScene2609Button::handleMessage);
+
+ loadSprite(0x825A6923, kSLFDefDrawOffset | kSLFDefPosition | kSLFDefCollisionBoundsOffset, 400);
+ if (!getGlobalVar(V_WATER_RUNNING))
+ setVisible(false);
+ loadSound(0, 0x10267160);
+ loadSound(1, 0x7027FD64);
+ loadSound(2, 0x44043000);
+ loadSound(3, 0x44045000);
+}
+
+void SsScene2609Button::update() {
+ updatePosition();
+ if (_countdown != 0 && (--_countdown == 0)) {
+ if (getGlobalVar(V_WATER_RUNNING)) {
+ setGlobalVar(V_WATER_RUNNING, 0);
+ sendMessage(_parentScene, 0x2001, 0);
+ } else {
+ setGlobalVar(V_WATER_RUNNING, 1);
+ sendMessage(_parentScene, NM_POSITION_CHANGE, 0);
+ }
+ }
+}
+
+uint32 SsScene2609Button::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x1011:
+ if (_countdown == 0) {
+ sendMessage(_parentScene, 0x2000, 0);
+ if (getGlobalVar(V_WATER_RUNNING)) {
+ setVisible(false);
+ playSound(3);
+ playSound(1);
+ _countdown = 12;
+ } else {
+ setVisible(true);
+ playSound(2);
+ playSound(0);
+ _countdown = 96;
+ }
+ }
+ messageResult = 1;
+ break;
+ }
+ return messageResult;
+}
+
+AsScene2609Water::AsScene2609Water(NeverhoodEngine *vm)
+ : AnimatedSprite(vm, 1000) {
+
+ _x = 240;
+ _y = 420;
+ setDoDeltaX(1);
+ createSurface1(0x9C210C90, 1200);
+ setClipRect(260, 260, 400, 368);
+ _vm->_soundMan->addSound(0x08526C36, 0xDC2769B0);
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsScene2609Water::handleMessage);
+ if (getGlobalVar(V_WATER_RUNNING))
+ sendMessage(this, NM_POSITION_CHANGE, 0);
+}
+
+AsScene2609Water::~AsScene2609Water() {
+ _vm->_soundMan->deleteSoundGroup(0x08526C36);
+}
+
+uint32 AsScene2609Water::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x2001:
+ stopAnimation();
+ setVisible(false);
+ _vm->_soundMan->stopSound(0xDC2769B0);
+ break;
+ case NM_POSITION_CHANGE:
+ startAnimation(0x9C210C90, 0, -1);
+ setVisible(true);
+ _vm->_soundMan->playSoundLooping(0xDC2769B0);
+ break;
+ }
+ return messageResult;
+}
+
+} // End of namespace Neverhood
diff --git a/engines/neverhood/modules/module2600_sprites.h b/engines/neverhood/modules/module2600_sprites.h
new file mode 100644
index 0000000000..c36e72cae8
--- /dev/null
+++ b/engines/neverhood/modules/module2600_sprites.h
@@ -0,0 +1,54 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef NEVERHOOD_MODULES_MODULE2600_SPRITES_H
+#define NEVERHOOD_MODULES_MODULE2600_SPRITES_H
+
+#include "neverhood/neverhood.h"
+#include "neverhood/module.h"
+#include "neverhood/scene.h"
+
+namespace Neverhood {
+
+// Module2600
+
+class SsScene2609Button : public StaticSprite {
+public:
+ SsScene2609Button(NeverhoodEngine *vm, Scene *parentScene);
+protected:
+ Scene *_parentScene;
+ int _countdown;
+ void update();
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class AsScene2609Water : public AnimatedSprite {
+public:
+ AsScene2609Water(NeverhoodEngine *vm);
+ virtual ~AsScene2609Water();
+protected:
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+} // End of namespace Neverhood
+
+#endif /* NEVERHOOD_MODULES_MODULE2600_SPRITES_H */
diff --git a/engines/neverhood/modules/module2700.cpp b/engines/neverhood/modules/module2700.cpp
index 7aea82f6b1..13c30048a4 100644
--- a/engines/neverhood/modules/module2700.cpp
+++ b/engines/neverhood/modules/module2700.cpp
@@ -20,9 +20,10 @@
*
*/
-#include "neverhood/modules/module2700.h"
#include "neverhood/gamemodule.h"
-#include "neverhood/modules/module1000.h"
+#include "neverhood/modules/module1600_sprites.h"
+#include "neverhood/modules/module2700.h"
+#include "neverhood/modules/module2700_sprites.h"
namespace Neverhood {
@@ -536,83 +537,6 @@ void Module2700::createScene2704(int which, uint32 trackInfoId, int16 value, con
_childObject = new Scene2704(_vm, this, which, trackInfoId, value, staticSprites, clipRect);
}
-static const NPoint kCarShadowOffsets[] = {
- {-63, 3}, {-48, 40}, {-33, 58},
- { 0, 65}, { 40, 53}, { 56, 27},
- { 63, 0}, {-30, 26}, { 0, 30},
- { 26, 25}
-};
-
-SsCommonTrackShadowBackground::SsCommonTrackShadowBackground(NeverhoodEngine *vm, uint32 fileHash)
- : StaticSprite(vm, 0) {
-
- loadSprite(fileHash, kSLFDefDrawOffset | kSLFDefPosition, 0);
-}
-
-AsCommonCarShadow::AsCommonCarShadow(NeverhoodEngine *vm, AnimatedSprite *asCar, BaseSurface *shadowSurface, uint index)
- : AnimatedSprite(vm, 1100), _asCar(asCar), _index(index), _animFileHash(0) {
-
- SetUpdateHandler(&AsCommonCarShadow::update);
- createShadowSurface(shadowSurface, 211, 147, 100);
- updateShadow();
-}
-
-void AsCommonCarShadow::update() {
- updateShadow();
- AnimatedSprite::update();
-}
-
-void AsCommonCarShadow::updateShadow() {
- if (_asCar->getFrameIndex() != _currFrameIndex || _asCar->getCurrAnimFileHash() != _animFileHash) {
- uint32 fileHash = _asCar->getCurrAnimFileHash();
- if (fileHash == 0x35698F78 || fileHash == 0x192ADD30 || fileHash == 0x9C220DA4 ||
- fileHash == 0x9966B138 || fileHash == 0xB579A77C || fileHash == 0xA86A9538 ||
- fileHash == 0xD4220027 || fileHash == 0xD00A1364 || fileHash == 0xD4AA03A4 ||
- fileHash == 0xF46A0324) {
- startAnimation(fileHash, _asCar->getFrameIndex(), -1);
- _newStickFrameIndex = _asCar->getFrameIndex();
- }
- _animFileHash = fileHash;
- }
- _x = _asCar->getX() + kCarShadowOffsets[_index].x;
- _y = _asCar->getY() + kCarShadowOffsets[_index].y;
- if (!_asCar->getVisible()) {
- startAnimation(0x1209E09F, 0, -1);
- _newStickFrameIndex = 0;
- }
- setDoDeltaX(_asCar->isDoDeltaX() ? 1 : 0);
-}
-
-AsCommonCarConnectorShadow::AsCommonCarConnectorShadow(NeverhoodEngine *vm, Sprite *asCar, BaseSurface *shadowSurface, uint index)
- : AnimatedSprite(vm, 1100), _asCar(asCar), _index(index) {
-
- SetUpdateHandler(&AsCommonCarConnectorShadow::update);
- createShadowSurface1(shadowSurface, 0x60281C10, 150);
- startAnimation(0x60281C10, -1, -1);
- _newStickFrameIndex = STICK_LAST_FRAME;
-}
-
-void AsCommonCarConnectorShadow::update() {
- _x = _asCar->getX() + kCarShadowOffsets[_index].x;
- _y = _asCar->getY() + kCarShadowOffsets[_index].y;
- AnimatedSprite::update();
-}
-
-AsCommonCarTrackShadow::AsCommonCarTrackShadow(NeverhoodEngine *vm, Sprite *asCar, BaseSurface *shadowSurface, int16 frameIndex)
- : AnimatedSprite(vm, 1100), _asCar(asCar) {
-
- SetUpdateHandler(&AsCommonCarTrackShadow::update);
- createShadowSurface1(shadowSurface, 0x0759129C, 100);
- startAnimation(0x0759129C, frameIndex, -1);
- _newStickFrameIndex = frameIndex;
-}
-
-void AsCommonCarTrackShadow::update() {
- _x = _asCar->getX();
- _y = _asCar->getY();
- AnimatedSprite::update();
-}
-
Scene2701::Scene2701(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule) {
@@ -652,14 +576,14 @@ Scene2701::Scene2701(NeverhoodEngine *vm, Module *parentModule, int which)
if (which == _which2) {
NPoint testPoint = (*_trackPoints)[_trackPoints->size() - 1];
- sendMessage(_asCar, 0x2002, _trackPoints->size() - 1);
+ sendMessage(_asCar, NM_POSITION_CHANGE, _trackPoints->size() - 1);
if (testPoint.x < 0 || testPoint.x >= 640 || testPoint.y < 0 || testPoint.y >= 480)
- sendMessage(_asCar, 0x2007, 150);
+ sendMessage(_asCar, NM_CAR_MOVE_TO_PREV_POINT, 150);
} else {
NPoint testPoint = (*_trackPoints)[0];
- sendMessage(_asCar, 0x2002, 0);
+ sendMessage(_asCar, NM_POSITION_CHANGE, 0);
if (testPoint.x < 0 || testPoint.x >= 640 || testPoint.y < 0 || testPoint.y >= 480)
- sendMessage(_asCar, 0x2008, 150);
+ sendMessage(_asCar, NM_CAR_MOVE_TO_NEXT_POINT, 150);
}
_asCar->setClipRect(clipRect);
@@ -668,7 +592,7 @@ Scene2701::Scene2701(NeverhoodEngine *vm, Module *parentModule, int which)
if (which == 1) {
SetMessageHandler(&Scene2701::hmRidingCar);
} else {
- sendMessage(_asCar, 0x2009, 0);
+ sendMessage(_asCar, NM_CAR_ENTER, 0);
SetMessageHandler(&Scene2701::hmCarAtHome);
}
@@ -677,14 +601,14 @@ Scene2701::Scene2701(NeverhoodEngine *vm, Module *parentModule, int which)
uint32 Scene2701::hmRidingCar(int messageNum, const MessageParam &param, Entity *sender) {
Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x0001:
+ case NM_MOUSE_CLICK:
sendPointMessage(_asCar, 0x2004, param.asPoint());
break;
- case 0x2005:
+ case NM_KLAYMEN_CLIMB_LADDER:
if (_which1 >= 0)
SetMessageHandler(&Scene2701::hmCarAtHome);
break;
- case 0x2006:
+ case NM_KLAYMEN_STOP_CLIMBING:
if (_which2 >= 0)
leaveScene(_which2);
break;
@@ -698,7 +622,7 @@ uint32 Scene2701::hmRidingCar(int messageNum, const MessageParam &param, Entity
uint32 Scene2701::hmCarAtHome(int messageNum, const MessageParam &param, Entity *sender) {
Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x0001:
+ case NM_MOUSE_CLICK:
if (param.asPoint().x >= 385)
leaveScene(0);
else {
@@ -778,11 +702,11 @@ Scene2702::Scene2702(NeverhoodEngine *vm, Module *parentModule, int which)
_asCar->setPathPoints(_trackPoints);
if (which == _tracks[_currTrackIndex]->which2) {
- sendMessage(_asCar, 0x2002, _trackPoints->size() - 1);
- sendMessage(_asCar, 0x2007, 150);
+ sendMessage(_asCar, NM_POSITION_CHANGE, _trackPoints->size() - 1);
+ sendMessage(_asCar, NM_CAR_MOVE_TO_PREV_POINT, 150);
} else {
- sendMessage(_asCar, 0x2002, 0);
- sendMessage(_asCar, 0x2008, 150);
+ sendMessage(_asCar, NM_POSITION_CHANGE, 0);
+ sendMessage(_asCar, NM_CAR_MOVE_TO_NEXT_POINT, 150);
}
_palette->copyBasePalette(0, 256, 0);
@@ -807,17 +731,17 @@ void Scene2702::update() {
uint32 Scene2702::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x0001:
+ case NM_MOUSE_CLICK:
moveCarToPoint(param.asPoint());
break;
- case 0x2005:
+ case NM_KLAYMEN_CLIMB_LADDER:
if (_newTrackIndex >= 0) {
if (_tracks[_currTrackIndex]->which1 < 0)
changeTrack();
} else if (_tracks[_currTrackIndex]->which1 >= 0)
leaveScene(_tracks[_currTrackIndex]->which1);
break;
- case 0x2006:
+ case NM_KLAYMEN_STOP_CLIMBING:
if (_newTrackIndex >= 0) {
if (_tracks[_currTrackIndex]->which2 < 0)
changeTrack();
@@ -858,13 +782,13 @@ void Scene2702::changeTrack() {
_asCar->setPathPoints(_trackPoints);
if (_isUpperTrack) {
if (_currTrackIndex == 0)
- sendMessage(_asCar, 0x2002, _trackPoints->size() - 1);
+ sendMessage(_asCar, NM_POSITION_CHANGE, _trackPoints->size() - 1);
else
- sendMessage(_asCar, 0x2002, 0);
+ sendMessage(_asCar, NM_POSITION_CHANGE, 0);
} else if (_currTrackIndex == 2)
- sendMessage(_asCar, 0x2002, 0);
+ sendMessage(_asCar, NM_POSITION_CHANGE, 0);
else
- sendMessage(_asCar, 0x2002, _trackPoints->size() - 1);
+ sendMessage(_asCar, NM_POSITION_CHANGE, _trackPoints->size() - 1);
sendMessage(_asCar, 0x2004, _newTrackDestX);
_newTrackIndex = -1;
}
@@ -908,18 +832,18 @@ Scene2703::Scene2703(NeverhoodEngine *vm, Module *parentModule, int which, uint3
if (which == _which2) {
NPoint testPoint = (*_trackPoints)[_trackPoints->size() - 1];
- sendMessage(_asCar, 0x2002, _trackPoints->size() - 1);
+ sendMessage(_asCar, NM_POSITION_CHANGE, _trackPoints->size() - 1);
if (testPoint.x > 0 && testPoint.x < 640 && testPoint.y > 0 && testPoint.y < 480)
- sendMessage(_asCar, 0x2009, 0);
+ sendMessage(_asCar, NM_CAR_ENTER, 0);
else
- sendMessage(_asCar, 0x2007, 150);
+ sendMessage(_asCar, NM_CAR_MOVE_TO_PREV_POINT, 150);
} else {
NPoint testPoint = (*_trackPoints)[0];
- sendMessage(_asCar, 0x2002, 0);
+ sendMessage(_asCar, NM_POSITION_CHANGE, 0);
if (testPoint.x > 0 && testPoint.x < 640 && testPoint.y > 0 && testPoint.y < 480)
- sendMessage(_asCar, 0x2009, 0);
+ sendMessage(_asCar, NM_CAR_ENTER, 0);
else
- sendMessage(_asCar, 0x2008, 150);
+ sendMessage(_asCar, NM_CAR_MOVE_TO_NEXT_POINT, 150);
}
if (which == 0) {
@@ -967,11 +891,11 @@ void Scene2703::update() {
uint32 Scene2703::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x2005:
+ case NM_KLAYMEN_CLIMB_LADDER:
if (_which1 >= 0)
leaveScene(_which1);
break;
- case 0x2006:
+ case NM_KLAYMEN_STOP_CLIMBING:
if (_which2 >= 0)
leaveScene(_which2);
break;
@@ -1027,18 +951,18 @@ Scene2704::Scene2704(NeverhoodEngine *vm, Module *parentModule, int which, uint3
if (which == _which2) {
NPoint testPoint = (*_trackPoints)[_trackPoints->size() - 1];
- sendMessage(_asCar, 0x2002, _trackPoints->size() - 1);
+ sendMessage(_asCar, NM_POSITION_CHANGE, _trackPoints->size() - 1);
if (testPoint.x > 0 && testPoint.x < 640 && testPoint.y > 0 && testPoint.y < 480)
- sendMessage(_asCar, 0x2009, 0);
+ sendMessage(_asCar, NM_CAR_ENTER, 0);
else
- sendMessage(_asCar, 0x2007, 0);
+ sendMessage(_asCar, NM_CAR_MOVE_TO_PREV_POINT, 150);
} else {
NPoint testPoint = (*_trackPoints)[0];
- sendMessage(_asCar, 0x2002, 0);
+ sendMessage(_asCar, NM_POSITION_CHANGE, 0);
if (testPoint.x > 0 && testPoint.x < 640 && testPoint.y > 0 && testPoint.y < 480)
- sendMessage(_asCar, 0x2009, 0);
+ sendMessage(_asCar, NM_CAR_ENTER, 0);
else
- sendMessage(_asCar, 0x2008, 0);
+ sendMessage(_asCar, NM_CAR_MOVE_TO_NEXT_POINT, 150);
}
if (clipRect) {
@@ -1066,11 +990,11 @@ void Scene2704::update() {
uint32 Scene2704::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x2005:
+ case NM_KLAYMEN_CLIMB_LADDER:
if (_which1 >= 0)
leaveScene(_which1);
break;
- case 0x2006:
+ case NM_KLAYMEN_STOP_CLIMBING:
if (_which2 >= 0)
leaveScene(_which2);
break;
@@ -1120,17 +1044,17 @@ Scene2706::Scene2706(NeverhoodEngine *vm, Module *parentModule, int which)
_asCar->setPathPoints(_trackPoints);
if (which == _tracks[_currTrackIndex]->which2) {
- sendMessage(_asCar, 0x2002, _trackPoints->size() - 1);
+ sendMessage(_asCar, NM_POSITION_CHANGE, _trackPoints->size() - 1);
if (which == 5)
- sendMessage(_asCar, 0x2007, 50);
+ sendMessage(_asCar, NM_CAR_MOVE_TO_PREV_POINT, 50);
else
- sendMessage(_asCar, 0x2007, 150);
+ sendMessage(_asCar, NM_CAR_MOVE_TO_PREV_POINT, 150);
} else {
- sendMessage(_asCar, 0x2002, 0);
+ sendMessage(_asCar, NM_POSITION_CHANGE, 0);
if (which == 5)
- sendMessage(_asCar, 0x2008, 50);
+ sendMessage(_asCar, NM_CAR_MOVE_TO_NEXT_POINT, 50);
else
- sendMessage(_asCar, 0x2008, 150);
+ sendMessage(_asCar, NM_CAR_MOVE_TO_NEXT_POINT, 150);
}
}
@@ -1138,17 +1062,17 @@ Scene2706::Scene2706(NeverhoodEngine *vm, Module *parentModule, int which)
uint32 Scene2706::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x0001:
+ case NM_MOUSE_CLICK:
moveCarToPoint(param.asPoint());
break;
- case 0x2005:
+ case NM_KLAYMEN_CLIMB_LADDER:
if (_newTrackIndex >= 0) {
if (_tracks[_currTrackIndex]->which1 < 0)
changeTrack();
} else if (_tracks[_currTrackIndex]->which1 >= 0)
leaveScene(_tracks[_currTrackIndex]->which1);
break;
- case 0x2006:
+ case NM_KLAYMEN_STOP_CLIMBING:
if (_newTrackIndex >= 0) {
if (_tracks[_currTrackIndex]->which2 < 0)
changeTrack();
@@ -1183,9 +1107,9 @@ void Scene2706::changeTrack() {
_trackPoints = _dataResource.getPointArray(_tracks[_currTrackIndex]->trackPointsName);
_asCar->setPathPoints(_trackPoints);
if (_currTrackIndex == 0)
- sendMessage(_asCar, 0x2002, _trackPoints->size() - 1);
+ sendMessage(_asCar, NM_POSITION_CHANGE, _trackPoints->size() - 1);
else
- sendMessage(_asCar, 0x2002, 0);
+ sendMessage(_asCar, NM_POSITION_CHANGE, 0);
sendMessage(_asCar, 0x2004, _newTrackDestX);
_newTrackIndex = -1;
}
diff --git a/engines/neverhood/modules/module2700.h b/engines/neverhood/modules/module2700.h
index 158bb609e9..97b4f1cbea 100644
--- a/engines/neverhood/modules/module2700.h
+++ b/engines/neverhood/modules/module2700.h
@@ -26,7 +26,7 @@
#include "neverhood/neverhood.h"
#include "neverhood/module.h"
#include "neverhood/scene.h"
-#include "neverhood/modules/module1600.h"
+#include "neverhood/modules/module1600_sprites.h" // for Tracks
namespace Neverhood {
@@ -49,38 +49,7 @@ protected:
void createScene2704(int which, uint32 trackInfoId, int16 value, const uint32 *staticSprites = NULL, const NRect *clipRect = NULL);
};
-class SsCommonTrackShadowBackground : public StaticSprite {
-public:
- SsCommonTrackShadowBackground(NeverhoodEngine *vm, uint32 fileHash);
-};
-
-class AsCommonCarShadow : public AnimatedSprite {
-public:
- AsCommonCarShadow(NeverhoodEngine *vm, AnimatedSprite *asCar, BaseSurface *shadowSurface, uint index);
-protected:
- uint _index;
- AnimatedSprite *_asCar;
- uint32 _animFileHash;
- void update();
- void updateShadow();
-};
-
-class AsCommonCarConnectorShadow : public AnimatedSprite {
-public:
- AsCommonCarConnectorShadow(NeverhoodEngine *vm, Sprite *asCar, BaseSurface *shadowSurface, uint index);
-protected:
- uint _index;
- Sprite *_asCar;
- void update();
-};
-
-class AsCommonCarTrackShadow : public AnimatedSprite {
-public:
- AsCommonCarTrackShadow(NeverhoodEngine *vm, Sprite *asCar, BaseSurface *shadowSurface, int16 frameIndex);
-protected:
- Sprite *_asCar;
- void update();
-};
+class AsCommonCar;
class Scene2701 : public Scene {
public:
diff --git a/engines/neverhood/modules/module2700_sprites.cpp b/engines/neverhood/modules/module2700_sprites.cpp
new file mode 100644
index 0000000000..8dd2fa3461
--- /dev/null
+++ b/engines/neverhood/modules/module2700_sprites.cpp
@@ -0,0 +1,178 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public 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 "neverhood/modules/module2700_sprites.h"
+
+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},
+ { 63, 0}, {-30, 26}, { 0, 30},
+ { 26, 25}
+};
+
+SsCommonTrackShadowBackground::SsCommonTrackShadowBackground(NeverhoodEngine *vm, uint32 fileHash)
+ : StaticSprite(vm, 0) {
+
+ loadSprite(fileHash, kSLFDefDrawOffset | kSLFDefPosition, 0);
+}
+
+AsCommonCarShadow::AsCommonCarShadow(NeverhoodEngine *vm, AnimatedSprite *asCar, BaseSurface *shadowSurface, uint index)
+ : AnimatedSprite(vm, 1100), _asCar(asCar), _index(index), _animFileHash(0) {
+
+ SetUpdateHandler(&AsCommonCarShadow::update);
+ createShadowSurface(shadowSurface, 211, 147, 100);
+ updateShadow();
+}
+
+void AsCommonCarShadow::update() {
+ updateShadow();
+ AnimatedSprite::update();
+}
+
+void AsCommonCarShadow::updateShadow() {
+ if (_asCar->getFrameIndex() != _currFrameIndex || _asCar->getCurrAnimFileHash() != _animFileHash) {
+ uint32 fileHash = _asCar->getCurrAnimFileHash();
+ if (fileHash == 0x35698F78 || fileHash == 0x192ADD30 || fileHash == 0x9C220DA4 ||
+ fileHash == 0x9966B138 || fileHash == 0xB579A77C || fileHash == 0xA86A9538 ||
+ fileHash == 0xD4220027 || fileHash == 0xD00A1364 || fileHash == 0xD4AA03A4 ||
+ fileHash == 0xF46A0324) {
+ startAnimation(fileHash, _asCar->getFrameIndex(), -1);
+ _newStickFrameIndex = _asCar->getFrameIndex();
+ }
+ _animFileHash = fileHash;
+ }
+ _x = _asCar->getX() + kCarShadowOffsets[_index].x;
+ _y = _asCar->getY() + kCarShadowOffsets[_index].y;
+ if (!_asCar->getVisible()) {
+ startAnimation(0x1209E09F, 0, -1);
+ _newStickFrameIndex = 0;
+ }
+ setDoDeltaX(_asCar->isDoDeltaX() ? 1 : 0);
+}
+
+AsCommonCarConnectorShadow::AsCommonCarConnectorShadow(NeverhoodEngine *vm, Sprite *asCar, BaseSurface *shadowSurface, uint index)
+ : AnimatedSprite(vm, 1100), _asCar(asCar), _index(index) {
+
+ SetUpdateHandler(&AsCommonCarConnectorShadow::update);
+ createShadowSurface1(shadowSurface, 0x60281C10, 150);
+ startAnimation(0x60281C10, -1, -1);
+ _newStickFrameIndex = STICK_LAST_FRAME;
+}
+
+void AsCommonCarConnectorShadow::update() {
+ _x = _asCar->getX() + kCarShadowOffsets[_index].x;
+ _y = _asCar->getY() + kCarShadowOffsets[_index].y;
+ AnimatedSprite::update();
+}
+
+AsCommonCarTrackShadow::AsCommonCarTrackShadow(NeverhoodEngine *vm, Sprite *asCar, BaseSurface *shadowSurface, int16 frameIndex)
+ : AnimatedSprite(vm, 1100), _asCar(asCar) {
+
+ SetUpdateHandler(&AsCommonCarTrackShadow::update);
+ createShadowSurface1(shadowSurface, 0x0759129C, 100);
+ startAnimation(0x0759129C, frameIndex, -1);
+ _newStickFrameIndex = frameIndex;
+}
+
+void AsCommonCarTrackShadow::update() {
+ _x = _asCar->getX();
+ _y = _asCar->getY();
+ AnimatedSprite::update();
+}
+
+KmScene2732::KmScene2732(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
+ : Klaymen(vm, parentScene, x, y) {
+
+ // Empty
+}
+
+uint32 KmScene2732::xHandleMessage(int messageNum, const MessageParam &param) {
+ switch (messageNum) {
+ case 0x4804:
+ GotoState(&Klaymen::stPeekInside);
+ break;
+ case 0x483C:
+ GotoState(&Klaymen::stPeekInsideReturn);
+ break;
+ }
+ return 0;
+}
+
+} // End of namespace Neverhood
diff --git a/engines/neverhood/modules/module2700_sprites.h b/engines/neverhood/modules/module2700_sprites.h
new file mode 100644
index 0000000000..394ba896a1
--- /dev/null
+++ b/engines/neverhood/modules/module2700_sprites.h
@@ -0,0 +1,74 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef NEVERHOOD_MODULES_MODULE2700_SPRITES_H
+#define NEVERHOOD_MODULES_MODULE2700_SPRITES_H
+
+#include "neverhood/neverhood.h"
+#include "neverhood/module.h"
+#include "neverhood/scene.h"
+
+namespace Neverhood {
+
+class SsCommonTrackShadowBackground : public StaticSprite {
+public:
+ SsCommonTrackShadowBackground(NeverhoodEngine *vm, uint32 fileHash);
+};
+
+class AsCommonCarShadow : public AnimatedSprite {
+public:
+ AsCommonCarShadow(NeverhoodEngine *vm, AnimatedSprite *asCar, BaseSurface *shadowSurface, uint index);
+protected:
+ uint _index;
+ AnimatedSprite *_asCar;
+ uint32 _animFileHash;
+ void update();
+ void updateShadow();
+};
+
+class AsCommonCarConnectorShadow : public AnimatedSprite {
+public:
+ AsCommonCarConnectorShadow(NeverhoodEngine *vm, Sprite *asCar, BaseSurface *shadowSurface, uint index);
+protected:
+ uint _index;
+ Sprite *_asCar;
+ void update();
+};
+
+class AsCommonCarTrackShadow : public AnimatedSprite {
+public:
+ AsCommonCarTrackShadow(NeverhoodEngine *vm, Sprite *asCar, BaseSurface *shadowSurface, int16 frameIndex);
+protected:
+ Sprite *_asCar;
+ void update();
+};
+
+class KmScene2732 : public Klaymen {
+public:
+ KmScene2732(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
+protected:
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+};
+
+} // End of namespace Neverhood
+
+#endif /* NEVERHOOD_MODULES_MODULE2700_SPRITES_H */
diff --git a/engines/neverhood/modules/module2800.cpp b/engines/neverhood/modules/module2800.cpp
index 3a33598090..5d892de224 100644
--- a/engines/neverhood/modules/module2800.cpp
+++ b/engines/neverhood/modules/module2800.cpp
@@ -20,14 +20,15 @@
*
*/
-#include "neverhood/modules/module2800.h"
+#include "neverhood/diskplayerscene.h"
#include "neverhood/gamemodule.h"
-#include "neverhood/modules/module1000.h"
-#include "neverhood/modules/module1200.h"
-#include "neverhood/modules/module1700.h"
-#include "neverhood/modules/module2200.h"
+#include "neverhood/scene.h"
+#include "neverhood/modules/module1000_sprites.h"
+#include "neverhood/modules/module1200_sprites.h"
+#include "neverhood/modules/module1700_sprites.h"
+#include "neverhood/modules/module2200_sprites.h"
+#include "neverhood/modules/module2800.h"
#include "neverhood/modules/module2800_sprites.h"
-#include "neverhood/diskplayerscene.h"
namespace Neverhood {
@@ -58,155 +59,126 @@ Module2800::~Module2800() {
_vm->_soundMan->deleteGroup(0x64210814);
}
+#define statueCloseup(backgroundFileHash, cursorFileHash) \
+ _vm->_soundMan->startMusic(0xD2FA4D14, 0, 2); \
+ createStaticScene(backgroundFileHash, cursorFileHash)
+
void Module2800::createScene(int sceneNum, int which) {
debug(1, "Module2800::createScene(%d, %d)", sceneNum, which);
_sceneNum = sceneNum;
+
+ if (_sceneNum != 1001)
+ _vm->gameState().sceneNum = _sceneNum;
+
switch (_sceneNum) {
- case 0:
- _vm->gameState().sceneNum = 0;
+ case 0: // in front of radio
_vm->_soundMan->stopMusic(0xD2FA4D14, 0, 0);
_childObject = new Scene2801(_vm, this, which);
break;
- case 1:
- _vm->gameState().sceneNum = 1;
+ case 1: // radio
_vm->_soundMan->stopMusic(0xD2FA4D14, 0, 0);
if (getGlobalVar(V_RADIO_ENABLED))
_childObject = new Scene2802(_vm, this, which);
else
createStaticScene(0x000C6444, 0xC6440008);
break;
- case 2:
- _vm->gameState().sceneNum = 2;
+ case 2: // outside shrink machine
_vm->_soundMan->startMusic(0xD2FA4D14, 0, 2);
if (getGlobalVar(V_KLAYMEN_SMALL))
_childObject = new Scene2803Small(_vm, this, which);
else
_childObject = new Scene2803(_vm, this, which);
break;
- case 3:
- _vm->gameState().sceneNum = 3;
+ case 3: // glass cylinder with diamonds
_childObject = new Scene2804(_vm, this, which);
break;
- case 4:
- _vm->gameState().sceneNum = 4;
+ case 4: // outside the transporter
_vm->_soundMan->stopMusic(0xD2FA4D14, 0, 2);
_childObject = new Scene2805(_vm, this, which);
break;
- case 5:
- _vm->gameState().sceneNum = 5;
+ case 5: // left test tube room
_vm->_soundMan->startMusic(0xD2FA4D14, 0, 2);
_childObject = new Scene2806(_vm, this, which);
break;
- case 6:
- _vm->gameState().sceneNum = 6;
+ case 6: // the three test tubes next to the window
_vm->_soundMan->startMusic(0xD2FA4D14, 0, 2);
_childObject = new Scene2807(_vm, this, which);
break;
- case 7:
- _vm->gameState().sceneNum = 7;
+ case 7: // left test tube room closeup
_vm->_soundMan->startMusic(0xD2FA4D14, 0, 2);
_childObject = new Scene2808(_vm, this, 0);
break;
- case 8:
- _vm->gameState().sceneNum = 8;
+ case 8: // right test tube room
_vm->_soundMan->startMusic(0xD2FA4D14, 0, 2);
_childObject = new Scene2809(_vm, this, which);
break;
- case 9:
- _vm->gameState().sceneNum = 9;
+ case 9: // statue room
_vm->_soundMan->startMusic(0xD2FA4D14, 0, 2);
_childObject = new Scene2810(_vm, this, which);
break;
- case 10:
- _vm->gameState().sceneNum = 10;
+ case 10: // right test tube room closeup
_vm->_soundMan->startMusic(0xD2FA4D14, 0, 2);
_childObject = new Scene2808(_vm, this, 1);
break;
- case 11:
- _vm->gameState().sceneNum = 11;
+ case 11: // disk player room (above the statue room)
_vm->_soundMan->startMusic(0xD2FA4D14, 0, 2);
_childObject = new Scene2812(_vm, this, which);
break;
case 12:
- _vm->gameState().sceneNum = 12;
- _vm->_soundMan->startMusic(0xD2FA4D14, 0, 2);
- createStaticScene(0x0000A245, 0x0A241008);
+ statueCloseup(0x0000A245, 0x0A241008);
break;
case 13:
- _vm->gameState().sceneNum = 13;
- _vm->_soundMan->startMusic(0xD2FA4D14, 0, 2);
- createStaticScene(0x81C60635, 0x60631814);
+ statueCloseup(0x81C60635, 0x60631814);
break;
case 14:
- _vm->gameState().sceneNum = 14;
- _vm->_soundMan->startMusic(0xD2FA4D14, 0, 2);
- createStaticScene(0xCA811204, 0x11200CA0);
+ statueCloseup(0xCA811204, 0x11200CA0);
break;
case 15:
- _vm->gameState().sceneNum = 15;
- _vm->_soundMan->startMusic(0xD2FA4D14, 0, 2);
- createStaticScene(0x2D438A00, 0x38A042DC);
+ statueCloseup(0x2D438A00, 0x38A042DC);
break;
case 16:
- _vm->gameState().sceneNum = 16;
- _vm->_soundMan->startMusic(0xD2FA4D14, 0, 2);
- createStaticScene(0x0A806204, 0x062000A0);
+ statueCloseup(0x0A806204, 0x062000A0);
break;
case 17:
- _vm->gameState().sceneNum = 17;
- _vm->_soundMan->startMusic(0xD2FA4D14, 0, 2);
- createStaticScene(0x010F9284, 0xF9280018);
+ statueCloseup(0x010F9284, 0xF9280018);
break;
case 18:
- _vm->gameState().sceneNum = 18;
- _vm->_soundMan->startMusic(0xD2FA4D14, 0, 2);
- createStaticScene(0x0100022B, 0x0022F018);
+ statueCloseup(0x0100022B, 0x0022F018);
break;
case 19:
- _vm->gameState().sceneNum = 19;
- _vm->_soundMan->startMusic(0xD2FA4D14, 0, 2);
- createStaticScene(0x10866205, 0x66201100);
+ statueCloseup(0x10866205, 0x66201100);
break;
case 20:
- _vm->gameState().sceneNum = 20;
- _vm->_soundMan->startMusic(0xD2FA4D14, 0, 2);
- createStaticScene(0x01C58000, 0x58004014);
+ statueCloseup(0x01C58000, 0x58004014);
break;
- case 21:
- _vm->gameState().sceneNum = 21;
+ case 21: // statue with ladder down button
_vm->_soundMan->startMusic(0xD2FA4D14, 0, 2);
_childObject = new Scene2822(_vm, this, which);
break;
case 22:
- _vm->gameState().sceneNum = 22;
- _vm->_soundMan->startMusic(0xD2FA4D14, 0, 2);
- createStaticScene(0x9408121E, 0x8121A948);
+ statueCloseup(0x9408121E, 0x8121A948);
break;
case 23:
- _vm->gameState().sceneNum = 23;
- _vm->_soundMan->startMusic(0xD2FA4D14, 0, 2);
- createStaticScene(0x048C0600, 0xC0604040);
+ statueCloseup(0x048C0600, 0xC0604040);
break;
case 24:
- _vm->gameState().sceneNum = 24;
- _vm->_soundMan->startMusic(0xD2FA4D14, 0, 2);
- createStaticScene(0x04270A94, 0x70A9004A);
+ statueCloseup(0x04270A94, 0x70A9004A);
break;
- case 25:
- _vm->gameState().sceneNum = 25;
+ case 25: // window
_vm->_soundMan->startMusic(0xD2FA4D14, 0, 2);
if (getGlobalVar(V_SHRINK_LIGHTS_ON))
createStaticScene(0x01600204, 0x0020001E);
else
createStaticScene(0x08611204, 0x1120008E);
break;
- case 26:
- _vm->gameState().sceneNum = 26;
- _vm->_soundMan->startMusic(0xD2FA4D14, 0, 2);
+ case 26: // disk player
+ _vm->_soundMan->stopMusic(0xD2FA4D14, 0, 2);
_childObject = new DiskplayerScene(_vm, this, 4);
break;
- case 1001:
+ case 1001: // tower rotation video
_vm->_soundMan->stopMusic(0xD2FA4D14, 0, 0);
+ _musicResource->stop(0);
+ _currentMusicFileHash = 0;
createSmackerScene(0x00800801, true, true, false);
break;
}
@@ -214,6 +186,8 @@ void Module2800::createScene(int sceneNum, int which) {
_childObject->handleUpdate();
}
+#undef statueCloseup
+
void Module2800::updateScene() {
if (!updateChild()) {
switch (_sceneNum) {
@@ -353,7 +327,6 @@ void Module2800::updateScene() {
}
void Module2800::updateMusic(bool halfVolume) {
-
uint32 newMusicFileHash = _vm->_gameModule->getCurrRadioMusicFileHash();
if (!_musicResource)
@@ -476,11 +449,11 @@ uint32 Scene2801::handleMessage(int messageNum, const MessageParam &param, Entit
setMessageList(0x004B6C40);
}
break;
- case 0x482A:
+ case NM_MOVE_TO_BACK:
_palette->addBasePalette(0xB103B604, 0, 65, 0);
_palette->startFadeToPalette(12);
break;
- case 0x482B:
+ case NM_MOVE_TO_FRONT:
_palette->addBasePalette(_paletteHash, 0, 65, 0);
_palette->startFadeToPalette(12);
break;
@@ -584,7 +557,7 @@ uint32 Scene2802::handleMessage(int messageNum, const MessageParam &param, Entit
int prevTuneStatus = _currTuneStatus;
Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x0001:
+ case NM_MOUSE_CLICK:
if (param.asPoint().x <= 20 || param.asPoint().x >= 620) {
leaveScene(0);
} else if (_currTuneStatus == 0) {
@@ -601,7 +574,7 @@ uint32 Scene2802::handleMessage(int messageNum, const MessageParam &param, Entit
}
}
break;
- case 0x0002:
+ case NM_MOUSE_RELEASE:
if (_countdown1 == 0)
_currTuneStatus = 0;
else {
@@ -777,10 +750,10 @@ void Scene2803::upKlaymenStairs() {
uint32 Scene2803::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x480F:
+ case NM_KLAYMEN_LOWER_LEVER:
toggleBackground();
// NOTE Intentional fall-through
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0x84251F82)
setMessageList(0x004B7A50);
else if (param.asInteger() == 0x4254A2D2)
@@ -795,11 +768,11 @@ uint32 Scene2803::handleMessage(int messageNum, const MessageParam &param, Entit
} else if (param.asInteger() == 0x9626F390)
setMessageList(0x004B7A88);
break;
- case 0x482A:
+ case NM_MOVE_TO_BACK:
klaymenStairs();
setPaletteArea1();
break;
- case 0x482B:
+ case NM_MOVE_TO_FRONT:
klaymenFloor();
setPaletteArea0();
break;
@@ -1013,7 +986,7 @@ Scene2803Small::Scene2803Small(NeverhoodEngine *vm, Module *parentModule, int wh
uint32 Scene2803Small::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0xB4E4884C) {
setMessageList(0x004B6180);
} else if (param.asInteger() == 0xB1FDAB2E) {
@@ -1041,7 +1014,7 @@ uint32 Scene2803Small::handleMessage(int messageNum, const MessageParam &param,
setMessageList(0x004B61A8);
}
break;
- case 0x482A:
+ case NM_MOVE_TO_BACK:
if (_klaymen->getX() < 200) {
setPaletteArea3();
} else if (_klaymen->getX() < 500) {
@@ -1053,7 +1026,7 @@ uint32 Scene2803Small::handleMessage(int messageNum, const MessageParam &param,
setPaletteArea2();
}
break;
- case 0x482B:
+ case NM_MOVE_TO_FRONT:
_sprite6->setVisible(false);
_sprite7->setVisible(false);
_klaymen->setClipRect(0, 0, 640, 480);
@@ -1204,14 +1177,14 @@ Scene2804::Scene2804(NeverhoodEngine *vm, Module *parentModule, int which)
uint32 Scene2804::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x0001:
+ case NM_MOUSE_CLICK:
if (param.asPoint().x <= 20 || param.asPoint().x >= 620) {
leaveScene(0);
}
break;
- case 0x2000:
+ case NM_ANIMATION_UPDATE:
_isWorking = true;
- sendMessage(_asCoil, 0x2002, 0);
+ sendMessage(_asCoil, NM_POSITION_CHANGE, 0);
if (getGlobalVar(V_SHRINK_LIGHTS_ON)) {
sendMessage(_asTarget, 0x2004, 0);
_countdown2 = 48;
@@ -1241,7 +1214,7 @@ void Scene2804::update() {
if (_countdown2 != 0 && (--_countdown2) == 0) {
_isWorking = false;
sendMessage(_asCoil, 0x2003, 0);
- sendMessage(_asTarget, 0x2005, 0);
+ sendMessage(_asTarget, NM_KLAYMEN_CLIMB_LADDER, 0);
for (uint index = 0; index < 5; index++)
_asCrystals[index]->hide();
}
@@ -1315,7 +1288,7 @@ Scene2805::Scene2805(NeverhoodEngine *vm, Module *parentModule, int which)
uint32 Scene2805::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x2000:
+ case NM_ANIMATION_UPDATE:
if (param.asInteger()) {
setRectList(0x004AE318);
_klaymen->setKlaymenIdleTable3();
@@ -1405,12 +1378,12 @@ Scene2806::Scene2806(NeverhoodEngine *vm, Module *parentModule, int which)
uint32 Scene2806::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0x44262B12) {
setMessageList(0x004AF0E0);
}
break;
- case 0x2000:
+ case NM_ANIMATION_UPDATE:
sendMessage(_asSpew, 0x2000, 0);
break;
}
@@ -1485,7 +1458,7 @@ Scene2807::Scene2807(NeverhoodEngine *vm, Module *parentModule, int which)
uint32 Scene2807::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x0001:
+ case NM_MOUSE_CLICK:
if (param.asPoint().x <= 20 || param.asPoint().x >= 620) {
leaveScene(0);
}
@@ -1555,19 +1528,19 @@ Scene2808::Scene2808(NeverhoodEngine *vm, Module *parentModule, int which)
uint32 Scene2808::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x0001:
+ case NM_MOUSE_CLICK:
if ((param.asPoint().x <= 20 || param.asPoint().x >= 620) && !isAnyTestTubeFilled()) {
leaveScene(1);
}
break;
- case 0x2000:
+ case NM_ANIMATION_UPDATE:
if (!_isFlowing)
_asTestTubes[param.asInteger()]->fill();
break;
case 0x2001:
_isFlowing = true;
break;
- case 0x2002:
+ case NM_POSITION_CHANGE:
if (isAnyTestTubeFilled()) {
_leaveResult = 3;
if (!isMixtureGood())
@@ -1695,12 +1668,12 @@ void Scene2809::update() {
uint32 Scene2809::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0x160DA937) {
setMessageList(0x004B5B98);
}
break;
- case 0x2000:
+ case NM_ANIMATION_UPDATE:
sendMessage(_asSpew, 0x2000, 0);
break;
}
@@ -1902,7 +1875,7 @@ void Scene2810::insertKlaymenLadder() {
uint32 Scene2810::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0xE574F14C)
setMessageList(0x004AE458);
else if (param.asInteger() == 0x7214A05C || param.asInteger() == 0x2905E574)
@@ -1932,7 +1905,7 @@ uint32 Scene2810::handleMessage(int messageNum, const MessageParam &param, Entit
else if (param.asInteger() == 0x2064294C || param.asInteger() == 0x2194E053)
setMessageList(0x004AE688);
break;
- case 0x2000:
+ case NM_ANIMATION_UPDATE:
setRectList(0x004AE800);
_isRopingDown = true;
break;
@@ -2035,7 +2008,7 @@ void Scene2812::update() {
uint32 Scene2812::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0x0004269B)
sendEntityMessage(_klaymen, 0x1014, _asRope);
break;
@@ -2044,12 +2017,12 @@ uint32 Scene2812::handleMessage(int messageNum, const MessageParam &param, Entit
setRectList(0x004AF710);
_klaymen->setClipRect(_sprite4->getDrawRect().x, 0, 640, _sprite4->getDrawRect().y2());
break;
- case 0x2002:
+ case NM_POSITION_CHANGE:
_isRopingDown = false;
setRectList(0x004AF700);
_klaymen->setClipRect(_sprite4->getDrawRect().x, 0, 640, _sprite3->getDrawRect().y2());
break;
- case 0x4806:
+ case NM_KLAYMEN_USE_OBJECT:
sendMessage(_asWinch, 0x2000, 0);
sendMessage(_asTrapDoor, 0x2000, 0);
break;
@@ -2062,12 +2035,12 @@ uint32 Scene2812::handleMessage(int messageNum, const MessageParam &param, Entit
setMessageList(0x004AF668);
}
break;
- case 0x482A:
+ case NM_MOVE_TO_BACK:
setPaletteArea1(false);
_sprite1->setVisible(true);
_klaymen->setClipRect(_sprite1->getDrawRect().x, 0, _sprite1->getDrawRect().x2(), _sprite3->getDrawRect().y2());
break;
- case 0x482B:
+ case NM_MOVE_TO_FRONT:
setPaletteArea0(false);
_sprite1->setVisible(false);
_klaymen->setClipRect(_sprite4->getDrawRect().x, 0, 640, _sprite3->getDrawRect().y2());
@@ -2158,7 +2131,7 @@ void Scene2822::update() {
uint32 Scene2822::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x0001:
+ case NM_MOUSE_CLICK:
if (param.asPoint().x <= 20 || param.asPoint().x >= 620) {
leaveScene(0);
} else if (param.asPoint().x >= 257 && param.asPoint().y >= 235 &&
diff --git a/engines/neverhood/modules/module2800_sprites.cpp b/engines/neverhood/modules/module2800_sprites.cpp
index 28e2657ee7..35596da6b5 100644
--- a/engines/neverhood/modules/module2800_sprites.cpp
+++ b/engines/neverhood/modules/module2800_sprites.cpp
@@ -22,12 +22,6 @@
#include "neverhood/modules/module2800.h"
#include "neverhood/modules/module2800_sprites.h"
-#include "neverhood/gamemodule.h"
-#include "neverhood/modules/module1000.h"
-#include "neverhood/modules/module1200.h"
-#include "neverhood/modules/module1700.h"
-#include "neverhood/modules/module2200.h"
-#include "neverhood/diskplayerscene.h"
namespace Neverhood {
@@ -46,20 +40,20 @@ AsScene2803LightCord::AsScene2803LightCord(NeverhoodEngine *vm, Scene *parentSce
uint32 AsScene2803LightCord::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (!_isBusy && param.asInteger() == calcHash("ClickSwitch")) {
- sendMessage(_parentScene, 0x480F, 0);
+ sendMessage(_parentScene, NM_KLAYMEN_LOWER_LEVER, 0);
playSound(0, 0x4E1CA4A0);
}
break;
- case 0x480F:
+ case NM_KLAYMEN_LOWER_LEVER:
stPulled();
break;
- case 0x482A:
- sendMessage(_parentScene, 0x1022, 990);
+ case NM_MOVE_TO_BACK:
+ sendMessage(_parentScene, NM_PRIORITY_CHANGE, 990);
break;
- case 0x482B:
- sendMessage(_parentScene, 0x1022, 1010);
+ case NM_MOVE_TO_FRONT:
+ sendMessage(_parentScene, NM_PRIORITY_CHANGE, 1010);
break;
}
return messageResult;
@@ -68,7 +62,7 @@ uint32 AsScene2803LightCord::handleMessage(int messageNum, const MessageParam &p
uint32 AsScene2803LightCord::hmPulled(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x3002:
+ case NM_ANIMATION_STOP:
gotoNextState();
break;
}
@@ -113,7 +107,7 @@ AsScene2803TestTubeOne::AsScene2803TestTubeOne(NeverhoodEngine *vm, uint32 fileH
uint32 AsScene2803TestTubeOne::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x2000:
+ case NM_ANIMATION_UPDATE:
if (param.asInteger())
startAnimation(_fileHash2, 0, -1);
else
@@ -139,15 +133,15 @@ AsScene2803Rope::AsScene2803Rope(NeverhoodEngine *vm, Scene *parentScene, int16
uint32 AsScene2803Rope::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x3002:
+ case NM_ANIMATION_STOP:
startAnimation(0x9D098C23, 50, -1);
SetMessageHandler(&AsScene2803Rope::hmReleased);
break;
- case 0x482A:
- sendMessage(_parentScene, 0x1022, 990);
+ case NM_MOVE_TO_BACK:
+ sendMessage(_parentScene, NM_PRIORITY_CHANGE, 990);
break;
- case 0x482B:
- sendMessage(_parentScene, 0x1022, 1010);
+ case NM_MOVE_TO_FRONT:
+ sendMessage(_parentScene, NM_PRIORITY_CHANGE, 1010);
break;
}
return messageResult;
@@ -156,14 +150,14 @@ uint32 AsScene2803Rope::handleMessage(int messageNum, const MessageParam &param,
uint32 AsScene2803Rope::hmReleased(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x3002:
+ case NM_ANIMATION_STOP:
gotoNextState();
break;
- case 0x482A:
- sendMessage(_parentScene, 0x1022, 990);
+ case NM_MOVE_TO_BACK:
+ sendMessage(_parentScene, NM_PRIORITY_CHANGE, 990);
break;
- case 0x482B:
- sendMessage(_parentScene, 0x1022, 1010);
+ case NM_MOVE_TO_FRONT:
+ sendMessage(_parentScene, NM_PRIORITY_CHANGE, 1010);
break;
}
return messageResult;
@@ -223,7 +217,7 @@ SsScene2804LightCoil::SsScene2804LightCoil(NeverhoodEngine *vm)
uint32 SsScene2804LightCoil::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x2002:
+ case NM_POSITION_CHANGE:
setVisible(true);
updatePosition();
messageResult = 1;
@@ -253,7 +247,7 @@ uint32 SsScene2804LightTarget::handleMessage(int messageNum, const MessageParam
updatePosition();
messageResult = 1;
break;
- case 0x2005:
+ case NM_KLAYMEN_CLIMB_LADDER:
setVisible(false);
updatePosition();
messageResult = 1;
@@ -476,7 +470,7 @@ void AsScene2804BeamCoil::update() {
uint32 AsScene2804BeamCoil::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x2002:
+ case NM_POSITION_CHANGE:
show();
_countdown = 92;
messageResult = 1;
@@ -515,7 +509,7 @@ void AsScene2804BeamCoil::stBeaming() {
uint32 AsScene2804BeamCoil::hmBeaming(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x3002:
+ case NM_ANIMATION_STOP:
gotoNextState();
break;
}
@@ -543,7 +537,7 @@ uint32 AsScene2804BeamTarget::handleMessage(int messageNum, const MessageParam &
startAnimation(0x03842000, 0, -1);
messageResult = 1;
break;
- case 0x2005:
+ case NM_KLAYMEN_CLIMB_LADDER:
setVisible(false);
stopAnimation();
messageResult = 1;
@@ -567,12 +561,12 @@ AsScene2806Spew::AsScene2806Spew(NeverhoodEngine *vm)
uint32 AsScene2806Spew::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x2000:
+ case NM_ANIMATION_UPDATE:
playSound(0, 0x48640244);
startAnimation(0x04211490, 0, -1);
setVisible(true);
break;
- case 0x3002:
+ case NM_ANIMATION_STOP:
stopAnimation();
setVisible(false);
break;
@@ -780,7 +774,7 @@ uint32 AsScene2808Handle::handleMessage(int messageNum, const MessageParam &para
uint32 AsScene2808Handle::hmActivating(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x3002:
+ case NM_ANIMATION_STOP:
gotoNextState();
break;
}
@@ -797,7 +791,7 @@ void AsScene2808Handle::activate() {
void AsScene2808Handle::stActivated() {
stopAnimation();
- sendMessage(_parentScene, 0x2002, 0);
+ sendMessage(_parentScene, NM_POSITION_CHANGE, 0);
}
AsScene2808Flow::AsScene2808Flow(NeverhoodEngine *vm, Scene *parentScene, int testTubeSetNum)
@@ -823,7 +817,7 @@ AsScene2808Flow::AsScene2808Flow(NeverhoodEngine *vm, Scene *parentScene, int te
uint32 AsScene2808Flow::hmFlowing(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x3002:
+ case NM_ANIMATION_STOP:
gotoNextState();
break;
}
@@ -881,12 +875,12 @@ AsScene2809Spew::AsScene2809Spew(NeverhoodEngine *vm)
uint32 AsScene2809Spew::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x2000:
+ case NM_ANIMATION_UPDATE:
playSound(0, 0x48640244);
startAnimation(0x04211490, 0, -1);
setVisible(true);
break;
- case 0x3002:
+ case NM_ANIMATION_STOP:
stopAnimation();
setVisible(false);
break;
@@ -895,7 +889,7 @@ uint32 AsScene2809Spew::handleMessage(int messageNum, const MessageParam &param,
}
AsScene2810Rope::AsScene2810Rope(NeverhoodEngine *vm, Scene *parentScene, int16 x)
- : AnimatedSprite(vm, 1100) {
+ : AnimatedSprite(vm, 1100), _parentScene(parentScene) {
createSurface(990, 68, 476);
SetUpdateHandler(&AnimatedSprite::update);
@@ -909,14 +903,14 @@ AsScene2810Rope::AsScene2810Rope(NeverhoodEngine *vm, Scene *parentScene, int16
uint32 AsScene2810Rope::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x3002:
+ case NM_ANIMATION_STOP:
startAnimation(0x9D098C23, 35, 53);
break;
- case 0x482A:
- sendMessage(_parentScene, 0x1022, 990);
+ case NM_MOVE_TO_BACK:
+ sendMessage(_parentScene, NM_PRIORITY_CHANGE, 990);
break;
- case 0x482B:
- sendMessage(_parentScene, 0x1022, 1010);
+ case NM_MOVE_TO_FRONT:
+ sendMessage(_parentScene, NM_PRIORITY_CHANGE, 1010);
break;
}
return messageResult;
@@ -940,13 +934,13 @@ AsScene2812Winch::~AsScene2812Winch() {
uint32 AsScene2812Winch::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x2000:
+ case NM_ANIMATION_UPDATE:
startAnimation(0x20DA08A0, 0, -1);
setVisible(true);
_vm->_soundMan->addSound(0x00B000E2, 0xC874EE6C);
_vm->_soundMan->playSoundLooping(0xC874EE6C);
break;
- case 0x3002:
+ case NM_ANIMATION_STOP:
startAnimation(0x20DA08A0, 7, -1);
break;
}
@@ -968,15 +962,15 @@ AsScene2812Rope::AsScene2812Rope(NeverhoodEngine *vm, Scene *parentScene)
uint32 AsScene2812Rope::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x4806:
+ case NM_KLAYMEN_USE_OBJECT:
setDoDeltaX(((Sprite*)sender)->isDoDeltaX() ? 1 : 0);
stRopingDown();
break;
- case 0x482A:
- sendMessage(_parentScene, 0x1022, 990);
+ case NM_MOVE_TO_BACK:
+ sendMessage(_parentScene, NM_PRIORITY_CHANGE, 990);
break;
- case 0x482B:
- sendMessage(_parentScene, 0x1022, 1010);
+ case NM_MOVE_TO_FRONT:
+ sendMessage(_parentScene, NM_PRIORITY_CHANGE, 1010);
break;
}
return messageResult;
@@ -985,7 +979,7 @@ uint32 AsScene2812Rope::handleMessage(int messageNum, const MessageParam &param,
uint32 AsScene2812Rope::hmRopingDown(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x3002:
+ case NM_ANIMATION_STOP:
gotoNextState();
break;
}
@@ -993,7 +987,7 @@ uint32 AsScene2812Rope::hmRopingDown(int messageNum, const MessageParam &param,
}
void AsScene2812Rope::stRopingDown() {
- sendMessage(_parentScene, 0x4806, 0);
+ sendMessage(_parentScene, NM_KLAYMEN_USE_OBJECT, 0);
startAnimation(0x9D098C23, 0, -1);
SetMessageHandler(&AsScene2812Rope::hmRopingDown);
}
@@ -1008,7 +1002,7 @@ AsScene2812TrapDoor::AsScene2812TrapDoor(NeverhoodEngine *vm)
uint32 AsScene2812TrapDoor::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x2000:
+ case NM_ANIMATION_UPDATE:
startAnimation(0x805D0029, 0, -1);
playSound(0, 0xEA005F40);
_newStickFrameIndex = STICK_LAST_FRAME;
@@ -1017,4 +1011,616 @@ uint32 AsScene2812TrapDoor::handleMessage(int messageNum, const MessageParam &pa
return messageResult;
}
+KmScene2801::KmScene2801(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
+ : Klaymen(vm, parentScene, x, y) {
+
+ // Empty
+}
+
+uint32 KmScene2801::xHandleMessage(int messageNum, const MessageParam &param) {
+ switch (messageNum) {
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case NM_KLAYMEN_STAND_IDLE:
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case NM_KLAYMEN_PICKUP:
+ GotoState(&Klaymen::stPickUpGeneric);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ gotoNextStateExt();
+ break;
+ case 0x481B:
+ if (param.asPoint().y != 0)
+ startWalkToXDistance(param.asPoint().y, param.asPoint().x);
+ else
+ startWalkToAttachedSpriteXDistance(param.asPoint().x);
+ break;
+ case NM_KLAYMEN_TURN_TO_USE:
+ GotoState(&Klaymen::stTurnToUse);
+ break;
+ case NM_KLAYMEN_RETURN_FROM_USE:
+ GotoState(&Klaymen::stReturnFromUse);
+ break;
+ case 0x481F:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stWonderAboutAfter);
+ else if (param.asInteger() == 0)
+ GotoState(&Klaymen::stWonderAboutHalf);
+ else if (param.asInteger() == 4)
+ GotoState(&Klaymen::stTurnAwayFromUse);
+ else if (param.asInteger() == 3)
+ GotoState(&Klaymen::stTurnToUseHalf);
+ else
+ GotoState(&Klaymen::stWonderAbout);
+ break;
+ case 0x482D:
+ setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
+ gotoNextStateExt();
+ break;
+ case 0x482E:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stWalkToFrontNoStep);
+ else
+ GotoState(&Klaymen::stWalkToFront);
+ break;
+ case 0x482F:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stTurnToFront);
+ else
+ GotoState(&Klaymen::stTurnToBack);
+ break;
+ case 0x4837:
+ stopWalking();
+ break;
+ }
+ return 0;
+}
+
+KmScene2803::KmScene2803(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y, NRect *clipRects, int clipRectsCount)
+ : Klaymen(vm, parentScene, x, y) {
+
+ _surface->setClipRects(clipRects, clipRectsCount);
+ _dataResource.load(0x00900849);
+}
+
+uint32 KmScene2803::xHandleMessage(int messageNum, const MessageParam &param) {
+ switch (messageNum) {
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case NM_KLAYMEN_STAND_IDLE:
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x4803:
+ _destY = param.asInteger();
+ GotoState(&Klaymen::stJumpToGrab);
+ break;
+ case 0x4804:
+ if (param.asInteger() == 3)
+ GotoState(&Klaymen::stFinishGrow);
+ break;
+ case 0x480D:
+ GotoState(&Klaymen::stPullCord);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ gotoNextStateExt();
+ break;
+ case 0x4818:
+ startWalkToX(_dataResource.getPoint(param.asInteger()).x, false);
+ break;
+ case NM_KLAYMEN_TURN_TO_USE:
+ GotoState(&Klaymen::stTurnToUse);
+ break;
+ case NM_KLAYMEN_RETURN_FROM_USE:
+ GotoState(&Klaymen::stReturnFromUse);
+ break;
+ case 0x481F:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stWonderAboutAfter);
+ else
+ GotoState(&Klaymen::stWonderAboutHalf);
+ break;
+ case 0x482E:
+ GotoState(&Klaymen::stWalkToFront);
+ break;
+ case 0x482F:
+ GotoState(&Klaymen::stTurnToBack);
+ break;
+ case 0x4834:
+ GotoState(&Klaymen::stStepOver);
+ break;
+ case 0x4838:
+ GotoState(&Klaymen::stJumpToGrabRelease);
+ break;
+ }
+ return 0;
+}
+
+KmScene2803Small::KmScene2803Small(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
+ : Klaymen(vm, parentScene, x, y) {
+
+ _dataResource.load(0x81120132);
+}
+
+uint32 KmScene2803Small::xHandleMessage(int messageNum, const MessageParam &param) {
+ switch (messageNum) {
+ case 0x4001:
+ case 0x4800:
+ startWalkToXSmall(param.asPoint().x);
+ break;
+ case NM_KLAYMEN_STAND_IDLE:
+ GotoState(&Klaymen::stStandIdleSmall);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ gotoNextStateExt();
+ break;
+ case 0x4818:
+ startWalkToXSmall(_dataResource.getPoint(param.asInteger()).x);
+ break;
+ case 0x481F:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stWonderAboutAfterSmall);
+ else if (param.asInteger() == 0)
+ GotoState(&Klaymen::stWonderAboutHalfSmall);
+ else
+ GotoState(&Klaymen::stWonderAboutSmall);
+ break;
+ case 0x482E:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stWalkToFrontNoStepSmall);
+ else if (param.asInteger() == 2)
+ GotoState(&Klaymen::stWalkToFront2Small);
+ else
+ GotoState(&Klaymen::stWalkToFrontSmall);
+ break;
+ case 0x482F:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stTurnToBackHalfSmall);
+ else if (param.asInteger() == 2)
+ GotoState(&Klaymen::stTurnToBackWalkSmall);
+ else
+ GotoState(&Klaymen::stTurnToBackSmall);
+ break;
+ case 0x4830:
+ GotoState(&KmScene2803Small::stShrink);
+ break;
+ }
+ return 0;
+}
+
+uint32 KmScene2803Small::hmShrink(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = hmLowLevelAnimation(messageNum, param, sender);
+ switch (messageNum) {
+ case NM_ANIMATION_START:
+ if (param.asInteger() == 0x80C110B5)
+ sendMessage(_parentScene, NM_MOVE_TO_BACK, 0);
+ else if (param.asInteger() == 0x33288344)
+ playSound(2, 0x10688664);
+ break;
+ }
+ return messageResult;
+}
+
+void KmScene2803Small::stShrink() {
+ _busyStatus = 0;
+ _acceptInput = false;
+ playSound(0, 0x4C69EA53);
+ startAnimation(0x1AE88904, 0, -1);
+ SetUpdateHandler(&Klaymen::update);
+ SetMessageHandler(&KmScene2803Small::hmShrink);
+ SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
+}
+
+KmScene2805::KmScene2805(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
+ : Klaymen(vm, parentScene, x, y) {
+
+ // Empty
+}
+
+uint32 KmScene2805::xHandleMessage(int messageNum, const MessageParam &param) {
+ uint32 messageResult = 0;
+ switch (messageNum) {
+ case NM_ANIMATION_UPDATE:
+ _isSittingInTeleporter = param.asInteger() != 0;
+ messageResult = 1;
+ break;
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case NM_KLAYMEN_STAND_IDLE:
+ if (_isSittingInTeleporter)
+ GotoState(&Klaymen::stSitIdleTeleporter);
+ else
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ gotoNextStateExt();
+ break;
+ case NM_KLAYMEN_TURN_TO_USE:
+ if (_isSittingInTeleporter)
+ GotoState(&Klaymen::stTurnToUseInTeleporter);
+ break;
+ case NM_KLAYMEN_RETURN_FROM_USE:
+ if (_isSittingInTeleporter)
+ GotoState(&Klaymen::stReturnFromUseInTeleporter);
+ break;
+ case 0x4834:
+ GotoState(&Klaymen::stStepOver);
+ break;
+ case 0x4835:
+ sendMessage(_parentScene, 0x2000, 1);
+ _isSittingInTeleporter = true;
+ GotoState(&Klaymen::stSitInTeleporter);
+ break;
+ case 0x4836:
+ sendMessage(_parentScene, 0x2000, 0);
+ _isSittingInTeleporter = false;
+ GotoState(&Klaymen::stGetUpFromTeleporter);
+ break;
+ case 0x483D:
+ teleporterAppear(0xDE284B74);
+ break;
+ case 0x483E:
+ teleporterDisappear(0xD82A4094);
+ break;
+ }
+ return messageResult;
+}
+
+KmScene2806::KmScene2806(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y,
+ bool needsLargeSurface, NRect *clipRects, uint clipRectsCount)
+ : Klaymen(vm, parentScene, x, y) {
+
+ if (needsLargeSurface) {
+ NDimensions dimensions = _animResource.loadSpriteDimensions(0x2838C010);
+ delete _surface;
+ createSurface(1000, dimensions.width, dimensions.height);
+ loadSound(3, 0x58E0C341);
+ loadSound(4, 0x40A00342);
+ loadSound(5, 0xD0A1C348);
+ loadSound(6, 0x166FC6E0);
+ loadSound(7, 0x00018040);
+ }
+
+ _dataResource.load(0x98182003);
+ _surface->setClipRects(clipRects, clipRectsCount);
+}
+
+uint32 KmScene2806::xHandleMessage(int messageNum, const MessageParam &param) {
+ switch (messageNum) {
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case NM_KLAYMEN_STAND_IDLE:
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x4804:
+ startWalkToX(440, true);
+ break;
+ case 0x480D:
+ GotoState(&Klaymen::stPullCord);
+ break;
+ case NM_KLAYMEN_PRESS_BUTTON:
+ if (param.asInteger() == 0)
+ GotoState(&Klaymen::stPressButtonSide);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ gotoNextStateExt();
+ break;
+ case 0x4818:
+ startWalkToX(_dataResource.getPoint(param.asInteger()).x, false);
+ break;
+ case 0x4831:
+ GotoState(&Klaymen::stGrow);
+ break;
+ case 0x4832:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stDrinkPotion);
+ else
+ GotoState(&Klaymen::stUseTube);
+ break;
+ }
+ return 0;
+}
+
+KmScene2809::KmScene2809(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y,
+ bool needsLargeSurface, NRect *clipRects, uint clipRectsCount)
+ : Klaymen(vm, parentScene, x, y) {
+
+ if (needsLargeSurface) {
+ NDimensions dimensions = _animResource.loadSpriteDimensions(0x2838C010);
+ delete _surface;
+ createSurface(1000, dimensions.width, dimensions.height);
+ loadSound(3, 0x58E0C341);
+ loadSound(4, 0x40A00342);
+ loadSound(5, 0xD0A1C348);
+ loadSound(6, 0x166FC6E0);
+ loadSound(7, 0x00018040);
+ }
+
+ _dataResource.load(0x1830009A);
+ _surface->setClipRects(clipRects, clipRectsCount);
+}
+
+uint32 KmScene2809::xHandleMessage(int messageNum, const MessageParam &param) {
+ switch (messageNum) {
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case NM_KLAYMEN_STAND_IDLE:
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x4804:
+ startWalkToX(226, true);
+ break;
+ case 0x480D:
+ GotoState(&Klaymen::stPullCord);
+ break;
+ case NM_KLAYMEN_PRESS_BUTTON:
+ if (param.asInteger() == 0)
+ GotoState(&Klaymen::stPressButtonSide);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ gotoNextStateExt();
+ break;
+ case 0x4818:
+ startWalkToX(_dataResource.getPoint(param.asInteger()).x, false);
+ break;
+ case 0x4831:
+ GotoState(&Klaymen::stGrow);
+ break;
+ case 0x4832:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stDrinkPotion);
+ else
+ GotoState(&Klaymen::stUseTube);
+ break;
+ }
+ return 0;
+}
+
+KmScene2810Small::KmScene2810Small(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
+ : Klaymen(vm, parentScene, x, y) {
+
+ // Empty
+}
+
+uint32 KmScene2810Small::xHandleMessage(int messageNum, const MessageParam &param) {
+ switch (messageNum) {
+ case 0x4001:
+ case 0x4800:
+ startWalkToXSmall(param.asPoint().x);
+ break;
+ case NM_KLAYMEN_STAND_IDLE:
+ GotoState(&Klaymen::stStandIdleSmall);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ gotoNextStateExt();
+ break;
+ case 0x4818:
+ startWalkToXSmall(_dataResource.getPoint(param.asInteger()).x);
+ break;
+ case 0x481F:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stWonderAboutAfterSmall);
+ else if (param.asInteger() == 0)
+ GotoState(&Klaymen::stWonderAboutHalfSmall);
+ else
+ GotoState(&Klaymen::stWonderAboutSmall);
+ break;
+ case 0x482E:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stWalkToFrontNoStepSmall);
+ else
+ GotoState(&Klaymen::stWalkToFrontSmall);
+ break;
+ case 0x482F:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stTurnToBackHalfSmall);
+ else
+ GotoState(&Klaymen::stTurnToBackSmall);
+ break;
+ case 0x4837:
+ stopWalking();
+ break;
+ }
+ return 0;
+}
+
+KmScene2810::KmScene2810(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y, NRect *clipRects, uint clipRectsCount)
+ : Klaymen(vm, parentScene, x, y) {
+
+ _surface->setClipRects(clipRects, clipRectsCount);
+}
+
+uint32 KmScene2810::xHandleMessage(int messageNum, const MessageParam &param) {
+ switch (messageNum) {
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case NM_KLAYMEN_STAND_IDLE:
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x4803:
+ _destY = param.asInteger();
+ GotoState(&Klaymen::stJumpToGrab);
+ break;
+ case 0x4804:
+ if (param.asInteger() == 3)
+ GotoState(&Klaymen::stFinishGrow);
+ break;
+ case NM_KLAYMEN_PICKUP:
+ GotoState(&Klaymen::stPickUpGeneric);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ gotoNextStateExt();
+ break;
+ case 0x4818:
+ startWalkToX(_dataResource.getPoint(param.asInteger()).x, false);
+ break;
+ case 0x481B:
+ if (param.asPoint().y != 0)
+ startWalkToXDistance(param.asPoint().y, param.asPoint().x);
+ else
+ startWalkToAttachedSpriteXDistance(param.asPoint().x);
+ break;
+ case 0x481F:
+ if (param.asInteger() == 0)
+ GotoState(&Klaymen::stWonderAboutHalf);
+ else if (param.asInteger() == 1)
+ GotoState(&Klaymen::stWonderAboutAfter);
+ else if (param.asInteger() == 3)
+ GotoState(&Klaymen::stTurnToUseHalf);
+ else if (param.asInteger() == 4)
+ GotoState(&Klaymen::stTurnAwayFromUse);
+ else if (param.asInteger() == 5)
+ GotoState(&Klaymen::stTurnToUseExt);
+ else
+ GotoState(&Klaymen::stWonderAbout);
+ break;
+ case 0x4820:
+ sendMessage(_parentScene, 0x2000, 0);
+ GotoState(&Klaymen::stContinueClimbLadderUp);
+ break;
+ case 0x4821:
+ sendMessage(_parentScene, 0x2000, 0);
+ _destY = param.asInteger();
+ GotoState(&Klaymen::stStartClimbLadderDown);
+ break;
+ case 0x4822:
+ sendMessage(_parentScene, 0x2000, 0);
+ _destY = param.asInteger();
+ GotoState(&Klaymen::stStartClimbLadderUp);
+ break;
+ case 0x4823:
+ sendMessage(_parentScene, 0x2001, 0);
+ GotoState(&Klaymen::stClimbLadderHalf);
+ break;
+ case 0x4824:
+ sendMessage(_parentScene, 0x2000, 0);
+ _destY = _dataResource.getPoint(param.asInteger()).y;
+ GotoState(&Klaymen::stStartClimbLadderDown);
+ break;
+ case 0x4825:
+ sendMessage(_parentScene, 0x2000, 0);
+ _destY = _dataResource.getPoint(param.asInteger()).y;
+ GotoState(&Klaymen::stStartClimbLadderUp);
+ break;
+ case 0x482D:
+ setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
+ gotoNextStateExt();
+ break;
+ case 0x4837:
+ stopWalking();
+ break;
+ }
+ return 0;
+}
+
+KmScene2812::KmScene2812(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
+ : Klaymen(vm, parentScene, x, y) {
+
+ // Empty
+}
+
+uint32 KmScene2812::xHandleMessage(int messageNum, const MessageParam &param) {
+ switch (messageNum) {
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case NM_KLAYMEN_STAND_IDLE:
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x4805:
+ _destY = param.asInteger();
+ GotoState(&Klaymen::stJumpToGrabFall);
+ break;
+ case NM_KLAYMEN_PICKUP:
+ if (param.asInteger() == 2)
+ GotoState(&Klaymen::stPickUpNeedle);
+ else if (param.asInteger() == 1)
+ GotoState(&Klaymen::stPickUpTube);
+ else
+ GotoState(&Klaymen::stPickUpGeneric);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ gotoNextStateExt();
+ break;
+ case NM_KLAYMEN_INSERT_DISK:
+ GotoState(&Klaymen::stInsertDisk);
+ break;
+ case 0x481B:
+ if (param.asPoint().y != 0)
+ startWalkToXDistance(param.asPoint().y, param.asPoint().x);
+ else
+ startWalkToAttachedSpriteXDistance(param.asPoint().x);
+ break;
+ case NM_KLAYMEN_TURN_TO_USE:
+ GotoState(&Klaymen::stTurnToUse);
+ break;
+ case NM_KLAYMEN_RETURN_FROM_USE:
+ GotoState(&Klaymen::stReturnFromUse);
+ break;
+ case 0x4820:
+ sendMessage(_parentScene, 0x2001, 0);
+ GotoState(&Klaymen::stContinueClimbLadderUp);
+ break;
+ case 0x4821:
+ sendMessage(_parentScene, 0x2001, 0);
+ _destY = param.asInteger();
+ GotoState(&Klaymen::stStartClimbLadderDown);
+ break;
+ case 0x4822:
+ sendMessage(_parentScene, 0x2001, 0);
+ _destY = param.asInteger();
+ GotoState(&Klaymen::stStartClimbLadderUp);
+ break;
+ case 0x4823:
+ sendMessage(_parentScene, NM_POSITION_CHANGE, 0);
+ GotoState(&Klaymen::stClimbLadderHalf);
+ break;
+ case 0x482D:
+ setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
+ gotoNextStateExt();
+ break;
+ case 0x482E:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stWalkToFrontNoStep);
+ else
+ GotoState(&Klaymen::stWalkToFront);
+ break;
+ case 0x482F:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stTurnToFront);
+ else
+ GotoState(&Klaymen::stTurnToBack);
+ break;
+ case 0x483F:
+ startSpecialWalkRight(param.asInteger());
+ break;
+ case 0x4840:
+ startSpecialWalkLeft(param.asInteger());
+ break;
+ }
+ return 0;
+}
+
} // End of namespace Neverhood
diff --git a/engines/neverhood/modules/module2800_sprites.h b/engines/neverhood/modules/module2800_sprites.h
index 39ca88ef73..91f26d7849 100644
--- a/engines/neverhood/modules/module2800_sprites.h
+++ b/engines/neverhood/modules/module2800_sprites.h
@@ -263,6 +263,75 @@ protected:
uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
};
+class KmScene2801 : public Klaymen {
+public:
+ KmScene2801(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
+protected:
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+};
+
+class KmScene2803 : public Klaymen {
+public:
+ KmScene2803(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y, NRect *clipRects, int clipRectsCount);
+protected:
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+};
+
+class KmScene2803Small : public Klaymen {
+public:
+ KmScene2803Small(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
+protected:
+ void stShrink();
+ uint32 hmShrink(int messageNum, const MessageParam &param, Entity *sender);
+
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+};
+
+class KmScene2805 : public Klaymen {
+public:
+ KmScene2805(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
+protected:
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+};
+
+class KmScene2806 : public Klaymen {
+public:
+ KmScene2806(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y,
+ bool needsLargeSurface, NRect *clipRects, uint clipRectsCount);
+protected:
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+};
+
+class KmScene2809 : public Klaymen {
+public:
+ KmScene2809(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y,
+ bool needsLargeSurface, NRect *clipRects, uint clipRectsCount);
+protected:
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+};
+
+class KmScene2810Small : public Klaymen {
+public:
+ KmScene2810Small(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
+protected:
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+};
+
+class KmScene2810 : public Klaymen {
+public:
+ KmScene2810(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y,
+ NRect *clipRects, uint clipRectsCount);
+protected:
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+};
+
+class KmScene2812 : public Klaymen {
+public:
+ KmScene2812(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
+protected:
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+};
+
} // End of namespace Neverhood
#endif /* NEVERHOOD_MODULES_MODULE2800_SPRITES_H */
diff --git a/engines/neverhood/modules/module2900.cpp b/engines/neverhood/modules/module2900.cpp
index 9e51001a2e..ca734972ca 100644
--- a/engines/neverhood/modules/module2900.cpp
+++ b/engines/neverhood/modules/module2900.cpp
@@ -21,7 +21,7 @@
*/
#include "neverhood/modules/module2900.h"
-#include "neverhood/gamemodule.h"
+#include "neverhood/modules/module2900_sprites.h"
#include "neverhood/modules/module1100.h"
#include "neverhood/modules/module1300.h"
#include "neverhood/modules/module1700.h"
@@ -141,211 +141,6 @@ static const uint32 kScene2901FileHashes2[] = {
0x08030029
};
-static const uint32 kSsScene2901LocationButtonFileHashes[] = {
- 0x2311326A,
- 0x212323AC,
- 0x10098138,
- 0x25213167,
- 0x1119A363,
- 0x94452612,
- 0x39464212,
- 0x01860450,
- 0x53002104,
- 0x58E68412,
- 0x18600300,
- 0xB650A890,
- 0x2452A7C4,
- 0xA0232748,
- 0x08862B02,
- 0x2491E648,
- 0x0010EB46,
- 0x214C8A11,
- 0x16A31921,
- 0x0AC33A00,
- 0x238028AA,
- 0x26737A21,
- 0x063039A8,
- 0x51286C60,
- 0x464006B4,
- 0x42242538,
- 0x20716010,
- 0x4A2000AE,
- 0x225124A6,
- 0x28E82E45,
- 0x58652C04,
- 0xC82210A4,
- 0x62A84060,
- 0xC0693CB4,
- 0x22212C64,
- 0x5034EA71
-};
-
-static const NPoint kSsScene2901LocationButtonPoints[] = {
- {525, 120}, {576, 149}, {587, 205},
- {538, 232}, {484, 205}, {479, 153}
-};
-
-static const uint32 kSsScene2901LocationButtonLightFileHashes1[] = {
- 0x03136246,
- 0x2106216E,
- 0x4025A13A,
- 0x21816927,
- 0x110B2202,
- 0xCC0522B2,
- 0x3CC24258,
- 0x59C600F0,
- 0x534A2480,
- 0x50E61019,
- 0x34400150,
- 0x225BA090,
- 0xB059AFC4,
- 0xE093A741,
- 0x0086BF09,
- 0x3281E760,
- 0xA048AB42,
- 0x20649C01,
- 0x14611904,
- 0x26E33850,
- 0x23A52A68,
- 0xA2733024,
- 0x10203880,
- 0x1B2DE860,
- 0x0644A6EC,
- 0x426E20BC,
- 0x80292014,
- 0x4360B02E,
- 0x22742664,
- 0x98682705,
- 0x0925B82C,
- 0x5C2918A4,
- 0xD2284920,
- 0x41083CA6,
- 0x6824A864,
- 0x50266B10
-};
-
-static const uint32 kSsScene2901LocationButtonLightFileHashes2[] = {
- 0x43C46D4C,
- 0x43C4AD4C,
- 0x43C52D4C,
- 0x43C62D4C,
- 0x43C02D4C,
- 0x43CC2D4C
-};
-
-static const uint32 kSsScene2901BrokenButtonFileHashes[] = {
- 0x3081BD3A,
- 0xD3443003,
- 0x0786A320,
- 0xE3A22029,
- 0x61611814,
- 0x425848E2
-};
-
-static const uint32 kSsScene2901BigButtonFileHashes[] = {
- 0x010D7748,
- 0x9D02019A,
- 0x351A2F43,
- 0x448138E5,
- 0x02788CF0,
- 0x71718024
-};
-
-SsScene2901LocationButton::SsScene2901LocationButton(NeverhoodEngine *vm, Scene *parentScene, int which, uint index)
- : StaticSprite(vm, 900), _parentScene(parentScene), _index(index), _countdown1(0) {
-
- const NPoint &pt = kSsScene2901LocationButtonPoints[_index];
-
- loadSprite(kSsScene2901LocationButtonFileHashes[which * 6 + index], kSLFDefDrawOffset | kSLFDefPosition, 800);
- _collisionBounds.set(pt.x - 25, pt.y - 25, pt.x + 25, pt.y + 25);
- setVisible(false);
- loadSound(0, 0x440430C0);
- SetUpdateHandler(&SsScene2901LocationButton::update);
- SetMessageHandler(&SsScene2901LocationButton::handleMessage);
-}
-
-void SsScene2901LocationButton::update() {
- updatePosition();
- if (_countdown1 != 0 && (--_countdown1) == 0) {
- setVisible(false);
- }
-}
-
-uint32 SsScene2901LocationButton::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x1011:
- if (_countdown1 == 0) {
- playSound(0);
- setVisible(true);
- _countdown1 = 4;
- sendMessage(_parentScene, 0x2001, _index);
- }
- messageResult = 1;
- break;
- }
- return messageResult;
-}
-
-SsScene2901LocationButtonLight::SsScene2901LocationButtonLight(NeverhoodEngine *vm, int which, uint index)
- : StaticSprite(vm, 900), _index(index) {
-
- loadSprite(kSsScene2901LocationButtonLightFileHashes1[which * 6 + index], kSLFDefDrawOffset | kSLFDefPosition, 900);
- setVisible(false);
- loadSound(0, kSsScene2901LocationButtonLightFileHashes2[_index]);
-}
-
-void SsScene2901LocationButtonLight::show() {
- playSound(0);
- setVisible(true);
- updatePosition();
-}
-
-void SsScene2901LocationButtonLight::hide() {
- setVisible(false);
- updatePosition();
-}
-
-SsScene2901BrokenButton::SsScene2901BrokenButton(NeverhoodEngine *vm, int which)
- : StaticSprite(vm, 900) {
-
- loadSprite(kSsScene2901BrokenButtonFileHashes[which], kSLFDefDrawOffset | kSLFDefPosition, 900);
-}
-
-SsScene2901BigButton::SsScene2901BigButton(NeverhoodEngine *vm, Scene *parentScene, int which)
- : StaticSprite(vm, 900), _parentScene(parentScene), _which(which), _countdown1(0) {
-
- loadSprite(kSsScene2901BigButtonFileHashes[which], kSLFDefDrawOffset | kSLFDefPosition, 400);
- _collisionBounds.set(62, 94, 322, 350);
- setVisible(false);
- loadSound(0, 0xF3D420C8);
- SetUpdateHandler(&SsScene2901BigButton::update);
- SetMessageHandler(&SsScene2901BigButton::handleMessage);
-}
-
-void SsScene2901BigButton::update() {
- updatePosition();
- if (_countdown1 != 0 && (--_countdown1) == 0) {
- setVisible(false);
- sendMessage(_parentScene, 0x2000, 0);
- }
-}
-
-uint32 SsScene2901BigButton::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x1011:
- if (_countdown1 == 0) {
- playSound(0);
- setVisible(true);
- _countdown1 = 4;
- }
- messageResult = 1;
- break;
- }
- return messageResult;
-}
-
Scene2901::Scene2901(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule), _currLocationButtonNum(which), _selectedButtonNum(which),
_currWhirlButtonNum(0), _prevWhirlButtonNum(0), _countdown1(1), _skipCountdown(0), _blinkOn(0) {
@@ -416,11 +211,11 @@ void Scene2901::update() {
uint32 Scene2901::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x0001:
+ case NM_MOUSE_CLICK:
if (param.asPoint().x <= 20 || param.asPoint().x >= 620)
leaveScene((uint32)-1);
break;
- case 0x2000:
+ case NM_ANIMATION_UPDATE:
if (_currLocationButtonNum != _selectedButtonNum)
leaveScene(_selectedButtonNum);
break;
diff --git a/engines/neverhood/modules/module2900.h b/engines/neverhood/modules/module2900.h
index 142f39a35c..5f6ed29a12 100644
--- a/engines/neverhood/modules/module2900.h
+++ b/engines/neverhood/modules/module2900.h
@@ -42,41 +42,7 @@ protected:
void updateMusic(bool halfVolume);
};
-class SsScene2901LocationButton : public StaticSprite {
-public:
- SsScene2901LocationButton(NeverhoodEngine *vm, Scene *parentScene, int which, uint index);
-protected:
- Scene *_parentScene;
- uint _index;
- int _countdown1;
- void update();
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
-
-class SsScene2901LocationButtonLight : public StaticSprite {
-public:
- SsScene2901LocationButtonLight(NeverhoodEngine *vm, int which, uint index);
- void show();
- void hide();
-protected:
- uint _index;
-};
-
-class SsScene2901BrokenButton : public StaticSprite {
-public:
- SsScene2901BrokenButton(NeverhoodEngine *vm, int which);
-};
-
-class SsScene2901BigButton : public StaticSprite {
-public:
- SsScene2901BigButton(NeverhoodEngine *vm, Scene *parentScene, int which);
-protected:
- Scene *_parentScene;
- int _which;
- int _countdown1;
- void update();
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
+class SsScene2901LocationButtonLight;
class Scene2901 : public Scene {
public:
diff --git a/engines/neverhood/modules/module2900_sprites.cpp b/engines/neverhood/modules/module2900_sprites.cpp
new file mode 100644
index 0000000000..59780b33a0
--- /dev/null
+++ b/engines/neverhood/modules/module2900_sprites.cpp
@@ -0,0 +1,232 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public 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 "neverhood/modules/module2900_sprites.h"
+
+namespace Neverhood {
+
+static const uint32 kSsScene2901LocationButtonFileHashes[] = {
+ 0x2311326A,
+ 0x212323AC,
+ 0x10098138,
+ 0x25213167,
+ 0x1119A363,
+ 0x94452612,
+ 0x39464212,
+ 0x01860450,
+ 0x53002104,
+ 0x58E68412,
+ 0x18600300,
+ 0xB650A890,
+ 0x2452A7C4,
+ 0xA0232748,
+ 0x08862B02,
+ 0x2491E648,
+ 0x0010EB46,
+ 0x214C8A11,
+ 0x16A31921,
+ 0x0AC33A00,
+ 0x238028AA,
+ 0x26737A21,
+ 0x063039A8,
+ 0x51286C60,
+ 0x464006B4,
+ 0x42242538,
+ 0x20716010,
+ 0x4A2000AE,
+ 0x225124A6,
+ 0x28E82E45,
+ 0x58652C04,
+ 0xC82210A4,
+ 0x62A84060,
+ 0xC0693CB4,
+ 0x22212C64,
+ 0x5034EA71
+};
+
+static const NPoint kSsScene2901LocationButtonPoints[] = {
+ {525, 120}, {576, 149}, {587, 205},
+ {538, 232}, {484, 205}, {479, 153}
+};
+
+static const uint32 kSsScene2901LocationButtonLightFileHashes1[] = {
+ 0x03136246,
+ 0x2106216E,
+ 0x4025A13A,
+ 0x21816927,
+ 0x110B2202,
+ 0xCC0522B2,
+ 0x3CC24258,
+ 0x59C600F0,
+ 0x534A2480,
+ 0x50E61019,
+ 0x34400150,
+ 0x225BA090,
+ 0xB059AFC4,
+ 0xE093A741,
+ 0x0086BF09,
+ 0x3281E760,
+ 0xA048AB42,
+ 0x20649C01,
+ 0x14611904,
+ 0x26E33850,
+ 0x23A52A68,
+ 0xA2733024,
+ 0x10203880,
+ 0x1B2DE860,
+ 0x0644A6EC,
+ 0x426E20BC,
+ 0x80292014,
+ 0x4360B02E,
+ 0x22742664,
+ 0x98682705,
+ 0x0925B82C,
+ 0x5C2918A4,
+ 0xD2284920,
+ 0x41083CA6,
+ 0x6824A864,
+ 0x50266B10
+};
+
+static const uint32 kSsScene2901LocationButtonLightFileHashes2[] = {
+ 0x43C46D4C,
+ 0x43C4AD4C,
+ 0x43C52D4C,
+ 0x43C62D4C,
+ 0x43C02D4C,
+ 0x43CC2D4C
+};
+
+static const uint32 kSsScene2901BrokenButtonFileHashes[] = {
+ 0x3081BD3A,
+ 0xD3443003,
+ 0x0786A320,
+ 0xE3A22029,
+ 0x61611814,
+ 0x425848E2
+};
+
+static const uint32 kSsScene2901BigButtonFileHashes[] = {
+ 0x010D7748,
+ 0x9D02019A,
+ 0x351A2F43,
+ 0x448138E5,
+ 0x02788CF0,
+ 0x71718024
+};
+
+SsScene2901LocationButton::SsScene2901LocationButton(NeverhoodEngine *vm, Scene *parentScene, int which, uint index)
+ : StaticSprite(vm, 900), _parentScene(parentScene), _index(index), _countdown1(0) {
+
+ const NPoint &pt = kSsScene2901LocationButtonPoints[_index];
+
+ loadSprite(kSsScene2901LocationButtonFileHashes[which * 6 + index], kSLFDefDrawOffset | kSLFDefPosition, 800);
+ _collisionBounds.set(pt.x - 25, pt.y - 25, pt.x + 25, pt.y + 25);
+ setVisible(false);
+ loadSound(0, 0x440430C0);
+ SetUpdateHandler(&SsScene2901LocationButton::update);
+ SetMessageHandler(&SsScene2901LocationButton::handleMessage);
+}
+
+void SsScene2901LocationButton::update() {
+ updatePosition();
+ if (_countdown1 != 0 && (--_countdown1) == 0) {
+ setVisible(false);
+ }
+}
+
+uint32 SsScene2901LocationButton::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x1011:
+ if (_countdown1 == 0) {
+ playSound(0);
+ setVisible(true);
+ _countdown1 = 4;
+ sendMessage(_parentScene, 0x2001, _index);
+ }
+ messageResult = 1;
+ break;
+ }
+ return messageResult;
+}
+
+SsScene2901LocationButtonLight::SsScene2901LocationButtonLight(NeverhoodEngine *vm, int which, uint index)
+ : StaticSprite(vm, 900), _index(index) {
+
+ loadSprite(kSsScene2901LocationButtonLightFileHashes1[which * 6 + index], kSLFDefDrawOffset | kSLFDefPosition, 900);
+ setVisible(false);
+ loadSound(0, kSsScene2901LocationButtonLightFileHashes2[_index]);
+}
+
+void SsScene2901LocationButtonLight::show() {
+ playSound(0);
+ setVisible(true);
+ updatePosition();
+}
+
+void SsScene2901LocationButtonLight::hide() {
+ setVisible(false);
+ updatePosition();
+}
+
+SsScene2901BrokenButton::SsScene2901BrokenButton(NeverhoodEngine *vm, int which)
+ : StaticSprite(vm, 900) {
+
+ loadSprite(kSsScene2901BrokenButtonFileHashes[which], kSLFDefDrawOffset | kSLFDefPosition, 900);
+}
+
+SsScene2901BigButton::SsScene2901BigButton(NeverhoodEngine *vm, Scene *parentScene, int which)
+ : StaticSprite(vm, 900), _parentScene(parentScene), _which(which), _countdown1(0) {
+
+ loadSprite(kSsScene2901BigButtonFileHashes[which], kSLFDefDrawOffset | kSLFDefPosition, 400);
+ _collisionBounds.set(62, 94, 322, 350);
+ setVisible(false);
+ loadSound(0, 0xF3D420C8);
+ SetUpdateHandler(&SsScene2901BigButton::update);
+ SetMessageHandler(&SsScene2901BigButton::handleMessage);
+}
+
+void SsScene2901BigButton::update() {
+ updatePosition();
+ if (_countdown1 != 0 && (--_countdown1) == 0) {
+ setVisible(false);
+ sendMessage(_parentScene, 0x2000, 0);
+ }
+}
+
+uint32 SsScene2901BigButton::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x1011:
+ if (_countdown1 == 0) {
+ playSound(0);
+ setVisible(true);
+ _countdown1 = 4;
+ }
+ messageResult = 1;
+ break;
+ }
+ return messageResult;
+}
+
+} // End of namespace Neverhood
diff --git a/engines/neverhood/modules/module2900_sprites.h b/engines/neverhood/modules/module2900_sprites.h
new file mode 100644
index 0000000000..9f7df502e1
--- /dev/null
+++ b/engines/neverhood/modules/module2900_sprites.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 NEVERHOOD_MODULES_MODULE2900_SPRITES_H
+#define NEVERHOOD_MODULES_MODULE2900_SPRITES_H
+
+#include "neverhood/neverhood.h"
+#include "neverhood/module.h"
+#include "neverhood/scene.h"
+
+namespace Neverhood {
+
+// Module2900
+
+class SsScene2901LocationButton : public StaticSprite {
+public:
+ SsScene2901LocationButton(NeverhoodEngine *vm, Scene *parentScene, int which, uint index);
+protected:
+ Scene *_parentScene;
+ uint _index;
+ int _countdown1;
+ void update();
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class SsScene2901LocationButtonLight : public StaticSprite {
+public:
+ SsScene2901LocationButtonLight(NeverhoodEngine *vm, int which, uint index);
+ void show();
+ void hide();
+protected:
+ uint _index;
+};
+
+class SsScene2901BrokenButton : public StaticSprite {
+public:
+ SsScene2901BrokenButton(NeverhoodEngine *vm, int which);
+};
+
+class SsScene2901BigButton : public StaticSprite {
+public:
+ SsScene2901BigButton(NeverhoodEngine *vm, Scene *parentScene, int which);
+protected:
+ Scene *_parentScene;
+ int _which;
+ int _countdown1;
+ void update();
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+} // End of namespace Neverhood
+
+#endif /* NEVERHOOD_MODULES_MODULE2900_SPRITES_H */
diff --git a/engines/neverhood/modules/module3000.cpp b/engines/neverhood/modules/module3000.cpp
index ab3c18d1f4..dc6fb984ef 100644
--- a/engines/neverhood/modules/module3000.cpp
+++ b/engines/neverhood/modules/module3000.cpp
@@ -20,9 +20,10 @@
*
*/
-#include "neverhood/modules/module3000.h"
#include "neverhood/gamemodule.h"
#include "neverhood/navigationscene.h"
+#include "neverhood/modules/module3000.h"
+#include "neverhood/modules/module3000_sprites.h"
namespace Neverhood {
@@ -415,343 +416,6 @@ static const uint32 kScene3009CannonActionVideos[] = {
0x240A1101 // 14 Lower the cannon
};
-static const uint32 kSsScene3009SymbolEdgesFileHashes[] = {
- 0x618827A0,
- 0xB1A92322
-};
-
-static const uint32 kSsScene3009TargetLineFileHashes[] = {
- 0x4011018C,
- 0x15086623
-};
-
-static const NPoint kAsScene3009SymbolPoints[] = {
- {289, 338},
- {285, 375},
- {284, 419},
- {456, 372},
- {498, 372},
- {541, 372}
-};
-
-static const uint32 kAsScene3009SymbolFileHashes[] = {
- 0x24542582,
- 0x1CD61D96
-};
-
-static const uint32 kSsScene3009SymbolArrowFileHashes1[] = {
- 0x24016060,
- 0x21216221,
- 0x486160A0,
- 0x42216422,
- 0x90A16120,
- 0x84216824,
- 0x08017029,
- 0x08217029,
- 0x10014032,
- 0x10214032,
- 0x20012004,
- 0x20212004
-};
-
-static const uint32 kSsScene3009SymbolArrowFileHashes2[] = {
- 0x40092024,
- 0x01636002,
- 0x8071E028,
- 0x02A56064,
- 0x00806031,
- 0x052960A8,
- 0x0A116130,
- 0x0A316130,
- 0x14216200,
- 0x14016200,
- 0x28416460,
- 0x28616460
-};
-
-SsScene3009FireCannonButton::SsScene3009FireCannonButton(NeverhoodEngine *vm, Scene3009 *parentScene)
- : StaticSprite(vm, 1400), _parentScene(parentScene), _isClicked(false) {
-
- loadSprite(0x120B24B0, kSLFDefDrawOffset | kSLFDefPosition | kSLFDefCollisionBoundsOffset, 400);
- setVisible(false);
- SetUpdateHandler(&SsScene3009FireCannonButton::update);
- SetMessageHandler(&SsScene3009FireCannonButton::handleMessage);
- loadSound(0, 0x3901B44F);
-}
-
-void SsScene3009FireCannonButton::update() {
- updatePosition();
- if (_isClicked && !isSoundPlaying(0)) {
- sendMessage(_parentScene, 0x2000, 0);
- setVisible(false);
- }
-}
-
-uint32 SsScene3009FireCannonButton::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x1011:
- if (!_isClicked && !_parentScene->isTurning()) {
- _isClicked = true;
- setVisible(true);
- playSound(0);
- }
- messageResult = 1;
- break;
- }
- return messageResult;
-}
-
-SsScene3009SymbolEdges::SsScene3009SymbolEdges(NeverhoodEngine *vm, int index)
- : StaticSprite(vm, 1400), _blinkCountdown(0) {
-
- loadSprite(kSsScene3009SymbolEdgesFileHashes[index], kSLFDefDrawOffset | kSLFDefPosition, 600);
- if (getGlobalVar(V_ROBOT_HIT))
- hide();
- else
- startBlinking();
- SetUpdateHandler(&SsScene3009SymbolEdges::update);
-}
-
-void SsScene3009SymbolEdges::update() {
- if (_blinkCountdown != 0 && (--_blinkCountdown == 0)) {
- if (_blinkToggle) {
- setVisible(true);
- } else {
- setVisible(false);
- }
- updatePosition();
- _blinkCountdown = 3;
- _blinkToggle = !_blinkToggle;
- }
-}
-
-void SsScene3009SymbolEdges::show() {
- setVisible(true);
- updatePosition();
- _blinkCountdown = 0;
-}
-
-void SsScene3009SymbolEdges::hide() {
- setVisible(false);
- updatePosition();
- _blinkCountdown = 0;
-}
-
-void SsScene3009SymbolEdges::startBlinking() {
- setVisible(true);
- updatePosition();
- _blinkCountdown = 3;
- _blinkToggle = true;
-}
-
-SsScene3009TargetLine::SsScene3009TargetLine(NeverhoodEngine *vm, int index)
- : StaticSprite(vm, 1400) {
-
- loadSprite(kSsScene3009TargetLineFileHashes[index], kSLFDefDrawOffset | kSLFDefPosition, 600);
- setVisible(false);
-}
-
-void SsScene3009TargetLine::show() {
- setVisible(true);
- updatePosition();
-}
-
-SsScene3009SymbolArrow::SsScene3009SymbolArrow(NeverhoodEngine *vm, Sprite *asSymbol, int index)
- : StaticSprite(vm, 1400), _asSymbol(asSymbol), _index(index), _enabled(true), _countdown(0) {
-
- _incrDecr = _index % 2;
-
- createSurface(1200, 33, 31);
- loadSprite(kSsScene3009SymbolArrowFileHashes2[_index], kSLFDefPosition);
- _drawOffset.set(0, 0, 33, 31);
- _collisionBoundsOffset = _drawOffset;
- updateBounds();
- _needRefresh = true;
-
- SetUpdateHandler(&SsScene3009SymbolArrow::update);
- SetMessageHandler(&SsScene3009SymbolArrow::handleMessage);
- loadSound(0, 0x2C852206);
-}
-
-void SsScene3009SymbolArrow::hide() {
- _enabled = false;
- setVisible(false);
-}
-
-void SsScene3009SymbolArrow::update() {
- updatePosition();
- if (_countdown != 0 && (--_countdown == 0)) {
- loadSprite(kSsScene3009SymbolArrowFileHashes2[_index], kSLFDefDrawOffset);
- }
-}
-
-uint32 SsScene3009SymbolArrow::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x1011:
- if (_enabled && _countdown == 0) {
- _countdown = 2;
- loadSprite(kSsScene3009SymbolArrowFileHashes1[_index], kSLFDefDrawOffset);
- playSound(0);
- sendMessage(_asSymbol, 0x2005, _incrDecr);
- }
- messageResult = 1;
- break;
- }
- return messageResult;
-}
-
-AsScene3009VerticalIndicator::AsScene3009VerticalIndicator(NeverhoodEngine *vm, Scene3009 *parentScene, int index)
- : AnimatedSprite(vm, 1000), _parentScene(parentScene), _enabled(false) {
-
- _x = 300;
- _y = getGlobalVar(V_CANNON_RAISED) ? 52 : 266;
- createSurface1(0xC2463913, 1200);
- _needRefresh = true;
- updatePosition();
- setVisible(false);
- SetUpdateHandler(&AnimatedSprite::update);
- SetMessageHandler(&AsScene3009VerticalIndicator::handleMessage);
-}
-
-void AsScene3009VerticalIndicator::show() {
- startAnimation(0xC2463913, 0, -1);
- setVisible(true);
- updatePosition();
- _enabled = true;
-}
-
-uint32 AsScene3009VerticalIndicator::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x1011:
- if (_enabled) {
- sendMessage(_parentScene, 0x2002, 0);
- }
- messageResult = 1;
- break;
- }
- return messageResult;
-}
-
-AsScene3009HorizontalIndicator::AsScene3009HorizontalIndicator(NeverhoodEngine *vm, Scene3009 *parentScene, uint32 cannonTargetStatus)
- : AnimatedSprite(vm, 1000), _parentScene(parentScene), _enabled(false) {
-
- _x = getGlobalVar(V_CANNON_TURNED) ? 533 : 92;
- _y = 150;
- createSurface1(0xC0C12954, 1200);
- _needRefresh = true;
- updatePosition();
- setVisible(false);
- SetUpdateHandler(&AnimatedSprite::update);
- SetMessageHandler(&AsScene3009HorizontalIndicator::handleMessage);
- if (cannonTargetStatus == kCTSRightRobotNoTarget || cannonTargetStatus == kCTSRightRobotIsTarget || cannonTargetStatus == kCTSRightNoRobot) {
- SetSpriteUpdate(&AsScene3009HorizontalIndicator::suMoveRight);
- _x = 280;
- }
-}
-
-uint32 AsScene3009HorizontalIndicator::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x1011:
- if (_enabled) {
- sendMessage(_parentScene, 0x2004, 0);
- }
- messageResult = 1;
- break;
- }
- return messageResult;
-}
-
-void AsScene3009HorizontalIndicator::suMoveLeft() {
- _x -= 6;
- if (_x < 92) {
- SetSpriteUpdate(NULL);
- _x = 92;
- }
-}
-
-void AsScene3009HorizontalIndicator::suMoveRight() {
- _x += 6;
- if (_x > 533) {
- SetSpriteUpdate(NULL);
- _x = 533;
- }
-}
-
-void AsScene3009HorizontalIndicator::show() {
- startAnimation(0xC0C12954, 0, -1);
- setVisible(true);
- updatePosition();
- _enabled = true;
-}
-
-void AsScene3009HorizontalIndicator::stMoveLeft() {
- _x = 533;
- SetSpriteUpdate(&AsScene3009HorizontalIndicator::suMoveLeft);
-}
-
-void AsScene3009HorizontalIndicator::stMoveRight() {
- _x = 330;
- SetSpriteUpdate(&AsScene3009HorizontalIndicator::suMoveRight);
-}
-
-AsScene3009Symbol::AsScene3009Symbol(NeverhoodEngine *vm, Scene3009 *parentScene, int symbolPosition)
- : AnimatedSprite(vm, 1100), _parentScene(parentScene), _symbolPosition(symbolPosition) {
-
- _symbolIndex = getSubVar(VA_CURR_CANNON_SYMBOLS, _symbolPosition);
-
- _x = kAsScene3009SymbolPoints[_symbolPosition].x;
- _y = kAsScene3009SymbolPoints[_symbolPosition].y;
- createSurface1(kAsScene3009SymbolFileHashes[_symbolPosition / 3], 1200);
- startAnimation(kAsScene3009SymbolFileHashes[_symbolPosition / 3], _symbolIndex, -1);
- _newStickFrameIndex = _symbolIndex;
- _needRefresh = true;
- updatePosition();
- SetUpdateHandler(&AnimatedSprite::update);
- SetMessageHandler(&AsScene3009Symbol::handleMessage);
- _ssArrowPrev = _parentScene->insertSprite<SsScene3009SymbolArrow>(this, _symbolPosition * 2 + 0);
- _parentScene->addCollisionSprite(_ssArrowPrev);
- _ssArrowNext = _parentScene->insertSprite<SsScene3009SymbolArrow>(this, _symbolPosition * 2 + 1);
- _parentScene->addCollisionSprite(_ssArrowNext);
-}
-
-uint32 AsScene3009Symbol::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x2005:
- if (param.asInteger()) {
- if (_symbolIndex == 11)
- _symbolIndex = 0;
- else
- _symbolIndex++;
- } else {
- if (_symbolIndex == 0)
- _symbolIndex = 11;
- else
- _symbolIndex--;
- }
- startAnimation(kAsScene3009SymbolFileHashes[_symbolPosition / 3], _symbolIndex, -1);
- _newStickFrameIndex = _symbolIndex;
- setSubVar(VA_CURR_CANNON_SYMBOLS, _symbolPosition, _symbolIndex);
- if (_symbolPosition / 3 == 0) {
- sendMessage(_parentScene, 0x2001, 0);
- } else {
- sendMessage(_parentScene, 0x2003, 0);
- }
- messageResult = 1;
- break;
- }
- return messageResult;
-}
-
-void AsScene3009Symbol::hide() {
- _ssArrowPrev->hide();
- _ssArrowNext->hide();
-}
-
Scene3009::Scene3009(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule), _keepVideo(false), _moveCannonLeftFirst(false),
_isTurning(false), _lockSymbolsPart1Countdown(1), _lockSymbolsPart2Countdown(1) {
@@ -888,13 +552,13 @@ void Scene3009::update() {
uint32 Scene3009::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x0001:
+ case NM_MOUSE_CLICK:
if ((param.asPoint().x <= 20 || param.asPoint().x >= 620) && !getGlobalVar(V_CANNON_RAISED)) {
setGlobalVar(V_CANNON_TARGET_STATUS, 0);
leaveScene(0);
}
break;
- case 0x2000:
+ case NM_ANIMATION_UPDATE:
if (!getGlobalVar(V_CANNON_RAISED)) {
if (!getGlobalVar(V_WALL_BROKEN)) {
_cannonTargetStatus = kCTSBreakWall;
@@ -917,7 +581,7 @@ uint32 Scene3009::handleMessage(int messageNum, const MessageParam &param, Entit
case 0x2001:
_lockSymbolsPart1Countdown = 24;
break;
- case 0x2002:
+ case NM_POSITION_CHANGE:
// Raise/lower the cannon
if (!getGlobalVar(V_CANNON_TURNED) && !_isTurning) {
if (getGlobalVar(V_CANNON_RAISED)) {
@@ -1015,206 +679,6 @@ static const uint32 kScene3010DeadBoltButtonFileHashes2[] = {
0x5000A7E8
};
-static const NPoint kAsScene3010DeadBoltPoints[] = {
- {550, 307},
- {564, 415},
- {560, 514}
-};
-
-static const uint32 kAsScene3010DeadBoltFileHashes2[] = {
- 0x181A0042,
- 0x580A08F2,
- 0x18420076
-};
-
-static const uint32 kAsScene3010DeadBoltFileHashes1[] = {
- 0x300E105A,
- 0x804E0052,
- 0x040E485A
-};
-
-SsScene3010DeadBoltButton::SsScene3010DeadBoltButton(NeverhoodEngine *vm, Scene *parentScene, int buttonIndex, int initCountdown, bool initDisabled)
- : StaticSprite(vm, 900), _parentScene(parentScene), _buttonLocked(false), _countdown1(0), _countdown2(0), _buttonIndex(buttonIndex) {
-
- _buttonEnabled = getSubVar(VA_LOCKS_DISABLED, kScene3010ButtonNameHashes[_buttonIndex]) != 0;
- createSurface(400, 88, 95);
- setSprite(kScene3010DeadBoltButtonFileHashes2[_buttonIndex]);
- if (initDisabled)
- disableButton();
- else if (_buttonEnabled)
- _countdown1 = initCountdown * 12 + 1;
- loadSound(0, 0xF4217243);
- loadSound(1, 0x44049000);
- loadSound(2, 0x6408107E);
- SetUpdateHandler(&SsScene3010DeadBoltButton::update);
- SetMessageHandler(&SsScene3010DeadBoltButton::handleMessage);
-}
-
-void SsScene3010DeadBoltButton::update() {
-
- if (_countdown1 != 0 && (--_countdown1 == 0)) {
- playSound(0);
- setVisible(false);
- setSprite(kScene3010DeadBoltButtonFileHashes1[_buttonIndex]);
- }
-
- if (_countdown2 != 0 && (--_countdown2 == 0)) {
- setVisible(true);
- setSprite(kScene3010DeadBoltButtonFileHashes2[_buttonIndex]);
- }
-
-}
-
-uint32 SsScene3010DeadBoltButton::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x1011:
- if (!_buttonLocked && _countdown1 == 0) {
- if (_buttonEnabled) {
- playSound(1);
- playSound(2);
- setVisible(true);
- _buttonLocked = true;
- sendMessage(_parentScene, 0x2000, _buttonIndex);
- } else {
- sendMessage(_parentScene, 0x2002, _buttonIndex);
- }
- _needRefresh = true;
- updatePosition();
- }
- messageResult = 1;
- break;
- }
- return messageResult;
-}
-
-void SsScene3010DeadBoltButton::disableButton() {
- _buttonLocked = true;
- setSprite(kScene3010DeadBoltButtonFileHashes1[_buttonIndex]);
- setVisible(true);
-}
-
-void SsScene3010DeadBoltButton::setSprite(uint32 fileHash) {
- loadSprite(fileHash, kSLFDefDrawOffset | kSLFDefPosition | kSLFDefCollisionBoundsOffset);
-}
-
-void SsScene3010DeadBoltButton::setCountdown(int count) {
- _countdown2 = count * 18 + 1;
-}
-
-AsScene3010DeadBolt::AsScene3010DeadBolt(NeverhoodEngine *vm, Scene *parentScene, int boltIndex, bool initUnlocked)
- : AnimatedSprite(vm, 1100), _parentScene(parentScene), _boltIndex(boltIndex), _soundToggle(true),
- _unlocked(false), _locked(false), _countdown(0) {
-
- _x = kAsScene3010DeadBoltPoints[_boltIndex].x;
- _y = kAsScene3010DeadBoltPoints[_boltIndex].y;
-
- if (getSubVar(VA_LOCKS_DISABLED, kScene3010ButtonNameHashes[_boltIndex])) {
- createSurface1(kAsScene3010DeadBoltFileHashes1[_boltIndex], 1200);
- startAnimation(kAsScene3010DeadBoltFileHashes1[_boltIndex], 0, -1);
- loadSound(0, 0x46005BC4);
- } else {
- createSurface1(kAsScene3010DeadBoltFileHashes2[_boltIndex], 1200);
- startAnimation(kAsScene3010DeadBoltFileHashes2[_boltIndex], 0, -1);
- loadSound(0, 0x420073DC);
- loadSound(1, 0x420073DC);
- }
-
- setVisible(false);
- stIdle();
- if (initUnlocked)
- unlock(true);
-
- _needRefresh = true;
- AnimatedSprite::updatePosition();
-
-}
-
-void AsScene3010DeadBolt::update() {
- updateAnim();
- updatePosition();
- if (_countdown != 0 && (--_countdown == 0)) {
- stDisabled();
- }
-}
-
-uint32 AsScene3010DeadBolt::hmAnimation(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x3002:
- gotoNextState();
- break;
- }
- return messageResult;
-}
-
-void AsScene3010DeadBolt::stIdle() {
- stopAnimation();
- SetUpdateHandler(&AsScene3010DeadBolt::update);
- SetMessageHandler(&Sprite::handleMessage);
- _locked = false;
-}
-
-void AsScene3010DeadBolt::unlock(bool skipAnim) {
- if (!_unlocked) {
- setVisible(true);
- if (skipAnim) {
- startAnimation(kAsScene3010DeadBoltFileHashes1[_boltIndex], -1, 0);
- _newStickFrameIndex = STICK_LAST_FRAME;
- } else {
- startAnimation(kAsScene3010DeadBoltFileHashes1[_boltIndex], 0, -1);
- SetMessageHandler(&AsScene3010DeadBolt::hmAnimation);
- FinalizeState(&AsScene3010DeadBolt::stIdleMessage);
- NextState(&AsScene3010DeadBolt::stIdle);
- playSound(0);
- }
- _unlocked = true;
- loadSound(2, 0x4010C345);
- }
-}
-
-void AsScene3010DeadBolt::stIdleMessage() {
- stopAnimation();
- SetMessageHandler(&Sprite::handleMessage);
- sendMessage(_parentScene, 0x2001, _boltIndex);
-}
-
-void AsScene3010DeadBolt::lock() {
- if (!_locked) {
- _locked = true;
- setVisible(true);
- startAnimation(kAsScene3010DeadBoltFileHashes2[_boltIndex], 0, -1);
- SetMessageHandler(&AsScene3010DeadBolt::hmAnimation);
- FinalizeState(&AsScene3010DeadBolt::stDisabledMessage);
- NextState(&AsScene3010DeadBolt::stIdle);
- if (_soundToggle) {
- playSound(0);
- } else {
- playSound(1);
- }
- _soundToggle = !_soundToggle;
- }
-}
-
-void AsScene3010DeadBolt::setCountdown(int count) {
- _countdown = count * 18 + 1;
-}
-
-void AsScene3010DeadBolt::stDisabled() {
- setVisible(true);
- startAnimation(kAsScene3010DeadBoltFileHashes1[_boltIndex], 0, -1);
- SetMessageHandler(&AsScene3010DeadBolt::hmAnimation);
- FinalizeState(&AsScene3010DeadBolt::stDisabledMessage);
- NextState(&AsScene3010DeadBolt::stIdle);
- _playBackwards = true;
- playSound(2);
-}
-
-void AsScene3010DeadBolt::stDisabledMessage() {
- setVisible(false);
- sendMessage(_parentScene, 0x2003, _boltIndex);
-}
-
Scene3010::Scene3010(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule), _countdown(0), _doorUnlocked(false), _checkUnlocked(false) {
@@ -1267,7 +731,7 @@ void Scene3010::update() {
uint32 Scene3010::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x0001:
+ case NM_MOUSE_CLICK:
if ((param.asPoint().x <= 20 || param.asPoint().x >= 620) && _countdown == 0 && !_checkUnlocked) {
if (!_boltUnlocking[0] && !_boltUnlocking[1] && !_boltUnlocking[2]) {
showMouse(false);
@@ -1285,7 +749,7 @@ uint32 Scene3010::handleMessage(int messageNum, const MessageParam &param, Entit
}
}
break;
- case 0x2000:
+ case NM_ANIMATION_UPDATE:
if (!_boltUnlocked[param.asInteger()] && !_checkUnlocked && _countdown == 0) {
_asDeadBolts[param.asInteger()]->unlock(false);
_boltUnlocking[param.asInteger()] = true;
@@ -1305,7 +769,7 @@ uint32 Scene3010::handleMessage(int messageNum, const MessageParam &param, Entit
_doorUnlocked = true;
}
break;
- case 0x2002:
+ case NM_POSITION_CHANGE:
if (!_checkUnlocked && _countdown == 0) {
_asDeadBolts[param.asInteger()]->lock();
}
@@ -1317,127 +781,6 @@ uint32 Scene3010::handleMessage(int messageNum, const MessageParam &param, Entit
return 0;
}
-// Scene3011
-
-static const uint32 kAsScene3011SymbolFileHashes[] = {
- 0x00C88050,
- 0x01488050,
- 0x02488050,
- 0x04488050,
- 0x08488050,
- 0x10488050,
- 0x20488050,
- 0x40488050,
- 0x80488050,
- 0x00488051,
- 0x00488052,
- 0x00488054,
- 0x008B0000,
- 0x008D0000,
- 0x00810000,
- 0x00990000,
- 0x00A90000,
- 0x00C90000,
- 0x00090000,
- 0x01890000,
- 0x02890000,
- 0x04890000,
- 0x08890000,
- 0x10890000
-};
-
-SsScene3011Button::SsScene3011Button(NeverhoodEngine *vm, Scene *parentScene, bool flag)
- : StaticSprite(vm, 1400), _parentScene(parentScene), _countdown(0) {
-
- loadSprite(flag ? 0x11282020 : 0x994D0433, kSLFDefDrawOffset | kSLFDefPosition | kSLFDefCollisionBoundsOffset, 400);
- setVisible(false);
- loadSound(0, 0x44061000);
- SetUpdateHandler(&SsScene3011Button::update);
- SetMessageHandler(&SsScene3011Button::handleMessage);
-}
-
-void SsScene3011Button::update() {
- updatePosition();
- if (_countdown != 0 && (--_countdown == 0)) {
- setVisible(false);
- }
-}
-
-uint32 SsScene3011Button::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = 0;
- StaticSprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x1011:
- if (_countdown == 0) {
- setVisible(true);
- _countdown = 4;
- sendMessage(_parentScene, 0x2000, 0);
- playSound(0);
- }
- messageResult = 1;
- break;
- }
- return messageResult;
-}
-
-AsScene3011Symbol::AsScene3011Symbol(NeverhoodEngine *vm, int symbolIndex, bool largeSymbol)
- : AnimatedSprite(vm, 1000), _symbolIndex(symbolIndex), _largeSymbol(largeSymbol), _isNoisy(false) {
-
- if (_largeSymbol) {
- _x = 310;
- _y = 200;
- createSurface1(kAsScene3011SymbolFileHashes[_symbolIndex], 1200);
- loadSound(0, 0x6052C60F);
- loadSound(1, 0x6890433B);
- } else {
- _symbolIndex = 12;
- _x = symbolIndex * 39 + 96;
- _y = 225;
- createSurface(1200, 41, 48);
- loadSound(0, 0x64428609);
- loadSound(1, 0x7080023B);
- }
- setVisible(false);
- _needRefresh = true;
- SetUpdateHandler(&AnimatedSprite::update);
-}
-
-void AsScene3011Symbol::show(bool isNoisy) {
- _isNoisy = isNoisy;
- startAnimation(kAsScene3011SymbolFileHashes[_symbolIndex], 0, -1);
- setVisible(true);
- if (_isNoisy) {
- playSound(1);
- } else {
- playSound(0);
- }
-}
-
-void AsScene3011Symbol::hide() {
- stopAnimation();
- setVisible(false);
-}
-
-void AsScene3011Symbol::stopSymbolSound() {
- if (_isNoisy) {
- stopSound(1);
- } else {
- stopSound(0);
- }
-}
-
-void AsScene3011Symbol::change(int symbolIndex, bool isNoisy) {
- _symbolIndex = symbolIndex;
- _isNoisy = isNoisy;
- startAnimation(kAsScene3011SymbolFileHashes[_symbolIndex], 0, -1);
- setVisible(true);
- if (_isNoisy) {
- playSound(1);
- } else {
- playSound(0);
- }
-}
-
Scene3011::Scene3011(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule), _updateStatus(0), _buttonClicked(false), _currentSymbolIndex(0), _countdown(0) {
@@ -1510,12 +853,12 @@ void Scene3011::update() {
uint32 Scene3011::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x0001:
+ case NM_MOUSE_CLICK:
if (param.asPoint().x <= 20 || param.asPoint().x >= 620) {
leaveScene(0);
}
break;
- case 0x2000:
+ case NM_ANIMATION_UPDATE:
_buttonClicked = true;
if (_countdown == 0)
_countdown = 1;
diff --git a/engines/neverhood/modules/module3000.h b/engines/neverhood/modules/module3000.h
index a6cecb227e..a88dea513e 100644
--- a/engines/neverhood/modules/module3000.h
+++ b/engines/neverhood/modules/module3000.h
@@ -26,7 +26,6 @@
#include "neverhood/neverhood.h"
#include "neverhood/module.h"
#include "neverhood/scene.h"
-#include "neverhood/modules/module1200.h"
namespace Neverhood {
@@ -41,89 +40,11 @@ protected:
void updateScene();
};
-// Scene3009
-
-class Scene3009;
-
-class SsScene3009FireCannonButton : public StaticSprite {
-public:
- SsScene3009FireCannonButton(NeverhoodEngine *vm, Scene3009 *parentScene);
-protected:
- Scene3009 *_parentScene;
- bool _isClicked;
- void update();
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
-
-class SsScene3009SymbolEdges : public StaticSprite {
-public:
- SsScene3009SymbolEdges(NeverhoodEngine *vm, int index);
- void show();
- void hide();
- void startBlinking();
-protected:
- int _blinkCountdown;
- bool _blinkToggle;
- void update();
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
-
-class SsScene3009TargetLine : public StaticSprite {
-public:
- SsScene3009TargetLine(NeverhoodEngine *vm, int index);
- void show();
-};
-
-class SsScene3009SymbolArrow : public StaticSprite {
-public:
- SsScene3009SymbolArrow(NeverhoodEngine *vm, Sprite *asSymbol, int index);
- void hide();
-protected:
- Sprite *_asSymbol;
- int _index;
- int _incrDecr;
- bool _enabled;
- int _countdown;
- void update();
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
-
-class AsScene3009VerticalIndicator : public AnimatedSprite {
-public:
- AsScene3009VerticalIndicator(NeverhoodEngine *vm, Scene3009 *parentScene, int index);
- void show();
-protected:
- Scene3009 *_parentScene;
- bool _enabled;
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
-
-class AsScene3009HorizontalIndicator : public AnimatedSprite {
-public:
- AsScene3009HorizontalIndicator(NeverhoodEngine *vm, Scene3009 *parentScene, uint32 cannonTargetStatus);
- void show();
- void stMoveLeft();
- void stMoveRight();
-protected:
- Scene3009 *_parentScene;
- bool _enabled;
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- void suMoveLeft();
- void suMoveRight();
-};
-
-class AsScene3009Symbol : public AnimatedSprite {
-public:
- AsScene3009Symbol(NeverhoodEngine *vm, Scene3009 *parentScene, int symbolPosition);
- void hide();
-protected:
- Scene3009 *_parentScene;
- int _symbolPosition;
- uint32 _symbolIndex;
- SsScene3009SymbolArrow *_ssArrowPrev;
- SsScene3009SymbolArrow *_ssArrowNext;
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
+class SsScene3009SymbolEdges;
+class SsScene3009TargetLine;
+class AsScene3009VerticalIndicator;
+class AsScene3009HorizontalIndicator;
+class AsScene3009Symbol;
class Scene3009 : public Scene {
public:
@@ -153,45 +74,8 @@ protected:
void openSmacker(uint32 fileHash, bool keepLastFrame);
};
-// Scene3010
-
-class SsScene3010DeadBoltButton : public StaticSprite {
-public:
- SsScene3010DeadBoltButton(NeverhoodEngine *vm, Scene *parentScene, int buttonIndex, int initCountdown, bool initDisabled);
- void setCountdown(int count);
-protected:
- Scene *_parentScene;
- int _buttonIndex;
- bool _buttonEnabled;
- bool _buttonLocked;
- int _countdown1;
- int _countdown2;
- void update();
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- void disableButton();
- void setSprite(uint32 fileHash);
-};
-
-class AsScene3010DeadBolt : public AnimatedSprite {
-public:
- AsScene3010DeadBolt(NeverhoodEngine *vm, Scene *parentScene, int boltIndex, bool initUnlocked);
- void setCountdown(int count);
- void lock();
- void unlock(bool skipAnim);
-protected:
- Scene *_parentScene;
- int _boltIndex;
- int _countdown;
- bool _soundToggle;
- bool _unlocked;
- bool _locked;
- void update();
- uint32 hmAnimation(int messageNum, const MessageParam &param, Entity *sender);
- void stIdle();
- void stIdleMessage();
- void stDisabled();
- void stDisabledMessage();
-};
+class SsScene3010DeadBoltButton;
+class AsScene3010DeadBolt;
class Scene3010 : public Scene {
public:
@@ -208,31 +92,7 @@ protected:
uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
};
-// Scene3011
-
-class SsScene3011Button : public StaticSprite {
-public:
- SsScene3011Button(NeverhoodEngine *vm, Scene *parentScene, bool flag);
-protected:
- Scene *_parentScene;
- int _countdown;
- void update();
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
-
-class AsScene3011Symbol : public AnimatedSprite {
-public:
- AsScene3011Symbol(NeverhoodEngine *vm, int symbolIndex, bool largeSymbol);
- void show(bool isNoisy);
- void hide();
- void stopSymbolSound();
- void change(int symbolIndex, bool isNoisy);
- int getSymbolIndex() { return _largeSymbol ? _symbolIndex : _symbolIndex - 12; }
-protected:
- bool _largeSymbol;
- bool _isNoisy;
- int _symbolIndex;
-};
+class AsScene3011Symbol;
class Scene3011 : public Scene {
public:
diff --git a/engines/neverhood/modules/module3000_sprites.cpp b/engines/neverhood/modules/module3000_sprites.cpp
new file mode 100644
index 0000000000..3c0c5fe209
--- /dev/null
+++ b/engines/neverhood/modules/module3000_sprites.cpp
@@ -0,0 +1,763 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public 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 "neverhood/modules/module3000.h"
+#include "neverhood/modules/module3000_sprites.h"
+
+namespace Neverhood {
+
+// Scene3009
+
+enum {
+ kCTSNull = 0,
+ kCTSBreakWall = 1,
+ kCTSWall = 2,
+ kCTSEmptyness = 3,
+ kCTSFireRobotNoTarget = 4,
+ kCTSFireRobotIsTarget = 5,
+ kCTSFireNoRobot = 6,
+ kCTSRaiseCannon = 7,
+ kCTSRightRobotNoTarget = 8,
+ kCTSRightRobotIsTarget = 9,
+ kCTSRightNoRobot = 10,
+ kCTSLeftRobotNoTarget = 11,
+ kCTSLeftRobotIsTarget = 12,
+ kCTSLeftNoRobot = 13,
+ kCTSLowerCannon = 14,
+ 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
+};
+
+static const uint32 kSsScene3009TargetLineFileHashes[] = {
+ 0x4011018C,
+ 0x15086623
+};
+
+static const NPoint kAsScene3009SymbolPoints[] = {
+ {289, 338},
+ {285, 375},
+ {284, 419},
+ {456, 372},
+ {498, 372},
+ {541, 372}
+};
+
+static const uint32 kAsScene3009SymbolFileHashes[] = {
+ 0x24542582,
+ 0x1CD61D96
+};
+
+static const uint32 kSsScene3009SymbolArrowFileHashes1[] = {
+ 0x24016060,
+ 0x21216221,
+ 0x486160A0,
+ 0x42216422,
+ 0x90A16120,
+ 0x84216824,
+ 0x08017029,
+ 0x08217029,
+ 0x10014032,
+ 0x10214032,
+ 0x20012004,
+ 0x20212004
+};
+
+static const uint32 kSsScene3009SymbolArrowFileHashes2[] = {
+ 0x40092024,
+ 0x01636002,
+ 0x8071E028,
+ 0x02A56064,
+ 0x00806031,
+ 0x052960A8,
+ 0x0A116130,
+ 0x0A316130,
+ 0x14216200,
+ 0x14016200,
+ 0x28416460,
+ 0x28616460
+};
+
+SsScene3009FireCannonButton::SsScene3009FireCannonButton(NeverhoodEngine *vm, Scene3009 *parentScene)
+ : StaticSprite(vm, 1400), _parentScene(parentScene), _isClicked(false) {
+
+ loadSprite(0x120B24B0, kSLFDefDrawOffset | kSLFDefPosition | kSLFDefCollisionBoundsOffset, 400);
+ setVisible(false);
+ SetUpdateHandler(&SsScene3009FireCannonButton::update);
+ SetMessageHandler(&SsScene3009FireCannonButton::handleMessage);
+ loadSound(0, 0x3901B44F);
+}
+
+void SsScene3009FireCannonButton::update() {
+ updatePosition();
+ if (_isClicked && !isSoundPlaying(0)) {
+ sendMessage(_parentScene, 0x2000, 0);
+ setVisible(false);
+ }
+}
+
+uint32 SsScene3009FireCannonButton::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x1011:
+ if (!_isClicked && !_parentScene->isTurning()) {
+ _isClicked = true;
+ setVisible(true);
+ playSound(0);
+ }
+ messageResult = 1;
+ break;
+ }
+ return messageResult;
+}
+
+SsScene3009SymbolEdges::SsScene3009SymbolEdges(NeverhoodEngine *vm, int index)
+ : StaticSprite(vm, 1400), _blinkCountdown(0) {
+
+ loadSprite(kSsScene3009SymbolEdgesFileHashes[index], kSLFDefDrawOffset | kSLFDefPosition, 600);
+ if (getGlobalVar(V_ROBOT_HIT))
+ hide();
+ else
+ startBlinking();
+ SetUpdateHandler(&SsScene3009SymbolEdges::update);
+}
+
+void SsScene3009SymbolEdges::update() {
+ if (_blinkCountdown != 0 && (--_blinkCountdown == 0)) {
+ if (_blinkToggle) {
+ setVisible(true);
+ } else {
+ setVisible(false);
+ }
+ updatePosition();
+ _blinkCountdown = 3;
+ _blinkToggle = !_blinkToggle;
+ }
+}
+
+void SsScene3009SymbolEdges::show() {
+ setVisible(true);
+ updatePosition();
+ _blinkCountdown = 0;
+}
+
+void SsScene3009SymbolEdges::hide() {
+ setVisible(false);
+ updatePosition();
+ _blinkCountdown = 0;
+}
+
+void SsScene3009SymbolEdges::startBlinking() {
+ setVisible(true);
+ updatePosition();
+ _blinkCountdown = 3;
+ _blinkToggle = true;
+}
+
+SsScene3009TargetLine::SsScene3009TargetLine(NeverhoodEngine *vm, int index)
+ : StaticSprite(vm, 1400) {
+
+ loadSprite(kSsScene3009TargetLineFileHashes[index], kSLFDefDrawOffset | kSLFDefPosition, 600);
+ setVisible(false);
+}
+
+void SsScene3009TargetLine::show() {
+ setVisible(true);
+ updatePosition();
+}
+
+SsScene3009SymbolArrow::SsScene3009SymbolArrow(NeverhoodEngine *vm, Sprite *asSymbol, int index)
+ : StaticSprite(vm, 1400), _asSymbol(asSymbol), _index(index), _enabled(true), _countdown(0) {
+
+ _incrDecr = _index % 2;
+
+ createSurface(1200, 33, 31);
+ loadSprite(kSsScene3009SymbolArrowFileHashes2[_index], kSLFDefPosition);
+ _drawOffset.set(0, 0, 33, 31);
+ _collisionBoundsOffset = _drawOffset;
+ updateBounds();
+ _needRefresh = true;
+
+ SetUpdateHandler(&SsScene3009SymbolArrow::update);
+ SetMessageHandler(&SsScene3009SymbolArrow::handleMessage);
+ loadSound(0, 0x2C852206);
+}
+
+void SsScene3009SymbolArrow::hide() {
+ _enabled = false;
+ setVisible(false);
+}
+
+void SsScene3009SymbolArrow::update() {
+ updatePosition();
+ if (_countdown != 0 && (--_countdown == 0)) {
+ loadSprite(kSsScene3009SymbolArrowFileHashes2[_index], kSLFDefDrawOffset);
+ }
+}
+
+uint32 SsScene3009SymbolArrow::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x1011:
+ if (_enabled && _countdown == 0) {
+ _countdown = 2;
+ loadSprite(kSsScene3009SymbolArrowFileHashes1[_index], kSLFDefDrawOffset);
+ playSound(0);
+ sendMessage(_asSymbol, NM_KLAYMEN_CLIMB_LADDER, _incrDecr);
+ }
+ messageResult = 1;
+ break;
+ }
+ return messageResult;
+}
+
+AsScene3009VerticalIndicator::AsScene3009VerticalIndicator(NeverhoodEngine *vm, Scene3009 *parentScene, int index)
+ : AnimatedSprite(vm, 1000), _parentScene(parentScene), _enabled(false) {
+
+ _x = 300;
+ _y = getGlobalVar(V_CANNON_RAISED) ? 52 : 266;
+ createSurface1(0xC2463913, 1200);
+ _needRefresh = true;
+ updatePosition();
+ setVisible(false);
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsScene3009VerticalIndicator::handleMessage);
+}
+
+void AsScene3009VerticalIndicator::show() {
+ startAnimation(0xC2463913, 0, -1);
+ setVisible(true);
+ updatePosition();
+ _enabled = true;
+}
+
+uint32 AsScene3009VerticalIndicator::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x1011:
+ if (_enabled) {
+ sendMessage(_parentScene, NM_POSITION_CHANGE, 0);
+ }
+ messageResult = 1;
+ break;
+ }
+ return messageResult;
+}
+
+AsScene3009HorizontalIndicator::AsScene3009HorizontalIndicator(NeverhoodEngine *vm, Scene3009 *parentScene, uint32 cannonTargetStatus)
+ : AnimatedSprite(vm, 1000), _parentScene(parentScene), _enabled(false) {
+
+ _x = getGlobalVar(V_CANNON_TURNED) ? 533 : 92;
+ _y = 150;
+ createSurface1(0xC0C12954, 1200);
+ _needRefresh = true;
+ updatePosition();
+ setVisible(false);
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsScene3009HorizontalIndicator::handleMessage);
+ if (cannonTargetStatus == kCTSRightRobotNoTarget || cannonTargetStatus == kCTSRightRobotIsTarget || cannonTargetStatus == kCTSRightNoRobot) {
+ SetSpriteUpdate(&AsScene3009HorizontalIndicator::suMoveRight);
+ _x = 280;
+ }
+}
+
+uint32 AsScene3009HorizontalIndicator::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x1011:
+ if (_enabled) {
+ sendMessage(_parentScene, 0x2004, 0);
+ }
+ messageResult = 1;
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene3009HorizontalIndicator::suMoveLeft() {
+ _x -= 6;
+ if (_x < 92) {
+ SetSpriteUpdate(NULL);
+ _x = 92;
+ }
+}
+
+void AsScene3009HorizontalIndicator::suMoveRight() {
+ _x += 6;
+ if (_x > 533) {
+ SetSpriteUpdate(NULL);
+ _x = 533;
+ }
+}
+
+void AsScene3009HorizontalIndicator::show() {
+ startAnimation(0xC0C12954, 0, -1);
+ setVisible(true);
+ updatePosition();
+ _enabled = true;
+}
+
+void AsScene3009HorizontalIndicator::stMoveLeft() {
+ _x = 533;
+ SetSpriteUpdate(&AsScene3009HorizontalIndicator::suMoveLeft);
+}
+
+void AsScene3009HorizontalIndicator::stMoveRight() {
+ _x = 330;
+ SetSpriteUpdate(&AsScene3009HorizontalIndicator::suMoveRight);
+}
+
+AsScene3009Symbol::AsScene3009Symbol(NeverhoodEngine *vm, Scene3009 *parentScene, int symbolPosition)
+ : AnimatedSprite(vm, 1100), _parentScene(parentScene), _symbolPosition(symbolPosition) {
+
+ _symbolIndex = getSubVar(VA_CURR_CANNON_SYMBOLS, _symbolPosition);
+
+ _x = kAsScene3009SymbolPoints[_symbolPosition].x;
+ _y = kAsScene3009SymbolPoints[_symbolPosition].y;
+ createSurface1(kAsScene3009SymbolFileHashes[_symbolPosition / 3], 1200);
+ startAnimation(kAsScene3009SymbolFileHashes[_symbolPosition / 3], _symbolIndex, -1);
+ _newStickFrameIndex = _symbolIndex;
+ _needRefresh = true;
+ updatePosition();
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsScene3009Symbol::handleMessage);
+ _ssArrowPrev = _parentScene->insertSprite<SsScene3009SymbolArrow>(this, _symbolPosition * 2 + 0);
+ _parentScene->addCollisionSprite(_ssArrowPrev);
+ _ssArrowNext = _parentScene->insertSprite<SsScene3009SymbolArrow>(this, _symbolPosition * 2 + 1);
+ _parentScene->addCollisionSprite(_ssArrowNext);
+}
+
+uint32 AsScene3009Symbol::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case NM_KLAYMEN_CLIMB_LADDER:
+ if (param.asInteger()) {
+ if (_symbolIndex == 11)
+ _symbolIndex = 0;
+ else
+ _symbolIndex++;
+ } else {
+ if (_symbolIndex == 0)
+ _symbolIndex = 11;
+ else
+ _symbolIndex--;
+ }
+ startAnimation(kAsScene3009SymbolFileHashes[_symbolPosition / 3], _symbolIndex, -1);
+ _newStickFrameIndex = _symbolIndex;
+ setSubVar(VA_CURR_CANNON_SYMBOLS, _symbolPosition, _symbolIndex);
+ if (_symbolPosition / 3 == 0) {
+ sendMessage(_parentScene, 0x2001, 0);
+ } else {
+ sendMessage(_parentScene, 0x2003, 0);
+ }
+ messageResult = 1;
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene3009Symbol::hide() {
+ _ssArrowPrev->hide();
+ _ssArrowNext->hide();
+}
+
+// Scene3010
+
+static const uint32 kScene3010ButtonNameHashes[] = {
+ 0x304008D2,
+ 0x40119852,
+ 0x01180951
+};
+
+static const uint32 kScene3010DeadBoltButtonFileHashes1[] = {
+ 0x301024C2,
+ 0x20280580,
+ 0x30200452
+};
+
+static const uint32 kScene3010DeadBoltButtonFileHashes2[] = {
+ 0x50C025A8,
+ 0x1020A0A0,
+ 0x5000A7E8
+};
+
+static const NPoint kAsScene3010DeadBoltPoints[] = {
+ {550, 307},
+ {564, 415},
+ {560, 514}
+};
+
+static const uint32 kAsScene3010DeadBoltFileHashes2[] = {
+ 0x181A0042,
+ 0x580A08F2,
+ 0x18420076
+};
+
+static const uint32 kAsScene3010DeadBoltFileHashes1[] = {
+ 0x300E105A,
+ 0x804E0052,
+ 0x040E485A
+};
+
+SsScene3010DeadBoltButton::SsScene3010DeadBoltButton(NeverhoodEngine *vm, Scene *parentScene, int buttonIndex, int initCountdown, bool initDisabled)
+ : StaticSprite(vm, 900), _parentScene(parentScene), _buttonLocked(false), _countdown1(0), _countdown2(0), _buttonIndex(buttonIndex) {
+
+ _buttonEnabled = getSubVar(VA_LOCKS_DISABLED, kScene3010ButtonNameHashes[_buttonIndex]) != 0;
+ createSurface(400, 88, 95);
+ setSprite(kScene3010DeadBoltButtonFileHashes2[_buttonIndex]);
+ if (initDisabled)
+ disableButton();
+ else if (_buttonEnabled)
+ _countdown1 = initCountdown * 12 + 1;
+ loadSound(0, 0xF4217243);
+ loadSound(1, 0x44049000);
+ loadSound(2, 0x6408107E);
+ SetUpdateHandler(&SsScene3010DeadBoltButton::update);
+ SetMessageHandler(&SsScene3010DeadBoltButton::handleMessage);
+}
+
+void SsScene3010DeadBoltButton::update() {
+
+ if (_countdown1 != 0 && (--_countdown1 == 0)) {
+ playSound(0);
+ setVisible(false);
+ setSprite(kScene3010DeadBoltButtonFileHashes1[_buttonIndex]);
+ }
+
+ if (_countdown2 != 0 && (--_countdown2 == 0)) {
+ setVisible(true);
+ setSprite(kScene3010DeadBoltButtonFileHashes2[_buttonIndex]);
+ }
+
+}
+
+uint32 SsScene3010DeadBoltButton::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x1011:
+ if (!_buttonLocked && _countdown1 == 0) {
+ if (_buttonEnabled) {
+ playSound(1);
+ playSound(2);
+ setVisible(true);
+ _buttonLocked = true;
+ sendMessage(_parentScene, 0x2000, _buttonIndex);
+ } else {
+ sendMessage(_parentScene, NM_POSITION_CHANGE, _buttonIndex);
+ }
+ _needRefresh = true;
+ updatePosition();
+ }
+ messageResult = 1;
+ break;
+ }
+ return messageResult;
+}
+
+void SsScene3010DeadBoltButton::disableButton() {
+ _buttonLocked = true;
+ setSprite(kScene3010DeadBoltButtonFileHashes1[_buttonIndex]);
+ setVisible(true);
+}
+
+void SsScene3010DeadBoltButton::setSprite(uint32 fileHash) {
+ loadSprite(fileHash, kSLFDefDrawOffset | kSLFDefPosition | kSLFDefCollisionBoundsOffset);
+}
+
+void SsScene3010DeadBoltButton::setCountdown(int count) {
+ _countdown2 = count * 18 + 1;
+}
+
+AsScene3010DeadBolt::AsScene3010DeadBolt(NeverhoodEngine *vm, Scene *parentScene, int boltIndex, bool initUnlocked)
+ : AnimatedSprite(vm, 1100), _parentScene(parentScene), _boltIndex(boltIndex), _soundToggle(true),
+ _unlocked(false), _locked(false), _countdown(0) {
+
+ _x = kAsScene3010DeadBoltPoints[_boltIndex].x;
+ _y = kAsScene3010DeadBoltPoints[_boltIndex].y;
+
+ if (getSubVar(VA_LOCKS_DISABLED, kScene3010ButtonNameHashes[_boltIndex])) {
+ createSurface1(kAsScene3010DeadBoltFileHashes1[_boltIndex], 1200);
+ startAnimation(kAsScene3010DeadBoltFileHashes1[_boltIndex], 0, -1);
+ loadSound(0, 0x46005BC4);
+ } else {
+ createSurface1(kAsScene3010DeadBoltFileHashes2[_boltIndex], 1200);
+ startAnimation(kAsScene3010DeadBoltFileHashes2[_boltIndex], 0, -1);
+ loadSound(0, 0x420073DC);
+ loadSound(1, 0x420073DC);
+ }
+
+ setVisible(false);
+ stIdle();
+ if (initUnlocked)
+ unlock(true);
+
+ _needRefresh = true;
+ AnimatedSprite::updatePosition();
+
+}
+
+void AsScene3010DeadBolt::update() {
+ updateAnim();
+ updatePosition();
+ if (_countdown != 0 && (--_countdown == 0)) {
+ stDisabled();
+ }
+}
+
+uint32 AsScene3010DeadBolt::hmAnimation(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case NM_ANIMATION_STOP:
+ gotoNextState();
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene3010DeadBolt::stIdle() {
+ stopAnimation();
+ SetUpdateHandler(&AsScene3010DeadBolt::update);
+ SetMessageHandler(&Sprite::handleMessage);
+ _locked = false;
+}
+
+void AsScene3010DeadBolt::unlock(bool skipAnim) {
+ if (!_unlocked) {
+ setVisible(true);
+ if (skipAnim) {
+ startAnimation(kAsScene3010DeadBoltFileHashes1[_boltIndex], -1, 0);
+ _newStickFrameIndex = STICK_LAST_FRAME;
+ } else {
+ startAnimation(kAsScene3010DeadBoltFileHashes1[_boltIndex], 0, -1);
+ SetMessageHandler(&AsScene3010DeadBolt::hmAnimation);
+ FinalizeState(&AsScene3010DeadBolt::stIdleMessage);
+ NextState(&AsScene3010DeadBolt::stIdle);
+ playSound(0);
+ }
+ _unlocked = true;
+ loadSound(2, 0x4010C345);
+ }
+}
+
+void AsScene3010DeadBolt::stIdleMessage() {
+ stopAnimation();
+ SetMessageHandler(&Sprite::handleMessage);
+ sendMessage(_parentScene, 0x2001, _boltIndex);
+}
+
+void AsScene3010DeadBolt::lock() {
+ if (!_locked) {
+ _locked = true;
+ setVisible(true);
+ startAnimation(kAsScene3010DeadBoltFileHashes2[_boltIndex], 0, -1);
+ SetMessageHandler(&AsScene3010DeadBolt::hmAnimation);
+ FinalizeState(&AsScene3010DeadBolt::stDisabledMessage);
+ NextState(&AsScene3010DeadBolt::stIdle);
+ if (_soundToggle) {
+ playSound(0);
+ } else {
+ playSound(1);
+ }
+ _soundToggle = !_soundToggle;
+ }
+}
+
+void AsScene3010DeadBolt::setCountdown(int count) {
+ _countdown = count * 18 + 1;
+}
+
+void AsScene3010DeadBolt::stDisabled() {
+ setVisible(true);
+ startAnimation(kAsScene3010DeadBoltFileHashes1[_boltIndex], 0, -1);
+ SetMessageHandler(&AsScene3010DeadBolt::hmAnimation);
+ FinalizeState(&AsScene3010DeadBolt::stDisabledMessage);
+ NextState(&AsScene3010DeadBolt::stIdle);
+ _playBackwards = true;
+ playSound(2);
+}
+
+void AsScene3010DeadBolt::stDisabledMessage() {
+ setVisible(false);
+ sendMessage(_parentScene, 0x2003, _boltIndex);
+}
+
+// Scene3011
+
+static const uint32 kAsScene3011SymbolFileHashes[] = {
+ 0x00C88050,
+ 0x01488050,
+ 0x02488050,
+ 0x04488050,
+ 0x08488050,
+ 0x10488050,
+ 0x20488050,
+ 0x40488050,
+ 0x80488050,
+ 0x00488051,
+ 0x00488052,
+ 0x00488054,
+ 0x008B0000,
+ 0x008D0000,
+ 0x00810000,
+ 0x00990000,
+ 0x00A90000,
+ 0x00C90000,
+ 0x00090000,
+ 0x01890000,
+ 0x02890000,
+ 0x04890000,
+ 0x08890000,
+ 0x10890000
+};
+
+SsScene3011Button::SsScene3011Button(NeverhoodEngine *vm, Scene *parentScene, bool flag)
+ : StaticSprite(vm, 1400), _parentScene(parentScene), _countdown(0) {
+
+ loadSprite(flag ? 0x11282020 : 0x994D0433, kSLFDefDrawOffset | kSLFDefPosition | kSLFDefCollisionBoundsOffset, 400);
+ setVisible(false);
+ loadSound(0, 0x44061000);
+ SetUpdateHandler(&SsScene3011Button::update);
+ SetMessageHandler(&SsScene3011Button::handleMessage);
+}
+
+void SsScene3011Button::update() {
+ updatePosition();
+ if (_countdown != 0 && (--_countdown == 0)) {
+ setVisible(false);
+ }
+}
+
+uint32 SsScene3011Button::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = 0;
+ StaticSprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x1011:
+ if (_countdown == 0) {
+ setVisible(true);
+ _countdown = 4;
+ sendMessage(_parentScene, 0x2000, 0);
+ playSound(0);
+ }
+ messageResult = 1;
+ break;
+ }
+ return messageResult;
+}
+
+AsScene3011Symbol::AsScene3011Symbol(NeverhoodEngine *vm, int symbolIndex, bool largeSymbol)
+ : AnimatedSprite(vm, 1000), _symbolIndex(symbolIndex), _largeSymbol(largeSymbol), _isNoisy(false) {
+
+ if (_largeSymbol) {
+ _x = 310;
+ _y = 200;
+ createSurface1(kAsScene3011SymbolFileHashes[_symbolIndex], 1200);
+ loadSound(0, 0x6052C60F);
+ loadSound(1, 0x6890433B);
+ } else {
+ _symbolIndex = 12;
+ _x = symbolIndex * 39 + 96;
+ _y = 225;
+ createSurface(1200, 41, 48);
+ loadSound(0, 0x64428609);
+ loadSound(1, 0x7080023B);
+ }
+ setVisible(false);
+ _needRefresh = true;
+ SetUpdateHandler(&AnimatedSprite::update);
+}
+
+void AsScene3011Symbol::show(bool isNoisy) {
+ _isNoisy = isNoisy;
+ startAnimation(kAsScene3011SymbolFileHashes[_symbolIndex], 0, -1);
+ setVisible(true);
+ if (_isNoisy) {
+ playSound(1);
+ } else {
+ playSound(0);
+ }
+}
+
+void AsScene3011Symbol::hide() {
+ stopAnimation();
+ setVisible(false);
+}
+
+void AsScene3011Symbol::stopSymbolSound() {
+ if (_isNoisy) {
+ stopSound(1);
+ } else {
+ stopSound(0);
+ }
+}
+
+void AsScene3011Symbol::change(int symbolIndex, bool isNoisy) {
+ _symbolIndex = symbolIndex;
+ _isNoisy = isNoisy;
+ startAnimation(kAsScene3011SymbolFileHashes[_symbolIndex], 0, -1);
+ setVisible(true);
+ if (_isNoisy) {
+ playSound(1);
+ } else {
+ playSound(0);
+ }
+}
+
+} // End of namespace Neverhood
diff --git a/engines/neverhood/modules/module3000_sprites.h b/engines/neverhood/modules/module3000_sprites.h
new file mode 100644
index 0000000000..7316613327
--- /dev/null
+++ b/engines/neverhood/modules/module3000_sprites.h
@@ -0,0 +1,185 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef NEVERHOOD_MODULES_MODULE3000_SPRITES_H
+#define NEVERHOOD_MODULES_MODULE3000_SPRITES_H
+
+#include "neverhood/neverhood.h"
+#include "neverhood/module.h"
+#include "neverhood/scene.h"
+#include "neverhood/modules/module1200.h"
+
+namespace Neverhood {
+
+// Scene3009
+
+class Scene3009;
+
+class SsScene3009FireCannonButton : public StaticSprite {
+public:
+ SsScene3009FireCannonButton(NeverhoodEngine *vm, Scene3009 *parentScene);
+protected:
+ Scene3009 *_parentScene;
+ bool _isClicked;
+ void update();
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class SsScene3009SymbolEdges : public StaticSprite {
+public:
+ SsScene3009SymbolEdges(NeverhoodEngine *vm, int index);
+ void show();
+ void hide();
+ void startBlinking();
+protected:
+ int _blinkCountdown;
+ bool _blinkToggle;
+ void update();
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class SsScene3009TargetLine : public StaticSprite {
+public:
+ SsScene3009TargetLine(NeverhoodEngine *vm, int index);
+ void show();
+};
+
+class SsScene3009SymbolArrow : public StaticSprite {
+public:
+ SsScene3009SymbolArrow(NeverhoodEngine *vm, Sprite *asSymbol, int index);
+ void hide();
+protected:
+ Sprite *_asSymbol;
+ int _index;
+ int _incrDecr;
+ bool _enabled;
+ int _countdown;
+ void update();
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class AsScene3009VerticalIndicator : public AnimatedSprite {
+public:
+ AsScene3009VerticalIndicator(NeverhoodEngine *vm, Scene3009 *parentScene, int index);
+ void show();
+protected:
+ Scene3009 *_parentScene;
+ bool _enabled;
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class AsScene3009HorizontalIndicator : public AnimatedSprite {
+public:
+ AsScene3009HorizontalIndicator(NeverhoodEngine *vm, Scene3009 *parentScene, uint32 cannonTargetStatus);
+ void show();
+ void stMoveLeft();
+ void stMoveRight();
+protected:
+ Scene3009 *_parentScene;
+ bool _enabled;
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ void suMoveLeft();
+ void suMoveRight();
+};
+
+class AsScene3009Symbol : public AnimatedSprite {
+public:
+ AsScene3009Symbol(NeverhoodEngine *vm, Scene3009 *parentScene, int symbolPosition);
+ void hide();
+protected:
+ Scene3009 *_parentScene;
+ int _symbolPosition;
+ uint32 _symbolIndex;
+ SsScene3009SymbolArrow *_ssArrowPrev;
+ SsScene3009SymbolArrow *_ssArrowNext;
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+// Scene3010
+
+class SsScene3010DeadBoltButton : public StaticSprite {
+public:
+ SsScene3010DeadBoltButton(NeverhoodEngine *vm, Scene *parentScene, int buttonIndex, int initCountdown, bool initDisabled);
+ void setCountdown(int count);
+protected:
+ Scene *_parentScene;
+ int _buttonIndex;
+ bool _buttonEnabled;
+ bool _buttonLocked;
+ int _countdown1;
+ int _countdown2;
+ void update();
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ void disableButton();
+ void setSprite(uint32 fileHash);
+};
+
+class AsScene3010DeadBolt : public AnimatedSprite {
+public:
+ AsScene3010DeadBolt(NeverhoodEngine *vm, Scene *parentScene, int boltIndex, bool initUnlocked);
+ void setCountdown(int count);
+ void lock();
+ void unlock(bool skipAnim);
+protected:
+ Scene *_parentScene;
+ int _boltIndex;
+ int _countdown;
+ bool _soundToggle;
+ bool _unlocked;
+ bool _locked;
+ void update();
+ uint32 hmAnimation(int messageNum, const MessageParam &param, Entity *sender);
+ void stIdle();
+ void stIdleMessage();
+ void stDisabled();
+ void stDisabledMessage();
+};
+
+// Scene3011
+
+class SsScene3011Button : public StaticSprite {
+public:
+ SsScene3011Button(NeverhoodEngine *vm, Scene *parentScene, bool flag);
+protected:
+ Scene *_parentScene;
+ int _countdown;
+ void update();
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class AsScene3011Symbol : public AnimatedSprite {
+public:
+ AsScene3011Symbol(NeverhoodEngine *vm, int symbolIndex, bool largeSymbol);
+ void show(bool isNoisy);
+ void hide();
+ void stopSymbolSound();
+ void change(int symbolIndex, bool isNoisy);
+ int getSymbolIndex() { return _largeSymbol ? _symbolIndex : _symbolIndex - 12; }
+protected:
+ bool _largeSymbol;
+ bool _isNoisy;
+ int _symbolIndex;
+};
+
+} // End of namespace Neverhood
+
+#endif /* NEVERHOOD_MODULES_MODULE3000_SPRITES_H */
diff --git a/engines/neverhood/navigationscene.cpp b/engines/neverhood/navigationscene.cpp
index a15c00de07..adbb6aef7a 100644
--- a/engines/neverhood/navigationscene.cpp
+++ b/engines/neverhood/navigationscene.cpp
@@ -106,19 +106,19 @@ void NavigationScene::update() {
uint32 NavigationScene::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
switch (messageNum) {
- case 0x0000:
+ case NM_MOUSE_MOVE:
if (_interactive)
sendMessage(_mouseCursor, 0x4002, param);
break;
- case 0x0001:
+ case NM_MOUSE_CLICK:
if (_interactive)
handleNavigation(param.asPoint());
break;
- case 0x0009:
+ case NM_KEYPRESS_SPACE:
if (!_interactive)
_smackerDone = true;
break;
- case 0x3002:
+ case NM_ANIMATION_STOP:
_smackerDone = true;
break;
}
diff --git a/engines/neverhood/neverhood.cpp b/engines/neverhood/neverhood.cpp
index 1fb32a1834..1119bfbb08 100644
--- a/engines/neverhood/neverhood.cpp
+++ b/engines/neverhood/neverhood.cpp
@@ -45,7 +45,7 @@
namespace Neverhood {
-NeverhoodEngine::NeverhoodEngine(OSystem *syst, const NeverhoodGameDescription *gameDesc) : Engine(syst), _gameDescription(gameDesc) {
+NeverhoodEngine::NeverhoodEngine(OSystem *syst, const NeverhoodGameDescription *gameDesc) : Engine(syst), _gameDescription(gameDesc), _console(nullptr) {
// Setup mixer
if (!_mixer->isReady()) {
warning("Sound initialization failed.");
@@ -79,6 +79,7 @@ Common::Error NeverhoodEngine::run() {
// Assign default values to the config manager, in case settings are missing
ConfMan.registerDefault("originalsaveload", "false");
+ ConfMan.registerDefault("skiphallofrecordsscenes", "false");
_staticData = new StaticData();
_staticData->load("neverhood.dat");
@@ -177,6 +178,12 @@ void NeverhoodEngine::mainLoop() {
case Common::EVENT_RBUTTONUP:
_gameModule->handleMouseUp(event.mouse.x, event.mouse.y);
break;
+ case Common::EVENT_WHEELUP:
+ _gameModule->handleWheelUp();
+ break;
+ case Common::EVENT_WHEELDOWN:
+ _gameModule->handleWheelDown();
+ break;
case Common::EVENT_QUIT:
_system->quit();
break;
@@ -190,13 +197,12 @@ void NeverhoodEngine::mainLoop() {
_gameModule->draw();
_console->onFrame();
_screen->update();
+ if (_updateSound)
+ _soundMan->update();
nextFrameTime = _screen->getNextFrameTime();
};
- if (_updateSound) {
- _soundMan->update();
- _audioResourceMan->updateMusic();
- }
+ _audioResourceMan->updateMusic();
_system->updateScreen();
_system->delayMillis(10);
diff --git a/engines/neverhood/neverhood.h b/engines/neverhood/neverhood.h
index 0561aa251e..4d923d1f0e 100644
--- a/engines/neverhood/neverhood.h
+++ b/engines/neverhood/neverhood.h
@@ -32,6 +32,8 @@
#include "common/system.h"
#include "audio/mixer.h"
#include "engines/engine.h"
+#include "gui/debugger.h"
+#include "neverhood/console.h"
#include "neverhood/messages.h"
namespace Neverhood {
@@ -48,7 +50,6 @@ class Screen;
class SoundMan;
class AudioResourceMan;
class StaticData;
-class Console;
struct NPoint;
struct GameState {
@@ -90,6 +91,7 @@ public:
GameModule *_gameModule;
StaticData *_staticData;
Console *_console;
+ GUI::Debugger *getDebugger() { return _console; }
SoundMan *_soundMan;
AudioResourceMan *_audioResourceMan;
diff --git a/engines/neverhood/palette.cpp b/engines/neverhood/palette.cpp
index c381f46671..134fec7163 100644
--- a/engines/neverhood/palette.cpp
+++ b/engines/neverhood/palette.cpp
@@ -66,6 +66,11 @@ void Palette::init() {
_status = 0;
_palette = new byte[1024];
_basePalette = new byte[1024];
+ _palCounter = 0;
+ _fadeToR = 0;
+ _fadeToG = 0;
+ _fadeToB = 0;
+ _fadeStep = 0;
}
void Palette::usePalette() {
@@ -114,7 +119,7 @@ void Palette::startFadeToBlack(int counter) {
_fadeToG = 0;
_fadeToB = 0;
_palCounter = counter;
- _fadeStep = 255 / counter;
+ _fadeStep = calculateFadeStep(counter);
_status = 1;
}
@@ -126,7 +131,7 @@ void Palette::startFadeToWhite(int counter) {
_fadeToG = 255;
_fadeToB = 255;
_palCounter = counter;
- _fadeStep = 255 / counter;
+ _fadeStep = calculateFadeStep(counter);
_status = 1;
}
@@ -135,7 +140,7 @@ void Palette::startFadeToPalette(int counter) {
if (counter == 0)
counter = 1;
_palCounter = counter;
- _fadeStep = 255 / counter;
+ _fadeStep = calculateFadeStep(counter);
_status = 2;
}
@@ -198,4 +203,11 @@ void Palette::fadeColor(byte *rgb, byte toR, byte toG, byte toB) {
#undef FADE
}
+int Palette::calculateFadeStep(int counter) {
+ int fadeStep = 255 / counter;
+ if (255 % counter)
+ fadeStep++;
+ return fadeStep;
+}
+
} // End of namespace Neverhood
diff --git a/engines/neverhood/palette.h b/engines/neverhood/palette.h
index c83207caae..016f856104 100644
--- a/engines/neverhood/palette.h
+++ b/engines/neverhood/palette.h
@@ -61,6 +61,7 @@ protected:
int _fadeStep;
void update();
void fadeColor(byte *rgb, byte toR, byte toG, byte toB);
+ int calculateFadeStep(int counter);
};
} // End of namespace Neverhood
diff --git a/engines/neverhood/resourceman.cpp b/engines/neverhood/resourceman.cpp
index 518755a846..f6937384c0 100644
--- a/engines/neverhood/resourceman.cpp
+++ b/engines/neverhood/resourceman.cpp
@@ -94,11 +94,30 @@ struct EntrySizeFix {
};
static const EntrySizeFix entrySizeFixes[] = {
- // fileHash offset diskSize size fixedSize
+ // fileHash offset diskSize size fixedSize
// Fixes for the Russian "Dyadyushka Risech" version
- // TODO
+ { 0x041137051, 667019, 23391, 41398, 41401 }, // "Options" menu header text
+ { 0x00f960021, 402268, 1704, 4378, 1870 }, // "Save" menu
+ { 0x01301a7ea, 1220008, 2373, 4146, 2877 }, // "Load" menu
+ { 0x084181e81, 201409, 1622, 5058, 1833 }, // "Delete" menu
+ { 0x008C0AC24, 1031009, 3030, 6498, 3646 }, // Overwrite dialog
+ { 0x0c6604282, 12813649, 19623, 35894, 35895 }, // One of the fonts when reading Willie's notes
+ { 0x080283101, 13104841, 1961, 3712, 3511 }, // First message from Willie
+ { 0x000918480, 17676417, 581, 916, 706 }, // First wall in the museum
+ { 0x00800090C, 16064875, 19555, 38518, 38526 }, // First wall in the museum
+ { 0x058208810, 46010519, 24852, 131874, 131776 }, // Entry to hut with musical lock
+ { 0x00008E486, 39600019, 240, 454, 271 }, // Second wall in the museum
+ { 0x003086004, 39621755, 482, 614, 600 }, // Second wall in the museum
+ { 0x02008048E, 39611075, 3798, 21089, 21087 }, // Next couple of walls in the museum
+ { 0x008586283, 39587864, 12155, 29731, 29730 }, // Next couple of walls in the museum
+ { 0x030A84C80, 39606142, 4933, 16305, 16275 }, // Next couple of walls in the museum
+ { 0x000C9A480, 39614873, 6882, 23915, 23913 }, // Next couple of walls in the museum
+ { 0x000098880, 39603114, 3028, 10860, 10859 }, // Next couple of walls in the museum
+ { 0x040080183, 39600259, 2855, 13400, 13395 }, // Last buggy wall in the museum
+
// Fixes for the Russian "Fargus" version
- // TODO
+ { 0x041137051, 758264, 29037, 49590, 49591 }, // "Options" menu header text
+ { 0x0c10b2015, 787304, 4414, 15848, 15853 }, // Text on option buttons
//
{ 0, 0, 0, 0, 0 }
};
diff --git a/engines/neverhood/scene.cpp b/engines/neverhood/scene.cpp
index 0b2e9c6b75..b8cde73e81 100644
--- a/engines/neverhood/scene.cpp
+++ b/engines/neverhood/scene.cpp
@@ -50,6 +50,9 @@ Scene::Scene(NeverhoodEngine *vm, Module *parentModule)
_smackerPlayer = NULL;
_isMessageListBusy = false;
_messageValue = -1;
+ _messageListStatus = 0;
+ _messageListCount = 0;
+ _messageListIndex = 0;
_backgroundFileHash = _cursorFileHash = 0;
@@ -280,11 +283,11 @@ void Scene::leaveScene(uint32 result) {
uint32 Scene::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
switch (messageNum) {
- case 0x0000: // mouse moved
+ case NM_MOUSE_MOVE:
if (_mouseCursor && _mouseCursor->hasMessageHandler())
sendMessage(_mouseCursor, 0x4002, param);
break;
- case 0x0001: // mouse clicked
+ case NM_MOUSE_CLICK:
_mouseClicked = true;
_mouseClickPos = param.asPoint();
break;
@@ -298,7 +301,7 @@ uint32 Scene::handleMessage(int messageNum, const MessageParam &param, Entity *s
if (_messageListIndex == _messageListCount) {
// If the current message list was processed completely,
// sent Klaymen into the idle state.
- sendMessage(_klaymen, 0x4004, 0);
+ sendMessage(_klaymen, NM_KLAYMEN_STAND_IDLE, 0);
} else {
// Else continue with the next message in the current message list
processMessageList();
@@ -311,23 +314,21 @@ uint32 Scene::handleMessage(int messageNum, const MessageParam &param, Entity *s
if (_isKlaymenBusy) {
_isKlaymenBusy = false;
_messageList = NULL;
- sendMessage(_klaymen, 0x4004, 0);
+ sendMessage(_klaymen, NM_KLAYMEN_STAND_IDLE, 0);
}
break;
- case 0x101D:
- // Hide the mouse cursor
+ case NM_MOUSE_HIDE:
if (_mouseCursor) {
_mouseCursorWasVisible = _mouseCursor->getSurface()->getVisible();
_mouseCursor->getSurface()->setVisible(false);
}
break;
- case 0x101E:
- // Show the mouse cursor
+ case NM_MOUSE_SHOW:
if (_mouseCursorWasVisible && _mouseCursor) {
_mouseCursor->getSurface()->setVisible(true);
}
break;
- case 0x1022:
+ case NM_PRIORITY_CHANGE:
// Set the sender's surface priority
setSurfacePriority(((Sprite*)sender)->getSurface(), param.asInteger());
break;
@@ -448,7 +449,7 @@ void Scene::processMessageList() {
_isKlaymenBusy = true;
sendPointMessage(_klaymen, 0x4001, _mouseClickPos);
} else if (messageNum == 0x100D) {
- if (this->hasMessageHandler() && sendMessage(this, 0x100D, messageParam) != 0)
+ if (this->hasMessageHandler() && sendMessage(this, NM_ANIMATION_START, messageParam) != 0)
continue;
} else if (messageNum == 0x101A) {
_messageListStatus = 0;
@@ -482,7 +483,7 @@ void Scene::cancelMessageList() {
_isKlaymenBusy = false;
_messageList = NULL;
_canAcceptInput = true;
- sendMessage(_klaymen, 0x4004, 0);
+ sendMessage(_klaymen, NM_KLAYMEN_STAND_IDLE, 0);
}
void Scene::setRectList(uint32 id) {
@@ -614,7 +615,7 @@ StaticScene::StaticScene(NeverhoodEngine *vm, Module *parentModule, uint32 backg
uint32 StaticScene::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x0001:
+ case NM_MOUSE_CLICK:
if (param.asPoint().x <= 20 || param.asPoint().x >= 620)
leaveScene(0);
break;
diff --git a/engines/neverhood/scene.h b/engines/neverhood/scene.h
index f60e291395..e6183199ce 100644
--- a/engines/neverhood/scene.h
+++ b/engines/neverhood/scene.h
@@ -204,8 +204,6 @@ protected:
// Used for debugging
uint32 _backgroundFileHash, _cursorFileHash; // for StaticScene and all Scene* classes
- void (Entity::*_savedUpdateHandlerCb)();
- uint32 (Entity::*_savedMessageHandlerCb)(int messageNum, const MessageParam &param, Entity *sender);
int _messageValue;
uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
bool queryPositionSprite(int16 mouseX, int16 mouseY);
diff --git a/engines/neverhood/screen.cpp b/engines/neverhood/screen.cpp
index 4c8dd9add0..901ab73b39 100644
--- a/engines/neverhood/screen.cpp
+++ b/engines/neverhood/screen.cpp
@@ -27,7 +27,8 @@ namespace Neverhood {
Screen::Screen(NeverhoodEngine *vm)
: _vm(vm), _paletteData(NULL), _paletteChanged(false), _smackerDecoder(NULL),
- _yOffset(0), _fullRefresh(false) {
+ _yOffset(0), _fullRefresh(false), _frameDelay(0), _savedSmackerDecoder(NULL),
+ _savedFrameDelay(0), _savedYOffset(0) {
_ticks = _vm->_system->getMillis();
diff --git a/engines/neverhood/screen.h b/engines/neverhood/screen.h
index c778066152..a9b5af02f6 100644
--- a/engines/neverhood/screen.h
+++ b/engines/neverhood/screen.h
@@ -79,7 +79,6 @@ public:
void drawSurface2(const Graphics::Surface *surface, NDrawRect &drawRect, NRect &clipRect, bool transparent, byte version,
const Graphics::Surface *shadowSurface = NULL);
void drawSurface3(const Graphics::Surface *surface, int16 x, int16 y, NDrawRect &drawRect, NRect &clipRect, bool transparent, byte version);
- void drawShadowSurface(const Graphics::Surface *surface, const Graphics::Surface *shadowSurface, int16 x, int16 y, NDrawRect &drawRect, NRect &clipRect);
void drawDoubleSurface2(const Graphics::Surface *surface, NDrawRect &drawRect);
void drawUnk(const Graphics::Surface *surface, NDrawRect &drawRect, NDrawRect &sysRect, NRect &clipRect, bool transparent, byte version);
void drawSurfaceClipRects(const Graphics::Surface *surface, NDrawRect &drawRect, NRect *clipRects, uint clipRectsCount, bool transparent, byte version);
diff --git a/engines/neverhood/smackerplayer.cpp b/engines/neverhood/smackerplayer.cpp
index 187939faee..014e094b94 100644
--- a/engines/neverhood/smackerplayer.cpp
+++ b/engines/neverhood/smackerplayer.cpp
@@ -21,6 +21,7 @@
*/
#include "graphics/palette.h"
+#include "neverhood/gamemodule.h"
#include "neverhood/smackerplayer.h"
#include "neverhood/palette.h"
#include "neverhood/resourceman.h"
@@ -160,7 +161,7 @@ void SmackerPlayer::close() {
void SmackerPlayer::gotoFrame(int frameNumber) {
if (_smackerDecoder) {
_smackerDecoder->forceSeekToFrame(frameNumber);
- _smackerDecoder->decodeNextFrame();
+ updateFrame();
}
}
@@ -204,7 +205,7 @@ void SmackerPlayer::update() {
} else if (!_keepLastFrame) {
// Inform the scene about the end of the video playback
if (_scene)
- sendMessage(_scene, 0x3002, 0);
+ sendMessage(_scene, NM_ANIMATION_STOP, 0);
_videoDone = true;
} else {
rewind();
@@ -251,6 +252,15 @@ void SmackerPlayer::updatePalette() {
tempPalette[i * 4 + 1] = smackerPalette[i * 3 + 1];
tempPalette[i * 4 + 2] = smackerPalette[i * 3 + 2];
}
+
+ // WORKAROUND: Scene 3, module 3000 defines a black color 255 instead of
+ // white, which results in the mouse cursor showing black. I'm not sure if
+ // color 255 is always supposed to be white. It's not feasible to check
+ // all scenes for a glitch that only seems to manifest in one, therefore
+ // we define color 255 to be white only for that scene.
+ if (_vm->_gameModule->getCurrentModuleNum() == 3000 && _vm->_gameState.sceneNum == 3)
+ tempPalette[255 * 4 + 0] = tempPalette[255 * 4 + 1] = tempPalette[255 * 4 + 2] = 0xFF;
+
_palette->copyPalette(tempPalette, 0, 256, 0);
}
diff --git a/engines/neverhood/smackerscene.cpp b/engines/neverhood/smackerscene.cpp
index d9d032a3b5..c3915200b5 100644
--- a/engines/neverhood/smackerscene.cpp
+++ b/engines/neverhood/smackerscene.cpp
@@ -104,15 +104,15 @@ void SmackerScene::update() {
uint32 SmackerScene::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x0009:
+ case NM_KEYPRESS_SPACE:
if ((_videoPlayedBefore && _canSkip) || (_canAbort && _canSkip))
_playNextVideoFlag = true;
break;
- case 0x000C:
+ case NM_KEYPRESS_ESC:
if (_canAbort)
sendMessage(_parentModule, 0x1009, 0);
break;
- case 0x3002:
+ case NM_ANIMATION_STOP:
_playNextVideoFlag = true;
break;
}
diff --git a/engines/neverhood/sound.cpp b/engines/neverhood/sound.cpp
index 746dd17de0..023eda4c02 100644
--- a/engines/neverhood/sound.cpp
+++ b/engines/neverhood/sound.cpp
@@ -66,6 +66,12 @@ void SoundResource::play() {
soundItem->playSound(false);
}
+void SoundResource::playLooping() {
+ AudioResourceManSoundItem *soundItem = getSoundItem();
+ if (soundItem)
+ soundItem->playSound(true);
+}
+
void SoundResource::stop() {
AudioResourceManSoundItem *soundItem = getSoundItem();
if (soundItem)
@@ -208,7 +214,7 @@ void SoundItem::setSoundParams(bool playOnceAfterRandomCountdown, int16 minCount
_minCountdown = minCountdown;
if (maxCountdown > 0)
_maxCountdown = maxCountdown;
- if (firstMinCountdown >= firstMaxCountdown)
+ if (firstMinCountdown > firstMaxCountdown)
_currCountdown = firstMinCountdown;
else if (firstMinCountdown > 0 && firstMaxCountdown > 0 && firstMinCountdown < firstMaxCountdown)
_currCountdown = _vm->_rnd->getRandomNumberRng(firstMinCountdown, firstMaxCountdown);
@@ -235,22 +241,24 @@ void SoundItem::update() {
if (_playOnceAfterCountdown) {
if (_currCountdown == 0)
_currCountdown = _initialCountdown;
- else if (--_currCountdown == 0)
+ else if (--_currCountdown <= 0)
_soundResource->play();
} else if (_playOnceAfterRandomCountdown) {
if (_currCountdown == 0) {
if (_minCountdown > 0 && _maxCountdown > 0 && _minCountdown < _maxCountdown)
_currCountdown = _vm->_rnd->getRandomNumberRng(_minCountdown, _maxCountdown);
- } else if (--_currCountdown == 0)
+ } else if (--_currCountdown <= 0)
_soundResource->play();
} else if (_playLooping && !_soundResource->isPlaying())
- _soundResource->play();
+ _soundResource->playLooping();
}
// SoundMan
SoundMan::SoundMan(NeverhoodEngine *vm)
- : _vm(vm), _soundIndex1(-1), _soundIndex2(-1), _soundIndex3(-1) {
+ : _vm(vm), _soundIndex1(-1), _soundIndex2(-1), _soundIndex3(-1),
+ _initialCountdown(15), _playOnceAfterCountdown(false),
+ _initialCountdown3(9), _playOnceAfterCountdown3(false) {
}
SoundMan::~SoundMan() {
@@ -371,7 +379,6 @@ void SoundMan::update() {
if (soundItem)
soundItem->update();
}
-
for (uint i = 0; i < _musicItems.size(); ++i) {
MusicItem *musicItem = _musicItems[i];
if (musicItem)
@@ -551,15 +558,19 @@ int NeverhoodAudioStream::readBuffer(int16 *buffer, const int numSamples) {
*buffer++ = _prevValue << _shiftValue;
}
} else {
- memcpy(buffer, _buffer, bytesRead);
- buffer += bytesRead;
+ while (samplesRead--) {
+ *buffer++ = READ_LE_UINT16(src);
+ src += 2;
+ }
}
if (bytesRead < bytesToRead || _stream->pos() >= _stream->size() || _stream->err() || _stream->eos()) {
- if (_isLooping)
+ if (_isLooping) {
_stream->seek(0);
- else
+ _prevValue = 0;
+ } else {
_endOfData = true;
+ }
}
}
@@ -607,7 +618,7 @@ void AudioResourceManSoundItem::playSound(bool looping) {
if (_data) {
const byte *shiftValue = _resourceHandle.extData();
Common::MemoryReadStream *stream = new Common::MemoryReadStream(_data, _resourceHandle.size(), DisposeAfterUse::NO);
- NeverhoodAudioStream *audioStream = new NeverhoodAudioStream(22050, *shiftValue, false, DisposeAfterUse::YES, stream);
+ NeverhoodAudioStream *audioStream = new NeverhoodAudioStream(22050, *shiftValue, looping, DisposeAfterUse::YES, stream);
_vm->_mixer->playStream(Audio::Mixer::kSFXSoundType, &_soundHandle,
audioStream, -1, VOLUME(_volume), PANNING(_panning));
debug(1, "playing sound %08X", _fileHash);
@@ -627,7 +638,8 @@ bool AudioResourceManSoundItem::isPlaying() {
AudioResourceManMusicItem::AudioResourceManMusicItem(NeverhoodEngine *vm, uint32 fileHash)
: _vm(vm), _fileHash(fileHash), _terminate(false), _canRestart(false),
- _volume(100), _panning(50), _start(false), _isFadingIn(false), _isFadingOut(false), _isPlaying(false) {
+ _volume(100), _panning(50), _start(false), _isFadingIn(false), _isFadingOut(false), _isPlaying(false),
+ _fadeVolume(0), _fadeVolumeStep(0) {
}
diff --git a/engines/neverhood/sound.h b/engines/neverhood/sound.h
index 548fe88501..1f80f8d6b0 100644
--- a/engines/neverhood/sound.h
+++ b/engines/neverhood/sound.h
@@ -50,6 +50,7 @@ public:
void unload();
void play(uint32 fileHash);
void play();
+ void playLooping();
void stop();
void setVolume(int16 volume);
void setPan(int16 pan);
diff --git a/engines/neverhood/sprite.cpp b/engines/neverhood/sprite.cpp
index 1a432461fb..05fc9b256f 100644
--- a/engines/neverhood/sprite.cpp
+++ b/engines/neverhood/sprite.cpp
@@ -372,7 +372,7 @@ void AnimatedSprite::updateFrameIndex() {
} else {
// Inform self about end of current animation
// The caller can then e.g. set a new animation fileHash
- sendMessage(this, 0x3002, 0);
+ sendMessage(this, NM_ANIMATION_STOP, 0);
if (_newAnimFileHash == 0)
_currFrameIndex = 0;
}
@@ -380,7 +380,7 @@ void AnimatedSprite::updateFrameIndex() {
if (_currFrameIndex > 0) {
_currFrameIndex--;
} else {
- sendMessage(this, 0x3002, 0);
+ sendMessage(this, NM_ANIMATION_STOP, 0);
if (_newAnimFileHash == 0)
_currFrameIndex = _lastFrameIndex;
}
@@ -399,7 +399,7 @@ void AnimatedSprite::updateFrameInfo() {
updateBounds();
_needRefresh = true;
if (frameInfo.frameHash != 0)
- sendMessage(this, 0x100D, frameInfo.frameHash);
+ sendMessage(this, NM_ANIMATION_START, frameInfo.frameHash);
}
void AnimatedSprite::createSurface1(uint32 fileHash, int surfacePriority) {
diff --git a/engines/neverhood/staticdata.cpp b/engines/neverhood/staticdata.cpp
index 006992641a..ec9c852118 100644
--- a/engines/neverhood/staticdata.cpp
+++ b/engines/neverhood/staticdata.cpp
@@ -53,6 +53,22 @@ void StaticData::load(const char *filename) {
messageItem.messageValue = fd.readUint32LE();
messageList->push_back(messageItem);
}
+
+ // WORKAROUND for a problem in two of the game's message lists:
+ // the message lists used when Klaymen is drinking the wrong potion
+ // have as a last element the animation itself (message 0x4832).
+ // However, when processMessageList() reaches the last element in a
+ // message list, it allows player input, which means that the player
+ // can erroneously skip these potion drinking animations. We insert
+ // another message at the end of these lists to prevent player input
+ // till the animations are finished
+ if (id == 0x004AF0C8 || id == 0x004B5BD0) { // wrong potion message lists
+ MessageItem messageItem;
+ messageItem.messageNum = 0x4004; // set Klaymen's state to idle
+ messageItem.messageValue = 0;
+ messageList->push_back(messageItem);
+ }
+
_messageLists[id] = messageList;
}
diff --git a/engines/parallaction/configure.engine b/engines/parallaction/configure.engine
new file mode 100644
index 0000000000..babca4579f
--- /dev/null
+++ b/engines/parallaction/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 parallaction "Parallaction" yes
diff --git a/engines/parallaction/debug.cpp b/engines/parallaction/debug.cpp
index 25acac9b06..4a8f8c71d7 100644
--- a/engines/parallaction/debug.cpp
+++ b/engines/parallaction/debug.cpp
@@ -62,8 +62,8 @@ void Debugger::postEnter() {
bool Debugger::Cmd_Location(int argc, const char **argv) {
- const char *character = _vm->_char.getName();
- const char *location = _vm->_location._name;
+ const char *character; // = _vm->_char.getName();
+ const char *location; // = _vm->_location._name;
char tmp[PATH_LEN];
diff --git a/engines/parallaction/exec.h b/engines/parallaction/exec.h
index b966d677cd..5968954ba0 100644
--- a/engines/parallaction/exec.h
+++ b/engines/parallaction/exec.h
@@ -62,7 +62,7 @@ struct ProgramContext {
AnimationPtr _anim;
ProgramPtr _program;
InstructionPtr _inst;
- uint32 _ip;
+ uint32 _ip;
uint16 _modCounter;
bool _suspend;
};
diff --git a/engines/parallaction/font.cpp b/engines/parallaction/font.cpp
index 03b1ced8e1..627c6ebe22 100644
--- a/engines/parallaction/font.cpp
+++ b/engines/parallaction/font.cpp
@@ -518,6 +518,9 @@ AmigaFont::AmigaFont(Common::SeekableReadStream &stream) {
_charSpace = 0;
_charKern = 0;
+ _cp = 0;
+ _pitch = 0;
+
if (_font->_charSpace != 0)
_charSpace = (uint16 *)(_data + FROM_BE_32(_font->_charSpace));
if (_font->_charKern != 0)
diff --git a/engines/parallaction/graphics.cpp b/engines/parallaction/graphics.cpp
index 3f36d56420..dca1870cb7 100644
--- a/engines/parallaction/graphics.cpp
+++ b/engines/parallaction/graphics.cpp
@@ -218,7 +218,7 @@ void Palette::rotate(uint first, uint last, bool forward) {
-void Gfx::setPalette(Palette pal) {
+void Gfx::setPalette(Palette &pal) {
byte sysPal[256*3];
uint n = pal.fillRGB(sysPal);
diff --git a/engines/parallaction/graphics.h b/engines/parallaction/graphics.h
index 55c1c0c04e..401e753775 100644
--- a/engines/parallaction/graphics.h
+++ b/engines/parallaction/graphics.h
@@ -138,7 +138,7 @@ public:
}
Cnv(uint16 numFrames, uint16 width, uint16 height, byte* data, bool freeData = false)
- : _count(numFrames), _width(width), _height(height), _data(data), _freeData(freeData) {
+ : _count(numFrames), _width(width), _height(height), _data(data), _freeData(freeData), field_8(0) {
}
@@ -465,7 +465,7 @@ public:
void invertBackground(const Common::Rect& r);
// palette
- void setPalette(Palette palette);
+ void setPalette(Palette &palette);
void setBlackPalette();
void animatePalette();
diff --git a/engines/parallaction/gui.h b/engines/parallaction/gui.h
index a6eed240c4..9f2e96475b 100644
--- a/engines/parallaction/gui.h
+++ b/engines/parallaction/gui.h
@@ -43,7 +43,7 @@ class MenuInputHelper {
MenuInputState *_newState;
public:
- MenuInputHelper() : _state(0) {
+ MenuInputHelper() : _state(0), _newState(0) {
}
~MenuInputHelper();
diff --git a/engines/parallaction/gui_br.cpp b/engines/parallaction/gui_br.cpp
index ddbc31d730..2ec5ba6e8d 100644
--- a/engines/parallaction/gui_br.cpp
+++ b/engines/parallaction/gui_br.cpp
@@ -196,6 +196,11 @@ class MainMenuInputState_BR : public MenuInputState {
public:
MainMenuInputState_BR(Parallaction_br *vm, MenuInputHelper *helper) : MenuInputState("mainmenu", helper), _vm(vm) {
memset(_lines, 0, sizeof(_lines));
+
+ _menuStrings = 0;
+ _options = 0;
+ _availItems = 0;
+ _selection = 0;
}
~MainMenuInputState_BR() {
diff --git a/engines/parallaction/gui_ns.cpp b/engines/parallaction/gui_ns.cpp
index 082c37f666..ae32a416e3 100644
--- a/engines/parallaction/gui_ns.cpp
+++ b/engines/parallaction/gui_ns.cpp
@@ -117,6 +117,7 @@ public:
_allowChoice = false;
_nextState = "selectgame";
_label = 0;
+ _blocks = 0;
_dosLanguageSelectBlocks[0] = Common::Rect( 80, 110, 128, 180 ); // Italian
_dosLanguageSelectBlocks[1] = Common::Rect( 129, 85, 177, 155 ); // French
@@ -414,7 +415,7 @@ class SelectCharacterInputState_NS : public MenuInputState {
#define CHAR_DONNA 1
#define CHAR_DOUGH 2
- Common::Rect _codeSelectBlocks[9];
+ Common::Rect _codeSelectBlocks[9];
Common::Rect _codeTrueBlocks[9];
Parallaction_ns *_vm;
diff --git a/engines/parallaction/input.h b/engines/parallaction/input.h
index a815469ec3..a303eb96c8 100644
--- a/engines/parallaction/input.h
+++ b/engines/parallaction/input.h
@@ -114,7 +114,7 @@ public:
void trackMouse(ZonePtr z);
void waitForButtonEvent(uint32 buttonEventMask, int32 timeout = -1);
uint32 getLastButtonEvent() { return _mouseButtons; }
- bool getLastKeyDown(uint16 &ascii);
+ bool getLastKeyDown(uint16 &ascii);
void stopHovering();
diff --git a/engines/parallaction/objects.h b/engines/parallaction/objects.h
index 81761b2c6b..89e8134431 100644
--- a/engines/parallaction/objects.h
+++ b/engines/parallaction/objects.h
@@ -147,7 +147,7 @@ typedef Common::List<CommandPtr> CommandList;
struct Answer {
Common::String _text;
uint16 _mood;
- Common::String _followingName;
+ Common::String _followingName;
CommandList _commands;
uint32 _noFlags;
@@ -188,7 +188,7 @@ struct Dialogue {
~Dialogue();
};
-#define MAX_WALKPOINT_LISTS 20
+#define MAX_WALKPOINT_LISTS 20
#define FREE_HEAR_CHANNEL -1
#define MUSIC_HEAR_CHANNEL -2
@@ -452,7 +452,7 @@ struct Program {
uint16 _numLocals;
uint32 _ip;
- uint32 _loopStart;
+ uint32 _loopStart;
InstructionList _instructions;
uint32 _status;
diff --git a/engines/parallaction/parallaction.cpp b/engines/parallaction/parallaction.cpp
index f868abfbf4..e7be1eb8a3 100644
--- a/engines/parallaction/parallaction.cpp
+++ b/engines/parallaction/parallaction.cpp
@@ -59,6 +59,33 @@ Parallaction::Parallaction(OSystem *syst, const PARALLACTIONGameDescription *gam
DebugMan.addDebugChannel(kDebugAudio, "audio", "Audio debug level");
DebugMan.addDebugChannel(kDebugMenu, "menu", "Menu debug level");
DebugMan.addDebugChannel(kDebugInventory, "inventory", "Inventory debug level");
+
+ _screenHeight = 0;
+ _screenSize = 0;
+ _gameType = 0;
+ _gfx = 0;
+ _disk = 0;
+ _input = 0;
+ _debugger = 0;
+ _saveLoad = 0;
+ _menuHelper = 0;
+ _soundMan = 0;
+ _labelFont = 0;
+ _menuFont = 0;
+ _introFont = 0;
+ _dialogueFont = 0;
+ _globalFlagsNames = 0;
+ _objectsNames = 0;
+ _objects = 0;
+ _callableNames = 0;
+ _localFlagNames = 0;
+ _cmdExec = 0;
+ _programExec = 0;
+ _balloonMan = 0;
+ _inventoryRenderer = 0;
+ _inventory = 0;
+ _currentLocationIndex = 0;
+ _numLocations = 0;
}
Parallaction::~Parallaction() {
@@ -882,6 +909,9 @@ void CharacterName::dummify() {
CharacterName::CharacterName() {
dummify();
+
+ _suffix = 0;
+ _prefix = 0;
}
CharacterName::CharacterName(const char *name) {
diff --git a/engines/parallaction/parallaction.h b/engines/parallaction/parallaction.h
index 2dbb0227d6..203a0168ea 100644
--- a/engines/parallaction/parallaction.h
+++ b/engines/parallaction/parallaction.h
@@ -360,7 +360,7 @@ public:
uint32 getLocationFlags();
bool checkSpecialZoneBox(ZonePtr z, uint32 type, uint x, uint y);
bool checkZoneBox(ZonePtr z, uint32 type, uint x, uint y);
- bool checkZoneType(ZonePtr z, uint32 type);
+ bool checkZoneType(ZonePtr z, uint32 type);
bool checkLinkedAnimBox(ZonePtr z, uint32 type, uint x, uint y);
ZonePtr hitZone(uint32 type, uint16 x, uint16 y);
void runZone(ZonePtr z);
@@ -579,7 +579,7 @@ private:
void freeLocation(bool removeAll);
void loadProgram(AnimationPtr a, const char *filename);
void startGui(bool showSplash);
- void startIngameMenu();
+ void startIngameMenu();
void freeCharacter();
typedef void (Parallaction_br::*Callable)(void *);
diff --git a/engines/parallaction/parallaction_br.cpp b/engines/parallaction/parallaction_br.cpp
index f9df9d85db..586e4bbd6a 100644
--- a/engines/parallaction/parallaction_br.cpp
+++ b/engines/parallaction/parallaction_br.cpp
@@ -45,6 +45,18 @@ const char *Parallaction_br::_partNames[] = {
Parallaction_br::Parallaction_br(OSystem* syst, const PARALLACTIONGameDescription *gameDesc) : Parallaction(syst, gameDesc),
_locationParser(0), _programParser(0), _soundManI(0) {
+ _audioCommandsNamesRes = 0;
+ _part = 0;
+ _nextPart = 0;
+ _subtitleY = 0;
+ _subtitle[0] = 0;
+ _subtitle[1] = 0;
+ _charInventories[0] = 0;
+ _charInventories[1] = 0;
+ _charInventories[2] = 0;
+ _countersNames = 0;
+ _callables = 0;
+ _walker = 0;
}
Common::Error Parallaction_br::init() {
diff --git a/engines/parallaction/parallaction_ns.cpp b/engines/parallaction/parallaction_ns.cpp
index 49b63dcac3..91e8c78fc2 100644
--- a/engines/parallaction/parallaction_ns.cpp
+++ b/engines/parallaction/parallaction_ns.cpp
@@ -145,6 +145,18 @@ void LocationName::bind(const char *s) {
Parallaction_ns::Parallaction_ns(OSystem* syst, const PARALLACTIONGameDescription *gameDesc) : Parallaction(syst, gameDesc),
_locationParser(0), _programParser(0), _walker(0) {
+ _soundManI = 0;
+ _score = 0;
+ _inTestResult = 0;
+ _callables = 0;
+ num_foglie = 0;
+ _sarcophagusDeltaX = 0;
+ _movingSarcophagus = 0;
+ _freeSarcophagusSlotX = 0;
+ _intro = 0;
+
+ _testResultLabels[0] = 0;
+ _testResultLabels[1] = 0;
}
Common::Error Parallaction_ns::init() {
diff --git a/engines/parallaction/parser.h b/engines/parallaction/parser.h
index 3e2604eda2..622e507aad 100644
--- a/engines/parallaction/parser.h
+++ b/engines/parallaction/parser.h
@@ -207,6 +207,11 @@ protected:
public:
LocationParser_ns(Parallaction_ns *vm) : _vm(vm), _commandsNames(0), _locationStmt(0),
_locationZoneStmt(0), _locationAnimStmt(0) {
+ _script = 0;
+ _parser = 0;
+ _zoneTypeNames = 0;
+ _zoneFlagNames = 0;
+ _zoneProg = 0;
}
virtual void init();
@@ -292,14 +297,14 @@ public:
virtual void parseGetData(ZonePtr z);
virtual void parseDoorData(ZonePtr z);
virtual void parseHearData(ZonePtr z);
- virtual void parseNoneData(ZonePtr z);
+ virtual void parseNoneData(ZonePtr z);
protected:
void parseAnswerCounter(Answer *answer);
virtual Answer *parseAnswer();
public:
LocationParser_br(Parallaction_br *vm) : LocationParser_ns((Parallaction_ns*)vm), _vm(vm),
- _audioCommandsNames(0) {
+ _audioCommandsNames(0), _out(0) {
}
virtual void init();
@@ -363,7 +368,7 @@ protected:
}
public:
- ProgramParser_ns(Parallaction_ns *vm) : _vm(vm), _parser(0), _instructionNames(0) {
+ ProgramParser_ns(Parallaction_ns *vm) : _vm(vm), _parser(0), _instructionNames(0), _script(0), _currentInstruction(0) {
}
virtual void init();
diff --git a/engines/parallaction/sound.h b/engines/parallaction/sound.h
index e12e50e278..e8dde78ddc 100644
--- a/engines/parallaction/sound.h
+++ b/engines/parallaction/sound.h
@@ -103,7 +103,7 @@ protected:
Audio::Mixer *_mixer;
char _musicFile[PATH_LEN];
- bool _sfxLooping;
+ bool _sfxLooping;
int _sfxVolume;
int _sfxRate;
uint _sfxChannel;
@@ -156,7 +156,7 @@ class AmigaSoundMan_ns : public SoundMan_ns {
Audio::AudioStream *_musicStream;
Audio::SoundHandle _musicHandle;
- uint32 beepSoundBufferSize;
+ uint32 beepSoundBufferSize;
int8 *beepSoundBuffer;
Channel _channels[NUM_SFX_CHANNELS];
@@ -188,7 +188,7 @@ protected:
Common::String _musicFile;
- bool _sfxLooping;
+ bool _sfxLooping;
int _sfxVolume;
int _sfxRate;
uint _sfxChannel;
diff --git a/engines/parallaction/sound_br.cpp b/engines/parallaction/sound_br.cpp
index 4a643aaf1d..ea769de9e8 100644
--- a/engines/parallaction/sound_br.cpp
+++ b/engines/parallaction/sound_br.cpp
@@ -207,6 +207,7 @@ public:
void play(Common::SeekableReadStream *stream);
virtual void pause(bool p);
+ virtual void pause() { assert(0); } // overridden
virtual void setVolume(int volume);
virtual void onTimer();
diff --git a/engines/parallaction/sound_ns.cpp b/engines/parallaction/sound_ns.cpp
index 0ee3d73556..ed3031e94e 100644
--- a/engines/parallaction/sound_ns.cpp
+++ b/engines/parallaction/sound_ns.cpp
@@ -43,6 +43,7 @@ public:
void play(Common::SeekableReadStream *stream);
void pause(bool p);
+ virtual void pause() { assert(0); } // overridden
virtual void onTimer();
private:
diff --git a/engines/pegasus/configure.engine b/engines/pegasus/configure.engine
new file mode 100644
index 0000000000..ed7e295287
--- /dev/null
+++ b/engines/pegasus/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 pegasus "The Journeyman Project: Pegasus Prime" yes "" "" "16bit"
diff --git a/engines/pegasus/neighborhood/caldoria/caldoria.cpp b/engines/pegasus/neighborhood/caldoria/caldoria.cpp
index 0b3e1ee040..0707a83e87 100644
--- a/engines/pegasus/neighborhood/caldoria/caldoria.cpp
+++ b/engines/pegasus/neighborhood/caldoria/caldoria.cpp
@@ -386,54 +386,72 @@ void Caldoria::startSpotOnceOnly(TimeValue startTime, TimeValue stopTime) {
if (!_privateFlags.getFlag(kCaldoriaPrivateSeen13CarFlag) && _vm->getRandomBit() == 0) {
_privateFlags.setFlag(kCaldoriaPrivateSeen13CarFlag, true);
Neighborhood::startSpotOnceOnly(startTime, stopTime);
+ } else {
+ showViewFrame(getViewTime(GameState.getCurrentRoom(), GameState.getCurrentDirection()));
}
break;
case MakeRoomView(kCaldoria14, kEast):
if (!_privateFlags.getFlag(kCaldoriaPrivateSeen14CarFlag) && _vm->getRandomBit() == 0) {
_privateFlags.setFlag(kCaldoriaPrivateSeen14CarFlag, true);
Neighborhood::startSpotOnceOnly(startTime, stopTime);
+ } else {
+ showViewFrame(getViewTime(GameState.getCurrentRoom(), GameState.getCurrentDirection()));
}
break;
case MakeRoomView(kCaldoria18, kWest):
if (!_privateFlags.getFlag(kCaldoriaPrivateSeen18CarFlag) && _vm->getRandomBit() == 0) {
_privateFlags.setFlag(kCaldoriaPrivateSeen18CarFlag, true);
Neighborhood::startSpotOnceOnly(startTime, stopTime);
+ } else {
+ showViewFrame(getViewTime(GameState.getCurrentRoom(), GameState.getCurrentDirection()));
}
break;
case MakeRoomView(kCaldoria23, kSouth):
if (!_privateFlags.getFlag(kCaldoriaPrivateSeen23CarFlag) && _vm->getRandomBit() == 0) {
_privateFlags.setFlag(kCaldoriaPrivateSeen23CarFlag, true);
Neighborhood::startSpotOnceOnly(startTime, stopTime);
+ } else {
+ showViewFrame(getViewTime(GameState.getCurrentRoom(), GameState.getCurrentDirection()));
}
break;
case MakeRoomView(kCaldoria33, kSouth):
if (!_privateFlags.getFlag(kCaldoriaPrivateSeen33CarFlag) && _vm->getRandomBit() == 0) {
_privateFlags.setFlag(kCaldoriaPrivateSeen33CarFlag, true);
Neighborhood::startSpotOnceOnly(startTime, stopTime);
+ } else {
+ showViewFrame(getViewTime(GameState.getCurrentRoom(), GameState.getCurrentDirection()));
}
break;
case MakeRoomView(kCaldoria36, kNorth):
if (!_privateFlags.getFlag(kCaldoriaPrivateSeen36CarFlag) && _vm->getRandomBit() == 0) {
_privateFlags.setFlag(kCaldoriaPrivateSeen36CarFlag, true);
Neighborhood::startSpotOnceOnly(startTime, stopTime);
+ } else {
+ showViewFrame(getViewTime(GameState.getCurrentRoom(), GameState.getCurrentDirection()));
}
break;
case MakeRoomView(kCaldoria41, kNorth):
if (!_privateFlags.getFlag(kCaldoriaPrivateSeen41NorthCarFlag) && _vm->getRandomBit() == 0) {
_privateFlags.setFlag(kCaldoriaPrivateSeen41NorthCarFlag, true);
Neighborhood::startSpotOnceOnly(startTime, stopTime);
+ } else {
+ showViewFrame(getViewTime(GameState.getCurrentRoom(), GameState.getCurrentDirection()));
}
break;
case MakeRoomView(kCaldoria41, kEast):
if (!_privateFlags.getFlag(kCaldoriaPrivateSeen41EastCarFlag) && _vm->getRandomBit() == 0) {
_privateFlags.setFlag(kCaldoriaPrivateSeen41EastCarFlag, true);
Neighborhood::startSpotOnceOnly(startTime, stopTime);
+ } else {
+ showViewFrame(getViewTime(GameState.getCurrentRoom(), GameState.getCurrentDirection()));
}
break;
case MakeRoomView(kCaldoria41, kWest):
if (!_privateFlags.getFlag(kCaldoriaPrivateSeen41WestCarFlag) && _vm->getRandomBit() == 0) {
_privateFlags.setFlag(kCaldoriaPrivateSeen41WestCarFlag, true);
Neighborhood::startSpotOnceOnly(startTime, stopTime);
+ } else {
+ showViewFrame(getViewTime(GameState.getCurrentRoom(), GameState.getCurrentDirection()));
}
break;
default:
diff --git a/engines/pegasus/neighborhood/mars/mars.cpp b/engines/pegasus/neighborhood/mars/mars.cpp
index 775221589a..435bcd4c9e 100644
--- a/engines/pegasus/neighborhood/mars/mars.cpp
+++ b/engines/pegasus/neighborhood/mars/mars.cpp
@@ -2011,7 +2011,7 @@ void Mars::dropItemIntoRoom(Item *item, Hotspot *dropSpot) {
void Mars::robotTiredOfWaiting() {
if (GameState.getCurrentRoomAndView() == MakeRoomView(kMars48, kEast)) {
- if (_attackingItem) {
+ if (!_attackingItem) {
startExtraSequence(kMars48RobotKillsPlayer, kExtraCompletedFlag, kFilterNoInput);
loadLoopSound2("");
} else {
diff --git a/engines/pegasus/neighborhood/norad/delta/globegame.cpp b/engines/pegasus/neighborhood/norad/delta/globegame.cpp
index 1416c51c8d..0b95e9bc2b 100644
--- a/engines/pegasus/neighborhood/norad/delta/globegame.cpp
+++ b/engines/pegasus/neighborhood/norad/delta/globegame.cpp
@@ -905,6 +905,11 @@ void GlobeGame::clickGlobe(const Input &input) {
_monitorMovie.start();
_owner->requestSpotSound(kMaximumDeactivationIn, kMaximumDeactivationOut,
kFilterNoInput, kSpotSoundCompletedFlag);
+
+ // This sound was left out of the original.
+ _owner->requestSpotSound(kAllSilosDeactivatedIn, kAllSilosDeactivatedOut,
+ kFilterNoInput, kSpotSoundCompletedFlag);
+
_gameState = kPlayerWon1;
} else {
_owner->requestDelay(2, 1, kFilterNoInput, kDelayCompletedFlag);
@@ -1060,12 +1065,13 @@ void GlobeGame::doSolve() {
_upperNamesMovie.hide();
_lowerNamesMovie.hide();
_countdown.hide();
- _monitorMovie.setSegment(kMaxDeactivatedStart * _monitorMovie.getScale(), kMaxDeactivatedStop * _monitorMovie.getScale());
- _monitorMovie.setTime(kMaxDeactivatedStart * _monitorMovie.getScale());
+ _monitorMovie.setSegment(kMaxDeactivatedStart * _monitorMovie.getScale() + (kSiloDeactivatedOut - kSiloDeactivatedIn), kMaxDeactivatedStop * _monitorMovie.getScale());
+ _monitorMovie.setTime(kMaxDeactivatedStart * _monitorMovie.getScale() + (kSiloDeactivatedOut - kSiloDeactivatedIn));
_monitorCallBack.setCallBackFlag(kMaxDeactivatedFinished);
_monitorCallBack.scheduleCallBack(kTriggerAtStop, 0, 0);
_monitorMovie.start();
_owner->requestSpotSound(kMaximumDeactivationIn, kMaximumDeactivationOut, kFilterNoInput, kSpotSoundCompletedFlag);
+ _owner->requestSpotSound(kAllSilosDeactivatedIn, kAllSilosDeactivatedOut, kFilterNoInput, kSpotSoundCompletedFlag);
_gameState = kPlayerWon1;
}
diff --git a/engines/pegasus/neighborhood/norad/delta/noraddelta.cpp b/engines/pegasus/neighborhood/norad/delta/noraddelta.cpp
index f2ea53ff89..1eea2f0156 100644
--- a/engines/pegasus/neighborhood/norad/delta/noraddelta.cpp
+++ b/engines/pegasus/neighborhood/norad/delta/noraddelta.cpp
@@ -565,6 +565,11 @@ void NoradDelta::activateHotspots() {
} else if (GameState.getCurrentRoomAndView() == MakeRoomView(kNorad59, kWest)) {
if (GameState.isCurrentDoorOpen())
_vm->getAllHotspots().deactivateOneHotspot(kNorad59WestSpotID);
+ } else if (GameState.getCurrentRoomAndView() == MakeRoomView(kNorad68, kWest)) {
+ // WORKAROUND: Make sure the retinal hotspot is disabled after the door opens.
+ // Fixes a bug in the original.
+ if (GameState.isCurrentDoorOpen())
+ _vm->getAllHotspots().deactivateOneHotspot(kNorad68WestSpotID);
}
}
diff --git a/engines/pegasus/neighborhood/prehistoric/prehistoric.cpp b/engines/pegasus/neighborhood/prehistoric/prehistoric.cpp
index d62b069e46..190984f8bc 100644
--- a/engines/pegasus/neighborhood/prehistoric/prehistoric.cpp
+++ b/engines/pegasus/neighborhood/prehistoric/prehistoric.cpp
@@ -124,11 +124,6 @@ void Prehistoric::setUpAIRules() {
AIHasItemCondition *hasLogCondition = new AIHasItemCondition(kHistoricalLog);
AIRule *rule = new AIRule(hasLogCondition, doneAction);
g_AIArea->addAIRule(rule);
- } else {
- AIPlayMessageAction *messageAction = new AIPlayMessageAction("Images/AI/Prehistoric/XP25W", false);
- AIHasItemCondition *hasLogCondition = new AIHasItemCondition(kHistoricalLog);
- AIRule *rule = new AIRule(hasLogCondition, messageAction);
- g_AIArea->addAIRule(rule);
}
if (!_vm->isOldDemo()) {
@@ -167,6 +162,13 @@ void Prehistoric::setUpAIRules() {
rule = new AIRule(timerCondition, messageAction);
g_AIArea->addAIRule(rule);
}
+
+ if (!_vm->isDemo()) {
+ AIPlayMessageAction *messageAction = new AIPlayMessageAction("Images/AI/Prehistoric/XP25W", false);
+ AIHasItemCondition *hasLogCondition = new AIHasItemCondition(kHistoricalLog);
+ AIRule *rule = new AIRule(hasLogCondition, messageAction);
+ g_AIArea->addAIRule(rule);
+ }
}
}
@@ -202,11 +204,11 @@ TimeValue Prehistoric::getViewTime(const RoomID room, const DirectionConstant di
void Prehistoric::findSpotEntry(const RoomID room, const DirectionConstant direction, SpotFlags flags, SpotTable::Entry &entry) {
Neighborhood::findSpotEntry(room, direction, flags, entry);
+ // The original strangely disabled the loop for the two volcano spots:
+ // (kPrehistoric01, kSouth) and (kPrehistoric25, kSouth)
+ // We don't do that here.
+
switch (MakeRoomView(room, direction)) {
- case MakeRoomView(kPrehistoric01, kSouth):
- case MakeRoomView(kPrehistoric25, kSouth):
- entry.clear();
- break;
case MakeRoomView(kPrehistoric01, kEast):
if (GameState.getPrehistoricSeenFlyer1())
entry.clear();
diff --git a/engines/pegasus/neighborhood/tsa/fulltsa.cpp b/engines/pegasus/neighborhood/tsa/fulltsa.cpp
index 9b843da5d6..99efe10272 100644
--- a/engines/pegasus/neighborhood/tsa/fulltsa.cpp
+++ b/engines/pegasus/neighborhood/tsa/fulltsa.cpp
@@ -2653,7 +2653,6 @@ void FullTSA::receiveNotification(Notification *notification, const Notification
GameState.setWSCAnalyzerOn(false);
GameState.setWSCDartInAnalyzer(false);
GameState.setWSCAnalyzedDart(false);
- GameState.setWSCPickedUpAntidote(false);
GameState.setWSCSawMorph(false);
GameState.setWSCDesignedAntidote(false);
GameState.setWSCOfficeMessagesOpen(false);
diff --git a/engines/pegasus/neighborhood/tsa/tinytsa.cpp b/engines/pegasus/neighborhood/tsa/tinytsa.cpp
index 4f109620c1..0d11f5d904 100644
--- a/engines/pegasus/neighborhood/tsa/tinytsa.cpp
+++ b/engines/pegasus/neighborhood/tsa/tinytsa.cpp
@@ -337,7 +337,6 @@ void TinyTSA::receiveNotification(Notification *notification, const Notification
GameState.setWSCRemovedDart(false);
GameState.setWSCAnalyzerOn(false);
GameState.setWSCAnalyzedDart(false);
- GameState.setWSCPickedUpAntidote(false);
GameState.setWSCSawMorph(false);
GameState.setWSCDesignedAntidote(false);
GameState.setWSCOfficeMessagesOpen(false);
diff --git a/engines/pegasus/neighborhood/wsc/wsc.cpp b/engines/pegasus/neighborhood/wsc/wsc.cpp
index 50b7774da4..09e2a48a52 100644
--- a/engines/pegasus/neighborhood/wsc/wsc.cpp
+++ b/engines/pegasus/neighborhood/wsc/wsc.cpp
@@ -2336,13 +2336,16 @@ Hotspot *WSC::getItemScreenSpot(Item *item, DisplayElement *element) {
void WSC::pickedUpItem(Item *item) {
switch (item->getObjectID()) {
case kAntidote:
+ // WORKAROUND: Make sure the poison is cleared separately from deactivating
+ // the synthesizer video.
+ GameState.setWSCPoisoned(false);
+ GameState.setWSCRemovedDart(false);
+ _privateFlags.setFlag(kWSCDraggingAntidoteFlag, false);
+ playSpotSoundSync(kDrinkAntidoteIn, kDrinkAntidoteOut);
+ setUpPoison();
+
if (!GameState.getWSCPickedUpAntidote()) {
- GameState.setWSCPoisoned(false);
- GameState.setWSCRemovedDart(false);
GameState.setWSCPickedUpAntidote(true);
- _privateFlags.setFlag(kWSCDraggingAntidoteFlag, false);
- playSpotSoundSync(kDrinkAntidoteIn, kDrinkAntidoteOut);
- setUpPoison();
startExtraSequence(kW03SouthDeactivate, kExtraCompletedFlag, kFilterNoInput);
}
break;
diff --git a/engines/pegasus/pegasus.cpp b/engines/pegasus/pegasus.cpp
index 3bd29ce8dd..0148470cd5 100644
--- a/engines/pegasus/pegasus.cpp
+++ b/engines/pegasus/pegasus.cpp
@@ -429,7 +429,7 @@ void PegasusEngine::removeTimeBase(TimeBase *timeBase) {
_timeBases.remove(timeBase);
}
-bool PegasusEngine::loadFromStream(Common::ReadStream *stream) {
+bool PegasusEngine::loadFromStream(Common::SeekableReadStream *stream) {
// Dispose currently running stuff
useMenu(0);
useNeighborhood(0);
@@ -520,8 +520,36 @@ bool PegasusEngine::loadFromStream(Common::ReadStream *stream) {
performJump(GameState.getCurrentNeighborhood());
// AI rules
- if (g_AIArea)
- g_AIArea->readAIRules(stream);
+ if (g_AIArea) {
+ // HACK: clone2727 accidentally changed some Prehistoric code to output some bad saves
+ // at one point. That's fixed now, but I don't want to leave the other users high
+ // and dry.
+ if (GameState.getCurrentNeighborhood() == kPrehistoricID && !isDemo()) {
+ uint32 pos = stream->pos();
+ stream->seek(0x208);
+ uint32 roomView = stream->readUint32BE();
+ stream->seek(pos);
+
+ if (roomView == 0x30019) {
+ // This is a bad save -> Let's fix the data
+ // One byte should be put at the end instead
+ uint32 size = stream->size() - pos;
+ byte *data = (byte *)malloc(size);
+ data[0] = stream->readByte();
+ data[1] = stream->readByte();
+ data[2] = stream->readByte();
+ byte wrongData = stream->readByte();
+ stream->read(data + 3, size - 4);
+ data[size - 1] = wrongData;
+ Common::MemoryReadStream tempStream(data, size, DisposeAfterUse::YES);
+ g_AIArea->readAIRules(&tempStream);
+ } else {
+ g_AIArea->readAIRules(stream);
+ }
+ } else {
+ g_AIArea->readAIRules(stream);
+ }
+ }
startNeighborhood();
diff --git a/engines/pegasus/pegasus.h b/engines/pegasus/pegasus.h
index 07e6d8f761..59637e38df 100644
--- a/engines/pegasus/pegasus.h
+++ b/engines/pegasus/pegasus.h
@@ -249,7 +249,7 @@ private:
Common::List<TimeBase *> _timeBases;
// Save/Load
- bool loadFromStream(Common::ReadStream *stream);
+ bool loadFromStream(Common::SeekableReadStream *stream);
bool writeToStream(Common::WriteStream *stream, int saveType);
void loadFromContinuePoint();
void writeContinueStream(Common::WriteStream *stream);
diff --git a/engines/pegasus/timers.cpp b/engines/pegasus/timers.cpp
index 8463d866e8..5fb2551e7a 100644
--- a/engines/pegasus/timers.cpp
+++ b/engines/pegasus/timers.cpp
@@ -333,6 +333,7 @@ void TimeBaseCallBack::releaseCallBack() {
void TimeBaseCallBack::disposeCallBack() {
_timeBase = 0;
+ _trigger = kTriggerNone;
_hasBeenTriggered = false;
}
diff --git a/engines/plugins_table.h b/engines/plugins_table.h
deleted file mode 100644
index 801f152760..0000000000
--- a/engines/plugins_table.h
+++ /dev/null
@@ -1,127 +0,0 @@
-// This file is being included by "base/plugins.cpp"
-#if PLUGIN_ENABLED_STATIC(SCUMM)
-LINK_PLUGIN(SCUMM)
-#endif
-#if PLUGIN_ENABLED_STATIC(AGI)
-LINK_PLUGIN(AGI)
-#endif
-#if PLUGIN_ENABLED_STATIC(AGOS)
-LINK_PLUGIN(AGOS)
-#endif
-#if PLUGIN_ENABLED_STATIC(BBVS)
-LINK_PLUGIN(BBVS)
-#endif
-#if PLUGIN_ENABLED_STATIC(CGE)
-LINK_PLUGIN(CGE)
-#endif
-#if PLUGIN_ENABLED_STATIC(CINE)
-LINK_PLUGIN(CINE)
-#endif
-#if PLUGIN_ENABLED_STATIC(COMPOSER)
-LINK_PLUGIN(COMPOSER)
-#endif
-#if PLUGIN_ENABLED_STATIC(CRUISE)
-LINK_PLUGIN(CRUISE)
-#endif
-#if PLUGIN_ENABLED_STATIC(DRACI)
-LINK_PLUGIN(DRACI)
-#endif
-#if PLUGIN_ENABLED_STATIC(DRASCULA)
-LINK_PLUGIN(DRASCULA)
-#endif
-#if PLUGIN_ENABLED_STATIC(DREAMWEB)
-LINK_PLUGIN(DREAMWEB)
-#endif
-#if PLUGIN_ENABLED_STATIC(FULLPIPE)
-LINK_PLUGIN(FULLPIPE)
-#endif
-#if PLUGIN_ENABLED_STATIC(GOB)
-LINK_PLUGIN(GOB)
-#endif
-#if PLUGIN_ENABLED_STATIC(GROOVIE)
-LINK_PLUGIN(GROOVIE)
-#endif
-#if PLUGIN_ENABLED_STATIC(HOPKINS)
-LINK_PLUGIN(HOPKINS)
-#endif
-#if PLUGIN_ENABLED_STATIC(HUGO)
-LINK_PLUGIN(HUGO)
-#endif
-#if PLUGIN_ENABLED_STATIC(KYRA)
-LINK_PLUGIN(KYRA)
-#endif
-#if PLUGIN_ENABLED_STATIC(MORTEVIELLE)
-LINK_PLUGIN(MORTEVIELLE)
-#endif
-#if PLUGIN_ENABLED_STATIC(LASTEXPRESS)
-LINK_PLUGIN(LASTEXPRESS)
-#endif
-#if PLUGIN_ENABLED_STATIC(LURE)
-LINK_PLUGIN(LURE)
-#endif
-#if PLUGIN_ENABLED_STATIC(MADE)
-LINK_PLUGIN(MADE)
-#endif
-#if PLUGIN_ENABLED_STATIC(MOHAWK)
-LINK_PLUGIN(MOHAWK)
-#endif
-#if PLUGIN_ENABLED_STATIC(NEVERHOOD)
-LINK_PLUGIN(NEVERHOOD)
-#endif
-#if PLUGIN_ENABLED_STATIC(PARALLACTION)
-LINK_PLUGIN(PARALLACTION)
-#endif
-#if PLUGIN_ENABLED_STATIC(PEGASUS)
-LINK_PLUGIN(PEGASUS)
-#endif
-#if PLUGIN_ENABLED_STATIC(QUEEN)
-LINK_PLUGIN(QUEEN)
-#endif
-#if PLUGIN_ENABLED_STATIC(SAGA)
-LINK_PLUGIN(SAGA)
-#endif
-#if PLUGIN_ENABLED_STATIC(SCI)
-LINK_PLUGIN(SCI)
-#endif
-#if PLUGIN_ENABLED_STATIC(SKY)
-LINK_PLUGIN(SKY)
-#endif
-#if PLUGIN_ENABLED_STATIC(SWORD1)
-LINK_PLUGIN(SWORD1)
-#endif
-#if PLUGIN_ENABLED_STATIC(SWORD2)
-LINK_PLUGIN(SWORD2)
-#endif
-#if PLUGIN_ENABLED_STATIC(SWORD25)
-LINK_PLUGIN(SWORD25)
-#endif
-#if PLUGIN_ENABLED_STATIC(TEENAGENT)
-LINK_PLUGIN(TEENAGENT)
-#endif
-#if PLUGIN_ENABLED_STATIC(TESTBED)
-LINK_PLUGIN(TESTBED)
-#endif
-#if PLUGIN_ENABLED_STATIC(TINSEL)
-LINK_PLUGIN(TINSEL)
-#endif
-#if PLUGIN_ENABLED_STATIC(TOLTECS)
-LINK_PLUGIN(TOLTECS)
-#endif
-#if PLUGIN_ENABLED_STATIC(TONY)
-LINK_PLUGIN(TONY)
-#endif
-#if PLUGIN_ENABLED_STATIC(TOON)
-LINK_PLUGIN(TOON)
-#endif
-#if PLUGIN_ENABLED_STATIC(TSAGE)
-LINK_PLUGIN(TSAGE)
-#endif
-#if PLUGIN_ENABLED_STATIC(TOUCHE)
-LINK_PLUGIN(TOUCHE)
-#endif
-#if PLUGIN_ENABLED_STATIC(TUCKER)
-LINK_PLUGIN(TUCKER)
-#endif
-#if PLUGIN_ENABLED_STATIC(WINTERMUTE)
-LINK_PLUGIN(WINTERMUTE)
-#endif
diff --git a/engines/queen/configure.engine b/engines/queen/configure.engine
new file mode 100644
index 0000000000..c8766743f9
--- /dev/null
+++ b/engines/queen/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 queen "Flight of the Amazon Queen" yes
diff --git a/engines/saga/configure.engine b/engines/saga/configure.engine
new file mode 100644
index 0000000000..99e2ab367b
--- /dev/null
+++ b/engines/saga/configure.engine
@@ -0,0 +1,5 @@
+# This file is included from the main "configure" script
+# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps]
+add_engine saga "SAGA" yes "ihnm saga2" "ITE"
+add_engine ihnm "IHNM" yes
+add_engine saga2 "SAGA 2 games" no
diff --git a/engines/saga/introproc_ite.cpp b/engines/saga/introproc_ite.cpp
index 484ebe1779..ed53e078a0 100644
--- a/engines/saga/introproc_ite.cpp
+++ b/engines/saga/introproc_ite.cpp
@@ -993,7 +993,7 @@ int Scene::ITEIntroTreeHouseProc(int param) {
}
// Queue game credits list
- eventColumns = ITEQueueCredits(DISSOLVE_DURATION + 2000, CREDIT_DURATION1, n_credits1, credits1);
+ ITEQueueCredits(DISSOLVE_DURATION + 2000, CREDIT_DURATION1, n_credits1, credits1);
eventColumns = ITEQueueCredits(DISSOLVE_DURATION + 7000, CREDIT_DURATION1, n_credits2, credits2);
// End scene after credit display
@@ -1073,7 +1073,7 @@ int Scene::ITEIntroFairePathProc(int param) {
_vm->_events->chain(eventColumns, event);
// Queue game credits list
- eventColumns = ITEQueueCredits(DISSOLVE_DURATION + 2000, CREDIT_DURATION1, n_credits1, credits1);
+ ITEQueueCredits(DISSOLVE_DURATION + 2000, CREDIT_DURATION1, n_credits1, credits1);
eventColumns = ITEQueueCredits(DISSOLVE_DURATION + 7000, CREDIT_DURATION1, n_credits2, credits2);
// End scene after credit display
diff --git a/engines/saga/saga.h b/engines/saga/saga.h
index 01cab21f5d..645e1c30d0 100644
--- a/engines/saga/saga.h
+++ b/engines/saga/saga.h
@@ -138,7 +138,7 @@ enum GameFileTypes {
enum GameFeatures {
GF_ITE_FLOPPY = 1 << 0,
#if 0
- GF_OLD_ITE_DOS = 1 << 1, // Currently unused
+ GF_OLD_ITE_DOS = 1 << 1, // Currently unused
#endif
GF_EXTRA_ITE_CREDITS = 1 << 2,
GF_8BIT_UNSIGNED_PCM = 1 << 3
diff --git a/engines/saga/sprite.cpp b/engines/saga/sprite.cpp
index 2895c6800c..bf550659e9 100644
--- a/engines/saga/sprite.cpp
+++ b/engines/saga/sprite.cpp
@@ -71,17 +71,7 @@ Sprite::~Sprite() {
}
void Sprite::loadList(int resourceId, SpriteList &spriteList) {
- SpriteInfo *spriteInfo;
ByteArray spriteListData;
- uint16 oldSpriteCount;
- uint16 newSpriteCount;
- uint16 spriteCount;
- uint i;
- int outputLength, inputLength;
- uint32 offset;
- const byte *spritePointer;
- const byte *spriteDataPointer;
-
_vm->_resource->loadResource(_spriteContext, resourceId, spriteListData);
if (spriteListData.empty()) {
@@ -90,19 +80,19 @@ void Sprite::loadList(int resourceId, SpriteList &spriteList) {
ByteArrayReadStreamEndian readS(spriteListData, _spriteContext->isBigEndian());
- spriteCount = readS.readUint16();
+ uint16 spriteCount = readS.readUint16();
debug(9, "Sprites: %d", spriteCount);
- oldSpriteCount = spriteList.size();
- newSpriteCount = oldSpriteCount + spriteCount;
+ uint16 oldSpriteCount = spriteList.size();
+ uint16 newSpriteCount = oldSpriteCount + spriteCount;
spriteList.resize(newSpriteCount);
bool bigHeader = _vm->getGameId() == GID_IHNM || _vm->isMacResources();
- for (i = oldSpriteCount; i < spriteList.size(); i++) {
- spriteInfo = &spriteList[i];
+ for (uint i = oldSpriteCount; i < spriteList.size(); i++) {
+ uint32 offset;
if (bigHeader)
offset = readS.readUint32();
else
@@ -115,9 +105,11 @@ void Sprite::loadList(int resourceId, SpriteList &spriteList) {
return;
}
- spritePointer = spriteListData.getBuffer();
+ const byte *spritePointer = spriteListData.getBuffer();
spritePointer += offset;
+ const byte *spriteDataPointer;
+ SpriteInfo *spriteInfo = &spriteList[i];
if (bigHeader) {
Common::MemoryReadStreamEndian readS2(spritePointer, 8, _spriteContext->isBigEndian());
@@ -139,8 +131,8 @@ void Sprite::loadList(int resourceId, SpriteList &spriteList) {
spriteDataPointer = spritePointer + readS2.pos();
}
- outputLength = spriteInfo->width * spriteInfo->height;
- inputLength = spriteListData.size() - (spriteDataPointer - spriteListData.getBuffer());
+ int outputLength = spriteInfo->width * spriteInfo->height;
+ int inputLength = spriteListData.size() - (spriteDataPointer - spriteListData.getBuffer());
spriteInfo->decodedBuffer.resize(outputLength);
if (outputLength > 0) {
decodeRLEBuffer(spriteDataPointer, inputLength, outputLength);
diff --git a/engines/sci/configure.engine b/engines/sci/configure.engine
new file mode 100644
index 0000000000..d1c45a4654
--- /dev/null
+++ b/engines/sci/configure.engine
@@ -0,0 +1,4 @@
+# This file is included from the main "configure" script
+# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps]
+add_engine sci "SCI" yes "sci32" "SCI 0-1.1 games"
+add_engine sci32 "SCI32 games" no
diff --git a/engines/sci/console.cpp b/engines/sci/console.cpp
index 50fae61de0..e7cbde6cbb 100644
--- a/engines/sci/console.cpp
+++ b/engines/sci/console.cpp
@@ -2980,7 +2980,7 @@ void Console::printKernelCallsFound(int kernelFuncNum, bool showFoundScripts) {
Script *script;
// Create a custom segment manager here, so that the game's segment
// manager won't be affected by loading and unloading scripts here.
- SegManager *customSegMan = new SegManager(_engine->getResMan());
+ SegManager *customSegMan = new SegManager(_engine->getResMan(), _engine->getScriptPatcher());
Common::List<ResourceId>::iterator itr;
for (itr = resources.begin(); itr != resources.end(); ++itr) {
@@ -3840,10 +3840,15 @@ static int parse_reg_t(EngineState *s, const char *str, reg_t *dest, bool mayBeV
const char *tmp = Common::find(str_objname.begin(), str_objname.end(), '.');
if (tmp != str_objname.end()) {
index = strtol(tmp + 1, &endptr, 16);
- if (*endptr)
- return -1;
- // Chop off the index
- str_objname = Common::String(str_objname.c_str(), tmp);
+ if (*endptr) {
+ // The characters after the dot do not represent an index.
+ // This can happen if an object contains a dot in its name,
+ // like 'dominoes.opt' in Hoyle 3.
+ index = -1;
+ } else {
+ // Valid index found, chop it off
+ str_objname = Common::String(str_objname.c_str(), tmp);
+ }
}
// Replace all underscores in the name with spaces
diff --git a/engines/sci/detection_tables.h b/engines/sci/detection_tables.h
index d0a0db2a3b..85d01ca380 100644
--- a/engines/sci/detection_tables.h
+++ b/engines/sci/detection_tables.h
@@ -50,7 +50,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "f3d1be7752d30ba60614533d531e2e98", 474},
{"resource.001", 0, "6fd05926c2199af0af6f72f90d0d7260", 126895},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Castle of Dr. Brain - English Amiga (from www.back2roots.org)
// Executable scanning reports "1.005.000"
@@ -62,7 +62,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.002", 0, "d226d7d3b4f77c4a566913fc310487fc", 792380},
{"resource.003", 0, "d226d7d3b4f77c4a566913fc310487fc", 464348},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Castle of Dr. Brain - German Amiga (from www.back2roots.org, also includes English language)
// Executable scanning reports "1.005.001"
@@ -74,7 +74,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.002", 0, "85e51acb5f9c539d66e3c8fe40e17da5", 826309},
{"resource.003", 0, "85e51acb5f9c539d66e3c8fe40e17da5", 493638},
AD_LISTEND},
- Common::DE_DEU, Common::kPlatformAmiga, ADGF_ADDENGLISH, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::DE_DEU, Common::kPlatformAmiga, ADGF_ADDENGLISH, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Castle of Dr. Brain Macintosh (from omer_mor, bug report #3328251)
{"castlebrain", "", {
@@ -84,7 +84,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.002", 0, "e1a6b6f1060f60be9dcb6d28ad7a2a20", 1168310},
{"resource.003", 0, "6c3d1bb26ad532c94046bc9ac49b5ff4", 891295},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformMacintosh, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformMacintosh, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Castle of Dr. Brain - English DOS Non-Interactive Demo
// SCI interpreter version 1.000.005
@@ -93,7 +93,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.000", 0, "9780f040d58182994e22d2e34fab85b0", 67367},
{"resource.001", 0, "2af49dbd8f2e1db4ab09f9310dc91259", 570553},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Castle of Dr. Brain - English DOS 5.25" Floppy EGA (from omer_mor, bug report #3035349)
{"castlebrain", "EGA", {
@@ -106,7 +106,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.005", 0, "8a5ed3ba96e2eaf18e36fedfaab89419", 297838},
{"resource.006", 0, "dceed92e709cad1bd9582809a235b0a0", 266682},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Castle of Dr. Brain - English DOS 3.5" Floppy EGA (from nozomi77, bug report #3405307)
{"castlebrain", "EGA", {
@@ -116,7 +116,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.002", 0, "de2f182529efaad2c4b510b452ab77ac", 633662},
{"resource.003", 0, "38b4b37febc6b4f5061c461a283df148", 430388},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Castle of Dr. Brain - English DOS Floppy (from jvprat)
// Executable scanning reports "1.000.044", Floppy label reports "1.0, 10.30.91", VERSION file reports "1.000"
@@ -127,7 +127,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.001", 0, "d2f5a1be74ed963fa849a76892be5290", 794832},
{"resource.002", 0, "c0c29c51af66d65cb53f49e785a2d978", 1280907},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Castle of Dr. Brain - English DOS 5.25" Floppy VGA 1.1 (from rnjacobs, bug report #3578286)
{"castlebrain", "", {
@@ -137,7 +137,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.002", 0, "583d348c908f89f94f8551d7fe0a2eca", 991752},
{"resource.003", 0, "6c3d1bb26ad532c94046bc9ac49b5ff4", 728315},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Castle of Dr. Brain - English DOS Floppy 1.1
{"castlebrain", "", {
@@ -146,7 +146,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.001", 0, "13e81e1839cd7b216d2bb5615c1ca160", 796776},
{"resource.002", 0, "930e416bec196b9703a331d81b3d66f2", 1283812},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Castle of Dr. Brain - English DOS Floppy 1.000
// Reported by graxer in bug report #3037942
@@ -161,7 +161,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.006", 0, "1d778a0c65cac9ddbab65495e50a94ee", 335281},
{"resource.007", 0, "063bb8ce4157c778cf30d1c912c006f1", 335631},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Castle of Dr. Brain - Spanish DOS (also includes english language)
// SCI interpreter version 1.000.510
@@ -170,7 +170,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.000", 0, "27ec5fa09cd12a7fd16e86d96a2ed245", 1197694},
{"resource.001", 0, "735be4e58957180cfc807d5e18fdffcd", 1433302},
AD_LISTEND},
- Common::ES_ESP, Common::kPlatformDOS, ADGF_ADDENGLISH, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::ES_ESP, Common::kPlatformDOS, ADGF_ADDENGLISH, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
#ifdef ENABLE_SCI32
// Inside the Chest / Behind the Developer's Shield
@@ -179,7 +179,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "9dd015e79cac4f91e7de805448f39775", 1912},
{"resource.000", 0, "e4efcd042f86679dd4e1834bb3a38edb", 3770943},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO3(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO3(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_FB01_MIDI) },
#endif
// Christmas Card 1988 - English DOS
@@ -188,7 +188,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "39485580d34a72997f3d5b3aba4d24f1", 426},
{"resource.001", 0, "11391434f41c834090d7a1e9488ce936", 129739},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Christmas Card 1990: The Seasoned Professional - English DOS (16 Colors)
// SCI interpreter version 1.000.172
@@ -196,7 +196,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "8f656714a05b94423ac6eb10ee8797d0", 600},
{"resource.001", 0, "acde93e58fca4f7a2a5a220558a94aa8", 272629},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Christmas Card 1990: The Seasoned Professional - English DOS (256 Colors)
// SCI interpreter version 1.000.174
@@ -204,7 +204,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "44b8f45b841b9b5e17e939a35e443988", 600},
{"resource.001", 0, "acde93e58fca4f7a2a5a220558a94aa8", 335362},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Christmas Card 1992 - English DOS
// SCI interpreter version 1.001.055
@@ -212,7 +212,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "f1f8c8a8443f523422af70b4ec85b71c", 318},
{"resource.000", 0, "62fb9256f8e7e6e65a6875efdb7939ac", 203396},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Codename: Iceman - English Amiga (from www.back2roots.org)
// Executable scanning reports "1.002.031"
@@ -226,7 +226,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.004", 0, "8613c45fc771d658e5a505b9a4a54f31", 713382},
{"resource.005", 0, "605b67a9ef199a9bb015745e7c004cf4", 478384},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Codename: Iceman - English DOS Non-Interactive Demo
// Executable scanning reports "0.000.685"
@@ -234,7 +234,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "782974f29d8a824782d2d4aea39964e3", 1056},
{"resource.001", 0, "d4b75e280d1c3a97cfef1b0bebff387c", 573647},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Codename: Iceman - English DOS (from jvprat)
// Executable scanning reports "0.000.685", Floppy label reports "1.033, 6.8.90", VERSION file reports "1.033"
@@ -247,7 +247,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.003", 0, "d97a96f1ab91b41cf46a02cc89b0a04e", 624303},
{"resource.004", 0, "8613c45fc771d658e5a505b9a4a54f31", 670883},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Codename: Iceman - English DOS (from FRG)
// SCI interpreter version 0.000.668
@@ -259,7 +259,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.003", 0, "dc7c5280e7acfaffe6ef2a6c963c5f94", 622118},
{"resource.004", 0, "64f342463f6f35ba71b3509ef696ae3f", 669188},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Codename: Iceman - English DOS (supplied by ssburnout in bug report #3049193)
// 1.022 9x5.25" (label: Int#0.000.668)
@@ -274,7 +274,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.006", 0, "08050329aa113a9f14ed99cbfe3536ec", 232942},
{"resource.007", 0, "64f342463f6f35ba71b3509ef696ae3f", 267811},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Codename: Iceman - English DOS 1.023 (from abevi, bug report #2612718)
{"iceman", "", {
@@ -288,7 +288,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.006", 0, "08050329aa113a9f14ed99cbfe3536ec", 232942},
{"resource.007", 0, "64f342463f6f35ba71b3509ef696ae3f", 267702},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Conquests of Camelot - English Amiga (from www.back2roots.org)
// Executable scanning reports "1.002.030"
@@ -303,7 +303,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.005", 0, "c6e551bdc24f0acc193159038d4ca767", 605882},
{"resource.006", 0, "8f880a536908ab496bbc552f7f5c3738", 585255},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Conquests of Camelot - English DOS Non-Interactive Demo
// SCI interpreter version 0.000.668
@@ -311,7 +311,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "f4cd75c15be75e04cdca3acda2c0b0ea", 468},
{"resource.001", 0, "4930708722f34bfbaa4945fb08f55f61", 232523},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Conquests of Camelot - English DOS (from jvprat)
// Executable scanning reports "0.000.685", Floppy label reports "1.001, 0.000.685", VERSION file reports "1.001.000"
@@ -323,7 +323,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.003", 0, "8e1a3a8c588007404b532b8dfacc1460", 723712},
{"resource.004", 0, "8e1a3a8c588007404b532b8dfacc1460", 729143},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Conquests of Camelot - English DOS
// SCI interpreter version 0.000.685
@@ -337,7 +337,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.006", 0, "8e1a3a8c588007404b532b8dfacc1460", 332446},
{"resource.007", 0, "8e1a3a8c588007404b532b8dfacc1460", 358182},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Conquests of the Longbow - English Amiga (from www.back2roots.org)
// Executable scanning reports "1.005.001"
@@ -352,7 +352,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.005", 0, "1c3804e56b114028c5873a35c2f06d13", 653002},
{"resource.006", 0, "f9487732289a4f4966b4e34eea413325", 842817},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Conquests of the Longbow - English DOS
// SCI interpreter version 1.000.510
@@ -366,7 +366,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.005", 0, "d036df0872f2db19bca34601276be2d7", 1154950},
{"resource.006", 0, "b367a6a59f29ee30dde1d88a5a41152d", 1042966},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Conquests of the Longbow - English DOS Floppy (from jvprat)
// Executable scanning reports "1.000.168", Floppy label reports "1.1, 1.13.92", VERSION file reports "1.1"
@@ -380,7 +380,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.004", 0, "9cfce07e204a329e94fda8b5657621da", 1261462},
{"resource.005", 0, "21ebe6b39b57a73fc449f67f013765aa", 1284720},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Conquests of the Longbow - English DOS
// SCI interpreter version 1.000.510
@@ -393,30 +393,32 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.004", 0, "9cfce07e204a329e94fda8b5657621da", 1260237},
{"resource.005", 0, "21ebe6b39b57a73fc449f67f013765aa", 1284609},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Conquests of the Longbow EGA - English DOS
// SCI interpreter version 1.000.510
{"longbow", "EGA", {
- {"resource.map", 0, "7676ec9f08967d7a9a7724f5170456e0", 6261},
- {"resource.000", 0, "36e8fda5d0b8c49e587c8a9617959f72", 718161},
- {"resource.001", 0, "3c3735caa34fa3f261a9552831bb43ed", 705680},
- {"resource.002", 0, "7025b87e735b1df3f0e9488a621f4333", 700633},
- {"resource.003", 0, "eaca7933e8e56bea22b42f7fd5d7a8a7", 686510},
- {"resource.004", 0, "b7bb35c027bb424ecefcd122768e5e60", 705631},
- {"resource.005", 0, "58942b1aa6d6ffeb66e9f8897fd4435f", 469243},
- {"resource.006", 0, "8c767b3939add63d11274065e46aad04", 713158},
- AD_LISTEND}, Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ {"resource.map", 0, "7676ec9f08967d7a9a7724f5170456e0", 6261},
+ {"resource.000", 0, "36e8fda5d0b8c49e587c8a9617959f72", 718161},
+ {"resource.001", 0, "3c3735caa34fa3f261a9552831bb43ed", 705680},
+ {"resource.002", 0, "7025b87e735b1df3f0e9488a621f4333", 700633},
+ {"resource.003", 0, "eaca7933e8e56bea22b42f7fd5d7a8a7", 686510},
+ {"resource.004", 0, "b7bb35c027bb424ecefcd122768e5e60", 705631},
+ {"resource.005", 0, "58942b1aa6d6ffeb66e9f8897fd4435f", 469243},
+ {"resource.006", 0, "8c767b3939add63d11274065e46aad04", 713158},
+ AD_LISTEND},
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Conquests of the Longbow DOS 1.0 EGA (4 x 5.25" disks)
// Provided by ssburnout in bug report #3046802
{"longbow", "EGA", {
- {"resource.map", 0, "0517ca368ec844df0cb21a05020fae01", 6021},
- {"resource.000", 0, "36e8fda5d0b8c49e587c8a9617959f72", 934643},
- {"resource.001", 0, "76c729e563809170e6cc8b2f3f6cf0a4", 1196133},
- {"resource.002", 0, "8c767b3939add63d11274065e46aad04", 1152478},
- {"resource.003", 0, "7025b87e735b1df3f0e9488a621f4333", 1171439},
- AD_LISTEND}, Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ {"resource.map", 0, "0517ca368ec844df0cb21a05020fae01", 6021},
+ {"resource.000", 0, "36e8fda5d0b8c49e587c8a9617959f72", 934643},
+ {"resource.001", 0, "76c729e563809170e6cc8b2f3f6cf0a4", 1196133},
+ {"resource.002", 0, "8c767b3939add63d11274065e46aad04", 1152478},
+ {"resource.003", 0, "7025b87e735b1df3f0e9488a621f4333", 1171439},
+ AD_LISTEND},
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Conquests of the Longbow - English DOS Non-Interactive Demo
// SCI interpreter version 1.000.510
@@ -424,7 +426,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "cbc5cb73341de1bff1b1e20a640af220", 588},
{"resource.001", 0, "f05a20cc07eee85da8e999d0ac0f596b", 869916},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Conquests of the Longbow - German DOS (suplied by markcoolio in bug report #2727681, also includes english language)
// SCI interpreter version 1.000.510
@@ -438,7 +440,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.005", 0, "d036df0872f2db19bca34601276be2d7", 1176914},
{"resource.006", 0, "b367a6a59f29ee30dde1d88a5a41152d", 1123585},
AD_LISTEND},
- Common::DE_DEU, Common::kPlatformDOS, ADGF_ADDENGLISH, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::DE_DEU, Common::kPlatformDOS, ADGF_ADDENGLISH, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Eco Quest - English DOS Non-Interactive Demo (from FRG)
// Executable scanning reports "x.yyy.zzz"
@@ -447,7 +449,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "c819e171359b7c95f4c13b846d5c034e", 873},
{"resource.001", 0, "baf9393a9bfa73098adb501e5bc5487b", 657518},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Eco Quest - English DOS CD 1.1
// SCI interpreter version 1.001.064
@@ -455,7 +457,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "a4b73d5d2b55bdb6e44345e99c8fbdd0", 4804},
{"resource.000", 0, "d908dbef56816ac6c60dd145fdeafb2b", 3536046},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_CD, GUIO3(GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_CD, GUIO3(GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Eco Quest - English DOS CD 1.1
// SCI interpreter version 1.001.064
@@ -465,7 +467,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "a4b73d5d2b55bdb6e44345e99c8fbdd0", 4804},
{"resource.000", 0, "d908dbef56816ac6c60dd145fdeafb2b", 3536046},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformWindows, ADGF_CD, GUIO4(GUIO_MIDIGM, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformWindows, ADGF_CD, GUIO4(GUIO_MIDIGM, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Eco Quest - English DOS Floppy
// SCI interpreter version 1.000.510
@@ -476,7 +478,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.002", 0, "28fe9b4f0567e71feb198bc9f3a2c605", 1241816},
{"resource.003", 0, "f3146df0ad4297f5ce35aa8c4753bf6c", 586832},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Eco Quest - English DOS Floppy
// SCI interpreter version 1.000.510
@@ -487,7 +489,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.002", 0, "323b3b12f43d53f27d259beb225f0aa7", 1129316},
{"resource.003", 0, "83ac03e4bddb2c1ac2d36d2a587d0536", 1145616},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Eco Quest - German DOS Floppy (supplied by markcoolio in bug report #2723744, also includes english language)
// SCI interpreter version 1.000.510
@@ -498,7 +500,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.002", 0, "02d7d0411f7903aacb3bc8b0f8ca8a9a", 1202581},
{"resource.003", 0, "84dd11b6825255671c703aee5ceff620", 1175835},
AD_LISTEND},
- Common::DE_DEU, Common::kPlatformDOS, ADGF_ADDENGLISH, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::DE_DEU, Common::kPlatformDOS, ADGF_ADDENGLISH, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Eco Quest - Spanish DOS Floppy (from jvprat, also includes english language)
// Executable scanning reports "1.ECO.013", VERSION file reports "1.000, 11.12.92"
@@ -510,7 +512,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.002", 0, "2d21a1d2dcbffa551552e3e0725d2284", 1186033},
{"resource.003", 0, "84dd11b6825255671c703aee5ceff620", 1174993},
AD_LISTEND},
- Common::ES_ESP, Common::kPlatformDOS, ADGF_ADDENGLISH, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::ES_ESP, Common::kPlatformDOS, ADGF_ADDENGLISH, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Eco Quest - French DOS Floppy (from Strangerke, also includes english language)
// SCI interpreter version 1.ECO.013
@@ -521,7 +523,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.002", 0, "b836c6ee9de67d814ac5d1b05f5b9858", 1173872},
{"resource.003", 0, "f8f767f9d6351432621c6e54c1b2ba8c", 1141520},
AD_LISTEND},
- Common::FR_FRA, Common::kPlatformDOS, ADGF_ADDENGLISH, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::FR_FRA, Common::kPlatformDOS, ADGF_ADDENGLISH, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Eco Quest 2 - English DOS Non-Interactive Demo
// SCI interpreter version 1.001.055
@@ -529,7 +531,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "607cfa0d8a03b7d348c06ee727e3d939", 1321},
{"resource.000", 0, "dd6f614c43c029f063e93cd243af90a4", 525992},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Eco Quest 2 - English DOS Floppy (supplied by markcoolio in bug report #2723761)
// SCI interpreter version 1.001.065
@@ -537,7 +539,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "28fb7b6abb9fc1cb8882d7c2e701b63f", 5658},
{"resource.000", 0, "cc1d17e5637528dbe4a812699e1cbfc6", 4208192},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Eco Quest 2 - French DOS Floppy (from Strangerke)
// SCI interpreter version 1.001.081
@@ -545,7 +547,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "c22ab8b33c339c138b6b1697b77b9e79", 5588},
{"resource.000", 0, "1c4093f7248240329121fdf8c0d59152", 4231946},
AD_LISTEND},
- Common::FR_FRA, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::FR_FRA, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Eco Quest 2 - Spanish DOS Floppy (supplied by umbrio in bug report #3313962)
{"ecoquest2", "Floppy", {
@@ -553,7 +555,15 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.000", 0, "1c4093f7248240329121fdf8c0d59152", 4209150},
{"resource.msg", 0, "eff8be1925d42288de55e405983e9314", 117810},
AD_LISTEND},
- Common::ES_ESP, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::ES_ESP, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+
+ // Eco Quest 2 - German DOS Floppy (supplied by frankenbuam in bug report #3615072)
+ {"ecoquest2", "Floppy", {
+ {"resource.map", 0, "d8b20073e64f41f6437f73143a186753", 5643},
+ {"resource.000", 0, "cc1d17e5637528dbe4a812699e1cbfc6", 4210876},
+ {"resource.msg", 0, "2f231d31af172ea72ed533fd112f971b", 133458},
+ AD_LISTEND},
+ Common::DE_DEU, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Freddy Pharkas - English DOS demo (from FRG)
// SCI interpreter version 1.001.069
@@ -561,7 +571,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "97aa9fcfe84c9993a64debd28c32393a", 1909},
{"resource.000", 0, "5ea8e7a3ea10cce6efd5c106dc62fd8c", 867724},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Freddy Pharkas - English CD DOS (from FRG)
// SCI interpreter version 1.001.132
@@ -569,7 +579,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "d46b282f228a67ba13bd4b4009e95f8f", 6058},
{"resource.000", 0, "ee3c64ffff0ba9fb08bea2624631c598", 5490246},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_CD, GUIO3(GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_CD, GUIO3(GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Freddy Pharkas - English DOS Floppy (updated information from markcoolio in bug reports #2723773 and #2724720)
// Executable scanning reports "1.cfs.081"
@@ -579,7 +589,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.000", 0, "96b07e9b914dba1c8dc6c78a176326df", 5233230},
{"resource.msg", 0, "554f65315d851184f6e38211489fdd8f", -1},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Freddy Pharkas - French DOS Floppy (supplied by misterhands in bug report #3589449)
// Executable scanning reports "1.cfs.081"
@@ -588,7 +598,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.000", 0, "fed4808fdb72486908ac7ad0044b14d8", 5233230},
{"resource.msg", 0, "4dc478f5c73b57e5d690bdfffdcf1c44", 816518},
AD_LISTEND},
- Common::FR_FRA, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::FR_FRA, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Freddy Pharkas - Windows (supplied by abevi in bug report #2612718)
// Executable scanning reports "1.cfs.081"
@@ -597,7 +607,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "a32674e7fbf7b213b4a066c8037f16b6", 5816},
{"resource.000", 0, "fed4808fdb72486908ac7ad0044b14d8", 5233230},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformWindows, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformWindows, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Freddy Pharkas - German DOS Floppy (from Tobis87, updated information from markcoolio in bug reports #2723772 and #2724720)
// Executable scanning reports "1.cfs.081"
@@ -607,7 +617,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.000", 0, "96b07e9b914dba1c8dc6c78a176326df", 5233230},
{"resource.msg", 0, "304b5a5781800affd2235152a5794fa8", -1},
AD_LISTEND},
- Common::DE_DEU, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::DE_DEU, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Freddy Pharkas - Spanish DOS (from jvprat)
// Executable scanning reports "1.cfs.081", VERSION file reports "1.000, March 30, 1995"
@@ -620,7 +630,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.003", 0, "05acdc256c742e79c50b9fe7ec2cc898", 863310},
{"resource.msg", 0, "45b5bf74933ac3727e4cc844446dc052", 796156},
AD_LISTEND},
- Common::ES_ESP, Common::kPlatformDOS, ADGF_CD, GUIO3(GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::ES_ESP, Common::kPlatformDOS, ADGF_CD, GUIO3(GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Freddy Pharkas - Spanish DOS (from jvprat)
// Executable scanning reports "1.cfs.081", VERSION file reports "1.000, March 30, 1995"
@@ -630,7 +640,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.000", 0, "96b07e9b914dba1c8dc6c78a176326df", 5233230},
{"resource.msg", 0, "45b5bf74933ac3727e4cc844446dc052", 796156},
AD_LISTEND},
- Common::ES_ESP, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::ES_ESP, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Freddy Pharkas - English DOS CD Demo
// SCI interpreter version 1.001.095
@@ -638,14 +648,14 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "a62a7eae85dd1e6b07f39662b278437e", 1918},
{"resource.000", 0, "4962a3c4dd44e36e78ea4a7a374c2220", 957382},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO3(GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO3(GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Freddy Pharkas - English Macintosh
{"freddypharkas", "", {
{"Data1", 0, "ef7cbd62727989818f1cfae69c9fd61d", 3038492},
{"Data2", 0, "2424b418f7d52c385cea4701f529c69a", 4721732},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformMacintosh, ADGF_MACRESFORK, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformMacintosh, ADGF_MACRESFORK, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Fun Seeker's Guide - English DOS
// SCI interpreter version 0.000.506
@@ -653,7 +663,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "7ee6859ef74314f6d91938c3595348a9", 282},
{"resource.001", 0, "f1e680095424e31f7fae1255d36bacba", 40692},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Gabriel Knight - English DOS CD Demo
// SCI interpreter version 1.001.092
@@ -661,7 +671,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "39645952ae0ed8072c7e838f31b75464", 2490},
{"resource.000", 0, "eb3ed7477ca4110813fe1fcf35928561", 1718450},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO3(GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO3(GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Gabriel Knight - English DOS CD Demo (from DrMcCoy)
// SCI interpreter version 1.001.092
@@ -669,7 +679,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "8cad2a256f41463030cbb7ea1bfb2857", 2490},
{"resource.000", 0, "eb3ed7477ca4110813fe1fcf35928561", 1718450},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO3(GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO3(GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
#ifdef ENABLE_SCI32
// Gabriel Knight - English DOS Floppy
@@ -678,7 +688,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "372d059f75856afa6d73dd84cbb8913d", 10783},
{"resource.000", 0, "69b7516962510f780d38519cc15fcc7c", 13022630},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Gabriel Knight - English DOS Floppy (supplied my markcoolio in bug report #2723777)
// SCI interpreter version 2.000.000
@@ -686,7 +696,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "65e8c14092e4c9b3b3538b7602c8c5ec", 10783},
{"resource.000", 0, "69b7516962510f780d38519cc15fcc7c", 13022630},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Gabriel Knight - English DOS Floppy
// SCI interpreter version 2.000.000, VERSION file reports "1.0\nGabriel Knight\n11/22/10:33 pm\n\x1A"
@@ -694,7 +704,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "ef41df08cf2c1f680216cdbeed0f8311", 10783},
{"resource.000", 0, "69b7516962510f780d38519cc15fcc7c", 13022630},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Gabriel Knight - German DOS Floppy (supplied my markcoolio in bug report #2723775)
// SCI interpreter version 2.000.000
@@ -702,7 +712,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "ad6508b0296b25c07b1f58828dc33696", 10789},
{"resource.000", 0, "091cf08910780feabc56f8551b09cb36", 13077029},
AD_LISTEND},
- Common::DE_DEU, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::DE_DEU, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Gabriel Knight - French DOS Floppy (supplied my kervala in bug report #3611487)
// SCI interpreter version 2.000.000
@@ -710,7 +720,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "236e36cc847cdeafdd5e5fa8cba916ed", 10801},
{"resource.000", 0, "091cf08910780feabc56f8551b09cb36", 13033072},
AD_LISTEND},
- Common::FR_FRA, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::FR_FRA, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Gabriel Knight - English DOS CD (from jvprat)
// Executable scanning reports "2.000.000", VERSION file reports "01.100.000"
@@ -718,7 +728,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "372d059f75856afa6d73dd84cbb8913d", 10996},
{"resource.000", 0, "69b7516962510f780d38519cc15fcc7c", 12581736},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_CD | ADGF_UNSTABLE, GUIO3(GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_CD | ADGF_UNSTABLE, GUIO3(GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Gabriel Knight - English Windows CD (from jvprat)
// Executable scanning reports "2.000.000", VERSION file reports "01.100.000"
@@ -726,7 +736,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "372d059f75856afa6d73dd84cbb8913d", 10996},
{"resource.000", 0, "69b7516962510f780d38519cc15fcc7c", 12581736},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformWindows, ADGF_CD | ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformWindows, ADGF_CD | ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Gabriel Knight - German DOS CD (from Tobis87)
// SCI interpreter version 2.000.000
@@ -734,7 +744,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "a7d3e55114c65647310373cb390815ba", 11392},
{"resource.000", 0, "091cf08910780feabc56f8551b09cb36", 13400497},
AD_LISTEND},
- Common::DE_DEU, Common::kPlatformDOS, ADGF_CD | ADGF_UNSTABLE, GUIO3(GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::DE_DEU, Common::kPlatformDOS, ADGF_CD | ADGF_UNSTABLE, GUIO3(GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Gabriel Knight - Spanish DOS CD (from jvprat)
// Executable scanning reports "2.000.000", VERSION file reports "1.000.000, April 13, 1995"
@@ -742,7 +752,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "7cb6e9bba15b544ec7a635c45bde9953", 11404},
{"resource.000", 0, "091cf08910780feabc56f8551b09cb36", 13381599},
AD_LISTEND},
- Common::ES_ESP, Common::kPlatformDOS, ADGF_CD | ADGF_UNSTABLE, GUIO3(GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::ES_ESP, Common::kPlatformDOS, ADGF_CD | ADGF_UNSTABLE, GUIO3(GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Gabriel Knight - French DOS CD (from Hkz)
// VERSION file reports "1.000.000, May 3, 1994"
@@ -750,7 +760,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "55f909ba93a2515042a08d8a2da8414e", 11392},
{"resource.000", 0, "091cf08910780feabc56f8551b09cb36", 13325145},
AD_LISTEND},
- Common::FR_FRA, Common::kPlatformDOS, ADGF_CD | ADGF_UNSTABLE, GUIO3(GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::FR_FRA, Common::kPlatformDOS, ADGF_CD | ADGF_UNSTABLE, GUIO3(GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Gabriel Knight - German Windows CD (from Tobis87)
// SCI interpreter version 2.000.000
@@ -758,7 +768,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "a7d3e55114c65647310373cb390815ba", 11392},
{"resource.000", 0, "091cf08910780feabc56f8551b09cb36", 13400497},
AD_LISTEND},
- Common::DE_DEU, Common::kPlatformWindows, ADGF_CD | ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::DE_DEU, Common::kPlatformWindows, ADGF_CD | ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Gabriel Knight - Spanish Windows CD (from jvprat)
// Executable scanning reports "2.000.000", VERSION file reports "1.000.000, April 13, 1995"
@@ -766,7 +776,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "7cb6e9bba15b544ec7a635c45bde9953", 11404},
{"resource.000", 0, "091cf08910780feabc56f8551b09cb36", 13381599},
AD_LISTEND},
- Common::ES_ESP, Common::kPlatformWindows, ADGF_CD | ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::ES_ESP, Common::kPlatformWindows, ADGF_CD | ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Gabriel Knight - English Macintosh
{"gk1", "", {
@@ -775,7 +785,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"Data3", 0, "f25068b408b09275d8b698866462f578", 3677599},
{"Data4", 0, "1cceebbe411b26c860a74f91c337fdf3", 3230086},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformMacintosh, ADGF_MACRESFORK | ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformMacintosh, ADGF_MACRESFORK | ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Gabriel Knight 2 - English Windows Non-Interactive Demo
// Executable scanning reports "2.100.002"
@@ -783,7 +793,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "e0effce11c4908f4b91838741716c83d", 1351},
{"resource.000", 0, "d04cfc7f04b6f74d13025378be49ec2b", 4640330},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformWindows, ADGF_DEMO | ADGF_UNSTABLE, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformWindows, ADGF_DEMO | ADGF_UNSTABLE, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Gabriel Knight 2 - English DOS (GOG version) - ressci.* merged in ressci.000
// using Enrico Rolfi's HD/DVD installer: http://gkpatches.vogons.zetafleet.com/
@@ -791,7 +801,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resmap.000", 0, "b996fa1e57389a1e179a00a0049de1f4", 8110},
{"ressci.000", 0, "a19fc3604c6e5407abcf03d59ee87217", 168522221},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Gabriel Knight 2 - English DOS (from jvprat)
// Executable scanning reports "2.100.002", VERSION file reports "1.1"
@@ -809,7 +819,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resmap.006", 0, "ce9359037277b7d7976da185c2fa0aad", 2977},
{"ressci.006", 0, "8e44e03890205a7be12f45aaba9644b4", 60659424},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Gabriel Knight 2 - French DOS (6-CDs Sierra Originals reedition)
// Executable scanning reports "2.100.002", VERSION file reports "1.0"
@@ -827,7 +837,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resmap.006", 0, "11b2e722170b8c93fdaa5428e2c7676f", 3001},
{"ressci.006", 0, "4037d941aec39d2e654e20960429aefc", 60568486},
AD_LISTEND},
- Common::FR_FRA, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::FR_FRA, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Gabriel Knight 2 - English Macintosh
// NOTE: This only contains disc 1 files (as well as the persistent file:
@@ -839,7 +849,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"Data4", 0, "8b843c62eb53136a855d6e0087e3cb0d", 5889553},
{"Data5", 0, "f9fcf9ab2eb13b2125c33a1cda03a093", 14349984},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformMacintosh, ADGF_MACRESFORK | ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformMacintosh, ADGF_MACRESFORK | ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
#endif // ENABLE_SCI32
@@ -851,7 +861,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.002", 0, "e0dd44069a62a463fd124974b915f10d", 342149},
{"resource.003", 0, "e0dd44069a62a463fd124974b915f10d", 328925},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Hoyle 1 - English DOS (supplied by wibble92 in bug report #2644547)
// SCI interpreter version 0.000.530
@@ -861,7 +871,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.002", 0, "e0dd44069a62a463fd124974b915f10d", 342309},
{"resource.003", 0, "e0dd44069a62a463fd124974b915f10d", 328912},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Hoyle 1 - English DOS (supplied by merkur in bug report #2719227)
// SCI interpreter version 0.000.530
@@ -869,14 +879,14 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "1034a218943d12f1f36e753fa10c95b8", 4386},
{"resource.001", 0, "e0dd44069a62a463fd124974b915f10d", 518308},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Hoyle 1 3.5' - English DOS (supplied by eddydrama in bug report #3052366 and dinnerx in bug report #3090841)
{"hoyle1", "", {
{"resource.map", 0, "0af9a3dcd72a091960de070432e1f524", 4386},
{"resource.001", 0, "e0dd44069a62a463fd124974b915f10d", 518127},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ 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)
@@ -886,7 +896,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"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) },
+ Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
#endif
// Hoyle 2 - English DOS
@@ -896,7 +906,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.001", 0, "8f2dd70abe01112eca464cda818b5eb6", 98138},
{"resource.002", 0, "8f2dd70abe01112eca464cda818b5eb6", 196631},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Hoyle 2 - English DOS (supplied by ssburnout in bug report #3049193)
// 1.000.011 1x3.5" (label:Int#6.21.90)
@@ -904,7 +914,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "db0ba08b953e9904a4960ad99cd29c20", 1356},
{"resource.001", 0, "8f2dd70abe01112eca464cda818b5eb6", 216315},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Hoyle 2 - English Amiga (from www.back2roots.org)
// Executable scanning reports "1.002.032"
@@ -913,7 +923,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "62ed48d20c580e5a98f102f7cd93706a", 1356},
{"resource.001", 0, "8f2dd70abe01112eca464cda818b5eb6", 222704},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Hoyle 2 - English Macintosh
// Executable scanning reports "x.yyy.zzz"
@@ -921,7 +931,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "1af1d3aa3cf564f93477c9f87e53f495", 1728},
{"resource.001", 0, "b73b8131669d69d41a326415e4519138", 482882},
{NULL, 0, NULL, 0}},
- Common::EN_ANY, Common::kPlatformMacintosh, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformMacintosh, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
#if 0 // TODO: unknown if these files are corrupt
// Hoyle 3 - English Amiga (from www.back2roots.org)
@@ -932,7 +942,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.000", 0, "595b6039ea1356e7f96a52c58eedcf22", 355791},
{"resource.001", 0, "143df8aef214a2db34c2d48190742012", 632273},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
#endif
// Hoyle 3 - English DOS Non-Interactive Demo
@@ -942,7 +952,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "0d06cacc87dc21a08cd017e73036f905", 735},
{"resource.001", 0, "24db2bccda0a3c43ac4a7b5edb116c7e", 797678},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Hoyle 3 - English DOS Floppy (from jvprat)
// Executable scanning reports "x.yyy.zzz", Floppy label reports "1.0, 11.2.91", VERSION file reports "1.000"
@@ -952,7 +962,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.000", 0, "6ef28cac094dcd97fdb461662ead6f92", 541845},
{"resource.001", 0, "0a98a268ee99b92c233a0d7187c1f0fa", 845795},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Hoyle 3 - English DOS Floppy (supplied by eddydrama in bug report #3038837)
{"hoyle3", "", {
@@ -963,7 +973,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.003", 0, "97cfd72633f8f9b2a0b1d4116cf3ee81", 346116},
{"resource.004", 0, "2884fb91b225fabd9ca87ea231293b48", 351218},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Hoyle 3 EGA - English DOS Floppy 1.0 (supplied by abevi in bug report #2612718)
{"hoyle3", "EGA", {
@@ -971,14 +981,14 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.000", 0, "6ef28cac094dcd97fdb461662ead6f92", 319905},
{"resource.001", 0, "0a98a268ee99b92c233a0d7187c1f0fa", 526438},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Hoyle 4 (Hoyle Classic Card Games) - English DOS Demo
{"hoyle4", "Demo", {
{"resource.map", 0, "60f764020a6b788bbbe415dbc2ccb9f3", 931},
{"resource.000", 0, "5fe3670e3ddcd4f85c10013b5453141a", 615522},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Hoyle 4 (Hoyle Classic Card Games) - English DOS Demo
// SCI interpreter version 1.001.200 (just a guess)
@@ -987,7 +997,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "662087cb383e52e3cc4ae7ecb10e20aa", 938},
{"resource.000", 0, "24c10844792c54d476d272213cbac300", 675252},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Hoyle 4 (Hoyle Classic Card Games) - English DOS/Win
// Supplied by abevi in bug report #3039291
@@ -995,7 +1005,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "2b577c975cc8d8d43f61b6a756129fe3", 4352},
{"resource.000", 0, "43e2c15ce436aab611a462ad0603e12d", 2000132},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Hoyle 4 (Hoyle Classic Card Games) - English Macintosh Floppy
// VERSION file reports "2.0"
@@ -1003,7 +1013,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"Data1", 0, "99575fae4579540a314bbedd72d51e8c", 7682887},
{"Data2", 0, "7d4bf5bdf3c02edbf35cb8471c84ec13", 1539134},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformMacintosh, ADGF_MACRESFORK, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformMacintosh, ADGF_MACRESFORK, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Jones in the Fast Lane EGA - English DOS
// SCI interpreter version 1.000.172 (not 100% sure FIXME)
@@ -1012,14 +1022,14 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.001", 0, "bac3ec6cb3e3920984ab0f32becf5163", 202105},
{"resource.002", 0, "b86daa3ba2784d1502da881eedb80d9b", 341771},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Jones in the Fast Lane EGA - English DOS (supplied by EddyDrama in bug report #3038761)
{"jones", "EGA", {
{"resource.map", 0, "8e92cf319180cc8b5b87b2ce93a4fe22", 1602},
{"resource.001", 0, "bac3ec6cb3e3920984ab0f32becf5163", 511528},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Jones in the Fast Lane VGA - English DOS
// SCI interpreter version 1.000.172
@@ -1028,7 +1038,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.001", 0, "bac3ec6cb3e3920984ab0f32becf5163", 313476},
{"resource.002", 0, "b86daa3ba2784d1502da881eedb80d9b", 719747},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Jones in the Fast Lane VGA - English DOS (supplied by omer_mor in bug report #3037054)
// VERSION file reports "1.000.060"
@@ -1036,14 +1046,14 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "db175ab494ab0666f19ab8f2597a8e49", 1602},
{"resource.001", 0, "bac3ec6cb3e3920984ab0f32becf5163", 994487},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Jones in the Fast Lane - English DOS CD
{"jones", "CD", {
{"resource.map", 0, "459f5b04467bc2107aec02f5c4b71b37", 4878},
{"resource.001", 0, "3876da2ce16fb7dea2f5d943d946fa84", 1652150},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_CD, GUIO1(GAMEOPTION_JONES_CDAUDIO) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_CD, GUIO1(GAMEOPTION_JONES_CDAUDIO) },
// Jones in the Fast Lane - English DOS CD
// Same entry as the DOS version above. This one is used for the alternate
@@ -1052,7 +1062,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "459f5b04467bc2107aec02f5c4b71b37", 4878},
{"resource.001", 0, "3876da2ce16fb7dea2f5d943d946fa84", 1652150},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformWindows, ADGF_CD, GUIO4(GUIO_MIDIGM, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_FB01_MIDI, GAMEOPTION_JONES_CDAUDIO) },
+ Common::EN_ANY, Common::kPlatformWindows, ADGF_CD, GUIO4(GUIO_MIDIGM, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_FB01_MIDI, GAMEOPTION_JONES_CDAUDIO) },
// Jones in the Fast Lane - English DOS US CD (alternate version)
// Supplied by collector9 in bug #3614668
@@ -1060,7 +1070,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "4344ff3f796707843b992adec2c87663", 4878},
{"resource.001", 0, "3876da2ce16fb7dea2f5d943d946fa84", 1652062},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_CD, GUIO1(GAMEOPTION_JONES_CDAUDIO) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_CD, GUIO1(GAMEOPTION_JONES_CDAUDIO) },
// Jones in the Fast Lane - English DOS US CD (alternate version)
// Same entry as the DOS version above. This one is used for the alternate
@@ -1069,7 +1079,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "4344ff3f796707843b992adec2c87663", 4878},
{"resource.001", 0, "3876da2ce16fb7dea2f5d943d946fa84", 1652062},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformWindows, ADGF_CD, GUIO4(GUIO_MIDIGM, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_FB01_MIDI, GAMEOPTION_JONES_CDAUDIO) },
+ Common::EN_ANY, Common::kPlatformWindows, ADGF_CD, GUIO4(GUIO_MIDIGM, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_FB01_MIDI, GAMEOPTION_JONES_CDAUDIO) },
// King's Quest 1 SCI Remake - English Amiga (from www.back2roots.org)
// Executable scanning reports "1.003.007"
@@ -1081,7 +1091,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.003", 0, "9ae2a13708d691cd42f9129173c4b39d", 763224},
{"resource.004", 0, "9ae2a13708d691cd42f9129173c4b39d", 820443},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// King's Quest 1 SCI Remake - English DOS Non-Interactive Demo
// Executable scanning reports "S.old.010"
@@ -1089,7 +1099,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "59b13619078bd47011421468959ee5d4", 954},
{"resource.001", 0, "4cfb9040db152868f7cb6a1e8151c910", 296555},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// King's Quest 1 SCI Remake - English DOS (from the King's Quest Collection)
// Executable scanning reports "S.old.010", VERSION file reports "1.000.051"
@@ -1100,7 +1110,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.002", 0, "fed9e0072ffd511d248674e60dee2099", 714062},
{"resource.003", 0, "fed9e0072ffd511d248674e60dee2099", 717478},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// King's Quest 1 SCI Remake - English DOS (supplied by ssburnout in bug report #3049193)
// 1.000.051 9x5.25" (label: INT#9.19.90)
@@ -1114,7 +1124,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.006", 0, "fed9e0072ffd511d248674e60dee2099", 351062},
{"resource.007", 0, "fed9e0072ffd511d248674e60dee2099", 330472},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// King's Quest 4 - English Amiga (from www.back2roots.org)
// Executable scanning reports "1.002.032"
@@ -1127,7 +1137,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.003", 0, "fd16c9c223f7dc5b65f06447615224ff", 683016},
{"resource.004", 0, "3fac034c7d130e055d05bc43a1f8d5f8", 549993},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// King's Quest 4 - English DOS Non-Interactive Demo
// Executable scanning reports "0.000.494"
@@ -1135,7 +1145,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "992ac7cc31d3717fe53818a9bb6d1dae", 594},
{"resource.001", 0, "143e1c14f15ad0fbfc714f648a65f661", 205330},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// King's Quest 4 - English DOS (original boxed release, 3 1/2" disks)
// SCI interpreter version 0.000.247
@@ -1146,7 +1156,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.003", 0, "851a62d00972dc4002f472cc0d84e71d", 683145},
{"resource.004", 0, "851a62d00972dc4002f472cc0d84e71d", 649441},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// King's Quest 4 - English DOS (from the King's Quest Collection)
// Executable scanning reports "0.000.502"
@@ -1158,7 +1168,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.003", 0, "77615c595388acf3d1df8e107bfb6b52", 707591},
{"resource.004", 0, "77615c595388acf3d1df8e107bfb6b52", 479562},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// King's Quest 4 - English DOS (supplied by ssburnout in bug report #3049193)
// 1.006.003 8x5.25" (label: Int.#0.000.502)
@@ -1172,7 +1182,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.006", 0, "6db7de6f93c6ea62dca78abee677f8c0", 324789},
{"resource.007", 0, "6db7de6f93c6ea62dca78abee677f8c0", 334441},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// King's Quest 4 - English DOS
// SCI interpreter version 0.000.274
@@ -1186,7 +1196,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.006", 0, "851a62d00972dc4002f472cc0d84e71d", 333777},
{"resource.007", 0, "851a62d00972dc4002f472cc0d84e71d", 341038},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// King's Quest 4 - English DOS
// SCI interpreter version 0.000.253
@@ -1200,7 +1210,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.006", 0, "0c8566848a76eea19a6d6220914030a7", 337288},
{"resource.007", 0, "0c8566848a76eea19a6d6220914030a7", 343882},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// King's Quest 4 - English Atari ST (double-sided diskettes)
// Game version 1.003.006 (January 12, 1989)
@@ -1213,7 +1223,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.003", 0, "a3cdb4848fb859fdd302976fff56490f", 705074},
{"resource.004", 0, "a3cdb4848fb859fdd302976fff56490f", 478366},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformAtariST, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformAtariST, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// King's Quest 5 - English Amiga (from www.back2roots.org)
// Executable scanning reports "1.004.018"
@@ -1229,7 +1239,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.006", 0, "26c0c25399b6715fec03fc3e12544fe3", 823048},
{"resource.007", 0, "b914b5901e786327213e779725d30dd1", 778772},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// King's Quest 5 - German Amiga (also includes english language)
// Executable scanning reports "1.004.024"
@@ -1245,7 +1255,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.006", 0, "56546b20db11a4836f900efa6d3a3e74", 672099},
{"resource.007", 0, "56546b20db11a4836f900efa6d3a3e74", 794194},
AD_LISTEND},
- Common::DE_DEU, Common::kPlatformAmiga, ADGF_ADDENGLISH, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::DE_DEU, Common::kPlatformAmiga, ADGF_ADDENGLISH, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// King's Quest 5 - Italian Amiga (also includes english language)
// Executable scanning reports "1.004.024"
@@ -1261,7 +1271,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.006", 0, "11cb750f5f816445ad0f4b9f50a4f59a", 672527},
{"resource.007", 0, "11cb750f5f816445ad0f4b9f50a4f59a", 794259},
AD_LISTEND},
- Common::IT_ITA, Common::kPlatformAmiga, ADGF_ADDENGLISH, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::IT_ITA, Common::kPlatformAmiga, ADGF_ADDENGLISH, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// King's Quest 5 - English DOS CD (from the King's Quest Collection)
// Executable scanning reports "x.yyy.zzz", VERSION file reports "1.000.052"
@@ -1271,7 +1281,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.000", 0, "449471bfd77be52f18a3773c7f7d843d", 571368},
{"resource.001", 0, "b45a581ff8751e052c7e364f58d3617f", 16800210},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_CD, GUIO3(GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_CD, GUIO3(GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// King's Quest 5 - English DOS CD (from the King's Quest Collection)
// Executable scanning reports "x.yyy.zzz", VERSION file reports "1.000.052"
@@ -1283,7 +1293,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.000", 0, "449471bfd77be52f18a3773c7f7d843d", 571368},
{"resource.001", 0, "b45a581ff8751e052c7e364f58d3617f", 16800210},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformWindows, ADGF_CD, GUIO4(GUIO_MIDIGM, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformWindows, ADGF_CD, GUIO4(GUIO_MIDIGM, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// King's Quest 5 - English DOS Floppy
// SCI interpreter version 1.000.060
@@ -1298,7 +1308,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.006", 0, "672ede1136e9e401658538e51bd5dc22", 1172619},
{"resource.007", 0, "2f48faf27666b58c276dda20f91f4a93", 1240456},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// King's Quest 5 - English DOS Floppy
// VERSION file reports "0.000.051"
@@ -1316,7 +1326,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.006", 0, "da82e4beb744731d0a151f1d4922fafa", 1170456},
{"resource.007", 0, "431def14ca29cdb5e6a5e84d3f38f679", 1240176},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// King's Quest 5 - English DOS Floppy (supplied by omer_mor in bug report #3036996)
// VERSION file reports "0.000.051"
@@ -1331,7 +1341,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.006", 0, "06cb3f689836086ebe08b1efc0126592", 921113},
{"resource.007", 0, "252249753c6e850eacceb8af634986d3", 1133608},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// King's Quest 5 EGA (supplied by markcoolio in bug report #2829470)
// SCI interpreter version 1.000.060
@@ -1347,7 +1357,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.006", 0, "698c698570cde9015e4d51eb8d2e9db1", 666527},
{"resource.007", 0, "703d8df30e89541af337d7706540d5c4", 541743},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// King's Quest 5 EGA 1.2M disk version (from LordHoto)
// VERSION file reports "0.000.055"
@@ -1359,7 +1369,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "53206afb4fd73871a484e83acab80f31", 7608},
{"resource.004", 0, "83568edf7fde18b3eed988bc5d22ceb1", 1188053},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// King's Quest 5 EGA (supplied by omer_mor in bug report #3035421)
// VERSION file reports "0.000.062"
@@ -1374,7 +1384,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.006", 0, "698c698570cde9015e4d51eb8d2e9db1", 666541},
{"resource.007", 0, "703d8df30e89541af337d7706540d5c4", 541762},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// King's Quest V DOS 0.000.062 EGA (5 x 5.25" disks)
// Supplied by ssburnout in bug report #3046780
@@ -1386,7 +1396,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.003", 0, "3cca5b2dae8afe94532edfdc98d7edbe", 1092325},
{"resource.004", 0, "8e5c1bc4d738cf7316ff506f59d265e2", 1187803},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// King's Quest 5 DOS Spanish Floppy 0.000.062 VGA (5 x 3.5" disks)
// Supplied by dianiu in bug report #3555646
@@ -1401,7 +1411,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.006", 0, "65b520e60c4217e6a6572d9edf77193b", 1141985},
{"resource.007", 0, "f42b0100f0a1c30806814f8648b6bc28", 1145583},
AD_LISTEND},
- Common::ES_ESP, Common::kPlatformDOS, ADGF_ADDENGLISH, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::ES_ESP, Common::kPlatformDOS, ADGF_ADDENGLISH, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// King's Quest 5 - German DOS Floppy (supplied by markcoolio in bug report #2727101, also includes english language)
// SCI interpreter version 1.000.060
@@ -1416,7 +1426,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.006", 0, "d1a75fdc01840664d00366cff6919366", 1208972},
{"resource.007", 0, "c07494f0cce7c05210893938786a955b", 1337361},
AD_LISTEND},
- Common::DE_DEU, Common::kPlatformDOS, ADGF_ADDENGLISH, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::DE_DEU, Common::kPlatformDOS, ADGF_ADDENGLISH, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// King's Quest 5 - French DOS Floppy (from the King's Quest Collector's Edition 1994, also includes english language)
// Supplied by aroenai in bug report #2812611
@@ -1432,7 +1442,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.006", 0, "f7dc85307632ef657ceb1651204f6f51", 1210081},
{"resource.007", 0, "7db4d0a1d8d547c0019cb7d2a6acbdd4", 1338473},
AD_LISTEND},
- Common::FR_FRA, Common::kPlatformDOS, ADGF_ADDENGLISH, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::FR_FRA, Common::kPlatformDOS, ADGF_ADDENGLISH, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// King's Quest 5 - Italian DOS Floppy (from glorifindel, includes english language)
// SCI interpreter version 1.000.060
@@ -1447,7 +1457,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.006", 0, "8eeabd92af71e766e323db2100879102", 1209325},
{"resource.007", 0, "dc10c107e0923b902326a040b9c166b9", 1337859},
AD_LISTEND},
- Common::IT_ITA, Common::kPlatformDOS, ADGF_ADDENGLISH, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::IT_ITA, Common::kPlatformDOS, ADGF_ADDENGLISH, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// King's Quest 5 - Polish DOS Floppy (supplied by jacek909 in bug report #2725722)
// SCI interpreter version 1.000.060
@@ -1465,7 +1475,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.007", 0, "431def14ca29cdb5e6a5e84d3f38f679", 1240176},
{"text.000", 0, "601aa35a3ddeb558e1280e0963e955a2", 1517},
AD_LISTEND},
- Common::PL_POL, Common::kPlatformDOS, ADGF_ADDENGLISH, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::PL_POL, Common::kPlatformDOS, ADGF_ADDENGLISH, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// King's Quest 5 - English Macintosh
// VERSION file reports "1.000.055"
@@ -1480,7 +1490,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.006", 0, "3d22904a374c192f51e5665b74364133", 1264079},
{"resource.007", 0, "ffe17e23d5833a79f3695addfc149a56", 1361965},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformMacintosh, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformMacintosh, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// King's Quest 5 - FM-Towns (supplied by abevi in bug report #3038720)
{"kq5", "", {
@@ -1488,7 +1498,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.000", 0, "71afd220d46bde1109c58e6acc0f3a01", 469094},
{"resource.001", 0, "72a569f46f1abf2d9d2b1526ad3799c3", 12808839},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformFMTowns, 0, GUIO2(GUIO_NOASPECT, GUIO_MIDITOWNS) },
+ Common::EN_ANY, Common::kPlatformFMTowns, 0, GUIO2(GUIO_NOASPECT, GUIO_MIDITOWNS) },
{"kq5", "", {
{"resource.map", 0, "20c7cd248ff1a349ed354568eebd972b", 12733},
{"resource.000", 0, "71afd220d46bde1109c58e6acc0f3a01", 469094},
@@ -1506,7 +1516,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.004", 0, "e114ce8f884601c43308fb5cbbea4874", 1174129},
{"resource.005", 0, "349ad9438172265d00680075c5a988d0", 1019669},
AD_LISTEND},
- Common::JA_JPN, Common::kPlatformPC98, ADGF_ADDENGLISH, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::JA_JPN, Common::kPlatformPC98, ADGF_ADDENGLISH, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// King's Quest 6 - English DOS Non-Interactive Demo
// Executable scanning reports "1.001.055", VERSION file reports "1.000.000"
@@ -1516,7 +1526,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.000", 0, "535b1b920441ec73f42eaa4ccfd47b89", 264116},
{"resource.msg", 0, "54d1fdc936f98c81f9e4c19e04fb1510", 8260},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ 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 Floppy
// SCI interpreter version 1.001.054
@@ -1525,7 +1535,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.000", 0, "f2b7f753992c56a0c7a08d6a5077c895", 7863324},
{"resource.msg", 0, "3cf5de44de36191f109d425b8450efc8", 258590},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// King's Quest 6 - French DOS Floppy (supplied by misterhands in bug #3503425)
// SCI interpreter version ???
@@ -1534,7 +1544,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.000", 0, "f2b7f753992c56a0c7a08d6a5077c895", 7863324},
{"resource.msg", 0, "adc2aa8adbdcc97507d44a6f492fbd77", 265194},
AD_LISTEND},
- Common::FR_FRA, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::FR_FRA, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// King's Quest 6 - German DOS Floppy (supplied by markcoolio in bug report #2727156)
// SCI interpreter version 1.001.054
@@ -1543,7 +1553,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.000", 0, "f2b7f753992c56a0c7a08d6a5077c895", 7863324},
{"resource.msg", 0, "756297b2155db9e43f621c6f6fb763c3", 282822},
AD_LISTEND},
- Common::DE_DEU, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::DE_DEU, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// King's Quest 6 - Spanish DOS Floppy (from jvprat)
// Executable scanning reports "1.cfs.158", VERSION file reports "1.000.000, July 5, 1994"
@@ -1553,7 +1563,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.000", 0, "4da3ad5868a775549a7cc4f72770a58e", 8537260},
{"resource.msg", 0, "41eed2d3893e1ca6c3695deba4e9d2e8", 267102},
AD_LISTEND},
- Common::ES_ESP, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::ES_ESP, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// King's Quest 6 - Italian DOS Floppy (supplied by guybrush79 in bug report #3606719)
{"kq6", "", {
@@ -1561,7 +1571,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.000", 0, "d3358ba7306378aed83d02b5c3f11311", 8531908},
{"resource.msg", 0, "b7e8220be596fd6a9287eae5a8fd354a", 279886},
AD_LISTEND},
- Common::IT_ITA, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::IT_ITA, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// King's Quest 6 - English DOS CD (from the King's Quest Collection)
// Executable scanning reports "1.cfs.158", VERSION file reports "1.034 9/11/94 - KQ6 version 1.000.00G"
@@ -1570,7 +1580,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "7a550ebfeae2575ca00d47703a6a774c", 9215},
{"resource.000", 0, "233394a5f33b475ae5975e7e9a420865", 8376352},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_CD, GUIO3(GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_CD, GUIO3(GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// King's Quest 6 - English Windows CD (from the King's Quest Collection)
// Executable scanning reports "1.cfs.158", VERSION file reports "1.034 9/11/94 - KQ6 version 1.000.00G"
@@ -1579,7 +1589,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "7a550ebfeae2575ca00d47703a6a774c", 9215},
{"resource.000", 0, "233394a5f33b475ae5975e7e9a420865", 8376352},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformWindows, ADGF_CD, GUIO5(GUIO_NOASPECT, GAMEOPTION_KQ6_WINDOWS_CURSORS, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformWindows, ADGF_CD, GUIO5(GUIO_NOASPECT, GAMEOPTION_KQ6_WINDOWS_CURSORS, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// King's Quest 6 - English Macintosh Floppy
// VERSION file reports "1.0"
@@ -1587,7 +1597,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"Data1", 0, "a183fc0c22fcbd9be4c8800d974b5599", 3892124},
{"Data2", 0, "b3722460dfd3097a1fbaf99a21ad8ea5", 15031272},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformMacintosh, ADGF_MACRESFORK, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformMacintosh, ADGF_MACRESFORK, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
#ifdef ENABLE_SCI32
@@ -1598,7 +1608,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.000", 0, "4948e4e1506f1e1c4e1d47abfa06b7f8", 204385195},
{"resource.map", 0, "40ccafb2195301504eba2e4f4f2c7f3d", 18925},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// King's Quest 7 - English Windows (from the King's Quest Collection)
// Executable scanning reports "2.100.002", VERSION file reports "1.4"
@@ -1606,7 +1616,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "2be9ab94429c721af8e05c507e048a15", 18697},
{"resource.000", 0, "eb63ea3a2c2469dc2d777d351c626404", 203882535},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// King's Quest 7 - English DOS (from FRG)
// SCI interpreter version 2.100.002, VERSION file reports "2.00b"
@@ -1614,7 +1624,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "8676b0fbbd7362989a029fe72fea14c6", 18709},
{"resource.000", 0, "51c1ead1163e19a2de8f121c39df7a76", 200764100},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// King's Quest 7 - English Windows (from FRG)
// SCI interpreter version 2.100.002, VERSION file reports "2.00b"
@@ -1622,7 +1632,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "8676b0fbbd7362989a029fe72fea14c6", 18709},
{"resource.000", 0, "51c1ead1163e19a2de8f121c39df7a76", 200764100},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// King's Quest 7 - German Windows (supplied by markcoolio in bug report #2727402)
// SCI interpreter version 2.100.002
@@ -1630,7 +1640,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "838b9ff132bd6962026fee832e8a7ddb", 18697},
{"resource.000", 0, "eb63ea3a2c2469dc2d777d351c626404", 206626576},
AD_LISTEND},
- Common::DE_DEU, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::DE_DEU, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// King's Quest 7 - Spanish DOS (from jvprat)
// Executable scanning reports "2.100.002", VERSION file reports "2.00"
@@ -1638,7 +1648,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "0b62693cbe87e3aaca3e8655a437f27f", 18709},
{"resource.000", 0, "51c1ead1163e19a2de8f121c39df7a76", 200764100},
AD_LISTEND},
- Common::ES_ESP, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::ES_ESP, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// King's Quest 7 - English DOS Non-Interactive Demo
// SCI interpreter version 2.100.002
@@ -1646,7 +1656,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "b44f774108d63faa1d021101221c5a54", 1690},
{"resource.000", 0, "d9659d2cf0c269c6a9dc776707f5bea0", 2433827},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO | ADGF_UNSTABLE, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO | ADGF_UNSTABLE, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// King's Quest 7 - English Windows Demo (from DrMcCoy)
// SCI interpreter version 2.100.002
@@ -1654,7 +1664,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "38e627a37a975aea40cc72b0518b0709", 18412},
{"resource.000", 0, "bad61d50aaa64298fa57a7c6ccd3bccf", 84020382},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformWindows, ADGF_DEMO | ADGF_UNSTABLE, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformWindows, ADGF_DEMO | ADGF_UNSTABLE, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// King's Questions mini-game from the King's Quest Collection
// SCI interpreter version 2.000.000
@@ -1662,7 +1672,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.000", 0, "9b1cddecd4f0720d83661ba7aed28891", 162697},
{"resource.map", 0, "93a2251fa64e729d7a7d2fe56b217c8e", 502},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO3(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO3(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_FB01_MIDI) },
#endif // ENABLE_SCI32
@@ -1678,7 +1688,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.004", 0, "aa553977f7e5804081de293800d3bcce", 695067},
{"resource.005", 0, "bfd870d51dc97729f0914095f58e6957", 676881},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Laura Bow - English Atari ST (from jvprat)
// Executable scanning reports "1.002.030", Floppy label reports "1.000.062, 9.23.90"
@@ -1690,7 +1700,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.003", 0, "e45c888d9c7c04aec0a20e9f820b79ff", 667365},
{"resource.004", 0, "e45c888d9c7c04aec0a20e9f820b79ff", 683737},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformAtariST, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformAtariST, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Laura Bow - English DOS Non-Interactive Demo
// Executable scanning reports "x.yyy.zzz"
@@ -1698,7 +1708,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "e625726268ff4e123ada11f31f0249f3", 768},
{"resource.001", 0, "0c8912290af0890f8d95faeb4ddb2d68", 333031},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Laura Bow - English DOS 3.5" Floppy (from "The Roberta Williams Anthology"/1996)
// SCI interpreter version 0.000.631
@@ -1709,7 +1719,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.003", 0, "e45c888d9c7c04aec0a20e9f820b79ff", 667468},
{"resource.004", 0, "e45c888d9c7c04aec0a20e9f820b79ff", 683807},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Laura Bow - English DOS (from FRG)
// SCI interpreter version 0.000.631
@@ -1723,7 +1733,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.006", 0, "e45c888d9c7c04aec0a20e9f820b79ff", 328390},
{"resource.007", 0, "e45c888d9c7c04aec0a20e9f820b79ff", 317687},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Laura Bow 2 - English DOS Non-Interactive Demo (from FRG)
// Executable scanning reports "x.yyy.zzz"
@@ -1732,7 +1742,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "24dffc5db1d88c7999f13e8767ed7346", 855},
{"resource.000", 0, "2b2b1b4f7584f9b38fd13f6ab95634d1", 781912},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Laura Bow 2 - English DOS Floppy
// Executable scanning reports "2.000.274"
@@ -1741,7 +1751,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "610bfd9a852004222f0faaf5fc9e630a", 6489},
{"resource.000", 0, "57084910bc923bff5d6d9bc1b56e9604", 5035964},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Laura Bow 2 - English DOS CD (from "The Roberta Williams Antology"/1996)
// Executable scanning reports "1.001.072", VERSION file reports "1.1" (from jvprat)
@@ -1750,7 +1760,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "a70945e61ba7ac7bfea6b7bd72c6aec5", 7274},
{"resource.000", 0, "82578b8d5a7e09c4c58891ca49fae35b", 5598672},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_CD, GUIO3(GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_CD, GUIO3(GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Laura Bow 2 v1.1 - French DOS Floppy (from Hkz)
{"laurabow2", "", {
@@ -1758,7 +1768,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.000", 0, "57084910bc923bff5d6d9bc1b56e9604", 5028766},
{"resource.msg", 0, "0fceedfbdd85a4bc7851fdd9dd2d2f19", 278253},
AD_LISTEND},
- Common::FR_FRA, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::FR_FRA, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Laura Bow 2 v1.1 - German DOS Floppy (from Tobis87, updated info from markcoolio in bug report #2723787, updated info from #2797962))
// Executable scanning reports "2.000.274"
@@ -1767,7 +1777,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.000", 0, "57084910bc923bff5d6d9bc1b56e9604", 5028766},
{"resource.msg", 0, "795c928cd00dfec9fbc62ebcd12e1f65", 303185},
AD_LISTEND},
- Common::DE_DEU, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::DE_DEU, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Laura Bow 2 - Spanish DOS CD (from jvprat)
// Executable scanning reports "2.000.274", VERSION file reports "1.000.000, May 10, 1994"
@@ -1776,7 +1786,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.000", 0, "57084910bc923bff5d6d9bc1b56e9604", 5028766},
{"resource.msg", 0, "71f1f0cd9f082da2e750c793a8ed9d84", 286141},
AD_LISTEND},
- Common::ES_ESP, Common::kPlatformDOS, ADGF_CD, GUIO3(GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::ES_ESP, Common::kPlatformDOS, ADGF_CD, GUIO3(GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Larry 1 EGA Remake - English DOS (from spookypeanut)
// SCI interpreter version 0.000.510 (or 0.000.577?)
@@ -1787,7 +1797,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.002", 0, "24c958bc922b07f91e25e8c93aa01fcf", 491230},
{"resource.003", 0, "685cd6c1e05a695ab1e0db826337ee2a", 553279},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
#if 0
// The resource.002 file, contained in disk 3, is broken in this version
@@ -1805,7 +1815,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.002", 0, "5790ac0505f7ca98d4567132b875eb1e", 681041},
{"resource.003", 0, "4a34c3367c2fe7eb380d741374da1989", 572251},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
#endif
// Larry 1 VGA Remake - English DOS (from spookypeanut)
@@ -1816,7 +1826,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.001", 0, "ec20246209d7b19f38989261e5c8f5b8", 1111226},
{"resource.002", 0, "85d6935ef77e6b0e16bc307640a0d913", 1088312},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Larry 1 VGA Remake - English DOS (from FRG)
// SCI interpreter version 1.000.510
@@ -1826,7 +1836,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.001", 0, "d34cadb11e1aefbb497cf91bc1d3baa7", 1114688},
{"resource.002", 0, "85b030bb66d5342b0a068f1208c431a8", 1078443},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Larry 1 VGA Remake - English Macintosh (from omer_mor, bug report #3328262)
{"lsl1sci", "SCI", {
@@ -1835,7 +1845,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.001", 0, "aa6f153f70f1e32d1bde465fff08eecf", 1137418},
{"resource.002", 0, "b22c616aa789ebef990290c7ffd86548", 1097477},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformMacintosh, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformMacintosh, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Larry 1 VGA Remake - English DOS Non-Interactive Demo
// SCI interpreter version 1.000.084
@@ -1843,7 +1853,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "434e1f6c39d71647b34f0ee57b2bbd68", 444},
{"resource.001", 0, "0c0768215c562d9dace4a5ca53696cf3", 359913},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Larry 1 VGA Remake - Spanish DOS (from the Leisure Suit Larry Collection, also includes english language)
// Executable scanning reports "1.SQ4.057", VERSION file reports "1.000"
@@ -1856,7 +1866,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.002", 0, "3fe2a3aec0ed53c7d6db1845a67e3aa2", 1095908},
{"resource.003", 0, "ac175df0ea9a2cba57f0248651856d27", 376556},
AD_LISTEND},
- Common::ES_ESP, Common::kPlatformDOS, ADGF_ADDENGLISH, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::ES_ESP, Common::kPlatformDOS, ADGF_ADDENGLISH, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Larry 1 VGA Remake - Russian DOS (also includes english language?!)
// Executable scanning reports "1.000.510", VERSION file reports "2.0"
@@ -1867,7 +1877,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.001", 0, "bc8ca10c807515d959cbd91f9ba47735", 1123759},
{"resource.002", 0, "b7409ab32bc3bee2d6cce887cd33f2b6", 1092160},
AD_LISTEND},
- Common::RU_RUS, Common::kPlatformDOS, ADGF_ADDENGLISH, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::RU_RUS, Common::kPlatformDOS, ADGF_ADDENGLISH, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Larry 1 VGA Remake - Polish DOS (from Polish Leisure Suit Larry Collection, official release)
// SCI interpreter version 1.000.577, VERSION file reports "2.1" (this release does NOT include english text)
@@ -1875,7 +1885,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "58330a85767e42a2487129913283ab5b", 3228},
{"resource.000", 0, "b6097ff35cdc8469f02150fe2f824198", 4781210},
AD_LISTEND},
- Common::PL_POL, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::PL_POL, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Larry 2 - English Amiga (from www.back2roots.org)
// Executable scanning reports "x.yyy.zzz"
@@ -1887,7 +1897,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.003", 0, "a0d4a625311d307257da7fc43d00459d", 570356},
{"resource.004", 0, "a0d4a625311d307257da7fc43d00459d", 717844},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Larry 2 - English DOS Non-Interactive Demo
// Executable scanning reports "x.yyy.zzz"
@@ -1896,7 +1906,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "03dba704bb77da55a91ad27b5a3cac09", 528},
{"resource.001", 0, "9f5520f0297206928df0b0b36493cd33", 127532},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Larry 2 - English DOS
// SCI interpreter version 0.000.409
@@ -1909,7 +1919,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.005", 0, "4a24443a25e2b1492462a52809605dc2", 277732},
{"resource.006", 0, "4a24443a25e2b1492462a52809605dc2", 345683},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Larry 2 - English DOS
// SCI interpreter version 0.000.343
@@ -1924,7 +1934,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
//{"resource.006", 0, "96033f57accfca903750413fd09193c8", 345818},
{"resource.006", 0, "96033f57accfca903750413fd09193c8", -1}, // 345818 or 208739
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Larry 2 - English DOS (supplied by ssburnout in bug report #3049193)
// 1.000.011 3x3.5" (label: Int. #0.000.343)
@@ -1934,7 +1944,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.002", 0, "96033f57accfca903750413fd09193c8", 407014},
{"resource.003", 0, "96033f57accfca903750413fd09193c8", 592834},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Larry 2 - English DOS (supplied by ssburnout in bug report #3049193)
// 1.002.000 3x3.5" (label: INT#0.000.409)
@@ -1944,7 +1954,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.002", 0, "4a24443a25e2b1492462a52809605dc2", 406935},
{"resource.003", 0, "4a24443a25e2b1492462a52809605dc2", 592533},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Larry 3 - English Amiga (from www.back2roots.org)
// Executable scanning reports "1.002.032"
@@ -1958,7 +1968,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.004", 0, "f408e59cbee1457f042e5773b8c53951", 651634},
{"resource.005", 0, "433911eb764089d493aed1f958a5615a", 524259},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Larry 3 - English DOS (supplied by ssburnout in bug report #3049193)
// 1.021 8x5.25" (label: Int#5.15.90)
@@ -1972,7 +1982,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.006", 0, "f18441027154292836b973c655fa3175", 282649},
{"resource.007", 0, "f18441027154292836b973c655fa3175", 257178},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Larry 3 - English DOS
// SCI interpreter version 0.000.572
@@ -1986,7 +1996,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.006", 0, "f18441027154292836b973c655fa3175", 282465},
{"resource.007", 0, "f18441027154292836b973c655fa3175", 257174},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Larry 3 - English DOS
// SCI interpreter version 0.000.572
@@ -1997,7 +2007,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.003", 0, "f18441027154292836b973c655fa3175", 506807},
{"resource.004", 0, "f18441027154292836b973c655fa3175", 513651},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Larry 3 - English DOS (supplied by kervala in bug report #3611488)
{"lsl3", "", {
@@ -2007,7 +2017,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.003", 0, "f18441027154292836b973c655fa3175", 506817},
{"resource.004", 0, "f18441027154292836b973c655fa3175", 513337},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Larry 3 - English DOS Non-Interactive Demo
// SCI interpreter version 0.000.530
@@ -2016,7 +2026,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.001", 0, "f773d79b93dfd4052ec8c1cc64c1e6ab", 76525},
{"resource.002", 0, "f773d79b93dfd4052ec8c1cc64c1e6ab", 268299},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Larry 3 - German DOS (from Tobis87, updated info from markcoolio in bug report #2723832, also includes english language)
// Executable scanning reports "S.old.123"
@@ -2028,7 +2038,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.003", 0, "3827a9b17b926e12dcc336860f50612a", 587036},
{"resource.004", 0, "3827a9b17b926e12dcc336860f50612a", 691932},
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) },
+ 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"
@@ -2040,7 +2050,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.003", 0, "65f1bdaa20f6d0470e9d969f22473873", 586921},
{"resource.004", 0, "65f1bdaa20f6d0470e9d969f22473873", 690826},
AD_LISTEND},
- Common::FR_FRA, Common::kPlatformDOS, ADGF_ADDENGLISH, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::FR_FRA, Common::kPlatformDOS, ADGF_ADDENGLISH, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Larry 3 1.050 Fr/En (9 x 5.25" disks)
// Provided by ssburnout in bug report #3046779
@@ -2054,7 +2064,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.006", 0, "65f1bdaa20f6d0470e9d969f22473873", 325292},
{"resource.007", 0, "65f1bdaa20f6d0470e9d969f22473873", 308982},
AD_LISTEND},
- Common::FR_FRA, Common::kPlatformDOS, ADGF_ADDENGLISH, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::FR_FRA, Common::kPlatformDOS, ADGF_ADDENGLISH, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Larry 5 - English Amiga
// Executable scanning reports "1.004.023"
@@ -2069,7 +2079,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.005", 0, "f8b2d1137bb767e5d232056b99dd69eb", 623621},
{"resource.006", 0, "bafc64e3144f115dc58c6aee02de98fb", 715598},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Larry 5 - German Amiga (also includes english language)
// Executable scanning reports "1.004.024"
@@ -2085,7 +2095,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.006", 0, "bafc64e3144f115dc58c6aee02de98fb", 754966},
{"resource.007", 0, "59eba83ad465b08d763b44f86afa86f6", 683135},
AD_LISTEND},
- Common::DE_DEU, Common::kPlatformAmiga, ADGF_ADDENGLISH, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::DE_DEU, Common::kPlatformAmiga, ADGF_ADDENGLISH, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Larry 5 - English DOS Non-Interactive Demo (from FRG)
// SCI interpreter version 1.000.181
@@ -2093,7 +2103,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "efe8d3f45ce4f6bd9a6643e0ac8d2a97", 504},
{"resource.001", 0, "8bd8d9c0b5f455ee1269d63ce86c50dd", 531380},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Larry 5 - English DOS (from spookypeanut)
// SCI interpreter version 1.000.510
@@ -2108,7 +2118,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.006", 0, "dda27ce00682aa76198dac124bbbe334", 1024810},
{"resource.007", 0, "ac443fae1285fb359bf2b2bc6a7301ae", 1030656},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Larry 5 - English Macintosh (from omer_mor, bug report #3328257)
{"lsl5", "", {
@@ -2122,7 +2132,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.006", 0, "dda27ce00682aa76198dac124bbbe334", 1110043},
{"resource.007", 0, "ac443fae1285fb359bf2b2bc6a7301ae", 989801},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformMacintosh, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformMacintosh, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Larry 5 - German DOS (from Tobis87)
// SCI interpreter version T.A00.196
@@ -2137,7 +2147,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.006", 0, "dda27ce00682aa76198dac124bbbe334", 1021774},
{"resource.007", 0, "ac443fae1285fb359bf2b2bc6a7301ae", 993408},
AD_LISTEND},
- Common::DE_DEU, Common::kPlatformDOS, ADGF_ADDENGLISH, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::DE_DEU, Common::kPlatformDOS, ADGF_ADDENGLISH, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Larry 5 - French DOS (provided by richiefs in bug report #2670691)
// Executable scanning reports "1.lsl5.019"
@@ -2153,7 +2163,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.006", 0, "dda27ce00682aa76198dac124bbbe334", 946540},
{"resource.007", 0, "ac443fae1285fb359bf2b2bc6a7301ae", 958842},
AD_LISTEND},
- Common::FR_FRA, Common::kPlatformDOS, ADGF_ADDENGLISH, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::FR_FRA, Common::kPlatformDOS, ADGF_ADDENGLISH, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Larry 5 - Spanish DOS (from the Leisure Suit Larry Collection)
// Executable scanning reports "1.ls5.006", VERSION file reports "1.000, 4/21/92"
@@ -2169,7 +2179,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.006", 0, "dda27ce00682aa76198dac124bbbe334", 1015136},
{"resource.007", 0, "ac443fae1285fb359bf2b2bc6a7301ae", 987222},
AD_LISTEND},
- Common::ES_ESP, Common::kPlatformDOS, ADGF_ADDENGLISH, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::ES_ESP, Common::kPlatformDOS, ADGF_ADDENGLISH, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Larry 5 - Italian DOS Floppy (from glorifindel)
// SCI interpreter version 1.000.510 (just a guess)
@@ -2177,7 +2187,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "a99776df795127f387cb35dae872d4e4", 5919},
{"resource.000", 0, "a8989a5a89e7d4f702b26b378c7a357a", 7001981},
AD_LISTEND},
- Common::IT_ITA, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::IT_ITA, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Larry 5 1.0 EGA DOS (8 x 3.5" disks)
// Provided by ssburnout in bug report #3046806
@@ -2192,7 +2202,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.006", 0, "f6046a8445422f17d40b1b10ab21ebf3", 568551},
{"resource.007", 0, "640ee65595d40372ef95462f2c1ae28a", 593429},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Larry 5 EGA
// Supplied by omer_mor in bug report #3049771
@@ -2203,7 +2213,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.002", 0, "5a55af4e40728b1a8103dc47ad2afa8d", 1100539},
{"resource.003", 0, "16f4d8fb1b526125edaca4fc6cbb7530", 1064563},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Larry 6 - English DOS (from spookypeanut)
// SCI interpreter version 1.001.113
@@ -2211,7 +2221,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "bb8a39d9e2a77ba449a1e591109ad9a8", 6973},
{"resource.000", 0, "4462fe48c7452d98fddcec327a3e738d", 5789138},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Larry 6 - English/German/French DOS CD - LOWRES
// SCI interpreter version 1.001.115
@@ -2219,7 +2229,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "0b91234b7112782962cb480b7791b6e2", 7263},
{"resource.000", 0, "57d5fe8bb9e044158514476ea7678eb0", 5754790},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_CD, GUIO3(GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_CD, GUIO3(GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Larry 6 - German DOS CD - LOWRES (provided by richiefs in bug report #2670691)
// SCI interpreter version 1.001.115
@@ -2227,7 +2237,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "bafe85f32738854135991d4324ad147e", 7268},
{"resource.000", 0, "f6cbc6da7b90ea135883e0759848ca2c", 5773160},
AD_LISTEND},
- Common::DE_DEU, Common::kPlatformDOS, ADGF_CD, GUIO3(GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::DE_DEU, Common::kPlatformDOS, ADGF_CD, GUIO3(GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Larry 6 - French DOS CD - LOWRES (provided by richiefs in bug report #2670691)
// SCI interpreter version 1.001.115
@@ -2235,7 +2245,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "97797ea775baaf18a1907d357d3c0ea6", 7268},
{"resource.000", 0, "f6cbc6da7b90ea135883e0759848ca2c", 5776092},
AD_LISTEND},
- Common::FR_FRA, Common::kPlatformDOS, ADGF_CD, GUIO3(GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::FR_FRA, Common::kPlatformDOS, ADGF_CD, GUIO3(GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Larry 6 - Spanish DOS - LOWRES (from the Leisure Suit Larry Collection)
// Executable scanning reports "1.001.113", VERSION file reports "1.000, 11.06.93, FIVE PATCHES ADDED TO DISK 6 ON 11-18-93"
@@ -2243,7 +2253,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "633bf8f42170b6271019917c8009989b", 6943},
{"resource.000", 0, "7884a8db9253e29e6b37a2651fd90ba3", 5733116},
AD_LISTEND},
- Common::ES_ESP, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::ES_ESP, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Crazy Nick's Software Picks: Leisure Suit Larry's Casino - English DOS (from the Leisure Suit Larry Collection)
// Executable scanning reports "1.001.029", VERSION file reports "1.000"
@@ -2251,35 +2261,35 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "194f1578f2624db813c9072359ad1639", 783},
{"resource.001", 0, "3733433b517ec3d14a3331d9ab3842ae", 344830},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Crazy Nick's Software Picks: King Graham's Board Game Challenge
{"cnick-kq", "", {
{"resource.map", 0, "44bc538a5cd24b39ffccc967c0ebf84d", 1137},
{"resource.001", 0, "470e7a4a3504635e70b623c44461e1ac", 451272},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Crazy Nick's Software Picks: Parlor Games with Laura Bow
{"cnick-laurabow", "", {
{"resource.map", 0, "3b826bfe64f8ff1ccf30eef93cd2f727", 999},
{"resource.001", 0, "985ac8db6f636f2b4334c04b0fbb44fb", 336698},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Crazy Nick's Software Picks: Robin Hood's Game of Skill and Chance
{"cnick-longbow", "", {
{"resource.map", 0, "4a5c81f485a2416bde12978506f2fb5f", 897},
{"resource.001", 0, "ef16dc9e867eb8eeb5b13e110b90bd4b", 571466},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Crazy Nick's Software Picks: Roger Wilco's Spaced Out Game Pack
{"cnick-sq", "", {
{"resource.map", 0, "b4d95b02d84e297441bd999d34eaa6b1", 879},
{"resource.001", 0, "82ff2b64a60117886fbcd6a3a8c977c6", 364921},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
#ifdef ENABLE_SCI32
// Larry 6 - English/German DOS CD - HIRES
@@ -2288,7 +2298,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "0c0804434ea62278dd15032b1947426c", 8872},
{"resource.000", 0, "9a9f4870504444cda863dd14d077a680", 18520872},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Larry 6 - German DOS CD - HIRES (provided by richiefs in bug report #2670691)
// SCI interpreter version 2.100.002
@@ -2296,7 +2306,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "badfdf446ffed569a310d2c63a249421", 8896},
{"resource.000", 0, "bd944d2b06614a5b39f1586906f0ee88", 18534274},
AD_LISTEND},
- Common::DE_DEU, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::DE_DEU, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Larry 6 - French DOS CD - HIRES (provided by richiefs in bug report #2670691)
// SCI interpreter version 2.100.002
@@ -2304,7 +2314,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "d184e9aa4f2d4b5670ddb3669db82cda", 8896},
{"resource.000", 0, "bd944d2b06614a5b39f1586906f0ee88", 18538987},
AD_LISTEND},
- Common::FR_FRA, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::FR_FRA, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Larry 7 - English DOS Demo (provided by richiefs in bug report #2670691)
// SCI interpreter version 2.100.002
@@ -2312,7 +2322,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"ressci.000", 0, "5cc6159688b2dc03790a67c90ccc67f9", 10195878},
{"resmap.000", 0, "6a2b2811eef82e87cde91cf1de845af8", 2695},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO | ADGF_UNSTABLE, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO | ADGF_UNSTABLE, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
#ifdef ENABLE_SCI3_GAMES
// Larry 7 - English DOS CD (from spookypeanut)
@@ -2321,7 +2331,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resmap.000", 0, "eae93e1b1d1ccc58b4691c371281c95d", 8188},
{"ressci.000", 0, "89353723488219e25589165d73ed663e", 66965678},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Larry 7 - German DOS (from Tobis87)
// SCI interpreter version 3.000.000
@@ -2329,7 +2339,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resmap.000", 0, "c11e6bfcfc2f2d05da47e5a7df3e9b1a", 8188},
{"ressci.000", 0, "a8c6817bb94f332ff498a71c8b47f893", 66971724},
AD_LISTEND},
- Common::DE_DEU, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::DE_DEU, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Larry 7 - French DOS (provided by richiefs in bug report #2670691)
// SCI interpreter version 3.000.000
@@ -2337,7 +2347,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resmap.000", 0, "4407849fd52fe3efb0c30fba60cd5cd4", 8206},
{"ressci.000", 0, "dc37c3055fffbefb494ff22b145d377b", 66964472},
AD_LISTEND},
- Common::FR_FRA, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::FR_FRA, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Larry 7 - Italian DOS CD (from glorifindel)
// SCI interpreter version 3.000.000
@@ -2345,7 +2355,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resmap.000", 0, "9852a97141f789413f29bf956052acdb", 8212},
{"ressci.000", 0, "440b9fed89590abb4e4386ed6f948ee2", 67140181},
AD_LISTEND},
- Common::IT_ITA, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::IT_ITA, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Larry 7 - Spanish DOS (from the Leisure Suit Larry Collection)
// Executable scanning reports "3.000.000", VERSION file reports "1.0s"
@@ -2353,7 +2363,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resmap.000", 0, "8f3d603e1acc834a5d598b30cdfc93f3", 8188},
{"ressci.000", 0, "32792f9bc1bf3633a88b382bb3f6e40d", 67071418},
AD_LISTEND},
- Common::ES_ESP, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::ES_ESP, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
#endif
// Lighthouse - English Windows Demo (from jvprat)
@@ -2362,7 +2372,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "543124606352bfa5e07696ddf2a669be", 64},
{"resource.000", 0, "5d7714416b612463d750fb9c5690c859", 28952},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO | ADGF_UNSTABLE, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO | ADGF_UNSTABLE, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
#ifdef ENABLE_SCI3_GAMES
// Lighthouse - English Windows Demo
@@ -2371,7 +2381,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resmap.000", 0, "3bdee7a16926975a4729f75cf6b80a92", 1525},
{"ressci.000", 0, "3c585827fa4a82f4c04a56a0bc52ccee", 11494351},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO | ADGF_UNSTABLE, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO | ADGF_UNSTABLE, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Lighthouse - English DOS (from jvprat)
// Executable scanning reports "3.000.000", VERSION file reports "1.1"
@@ -2381,7 +2391,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resmap.002", 0, "c68db5333f152fea6ca2dfc75cad8b34", 7573},
{"ressci.002", 0, "175468431a979b9f317c294ce3bc1430", 94628315},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Lighthouse - Spanish DOS (from jvprat)
// Executable scanning reports "3.000.000", VERSION file reports "1.1"
@@ -2391,7 +2401,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resmap.002", 0, "e7dc85884a2417e2eff9de0c63dd65fa", 7630},
{"ressci.002", 0, "3c8d627c555b0e3e4f1d9955bc0f0df4", 94631127},
AD_LISTEND},
- Common::ES_ESP, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::ES_ESP, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
#endif // ENABLE_SCI3_GAMES
#endif // ENABLE_SCI32
@@ -2402,7 +2412,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.000", 0, "8be56a3a88c065ee00c02c0e29199f3a", 14643},
{"resource.001", 0, "9e33566515b18bee7915db448063bba2", 871853},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Mixed-Up Fairy Tales - English DOS Floppy EGA (from omer_mor, bug report #3035350)
{"fairytales", "EGA", {
@@ -2413,7 +2423,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.003", 0, "509b2467ba779100d5933ed51a9ae32f", 560255},
{"resource.004", 0, "93afc85d5ffa60ea555d6cc336d22c03", 651109},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Mixed-Up Fairy Tales v1.000 - English DOS (supplied by markcoolio in bug report #2723791)
// Executable scanning reports "1.000.145"
@@ -2425,7 +2435,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.003", 0, "b1288e0821ee358d1ffe877e5900c8ec", 1047565},
{"resource.004", 0, "f79daa70390d73746742ffcfc3dc4471", 937580},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Mixed-Up Fairy Tales - English DOS Floppy (from jvprat)
// Executable scanning reports "1.000.145", Floppy label reports "1.0, 11.13.91", VERSION file reports "1.000"
@@ -2436,7 +2446,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.002", 0, "564f516d991032e781492592a4eaa275", 1414142},
{"resource.003", 0, "dd6cef0c592eadb7e6be9a25307c57a2", 1344719},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Mixed-Up Mother Goose - English Amiga (from www.back2roots.org)
// Executable scanning reports "1.003.009"
@@ -2446,7 +2456,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.001", 0, "fb552ae550ca1dac19ed8f6a3767612d", 262885},
{"resource.002", 0, "fb552ae550ca1dac19ed8f6a3767612d", 817191},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Mixed-Up Mother Goose - English DOS Floppy EGA (from omer_mor, bug report #3035354)
{"mothergoose", "EGA", {
@@ -2454,7 +2464,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.001", 0, "d893892d62b3f061357291d66775e360", 239906},
{"resource.002", 0, "d893892d62b3f061357291d66775e360", 719398},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Mixed-Up Mother Goose - English DOS Floppy EGA (supplied by ssburnout in bug report #3049193)
// 1.011 5x5.25" (label: Int#8.2.90)
@@ -2467,7 +2477,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.004", 0, "dbbc22f124533ce308bc386b08956326", 146251},
{"resource.005", 0, "2ba5348e7fad641b9c4c7ff7c7cf4e68", 110979},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Mixed-Up Mother Goose v2.000 - English DOS Floppy (supplied by markcoolio in bug report #2723795)
// Executable scanning reports "1.001.031"
@@ -2475,7 +2485,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "52aae15e493cafd1da7e1c9b657a5bb9", 7026},
{"resource.000", 0, "b7ecd8ae9e254e80310b5a668b276e6e", 2948975},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Mixed-Up Mother Goose - English DOS CD (from jvprat)
// Executable scanning reports "x.yyy.zzz"
@@ -2484,7 +2494,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "1c7f311b0a2c927b2fbe81ae341fb2f6", 5790},
{"resource.001", 0, "5a0ed1d745855148364de1b3be099bac", 4369438},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_CD, GUIO3(GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_CD, GUIO3(GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Mixed-Up Mother Goose - English Windows Interactive Demo
// Executable scanning reports "x.yyy.zzz"
@@ -2492,19 +2502,19 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "87f9dc1cafc4d4fa835fb2f00cf3a6ef", 4560},
{"resource.001", 0, "5a0ed1d745855148364de1b3be099bac", 2070072},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformWindows, ADGF_DEMO, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformWindows, ADGF_DEMO, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Mixed-Up Mother Goose - FM-Towns (supplied by abevi in bug report #3038720)
{"mothergoose256", "", {
{"resource.map", 0, "b11e971ccd2040bebba59dfb409a08ef", 5772},
{"resource.001", 0, "d49625d9b8005ec01c852f8322a82867", 4330713},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformFMTowns, 0, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformFMTowns, 0, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
{"mothergoose256", "", {
{"resource.map", 0, "b11e971ccd2040bebba59dfb409a08ef", 5772},
{"resource.001", 0, "d49625d9b8005ec01c852f8322a82867", 4330713},
AD_LISTEND},
- Common::JA_JPN, Common::kPlatformFMTowns, 0, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::JA_JPN, Common::kPlatformFMTowns, 0, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
#ifdef ENABLE_SCI32
// Mixed-Up Mother Goose Deluxe - English Windows/DOS CD (supplied by markcoolio in bug report #2723810)
@@ -2513,7 +2523,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "5159a1578c4306bfe070a3e4d8c2e1d3", 4741},
{"resource.000", 0, "1926925c95d82f0999590e93b02887c5", 15150768},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Mixed-Up Mother Goose Deluxe - Multilingual Windows CD (English/French/German/Spanish)
// Executable scanning reports "2.100.002"
@@ -2521,7 +2531,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resmap.000", 0, "ef611af561898dcfea87846919ebf3eb", 4969},
{"ressci.000", 0, "227685bc59d90821978d330713e44a7a", 17205800},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
#endif // ENABLE_SCI32
// Ms. Astro Chicken - English DOS
@@ -2530,7 +2540,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "5b457cbe5042f557e5b610148171f6c0", 1158},
{"resource.001", 0, "453ea81ef66a50cbe33ce06302afe47f", 229737},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
#ifdef ENABLE_SCI32
// Phantasmagoria - English DOS (from jvprat)
@@ -2551,7 +2561,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resmap.007", 0, "afbd16ea77869a720afa1c5371de107d", 7972},
//{"ressci.007", 0, "3aae6559aa1df273bc542d5ac6330d75", 25859038},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Phantasmagoria - English DOS Demo
// Executable scanning reports "2.100.002"
@@ -2559,7 +2569,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resmap.001", 0, "416138651ea828219ca454cae18341a3", 11518},
{"ressci.001", 0, "3aae6559aa1df273bc542d5ac6330d75", 65844612},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO | ADGF_UNSTABLE, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO | ADGF_UNSTABLE, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Phantasmagoria - English DOS/Windows (GOG version) - ressci.* merged in ressci.000
// Windows executable scanning reports "2.100.002" - "Sep 19 1995 15:09:43"
@@ -2570,7 +2580,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"ressci.000", 0, "cd5967f9b9586e3380645961c0765be3", 116822037},
{"resmap.000", 0, "3cafc1c6a53945c1f3babbfd6380c64c", 16468},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Phantasmagoria - English Macintosh
// NOTE: This only contains disc 1 files (as well as the two persistent files:
@@ -2603,7 +2613,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resmap.005", 0, "8bd5ceeedcbe16dfe55d1b90dcd4be84", 1942},
{"ressci.005", 0, "05f9fe2bee749659acb3cd2c90252fc5", 67905112},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, 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"
@@ -2613,7 +2623,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"ressci.000", 0, "c54f26d9f43f908151263254b6d97053", 108134481},
{"resmap.000", 0, "de154a223a9ef4ea7358b76adc38ef5b", 2956},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
#endif // ENABLE_SCI3_GAMES
#endif // ENABLE_SCI32
@@ -2624,7 +2634,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "72726dc81c1b4c1110c486be77369bc8", 5179},
{"resource.000", 0, "670d0c53622429f4b11275caf7f8d292", 5459574},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Pepper - English DOS Non-Interactive Demo
// Executable scanning reports "1.001.060", VERSION file reports "1.000"
@@ -2632,7 +2642,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "379bb4fb896630b14f2d91ed21e36ba1", 984},
{"resource.000", 0, "118f6c31a93ec7fd9a231c61125229e3", 645494},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Pepper - English DOS/Windows Interactive Demo
// Executable scanning reports "1.001.069", VERSION file reports ".001"
@@ -2640,7 +2650,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "975e8df76106a5c13d12ab674f906a02", 2514},
{"resource.000", 0, "e6a918a2dd7a4bcecd8fb389f43287c2", 1698164},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Pepper - English DOS Interactive Demo
// Executable scanning reports "1.001.072", VERSION file reports "1.000"
@@ -2648,7 +2658,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "9c9b7b900651a370dd3fb38d478b1798", 2524},
{"resource.000", 0, "e6a918a2dd7a4bcecd8fb389f43287c2", 1713544},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Police Quest 1 VGA Remake - English DOS (from the Police Quest Collection)
// Executable scanning reports "1.001.029", VERSION file reports "2.000"
@@ -2656,7 +2666,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "35efa814fb994b1cbdac9611e401da67", 5013},
{"resource.000", 0, "e0d5ddf34eda903a38f0837e2aa7145b", 6401433},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Police Quest 2 - English Amiga (from www.back2roots.org)
// SCI interpreter version 0.000.685 (just a guess)
@@ -2667,7 +2677,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.002", 0, "499737c21a28ac026e11ab817100d610", 511099},
{"resource.003", 0, "e008f5d6e2a7c4d4a0da0173e4fa8f8b", 553970},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Police Quest 2 - English DOS Non-Interactive Demo
// Executable scanning reports "0.000.413"
@@ -2675,7 +2685,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "8b77d0d4650c2052b356cece28294b58", 576},
{"resource.001", 0, "376ef6d6eaaeed66e1424bd219c4b9ab", 215398},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Police Quest 2 - English DOS (provided by richiefs in bug report #2670691)
// SCI interpreter version 0.000.395
@@ -2688,7 +2698,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.005", 0, "77f02def3094af804fd2371db25b7100", 349899},
{"resource.006", 0, "77f02def3094af804fd2371db25b7100", 354991},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Police Quest 2 - English DOS (from the Police Quest Collection)
// Executable scanning reports "0.000.490"
@@ -2698,7 +2708,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.002", 0, "77f02def3094af804fd2371db25b7100", 546000},
{"resource.003", 0, "77f02def3094af804fd2371db25b7100", 591851},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Police Quest 2 - English DOS (from FRG)
// SCI interpreter version 0.000.395
@@ -2708,7 +2718,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.002", 0, "77f02def3094af804fd2371db25b7100", 542897},
{"resource.003", 0, "77f02def3094af804fd2371db25b7100", 586857},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Police Quest 2 English DOS 1.001.006 (supplied by merkur-kun in bug report #3028479)
{"pq2", "", {
@@ -2717,7 +2727,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.002", 0, "77f02def3094af804fd2371db25b7100", 541261},
{"resource.003", 0, "77f02def3094af804fd2371db25b7100", 587511},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Police Quest 2 - Japanese PC-98 (also includes english language)
// SCI interpreter version unknown
@@ -2727,7 +2737,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.002", 0, "05fdee43a228dd6ea4d1a92ccae3f788", 637662},
{"resource.003", 0, "05fdee43a228dd6ea4d1a92ccae3f788", 684395},
AD_LISTEND},
- Common::JA_JPN, Common::kPlatformPC98, ADGF_ADDENGLISH, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::JA_JPN, Common::kPlatformPC98, ADGF_ADDENGLISH, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Police Quest 3 - English Amiga
// Executable scanning reports "1.004.024"
@@ -2740,7 +2750,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.003", 0, "630bfa65beb05f743552704ac2899dae", 759891},
{"resource.004", 0, "7b229fbdf30d670d0728cede3e984a7e", 838663},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Police Quest 3 - German Amiga (also includes english language)
// Executable scanning reports "1.004.024"
@@ -2754,7 +2764,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.004", 0, "6258d5dd85898d8e218eb8113ebc9059", 722738},
{"resource.005", 0, "6258d5dd85898d8e218eb8113ebc9059", 704485},
AD_LISTEND},
- Common::DE_DEU, Common::kPlatformAmiga, ADGF_ADDENGLISH, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::DE_DEU, Common::kPlatformAmiga, ADGF_ADDENGLISH, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Police Quest 3 - English DOS (from the Police Quest Collection)
// Executable scanning reports "T.A00.178", VERSION file reports "1.00"
@@ -2767,7 +2777,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.003", 0, "8791b9eef53edf77c2dac950142221d3", 1159791},
{"resource.004", 0, "1b91e891a3c60a941dac0eecdf83375b", 1143606},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Police Quest 3 - English DOS Non-Interactive Demo
// Executable scanning reports "T.A00.052"
@@ -2777,7 +2787,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.000", 0, "277f97771f7a6d89677141f02da313d6", 65150},
{"resource.001", 0, "5c5a551b6c86cce2ee75becb90e0b586", 624411},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Police Quest 3 - German DOS (supplied by markcoolio in bug report #2723837, also includes english language)
// Executable scanning reports "T.A00.178"
@@ -2790,14 +2800,14 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.003", 0, "4836f460f4cfc8de61e2df4c45775504", 1180956},
{"resource.004", 0, "0c3eb84b9755852d9e795e0d5c9373c7", 1171760},
AD_LISTEND},
- Common::DE_DEU, Common::kPlatformDOS, ADGF_ADDENGLISH, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::DE_DEU, Common::kPlatformDOS, ADGF_ADDENGLISH, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Police Quest 3 - Spanish DOS v1.000 - Supplied by dianiu in bug report #3555647
{"pq3", "", {
{"resource.map", 0, "ffa0b4631c4e36d69631256d19ba29e7", 5421},
{"resource.000", 0, "5ee460af3d70c06a745cc482b6c783ba", 5410263},
AD_LISTEND},
- Common::ES_ESP, Common::kPlatformDOS, ADGF_ADDENGLISH, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::ES_ESP, Common::kPlatformDOS, ADGF_ADDENGLISH, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Police Quest 3 EGA
// Reported by musiclyinspired in bug report #3046573
@@ -2810,7 +2820,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.004", 0, "b96a86ab681769e4cbb439670d967ca6", 449682},
{"resource.005", 0, "9e6c53a0e7eef53694d260fade8b1fc7", 724000},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Police Quest 4 - English DOS Non-Interactive Demo (from FRG)
// SCI interpreter version 1.001.096
@@ -2818,7 +2828,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "be56f87a1c4a13062a30a362df860c2f", 1472},
{"resource.000", 0, "527d5684016e6816157cd15d9071b11b", 1121310},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
#ifdef ENABLE_SCI32
// Police Quest 4 - English DOS CD (from the Police Quest Collection)
@@ -2827,7 +2837,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "379dfe80ed6bd16c47e4b950c4722eac", 11374},
{"resource.000", 0, "fd316a09b628b7032248139003369022", 18841068},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_CD | ADGF_UNSTABLE, GUIO3(GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_CD | ADGF_UNSTABLE, GUIO3(GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Police Quest 4 - German DOS CD (German text, English speech)
// Supplied by markcoolio in bug report #3392955
@@ -2835,7 +2845,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "a398076371ed0e1e706c8f9fb9fc7ac5", 11386},
{"resource.000", 0, "6ff21954e0a2c5992279e7eb787c8d56", 18918747},
AD_LISTEND},
- Common::DE_DEU, Common::kPlatformDOS, ADGF_CD | ADGF_UNSTABLE, GUIO3(GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::DE_DEU, Common::kPlatformDOS, ADGF_CD | ADGF_UNSTABLE, GUIO3(GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Police Quest 4 - English DOS
// SCI interpreter version 2.000.000 (a guess?)
@@ -2843,7 +2853,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "aed9643158ccf01b71f359db33137f82", 9895},
{"resource.000", 0, "da383857b3be1e4514daeba2524359e0", 15141432},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Police Quest 4 - French DOS (supplied by abevi in bug report #2612718)
// SCI interpreter version 2.000.000
@@ -2851,7 +2861,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "008030846edcc7c5c7a812c7f4ae4ceb", 9256},
{"resource.000", 0, "6ba98bd2e436739d87ecd2a9b99cabb4", 14730153},
AD_LISTEND},
- Common::FR_FRA, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::FR_FRA, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Police Quest 4 - German DOS (supplied by markcoolio in bug report #2723840)
// SCI interpreter version 2.000.000 (a guess?)
@@ -2859,7 +2869,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "2393ee728ab930b2762cb5889f9b5aff", 9256},
{"resource.000", 0, "6ba98bd2e436739d87ecd2a9b99cabb4", 14730155},
AD_LISTEND},
- Common::DE_DEU, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::DE_DEU, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Police Quest: SWAT - English DOS/Windows Demo (from jvprat)
// Executable scanning reports "2.100.002", VERSION file reports "0.001.200"
@@ -2867,7 +2877,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "8c96733ef94c21526792f7ca4e3f2120", 1648},
{"resource.000", 0, "d8892f1b8c56c8f7704325460f49b300", 3676175},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO | ADGF_UNSTABLE, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO | ADGF_UNSTABLE, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Police Quest: SWAT - English DOS (from GOG.com)
// Executable scanning reports "2.100.002", VERSION file reports "1.0c"
@@ -2875,7 +2885,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resmap.000", 0, "1c2563fee189885e29d9348f37306d94", 12175},
{"ressci.000", 0, "b2e1826ca81ce2e7e764587f5a14eee9", 127149181},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Police Quest: SWAT - English Windows (from the Police Quest Collection)
// Executable scanning reports "2.100.002", VERSION file reports "1.0c"
@@ -2890,7 +2900,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resmap.004", 0, "4228038906f041623e65789500b22285", 6835},
{"ressci.004", 0, "b7e619e6ecf62fe65d5116a3a422e5f0", 46223872},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
#endif // ENABLE_SCI32
// Quest for Glory 1 / Hero's Quest - English DOS 3.5" Floppy (supplied by merkur in bug report #2718784)
@@ -2903,7 +2913,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.003", 0, "7ab2bf8e224b57f75e0cd6e4ba790761", 642203},
{"resource.004", 0, "7ab2bf8e224b57f75e0cd6e4ba790761", 641688},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Quest for Glory 1 / Hero's Quest - English DOS 3.5" Floppy (supplied by alonzotg in bug report #3206006)
{"qfg1", "", {
@@ -2914,7 +2924,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.003", 0, "7ab2bf8e224b57f75e0cd6e4ba790761", 642203},
{"resource.004", 0, "7ab2bf8e224b57f75e0cd6e4ba790761", 641688},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Quest for Glory 1 / Hero's Quest - English DOS 3.5" Floppy v1.102 Int#0.000.629 (suppled by digitoxin1 in bug report #3554611)
{"qfg1", "", {
@@ -2925,7 +2935,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.003", 0, "f0af87c60ec869946da442833aa5afa8", 640502},
{"resource.004", 0, "f0af87c60ec869946da442833aa5afa8", 644575},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Quest for Glory 1 / Hero's Quest - English DOS 5.25" Floppy v1.102 Int#0.000.629 (suppled by digitoxin1 in bug report #3554611)
{"qfg1", "", {
@@ -2939,7 +2949,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.006", 0, "48b2b3c964dcbeccb68e984e6d4e97db", 278473},
{"resource.007", 0, "f0af87c60ec869946da442833aa5afa8", 269237},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Quest for Glory 1 / Hero's Quest - English DOS 5.25" Floppy (supplied by markcoolio in bug report #2723843)
// Executable scanning reports "0.000.566"
@@ -2954,7 +2964,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.006", 0, "69366c2a2f99917199fe1b60a4fee19d", 267852},
{"resource.007", 0, "7ab2bf8e224b57f75e0cd6e4ba790761", 272747},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Quest for Glory 1 / Hero's Quest - English DOS 5.25" Floppy (supplied by ssburnout in bug report #3049193)
// 1.001 10x5.25" (label: INT.#0.000.566)
@@ -2969,7 +2979,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.006", 0, "69366c2a2f99917199fe1b60a4fee19d", 267852},
{"resource.007", 0, "7ab2bf8e224b57f75e0cd6e4ba790761", 272747},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Quest for Glory 1 / Hero's Quest - English DOS 5.25" Floppy (supplied by ssburnout in bug report #3049193)
// 1.200 10x5.25" (label: INT#9.10.90)
@@ -2984,7 +2994,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.006", 0, "f46690dca714abc8c89357d30e363dd3", 278387},
{"resource.007", 0, "951299a82a8134ed12c5c18118d45c2f", 269173},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Quest for Glory 1 / Hero's Quest - English DOS Demo
// Executable scanning reports "0.000.685"
@@ -2992,7 +3002,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "df34c758cbb9026da175793ff686b0e6", 882},
{"resource.001", 0, "73fbaafdd313b39aeedb80fbf85ecef1", 389884},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Quest for Glory 1 - Japanese PC-98 5.25" Floppy (also includes English language)
// Executable scanning reports "S.old.201"
@@ -3002,7 +3012,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.002", 0, "a21451ef6fa8179bd4b22c4950004c44", 1136968},
{"resource.003", 0, "a21451ef6fa8179bd4b22c4950004c44", 769897},
AD_LISTEND},
- Common::JA_JPN, Common::kPlatformPC98, ADGF_ADDENGLISH, GUIO3(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_EGA_UNDITHER) },
+ Common::JA_JPN, Common::kPlatformPC98, ADGF_ADDENGLISH, GUIO3(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_EGA_UNDITHER) },
// Quest for Glory 1 - Japanese PC-98 5.25" Floppy (also includes English language)
// Executable scanning reports "S.old.201"
@@ -3012,7 +3022,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.002", 0, "a21451ef6fa8179bd4b22c4950004c44", 1147121},
{"resource.003", 0, "a21451ef6fa8179bd4b22c4950004c44", 777575},
AD_LISTEND},
- Common::JA_JPN, Common::kPlatformPC98, ADGF_ADDENGLISH, GUIO3(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_EGA_UNDITHER) },
+ Common::JA_JPN, Common::kPlatformPC98, ADGF_ADDENGLISH, GUIO3(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_EGA_UNDITHER) },
// Quest for Glory 1 - English Amiga
// Executable scanning reports "1.002.020"
@@ -3026,7 +3036,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.004", 0, "16cd4414c37ae3bb6d6da33dce8e25e8", 689124},
{"resource.005", 0, "5f3386ef2f2b1254e4a066f5d9027324", 609529},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Quest for Glory 1 - English DOS
// SCI interpreter version 0.000.629
@@ -3038,7 +3048,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.003", 0, "951299a82a8134ed12c5c18118d45c2f", 640483},
{"resource.004", 0, "951299a82a8134ed12c5c18118d45c2f", 644443},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Quest for Glory 1 VGA Remake - English DOS
// Executable scanning reports "2.000.411"
@@ -3046,7 +3056,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "a731fb6c9c0b282443f7027bc8694d4c", 8469},
{"resource.000", 0, "ecace1a2771846b1a8aa1afdd44111a0", 6570147},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Quest for Glory 1 VGA Remake - English DOS Non-Interactive Demo (from FRG)
// SCI interpreter version 1.001.029
@@ -3054,7 +3064,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "ac0257051c95a59c0cdc0be24d9b11fa", 729},
{"resource.000", 0, "ec6f5cf369054dd3e5392995e9975b9e", 768218},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Quest for Glory 1 VGA Remake - English Macintosh Floppy
// VERSION file reports "2.0"
@@ -3062,7 +3072,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"Data1", 0, "106527ff8756e4e1a795d63d23e8b833", 1752358},
{"Data2", 0, "5cdd92033231159c6e9c71d43e9f194d", 6574746},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformMacintosh, ADGF_MACRESFORK, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformMacintosh, ADGF_MACRESFORK, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Quest for Glory 2 - English Amiga
// Executable scanning reports "1.003.004"
@@ -3078,7 +3088,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.006", 0, "ccf5dba33e5cab6d5872838c0f8db44c", 500039},
{"resource.007", 0, "4c9fc1587545879295cb9627f56a2cb8", 575056},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Quest for Glory 2 - English (supplied by ssburnout in bug report #3049193)
// 1.000 5x5.25" (label: INT#10.31.90)
@@ -3090,7 +3100,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.003", 0, "0790f67d87642132be515cab05026baa", 972144},
{"resource.004", 0, "2ac1e6fea9aa1f5b91a06693a67b9766", 982830},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Quest for Glory 2 - English (supplied by ssburnout in bug report #3049193)
// 1.000 9x3.5" (label: INT#10.31.90)
@@ -3105,7 +3115,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.006", 0, "5e9deacbdb17198ad844988e04833520", 498593},
{"resource.007", 0, "2ac1e6fea9aa1f5b91a06693a67b9766", 490151},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Quest for Glory 2 - English (from FRG)
// Executable scanning reports "1.000.072"
@@ -3117,7 +3127,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.003", 0, "b192607c42f6960ecdf2ad2e4f90e9bc", 972804},
{"resource.004", 0, "cd2de58e27665d5853530de93fae7cd6", 983617},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Quest for Glory 2 - English DOS
// Executable scanning reports "1.000.072"
@@ -3132,7 +3142,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.006", 0, "b1944bd664ddbd2859cdaa0c4a0d6281", 507489},
{"resource.007", 0, "cd2de58e27665d5853530de93fae7cd6", 490794},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Quest for Glory 2 - English DOS (supplied by digitoxin1 in bug report #3554614)
// v1.102 9x3.5" (label: Int#11.20.90)
@@ -3147,7 +3157,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.006", 0, "b1944bd664ddbd2859cdaa0c4a0d6281", 507489},
{"resource.007", 0, "cd2de58e27665d5853530de93fae7cd6", 490794},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Quest for Glory 2 - English DOS Non-Interactive Demo
// Executable scanning reports "1.000.046"
@@ -3155,7 +3165,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "e75eb86bdd517b3ef709058249986a87", 906},
{"resource.001", 0, "9b098f9e1008abe30e56c93b896494e6", 362123},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Quest for Glory 3 - English DOS Non-Interactive Demo (from FRG)
// Executable scanning reports "1.001.021", VERSION file reports "1.000, 0.001.059, 6.12.92"
@@ -3163,7 +3173,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "fd71de9b588a45f085317caacf050e91", 687},
{"resource.000", 0, "b6c69bf6c18bf177492249fe81fc6a6d", 648702},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Quest for Glory 3 - English DOS
// SCI interpreter version 1.001.050
@@ -3171,7 +3181,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "19e2bf9b693932b5e2bb59b9f9ab86c9", 5958},
{"resource.000", 0, "6178ad2e83e58e4671ca03315f7a6498", 5868000},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Quest for Glory 3 - English DOS (supplied by abevi in bug report #2612718)
// SCI interpreter version 1.001.050
@@ -3179,7 +3189,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "62c185d190363d7df06330fa0cc45b36", 5958},
{"resource.000", 0, "6178ad2e83e58e4671ca03315f7a6498", 5867442},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Quest for Glory 3 - English DOS (supplied by dknute in bug report #3125559)
{"qfg3", "", {
@@ -3187,7 +3197,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.000", 0, "6178ad2e83e58e4671ca03315f7a6498", 5868042},
{"resource.msg", 0, "27e5419c98ce444253f88c95dced14a9", 246888},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Quest for Glory 3 - German DOS (supplied by markcoolio in bug report #2723846)
// Executable scanning reports "L.rry.083"
@@ -3195,7 +3205,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "19e2bf9b693932b5e2bb59b9f9ab86c9", 5958},
{"resource.000", 0, "6178ad2e83e58e4671ca03315f7a6498", 5868042},
AD_LISTEND},
- Common::DE_DEU, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::DE_DEU, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Quest for Glory 3 - French DOS v1.1 (supplied by misterhands in bug report #3586214)
// Executable scanning reports "L.rry.083"
@@ -3204,7 +3214,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.000", 0, "6178ad2e83e58e4671ca03315f7a6498", 5868000},
{"resource.msg", 0, "0fa1047002df904b8d1807bb7bab4fab", 267210},
AD_LISTEND},
- Common::FR_FRA, Common::kPlatformDOS, 0, GUIO3(GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::FR_FRA, Common::kPlatformDOS, 0, GUIO3(GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Quest for Glory 3 - Spanish DOS CD (from jvprat)
// Executable scanning reports "L.rry.083", VERSION file reports "1.000.000, June 30, 1994"
@@ -3213,7 +3223,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.000", 0, "ba7ac86155e4c531e46cd73c86daa80a", 5884098},
{"resource.msg", 0, "a63974730d294dec0bea10057c36e506", 256014},
AD_LISTEND},
- Common::ES_ESP, Common::kPlatformDOS, 0, GUIO3(GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::ES_ESP, Common::kPlatformDOS, 0, GUIO3(GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Quest for Glory 3 - Italian DOS
// Supplied by ghoost in bug report #3053457
@@ -3222,7 +3232,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.000", 0, "6178ad2e83e58e4671ca03315f7a6498", 5868000},
{"resource.msg", 0, "5a0a896ff3e4a628db38a75eb6c84114", 259018},
AD_LISTEND},
- Common::IT_ITA, Common::kPlatformDOS, 0, GUIO3(GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::IT_ITA, Common::kPlatformDOS, 0, GUIO3(GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Quest for Glory 4 - English DOS Non-Interactive Demo (from FRG)
// SCI interpreter version 1.001.069 (just a guess)
@@ -3230,7 +3240,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "1ba7c7ae1efb315326d45cb931569b1b", 922},
{"resource.000", 0, "41ba03f0b188b029132daa3ece0d3e14", 623154},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
#ifdef ENABLE_SCI32
// Quest for Glory 4 1.1 Floppy - English DOS (supplied by markcool in bug report #2723852)
@@ -3239,7 +3249,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "685bdb1ed47bbbb0e5e25db392da83ce", 9301},
{"resource.000", 0, "f64fd6aa3977939a86ff30783dd677e1", 11004993},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Quest for Glory 4 1.1 Floppy - English DOS (supplied by abevi in bug report #2612718)
// SCI interpreter version 2.000.000
@@ -3247,7 +3257,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "d10a4cc177d2091d744e2ad8c049b0ae", 9295},
{"resource.000", 0, "f64fd6aa3977939a86ff30783dd677e1", 11003589},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Quest for Glory 4 1.1 Floppy - German DOS (supplied by markcool in bug report #2723850)
// Executable scanning reports "2.000.000", VERSION file reports "1.1"
@@ -3255,7 +3265,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "9e0abba8746f40565bc7eb5720522ecd", 9301},
{"resource.000", 0, "57f22cdc54eeb35fce1f26b31b5c3ee1", 11076197},
AD_LISTEND},
- Common::DE_DEU, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::DE_DEU, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Quest for Glory 4 CD - English DOS/Windows (from jvprat)
// Executable scanning reports "2.100.002", VERSION file reports "1.0"
@@ -3263,7 +3273,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "aba367f2102e81782d961b14fbe3d630", 10246},
{"resource.000", 0, "263dce4aa34c49d3ad29bec889007b1c", 11571394},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_CD | ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_CD | ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// RAMA - English DOS/Windows Demo
// Executable scanning reports "2.100.002", VERSION file reports "000.000.008"
@@ -3271,7 +3281,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resmap.001", 0, "775304e9b2a545156be4d94209550094", 1393},
{"ressci.001", 0, "259437fd75fdf51e8207fda8c01fa4fd", 2334384},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformWindows, ADGF_DEMO | ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformWindows, ADGF_DEMO | ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
#ifdef ENABLE_SCI3_GAMES
// RAMA - English Windows (from jvprat)
@@ -3284,7 +3294,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resmap.003", 0, "31ef4c0621711585d031f0ae81707251", 1636},
{"ressci.003", 0, "2a68edd064e5e4937b5e9c74b38f2082", 6860492},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// RAMA - English Windows (from Quietust, in bug report #2850645)
{"rama", "", {
@@ -3295,18 +3305,18 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resmap.003", 0, "48841e4b84ef1b98b48d43566fda9e13", 1636},
{"ressci.003", 0, "2a68edd064e5e4937b5e9c74b38f2082", 6870356},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// RAMA - German Windows CD (from farmboy0, in pull request 397)
{"rama", "", {
{"resmap.001", 0, "f68cd73308c46977a9632dfc618e1e38", 8338},
- {"ressci.001", 0, "2a68edd064e5e4937b5e9c74b38f2082", 70595521},
- {"resmap.002", 0, "891fc2f5d9e23e7d9a9454acc7aaae52", 12082},
- {"ressci.002", 0, "2a68edd064e5e4937b5e9c74b38f2082", 128508558},
- {"resmap.003", 0, "222096000bd83a1d56577114a452cccf", 1636},
- {"ressci.003", 0, "2a68edd064e5e4937b5e9c74b38f2082", 6954219},
+ {"ressci.001", 0, "2a68edd064e5e4937b5e9c74b38f2082", 70595521},
+ {"resmap.002", 0, "891fc2f5d9e23e7d9a9454acc7aaae52", 12082},
+ {"ressci.002", 0, "2a68edd064e5e4937b5e9c74b38f2082", 128508558},
+ {"resmap.003", 0, "222096000bd83a1d56577114a452cccf", 1636},
+ {"ressci.003", 0, "2a68edd064e5e4937b5e9c74b38f2082", 6954219},
AD_LISTEND},
- Common::DE_DEU, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::DE_DEU, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// RAMA - Italian Windows CD (from glorifindel)
// SCI interpreter version 3.000.000 (a guess?)
@@ -3314,7 +3324,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"ressci.001", 0, "2a68edd064e5e4937b5e9c74b38f2082", 70611091},
{"resmap.001", 0, "70ba2ff04a2b7fb2c52420ba7fbd47c2", 8338},
AD_LISTEND},
- Common::IT_ITA, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::IT_ITA, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
#endif // ENABLE_SCI3_GAMES
// Shivers - English Windows (from jvprat)
@@ -3323,14 +3333,14 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resmap.000", 0, "f2ead37749ed8f6535a2445a7d05a0cc", 46525},
{"ressci.000", 0, "4294c6d7510935f2e0a52e302073c951", 262654836},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Shivers - German Windows (from Tobis87)
{"shivers", "", {
{"resmap.000", 0, "f483d0a1f78334c18052e92785c3086e", 46537},
{"ressci.000", 0, "6751b144671e2deed919eb9d284b07eb", 262390692},
AD_LISTEND},
- Common::DE_DEU, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::DE_DEU, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Shivers - English Windows Demo
// Executable scanning reports "2.100.002"
@@ -3338,7 +3348,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resmap.000", 0, "d9e0bc5eddefcbe47f528760085d8927", 1186},
{"ressci.000", 0, "3a93c6340b54e07e65d0e5583354d186", 10505469},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformWindows, ADGF_DEMO | ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformWindows, ADGF_DEMO | ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Shivers 2 doesn't contain SCI scripts. The whole game logic has
// been reimplemented from SCI in native code placed in DLL files.
@@ -3356,7 +3366,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resmap.000", 0, "d8659188b84beaef076bd869837cd530", 634},
{"ressci.000", 0, "7fbac0807a044c9543e8ac376d200e59", 4925003},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformWindows, ADGF_DEMO | ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformWindows, ADGF_DEMO | ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Shivers 2 - English Windows (from abevi)
// VERSION.TXT Version 1.0 (3/25/97)
@@ -3364,7 +3374,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"ressci.001", 0, "a79d03d6eb75be0a79324f14e3d2ace4", 95346793},
{"resmap.001", 0, "a4804d436d90c4ec2e46b537f5e954db", 6268},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
#endif
@@ -3377,7 +3387,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.msg", 0, "1aeafe2b495de288d002109650b66614", 1364},
{"resource.000", 0, "8e10d4f05c1fd9f883384fa38a898489", 377394},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO3(GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO3(GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Slater & Charlie Go Camping - English DOS/Windows
{"slater", "", {
@@ -3385,7 +3395,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "21f85414124dc23e54544a5536dc35cd", 4044},
{"resource.msg", 0, "c44f51fb955eae266fecf360ebcd5ad2", 1132},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO3(GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO3(GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Slater & Charlie Go Camping - English DOS/Windows (Sierra Originals)
@@ -3394,14 +3404,14 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "21f85414124dc23e54544a5536dc35cd", 4044},
{"resource.msg", 0, "c44f51fb955eae266fecf360ebcd5ad2", 1132},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO3(GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO3(GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Slater & Charlie Go Camping - English Macintosh
{"slater", "", {
{"Data1", 0, "7243b4390e5f0182d8133fbcae4b50c5", 2298853},
{"Data2", 0, "6b6f18f9b502dc0923eeae0ef47f02d5", 2276956},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformMacintosh, ADGF_MACRESFORK, GUIO1(GUIO_NONE) },
+ Common::EN_ANY, Common::kPlatformMacintosh, ADGF_MACRESFORK, GUIO1(GUIO_NONE) },
// Space Quest 1 VGA Remake - English Amiga (from www.back2roots.org)
// SCI interpreter version 1.000.510 (just a guess)
@@ -3414,7 +3424,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.004", 0, "b25a1539c71701f7715f738c5037e9a6", 775515},
{"resource.005", 0, "640ffe1a9acde392cc33cc1b1a528328", 806324},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Space Quest 1 VGA Remake - English DOS (from the Space Quest Collection)
// Executable scanning reports "T.A00.081", VERSION file reports "2.000"
@@ -3427,7 +3437,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.003", 0, "c47600e50c6fc591957ae0c5020ee7b8", 1213262},
{"resource.004", 0, "e19ea4ad131472f9238590f2e1d40289", 1203051},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Space Quest 1 VGA Remake - English Mac (from Fingolfin)
{"sq1sci", "SCI", {
@@ -3438,7 +3448,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.003", 0, "ae46e195e66df5a131917f0aa80b5669", 1242794},
{"resource.004", 0, "91d58a9eb2187c38424990afe4c12bc6", 1250949},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformMacintosh, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformMacintosh, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Space Quest 1 VGA Remake - English Non-Interactive Demo (from FRG)
// SCI interpreter version 1.000.181
@@ -3446,7 +3456,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "5af709ac5e0e923e0b8174f49978c30e", 636},
{"resource.001", 0, "fd99ea43f57576ded7c86036996346cf", 507642},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Space Quest 1 VGA Remake - Spanish DOS Floppy (from jvprat)
// Executable scanning reports "T.A00.081", VERSION file reports "2.000"
@@ -3460,7 +3470,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.004", 0, "9b78228ad4f9f335fedf74f1812dcfca", 513325},
{"resource.005", 0, "7d4ebcb745c0bf8fc42e4013f52ecd49", 1101812},
AD_LISTEND},
- Common::ES_ESP, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::ES_ESP, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Space Quest I 2.0 EGA DOS (6 x 3.5" disks)
// Provided by ssburnout in bug report #3046805
@@ -3473,7 +3483,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.004", 0, "975c6e81194ae6b65e960a248129ecaa", 684119},
{"resource.005", 0, "13d96f7905637552c0647175ff816145", 695589},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Space Quest 3 - English Amiga (from www.back2roots.org)
// SCI interpreter version 0.000.453 (just a guess)
@@ -3484,7 +3494,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.003", 0, "ceeda7202b96e5c85ecaa88a40a540fc", 746496},
{"resource.004", 0, "ceeda7202b96e5c85ecaa88a40a540fc", 761984},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Space Quest 3 - German Amiga (also includes english language)
// Executable scanning reports "1.004.006"
@@ -3505,7 +3515,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "ec66ac2b1ce58b2575ba00b65058de1a", 612},
{"resource.001", 0, "ceeda7202b96e5c85ecaa88a40a540fc", 180245},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Space Quest 3 - English DOS (provided by richiefs in bug report #2670691)
// SCI interpreter version 0.000.453
@@ -3515,7 +3525,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.002", 0, "ceeda7202b96e5c85ecaa88a40a540fc", 720244},
{"resource.003", 0, "ceeda7202b96e5c85ecaa88a40a540fc", 688367},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Space Quest 3 - English DOS (from the Space Quest Collection)
// Executable scanning reports "0.000.685", VERSION file reports "1.018"
@@ -3525,7 +3535,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.002", 0, "8b55c4875298f45ea5696a5ee8f6a7fe", 715777},
{"resource.003", 0, "8b55c4875298f45ea5696a5ee8f6a7fe", 703370},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Space Quest 3 - English DOS (from abevi, bug report #2612718)
{"sq3", "", {
@@ -3537,7 +3547,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.005", 0, "ceeda7202b96e5c85ecaa88a40a540fc", 328278},
{"resource.006", 0, "ceeda7202b96e5c85ecaa88a40a540fc", 356702},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Space Quest 3 - English Mac (from Fingolfin)
{"sq3", "", {
@@ -3546,7 +3556,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.002", 0, "0d8dfe42683b46f3131823233a91ce6a", 794072},
{"resource.003", 0, "0d8dfe42683b46f3131823233a91ce6a", 776536},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformMacintosh, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformMacintosh, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Space Quest 3 - German DOS (from Tobis87, also includes english language)
// SCI interpreter version 0.000.453 (?)
@@ -3560,7 +3570,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.006", 0, "9107c2aa5398e28b5c5406df13491f85", 320643},
{"resource.007", 0, "9107c2aa5398e28b5c5406df13491f85", 344287},
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) },
+ Common::DE_DEU, Common::kPlatformDOS, ADGF_ADDENGLISH, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Space Quest 3 v1.052 - German DOS (supplied by markcoolio in bug report #2723860, also includes english language)
// Executable scanning reports "S.old.114"
@@ -3570,7 +3580,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.002", 0, "9107c2aa5398e28b5c5406df13491f85", 596768},
{"resource.003", 0, "9107c2aa5398e28b5c5406df13491f85", 693573},
AD_LISTEND},
- Common::DE_DEU, Common::kPlatformDOS, ADGF_ADDENGLISH, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::DE_DEU, Common::kPlatformDOS, ADGF_ADDENGLISH, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Space Quest 4 - English Amiga
// Executable scanning reports "1.004.024"
@@ -3585,7 +3595,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.005", 0, "3540d1cc84d674cf4b2c898b88a3b563", 790296},
{"resource.006", 0, "ade814bc4d56244c156d9e9bcfebbc11", 664085},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Space Quest 4 - German Amiga (from www.back2roots.org, also includes english language)
// SCI interpreter version 1.000.200 (just a guess)
@@ -3599,7 +3609,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.005", 0, "10ee1709e6559c724676d058199b75b5", 818745},
{"resource.006", 0, "67fb188b191d88efe8414af6ea297b93", 672675},
AD_LISTEND},
- Common::DE_DEU, Common::kPlatformAmiga, ADGF_ADDENGLISH, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::DE_DEU, Common::kPlatformAmiga, ADGF_ADDENGLISH, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Space Quest 4 - English DOS - THIS VERSION IS PIRATED/CRACKED AND REPACKAGED =DO NOT RE-ADD=
// Executable scanning reports "1.000.753"
@@ -3608,7 +3618,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "a18088c8aceb06025dbc945f29e02935", 5124},
{"resource.000", 0, "e1f46832cd2458796028e054a0466031", 5502009},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_PIRATED, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_PIRATED, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Space Quest 4 - English DOS
// Executable scanning reports "1.000.753"
@@ -3617,7 +3627,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "71ccf4f82ac4efb588731acfb7bf2603", 5646},
{"resource.000", 0, "e1f46832cd2458796028e054a0466031", 933928},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Space Quest 4 1.052 - English DOS Floppy (supplied by markcoolio in bug report #2723865)
// Executable scanning reports "1.000.753"
@@ -3631,7 +3641,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.004", 0, "ff9c87da3bc53473fdee8b9d3edbc93c", 1200631},
{"resource.005", 0, "e33019ac19f755ae33fbf49b4fc9066c", 1053294},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Space Quest 4 1.000 - French DOS Floppy (supplied by misterhands in bug report #3515247)
{"sq4", "", {
@@ -3644,7 +3654,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.004", 0, "b2cca3afcf2e013b8ce86b64155af766", 1254353},
{"resource.005", 0, "9e520577e035547c4b5149a6d12ef85b", 1098814},
AD_LISTEND},
- Common::FR_FRA, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::FR_FRA, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Space Quest 4 1.000 - English DOS Floppy (from abevi, bug report #2612718)
{"sq4", "", {
@@ -3656,7 +3666,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.004", 0, "c06350184a490c10eb4585fff0aa3192", 1254368},
{"resource.005", 0, "b8d6efbd3235329bfe844c794097b2c9", 1098717},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Space Quest IV DOS 1.060 EGA (6 x 3.5" disks)
// Supplied by ssburnout in bug report #3046781
@@ -3669,7 +3679,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.004", 0, "9a673e33c3f6dd560b993ffed77eeb49", 534994},
{"resource.005", 0, "3c4841d0a3ebba4404af588c93620c22", 595465},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EGA_UNDITHER, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Space Quest 4 - German DOS (from Tobis87, also includes english language)
// SCI interpreter version 1.000.200 (just a guess)
@@ -3683,7 +3693,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.005", 0, "47ee647b5b12232d27e63cc627c25899", 1156765},
{"resource.006", 0, "dfb023e4e2a1e7a00fa18f9ede72a91b", 924059},
AD_LISTEND},
- Common::DE_DEU, Common::kPlatformDOS, ADGF_ADDENGLISH, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::DE_DEU, Common::kPlatformDOS, ADGF_ADDENGLISH, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Space Quest 4 - Italian DOS Floppy (from glorifindel, also includes english language)
// SCI interpreter version 1.000.200 (just a guess)
@@ -3696,7 +3706,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.004", 0, "4277c61bed40a50dadc4b5a344520af2", 1251000},
{"resource.005", 0, "5f885abd335978e2fd4e5f886d7676c8", 1102880},
AD_LISTEND},
- Common::IT_ITA, Common::kPlatformDOS, ADGF_ADDENGLISH, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::IT_ITA, Common::kPlatformDOS, ADGF_ADDENGLISH, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Space Quest 4 - Japanese PC-98 5.25" Floppy (also includes english language)
// SCI interpreter version 1.000.1068
@@ -3706,7 +3716,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.001", 0, "454684e3a7a68cbca073945e50778447", 1187088},
{"resource.002", 0, "6dc668326cc22cb9e8bd8ca9e68d2a66", 1181249},
AD_LISTEND},
- Common::JA_JPN, Common::kPlatformPC98, ADGF_ADDENGLISH, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::JA_JPN, Common::kPlatformPC98, ADGF_ADDENGLISH, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Space Quest 4 - Japanese PC-98 5.25" Floppy (also includes english language)
// SCI interpreter version 1.000.1068
@@ -3716,7 +3726,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.001", 0, "454684e3a7a68cbca073945e50778447", 1187088},
{"resource.002", 0, "6dc668326cc22cb9e8bd8ca9e68d2a66", 1181249},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformPC98, ADGF_ADDENGLISH, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformPC98, ADGF_ADDENGLISH, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Space Quest 4 - English DOS CD (from the Space Quest Collection)
// Executable scanning reports "1.001.064", VERSION file reports "1.0"
@@ -3724,7 +3734,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "ed90a8e3ccc53af6633ff6ab58392bae", 7054},
{"resource.000", 0, "63247e3901ab8963d4eece73747832e0", 5157378},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_CD, GUIO4(GAMEOPTION_SQ4_SILVER_CURSORS, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_CD, GUIO4(GAMEOPTION_SQ4_SILVER_CURSORS, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Space Quest 4 - English Windows CD (from the Space Quest Collection)
// Executable scanning reports "1.001.064", VERSION file reports "1.0"
@@ -3734,7 +3744,15 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "ed90a8e3ccc53af6633ff6ab58392bae", 7054},
{"resource.000", 0, "63247e3901ab8963d4eece73747832e0", 5157378},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformWindows, ADGF_CD, GUIO5(GUIO_MIDIGM, GAMEOPTION_SQ4_SILVER_CURSORS, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformWindows, ADGF_CD, GUIO5(GUIO_MIDIGM, GAMEOPTION_SQ4_SILVER_CURSORS, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+
+ // Space Quest 4 - English DOS CD patch 1.2 (unofficial - NRS) - THIS VERSION IS PIRATED/CRACKED AND REPACKAGED =DO NOT RE-ADD=
+ // In essence, this "patch" includes a mixture the CD and floppy versions (the whole game), without the speech file
+ {"sq4", "CD", {
+ {"resource.map", 0, "38287a646458a1dabded55d094407793", 7139},
+ {"resource.000", 0, "231fd8421e1f211e1bcf9d7b8b6408e7", 9525849},
+ AD_LISTEND},
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_PIRATED, GUIO4(GAMEOPTION_SQ4_SILVER_CURSORS, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Space Quest 4 - Spanish DOS CD (from jvprat, is still text only, not talkie, also includes english language)
// Executable scanning reports "1.SQ4.057", VERSION file reports "1.000"
@@ -3748,7 +3766,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.004", 0, "776fba81c110d1908776232cbe190e20", 1253752},
{"resource.005", 0, "55fae26c2a92f16ef72c1e216e827c0f", 1098328},
AD_LISTEND},
- Common::ES_ESP, Common::kPlatformDOS, ADGF_ADDENGLISH, GUIO4(GAMEOPTION_SQ4_SILVER_CURSORS, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::ES_ESP, Common::kPlatformDOS, ADGF_ADDENGLISH, GUIO4(GAMEOPTION_SQ4_SILVER_CURSORS, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Space Quest 4 - Spanish DOS Floppy (from jvprat, also includes english language)
// Executable scanning reports "1.SQ4.056", VERSION file reports "1.000"
@@ -3760,7 +3778,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.002", 0, "74c62fa2146ff3b3b2ea2b3fb95b9af9", 1140801},
{"resource.003", 0, "42a307941edeb1a3be31daeb2e4be90b", 1088408},
AD_LISTEND},
- Common::ES_ESP, Common::kPlatformDOS, ADGF_ADDENGLISH, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::ES_ESP, Common::kPlatformDOS, ADGF_ADDENGLISH, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Space Quest 4 1.000 - German DOS Floppy (supplied by markcoolio in bug report #2723862, also includes english language)
// Executable scanning reports "1.SQ4.030"
@@ -3774,7 +3792,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.004", 0, "c06350184a490c10eb4585fff0aa3192", 1254368},
{"resource.005", 0, "b8d6efbd3235329bfe844c794097b2c9", 1098717},
AD_LISTEND},
- Common::DE_DEU, Common::kPlatformDOS, ADGF_ADDENGLISH, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::DE_DEU, Common::kPlatformDOS, ADGF_ADDENGLISH, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Space Quest 4 - English Macintosh
// Executable scanning reports "x.yyy.zzz"
@@ -3789,7 +3807,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.005", 0, "869d16cab6641c80b06f4dcee18f86bc", 1426228},
{"resource.006", 0, "91d23407bc0447a3722fbeb952d7edee", 1402451},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformMacintosh, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformMacintosh, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Space Quest 4 - Russian DOS
// Executable scanning reports "1.000.753", VERSION file reports "1.994"
@@ -3802,7 +3820,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.004", 0, "2763fe4f0cb74df716ec8b0c464b0988", 1217428},
{"resource.005", 0, "d608713197c5ba1cd8c6ed46299c3069", 1057924},
AD_LISTEND},
- Common::RU_RUS, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::RU_RUS, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Space Quest 5 - English DOS (from the Space Quest Collection)
// Executable scanning reports "1.001.068", VERSION file reports "1.04"
@@ -3811,7 +3829,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.000", 0, "4147edc5045e6d62998018b5614c58ec", 5496486},
{"resource.msg", 0, "bb8ad78793c26bdb3f77498b1d6515a9", 125988},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Space Quest 5 - English DOS - THIS IS THE UNOFFICIAL BETA VERSION, WHICH IS OBVIOUSLY PIRATED AND CONTAINS MANY BUGS
// refer to http://www.akril15.com/sr/sq5alt/sq5alt.html =DO NOT RE-ADD=
@@ -3820,7 +3838,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "8bde0a9adb9a3e9aaa861826874c9834", 6473},
{"resource.000", 0, "f4a48705764544d7cc64a7bb22a610df", 6025184},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_PIRATED, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_PIRATED, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Space Quest 5 v1.04 - German DOS (from Tobis87, updated information by markcool from bug reports #2723935 and #2724762)
// SCI interpreter version 1.001.068
@@ -3829,7 +3847,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.000", 0, "4147edc5045e6d62998018b5614c58ec", 5496486},
{"resource.msg", 0, "7c71cfc36153cfe07b450423a51f7e68", 146282},
AD_LISTEND},
- Common::DE_DEU, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::DE_DEU, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Space Quest 5 v1.04 - French DOS (from Hkz, Included in Space Quest Collector's Edition, with chapters I-V)
{"sq5", "", {
@@ -3837,7 +3855,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.000", 0, "4147edc5045e6d62998018b5614c58ec", 5496486},
{"resource.msg", 0, "877c42380320eb1db7dad83ccd261214", 140374},
AD_LISTEND},
- Common::FR_FRA, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::FR_FRA, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Space Quest 5 - Italian DOS Floppy (from glorifindel)
// SCI interpreter version 1.001.068 (just a guess)
@@ -3845,7 +3863,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.000", 0, "5040026519f37199f3616fb1d4704dff", 6047170},
{"resource.map", 0, "5b09168baa2f6e2e22787429b2d72f54", 6492},
AD_LISTEND},
- Common::IT_ITA, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::IT_ITA, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Space Quest 5 - Spanish DOS Floppy (from mirir, bug report #3090664)
{"sq5", "", {
@@ -3853,7 +3871,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "5714a899033bdebf2d61ad333c8c6637", 6492},
{"resource.msg", 0, "46deca7ef9cf057f7d442df98c1a2ae2", 134612},
AD_LISTEND},
- Common::ES_ESP, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::ES_ESP, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Space Quest 5 - Russian DOS
// Executable scanning reports "1.001.068", VERSION file reports "1.994"
@@ -3862,7 +3880,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.000", 0, "6f9ed21e1001526b4137f6703ed476af", 6103778},
{"resource.msg", 0, "0a8931990cd2eac1691602391c68ab85", 147580},
AD_LISTEND},
- Common::RU_RUS, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::RU_RUS, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
#ifdef ENABLE_SCI32
// Space Quest 6 - English DOS/Win3.11 CD (from the Space Quest Collection)
@@ -3871,7 +3889,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "6dddfa3a8f3a3a513ec9dfdfae955005", 10528},
{"resource.000", 0, "c4259ab7355aead07773397b1052827d", 41150806},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_CD | ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_CD | ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Space Quest 6 - English DOS/Win3.11 CD ver 1.11 (from FRG)
// SCI interpreter version 2.100.002 (just a guess)
@@ -3879,7 +3897,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "e0615d6e4e10e37ae42e6a2a95aaf145", 10528},
{"resource.000", 0, "c4259ab7355aead07773397b1052827d", 41150806},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_CD | ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_CD | ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Space Quest 6 - French DOS/Win3.11 CD (from French magazine Joystick - September 1997)
// Executable scanning reports "2.100.002", VERSION file reports "1.0"
@@ -3887,7 +3905,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "3c831625931d5079b73ae8c275f52c95", 10534},
{"resource.000", 0, "4195ca940f759424f62b90e262cc1737", 40932397},
AD_LISTEND},
- Common::FR_FRA, Common::kPlatformDOS, ADGF_CD | ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::FR_FRA, Common::kPlatformDOS, ADGF_CD | ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Space Quest 6 - German DOS (from Tobis87, updated info from markcoolio in bug report #2723884)
// SCI interpreter version 2.100.002 (just a guess)
@@ -3895,7 +3913,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "664d797415484f85c90b1b45aedc7686", 10534},
{"resource.000", 0, "ba87ba91e5bdabb4169dd0df75777722", 40933685},
AD_LISTEND},
- Common::DE_DEU, Common::kPlatformDOS, ADGF_CD | ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::DE_DEU, Common::kPlatformDOS, ADGF_CD | ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Space Quest 6 - English DOS/Win3.11 Interactive Demo (from FRG)
// SCI interpreter version 2.100.002 (just a guess)
@@ -3903,7 +3921,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "368f07b07433db3f819fa3fa0e5efee5", 2572},
{"resource.000", 0, "ab12724e078dea34b624e0d2a38dcd7c", 2272050},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO | ADGF_UNSTABLE, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO | ADGF_UNSTABLE, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
#endif // ENABLE_SCI32
// The Island of Dr. Brain - English DOS CD (from jvprat)
@@ -3912,7 +3930,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "2388efef8430b041b0f3b00b9050e4a2", 3281},
{"resource.000", 0, "b3acd9b9dd7fe53c4ee133ac9a1acfab", 2103560},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO3(GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO3(GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// The Island of Dr. Brain - English DOS (from Quietust)
// Executable scanning reports "1.001.053", VERSION file reports "1.1 2.3.93"
@@ -3920,7 +3938,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "3c07da06bdd1689f9d07af78fb94d0ec", 3101},
{"resource.000", 0, "ecc686e0034fb4d41de077ac7167b3cf", 1947866},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// The Island of Dr. Brain - English DOS Non-Interactive Demo
// SCI interpreter version 1.001.053 (just a guess)
@@ -3928,7 +3946,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "a8e5ca8ed1996974afa59f4c45e06195", 986},
{"resource.000", 0, "b3acd9b9dd7fe53c4ee133ac9a1acfab", 586560},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
#ifdef ENABLE_SCI32
// Torin's Passage - English Windows Interactive Demo
@@ -3937,7 +3955,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resmap.000", 0, "9a3e172cde9963d0a969f26469318cec", 3403},
{"ressci.000", 0, "db3e290481c35c3224e9602e71e4a1f1", 5073868},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformWindows, ADGF_DEMO | ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformWindows, ADGF_DEMO | ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Torin's Passage (Multilingual) - English Windows CD
// SCI interpreter version 2.100.002
@@ -3945,7 +3963,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resmap.000", 0, "bb3b0b22ff08df54fbe2d06263409be6", 9799},
{"ressci.000", 0, "693a259d346c9360f4a0c11fdaae430a", 55973887},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Torin's Passage (Multilingual) - Spanish Windows CD (from jvprat)
// Executable scanning reports "2.100.002", VERSION file reports "1.0"
@@ -3954,7 +3972,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"ressci.000", 0, "693a259d346c9360f4a0c11fdaae430a", 55973887},
// TODO: depend on one of the patches?
AD_LISTEND},
- Common::ES_ESP, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::ES_ESP, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Torin's Passage (Multilingual) - French Windows CD
// SCI interpreter version 2.100.002
@@ -3962,7 +3980,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resmap.000", 0, "bb3b0b22ff08df54fbe2d06263409be6", 9799},
{"ressci.000", 0, "693a259d346c9360f4a0c11fdaae430a", 55973887},
AD_LISTEND},
- Common::FR_FRA, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::FR_FRA, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Torin's Passage (Multilingual) - German Windows CD
// SCI interpreter version 2.100.002
@@ -3970,7 +3988,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resmap.000", 0, "bb3b0b22ff08df54fbe2d06263409be6", 9799},
{"ressci.000", 0, "693a259d346c9360f4a0c11fdaae430a", 55973887},
AD_LISTEND},
- Common::DE_DEU, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::DE_DEU, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Torin's Passage (Multilingual) - Italian Windows CD (from glorifindel)
// SCI interpreter version 2.100.002
@@ -3978,7 +3996,7 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resmap.000", 0, "bb3b0b22ff08df54fbe2d06263409be6", 9799},
{"ressci.000", 0, "693a259d346c9360f4a0c11fdaae430a", 55973887},
AD_LISTEND},
- Common::IT_ITA, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::IT_ITA, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
// Torin's Passage - French Windows (from LePhilousophe)
// SCI interpreter version 2.100.002
@@ -3986,7 +4004,19 @@ static const struct ADGameDescription SciGameDescriptions[] = {
{"resmap.000", 0, "66ed46e3e56f487e688d52f05b33d0ba", 9787},
{"ressci.000", 0, "118f9bec04bfe17c4f87bbb5ddb43c18", 56126981},
AD_LISTEND},
- Common::FR_FRA, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::FR_FRA, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+
+ // Torin's Passage - English Macintosh
+ {"torin", "", {
+ {"Data1", 0, "63887e33cc282c92dc1f916f54aea8eb", 700786},
+ {"Data2", 0, "da2f13be2819a7333fee372d38b8d1a2", 122485},
+ {"Data3", 0, "e9fda4f1714ddb443545ba8a2d58ef18", 7299126},
+ {"Data4", 0, "59b432ec35b24a216432a556e25087ef", 7209309},
+ {"Data5", 0, "189e809f24aee83c707dea03a543c7c4", 6615563},
+ {"Data6", 0, "b639487c83d1dae0e001e700f3631566", 7594881},
+ {"Data7", 0, "2afd9b5434102b89610916b904c3f73a", 7627374},
+ AD_LISTEND},
+ Common::EN_ANY, Common::kPlatformMacintosh, ADGF_MACRESFORK | ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
#endif // ENABLE_SCI32
// SCI Fanmade Games
diff --git a/engines/sci/engine/kernel.cpp b/engines/sci/engine/kernel.cpp
index 8d55790ad2..12746e17d6 100644
--- a/engines/sci/engine/kernel.cpp
+++ b/engines/sci/engine/kernel.cpp
@@ -35,8 +35,6 @@ namespace Sci {
Kernel::Kernel(ResourceManager *resMan, SegManager *segMan)
: _resMan(resMan), _segMan(segMan), _invalid("<invalid>") {
- loadSelectorNames();
- mapSelectors(); // Map a few special selectors for later use
}
Kernel::~Kernel() {
@@ -53,6 +51,11 @@ Kernel::~Kernel() {
}
}
+void Kernel::init() {
+ loadSelectorNames();
+ mapSelectors(); // Map a few special selectors for later use
+}
+
uint Kernel::getSelectorNamesSize() const {
return _selectorNames.size();
}
@@ -104,6 +107,11 @@ int Kernel::findSelector(const char *selectorName) const {
return -1;
}
+// used by Script patcher to figure out, if it's okay to initialize signature/patch-table
+bool Kernel::selectorNamesAvailable() {
+ return !_selectorNames.empty();
+}
+
void Kernel::loadSelectorNames() {
Resource *r = _resMan->findResource(ResourceId(kResourceTypeVocab, VOCAB_RESOURCE_SELECTORS), 0);
bool oldScriptHeader = (getSciVersion() == SCI_VERSION_0_EARLY);
diff --git a/engines/sci/engine/kernel.h b/engines/sci/engine/kernel.h
index 8a021073fc..69c3a6d0c9 100644
--- a/engines/sci/engine/kernel.h
+++ b/engines/sci/engine/kernel.h
@@ -145,6 +145,8 @@ public:
*/
Kernel(ResourceManager *resMan, SegManager *segMan);
~Kernel();
+
+ void init();
uint getSelectorNamesSize() const;
const Common::String &getSelectorName(uint selector);
@@ -159,6 +161,8 @@ public:
* @return The appropriate selector ID, or -1 on error
*/
int findSelector(const char *selectorName) const;
+
+ bool selectorNamesAvailable();
// Script dissection/dumping functions
void dissectScript(int scriptNumber, Vocabulary *vocab);
diff --git a/engines/sci/engine/kernel_tables.h b/engines/sci/engine/kernel_tables.h
index d7858180f1..39244bd760 100644
--- a/engines/sci/engine/kernel_tables.h
+++ b/engines/sci/engine/kernel_tables.h
@@ -421,7 +421,7 @@ static SciKernelMapEntry s_kernelMap[] = {
{ MAP_CALL(PrevNode), SIG_EVERYWHERE, "n", NULL, NULL },
{ MAP_CALL(PriCoord), SIG_EVERYWHERE, "i", NULL, NULL },
{ MAP_CALL(Random), SIG_EVERYWHERE, "i(i)(i)", NULL, NULL },
- { MAP_CALL(ReadNumber), SIG_EVERYWHERE, "r", NULL, NULL },
+ { MAP_CALL(ReadNumber), SIG_EVERYWHERE, "r", NULL, kReadNumber_workarounds },
{ MAP_CALL(RemapColors), SIG_SCI11, SIGFOR_ALL, "i(i)(i)(i)(i)", NULL, NULL },
#ifdef ENABLE_SCI32
{ "RemapColors", kRemapColors32, SIG_SCI32, SIGFOR_ALL, "i(i)(i)(i)(i)(i)", NULL, NULL },
diff --git a/engines/sci/engine/kfile.cpp b/engines/sci/engine/kfile.cpp
index c6635f2f27..b940eca6f5 100644
--- a/engines/sci/engine/kfile.cpp
+++ b/engines/sci/engine/kfile.cpp
@@ -718,7 +718,7 @@ reg_t kSave(EngineState *s, int argc, reg_t *argv) {
reg_t kSaveGame(EngineState *s, int argc, reg_t *argv) {
Common::String game_id;
- int16 virtualId = argv[1].toSint16();
+ int16 virtualId = argv[1].toSint16();
int16 savegameId = -1;
Common::String game_description;
Common::String version;
diff --git a/engines/sci/engine/kgraphics.cpp b/engines/sci/engine/kgraphics.cpp
index e4b3028bcd..79ab2d138b 100644
--- a/engines/sci/engine/kgraphics.cpp
+++ b/engines/sci/engine/kgraphics.cpp
@@ -185,7 +185,8 @@ static reg_t kSetCursorSci11(EngineState *s, int argc, reg_t *argv) {
hotspot = new Common::Point(argv[3].toSint16(), argv[4].toSint16());
// Fallthrough
case 3:
- if (g_sci->getPlatform() == Common::kPlatformMacintosh) {
+ if (g_sci->getPlatform() == Common::kPlatformMacintosh && g_sci->getGameId() != GID_TORIN) {
+ // Torin Mac seems to be the only game that uses view cursors
delete hotspot; // Mac cursors have their own hotspot, so ignore any we get here
g_sci->_gfxCursor->kernelSetMacCursor(argv[0].toUint16(), argv[1].toUint16(), argv[2].toUint16());
} else {
diff --git a/engines/sci/engine/object.cpp b/engines/sci/engine/object.cpp
index b28026b71f..6f219b388e 100644
--- a/engines/sci/engine/object.cpp
+++ b/engines/sci/engine/object.cpp
@@ -175,6 +175,7 @@ bool Object::initBaseObject(SegManager *segMan, reg_t addr, bool doInitSuperClas
_variables.resize(baseObj->getVarCount());
// Copy base from species class, as we need its selector IDs
_baseObj = baseObj->_baseObj;
+ assert(_baseObj);
if (doInitSuperClass)
initSuperClass(segMan, addr);
diff --git a/engines/sci/engine/savegame.cpp b/engines/sci/engine/savegame.cpp
index c60b50a964..ce9a672572 100644
--- a/engines/sci/engine/savegame.cpp
+++ b/engines/sci/engine/savegame.cpp
@@ -219,25 +219,30 @@ void SegManager::saveLoadWithSerializer(Common::Serializer &s) {
syncArray<Class>(s, _classTable);
- // Now that all scripts are loaded, init their objects
- for (uint i = 0; i < _heap.size(); i++) {
- if (!_heap[i] || _heap[i]->getType() != SEG_TYPE_SCRIPT)
- continue;
+ // Now that all scripts are loaded, init their objects.
+ // Just like in Script::initializeObjectsSci0, we do two passes
+ // in case an object is loaded before its base.
+ int passes = getSciVersion() < SCI_VERSION_1_1 ? 2 : 1;
+ for (int pass = 1; pass <= passes; ++pass) {
+ for (uint i = 0; i < _heap.size(); i++) {
+ if (!_heap[i] || _heap[i]->getType() != SEG_TYPE_SCRIPT)
+ continue;
- Script *scr = (Script *)_heap[i];
- scr->syncLocalsBlock(this);
+ Script *scr = (Script *)_heap[i];
+ scr->syncLocalsBlock(this);
- ObjMap objects = scr->getObjectMap();
- for (ObjMap::iterator it = objects.begin(); it != objects.end(); ++it) {
- reg_t addr = it->_value.getPos();
- Object *obj = scr->scriptObjInit(addr, false);
+ ObjMap objects = scr->getObjectMap();
+ for (ObjMap::iterator it = objects.begin(); it != objects.end(); ++it) {
+ reg_t addr = it->_value.getPos();
+ Object *obj = scr->scriptObjInit(addr, false);
- if (getSciVersion() < SCI_VERSION_1_1) {
- if (!obj->initBaseObject(this, addr, false)) {
- // TODO/FIXME: This should not be happening at all. It might indicate a possible issue
- // with the garbage collector. It happens for example in LSL5 (German, perhaps English too).
- warning("Failed to locate base object for object at %04X:%04X; skipping", PRINT_REG(addr));
- objects.erase(addr.toUint16());
+ if (pass == 2) {
+ if (!obj->initBaseObject(this, addr, false)) {
+ // TODO/FIXME: This should not be happening at all. It might indicate a possible issue
+ // with the garbage collector. It happens for example in LSL5 (German, perhaps English too).
+ warning("Failed to locate base object for object at %04X:%04X; skipping", PRINT_REG(addr));
+ objects.erase(addr.toUint16());
+ }
}
}
}
@@ -465,7 +470,7 @@ void Script::syncStringHeap(Common::Serializer &s) {
break;
} while (1);
- } else if (getSciVersion() >= SCI_VERSION_1_1 && getSciVersion() <= SCI_VERSION_2_1){
+ } else if (getSciVersion() >= SCI_VERSION_1_1 && getSciVersion() <= SCI_VERSION_2_1){
// Strings in SCI1.1 come after the object instances
byte *buf = _heapStart + 4 + READ_SCI11ENDIAN_UINT16(_heapStart + 2) * 2;
@@ -484,7 +489,7 @@ void Script::saveLoadWithSerializer(Common::Serializer &s) {
s.syncAsSint32LE(_nr);
if (s.isLoading())
- load(_nr, g_sci->getResMan());
+ load(_nr, g_sci->getResMan(), g_sci->getScriptPatcher());
s.skip(4, VER(14), VER(22)); // OBSOLETE: Used to be _bufSize
s.skip(4, VER(14), VER(22)); // OBSOLETE: Used to be _scriptSize
s.skip(4, VER(14), VER(22)); // OBSOLETE: Used to be _heapSize
diff --git a/engines/sci/engine/script.cpp b/engines/sci/engine/script.cpp
index 36d2841b07..c661a00185 100644
--- a/engines/sci/engine/script.cpp
+++ b/engines/sci/engine/script.cpp
@@ -32,7 +32,8 @@
namespace Sci {
-Script::Script() : SegmentObj(SEG_TYPE_SCRIPT), _buf(NULL) {
+Script::Script()
+ : SegmentObj(SEG_TYPE_SCRIPT), _buf(NULL) {
freeScript();
}
@@ -65,7 +66,7 @@ void Script::freeScript() {
_objects.clear();
}
-void Script::load(int script_nr, ResourceManager *resMan) {
+void Script::load(int script_nr, ResourceManager *resMan, ScriptPatcher *scriptPatcher) {
freeScript();
Resource *script = resMan->findResource(ResourceId(kResourceTypeScript, script_nr), 0);
@@ -136,7 +137,7 @@ void Script::load(int script_nr, ResourceManager *resMan) {
memcpy(_buf, script->data, script->size);
// Check scripts for matching signatures and patch those, if found
- matchSignatureAndPatch(_nr, _buf, script->size);
+ 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);
diff --git a/engines/sci/engine/script.h b/engines/sci/engine/script.h
index 0b499203c2..9e016156b8 100644
--- a/engines/sci/engine/script.h
+++ b/engines/sci/engine/script.h
@@ -25,12 +25,13 @@
#include "common/str.h"
#include "sci/engine/segment.h"
+#include "sci/engine/script_patches.h"
namespace Sci {
struct EngineState;
class ResourceManager;
-struct SciScriptSignature;
+struct SciScriptPatcherEntry;
enum ScriptObjectTypes {
SCI_OBJ_TERMINATOR,
@@ -96,11 +97,7 @@ public:
~Script();
void freeScript();
- void load(int script_nr, ResourceManager *resMan);
-
- void matchSignatureAndPatch(uint16 scriptNr, byte *scriptData, const uint32 scriptSize);
- int32 findSignature(const SciScriptSignature *signature, const byte *scriptData, const uint32 scriptSize);
- void applyPatch(const uint16 *patch, byte *scriptData, const uint32 scriptSize, int32 signatureOffset);
+ void load(int script_nr, ResourceManager *resMan, ScriptPatcher *scriptPatcher);
virtual bool isValidOffset(uint16 offset) const;
virtual SegmentRef dereference(reg_t pointer);
diff --git a/engines/sci/engine/script_patches.cpp b/engines/sci/engine/script_patches.cpp
index d2c3356d54..8f05cc1453 100644
--- a/engines/sci/engine/script_patches.cpp
+++ b/engines/sci/engine/script_patches.cpp
@@ -21,43 +21,111 @@
*/
#include "sci/sci.h"
+#include "sci/engine/kernel.h"
#include "sci/engine/script.h"
#include "sci/engine/state.h"
#include "sci/engine/features.h"
+#include "sci/engine/script_patches.h"
#include "common/util.h"
namespace Sci {
-#define PATCH_END 0xFFFF
-#define PATCH_COMMANDMASK 0xF000
-#define PATCH_VALUEMASK 0x0FFF
-#define PATCH_ADDTOOFFSET 0xE000
-#define PATCH_GETORIGINALBYTE 0xD000
-#define PATCH_ADJUSTWORD 0xC000
-#define PATCH_ADJUSTWORD_NEG 0xB000
-#define PATCH_MAGICDWORD(a, b, c, d) CONSTANT_LE_32(a | (b << 8) | (c << 16) | (d << 24))
-#define PATCH_VALUELIMIT 4096
-
-struct SciScriptSignature {
- uint16 scriptNr;
- const char *description;
- int16 applyCount;
- uint32 magicDWord;
- int magicOffset;
- const byte *data;
- const uint16 *patch;
+// IMPORTANT:
+// every patch entry needs the following:
+// - script number (pretty obvious)
+//
+// - apply count
+// specifies the number of times a patch is supposed to get applied.
+// Most of the time, it should be 1.
+//
+// - magicDWORD + magicOffset
+// please ALWAYS put 0 for those two. Both will get filled out at runtime by the patcher.
+//
+// - signature data (is used to identify certain script code, that needs patching)
+// every signature needs to contain SIG_MAGICDWORD once.
+// The following 4 bytes after SIG_MAGICDWORD - which don't have to be fixed, you may for example
+// use SIG_SELECTOR16, will get used to quickly search for a partly match before verifying that
+// the whole signature actually matches. If it's not included, the script patcher will error() out
+// right when loading up the game.
+// If selector-IDs are included, please use SIG_SELECTOR16 + SIG_SELECTOR8 [1]. Simply
+// specify the selector that way, so that the patcher will search for the specific
+// selector instead of looking for a hardcoded value. Selectors may not be the same
+// between game versions.
+// For UINT16s either use SIG_UINT16 or SIG_SELECTOR16.
+// Macintosh versions of SCI games are using BE ordering instead of LE since SCI1.1 for UINT16s in scripts
+// By using those 2 commands, it's possible to make patches work for PC and Mac versions of the same game.
+// You may also skip bytes by using the SIG_ADDTOOFFSET command
+// Every signature data needs to get terminated using SIGNATURE_END
+//
+// - patch data (is used for actually patching scripts)
+// When a match is found, the patch data will get applied.
+// Patch data is similar to signature data. Just use PATCH_SELECTOR16 + PATCH_SELECTOR8 [1]
+// for patching in selectors.
+// There are also patch specific commands.
+// Those are PATCH_GETORIGINALBYTE, which fetches a byte from the original script
+// and PATCH_GETORIGINALBYTEADJUST, which does the same but gets a second value
+// from the uint16 array and uses that value to adjust the original byte.
+// Every patch data needs to get terminated using PATCH_END
+//
+// - and please always add a comment about why the patch was done and what's causing issues.
+// If possible make sure, that the patch works on localized (or just different) game versions
+// as well in case those need patching too.
+//
+// [1] - selectors need to get specified in selectorTable[] and ScriptPatcherSelectors-enum
+// before they can get used using the SIG_SELECTORx and PATCH_SELECTORx commands.
+// You have to use the exact same order in both the table and the enum, otherwise
+// it won't work.
+
+static const char *const selectorNameTable[] = {
+ "cycles", // system selector
+ "seconds", // system selector
+ "init", // system selector
+ "dispose", // system selector
+ "new", // system selector
+ "curEvent", // system selector
+ "disable", // system selector
+ "doit", // system selector
+ "show", // system selector
+ "x", // system selector
+ "cel", // system selector
+ "setMotion", // system selector
+ "overlay", // system selector
+ "deskSarg", // Gabriel Knight
+ "localize", // Freddy Pharkas
+ "put", // Police Quest 1 VGA
+ "solvePuzzle", // Quest For Glory 3
+ "timesShownID", // Space Quest 1 VGA
+ "startText", // King's Quest 6 CD / Laura Bow 2 CD for audio+text support
+ "startAudio", // King's Quest 6 CD / Laura Bow 2 CD for audio+text support
+ "modNum", // King's Quest 6 CD / Laura Bow 2 CD for audio+text support
+ NULL
+};
+
+enum ScriptPatcherSelectors {
+ SELECTOR_cycles = 0,
+ SELECTOR_seconds,
+ SELECTOR_init,
+ SELECTOR_dispose,
+ SELECTOR_new,
+ SELECTOR_curEvent,
+ SELECTOR_disable,
+ SELECTOR_doit,
+ SELECTOR_show,
+ SELECTOR_x,
+ SELECTOR_cel,
+ SELECTOR_setMotion,
+ SELECTOR_overlay,
+ SELECTOR_deskSarg,
+ SELECTOR_localize,
+ SELECTOR_put,
+ SELECTOR_solvePuzzle,
+ SELECTOR_timesShownID,
+ SELECTOR_startText,
+ SELECTOR_startAudio,
+ SELECTOR_modNum
};
-#define SCI_SIGNATUREENTRY_TERMINATOR { 0, NULL, 0, 0, 0, NULL, NULL }
-
-// signatures are built like this:
-// - first a counter of the bytes that follow
-// - then the actual bytes that need to get matched
-// - then another counter of bytes (0 for EOS)
-// - if not EOS, an adjust offset and the actual bytes
-// - rinse and repeat
-
// ===========================================================================
// Conquests of Camelot
// At the bazaar in Jerusalem, it's possible to see a girl taking a shower.
@@ -77,36 +145,33 @@ struct SciScriptSignature {
//
// We fix the script by patching in a jump to the proper code inside fawaz::doit.
// Responsible method: fawaz::handleEvent
-// Fixes bug #3614969
-const byte camelotSignaturePeepingTom[] = {
- 5,
- 0x72, 0x7e, 0x07, // lofsa fawaz <-- start of proper initializion code
- 0xa1, 0xb9, // sag b9h
- +255, 0,
- +255, 0,
- +61, 19, // skip 571 bytes
- 0x39, 0x7a, // pushi 7a <-- initialization code when walking automatically
- 0x78, // push1
- 0x7a, // push2
- 0x38, 0xa9, 0x00, // pushi 00a9 - script 169
- 0x78, // push1
- 0x43, 0x02, 0x04, // call kScriptID
- 0x36, // push
- 0x81, 0x00, // lag 00
- 0x4a, 0x06, // send 06
- 0x32, 0x20, 0x05, // jmp [end of fawaz::handleEvent]
- 0
-};
-
-const uint16 camelotPatchPeepingTom[] = {
- PATCH_ADDTOOFFSET | +576,
- 0x32, 0xbd, 0xfd, // jmp to fawaz::doit / properly init peepingTom code
+// Fixes bug: #6402
+static const uint16 camelotSignaturePeepingTom[] = {
+ 0x72, SIG_MAGICDWORD, SIG_UINT16(0x077e), // lofsa fawaz <-- start of proper initializion code
+ 0xa1, 0xb9, // sag b9h
+ SIG_ADDTOOFFSET(+571), // skip 571 bytes
+ 0x39, 0x7a, // pushi 7a <-- initialization code when walking automatically
+ 0x78, // push1
+ 0x7a, // push2
+ 0x38, SIG_UINT16(0x00a9), // + 0xa9, 0x00, // pushi 00a9 - script 169
+ 0x78, // push1
+ 0x43, 0x02, 0x04, // call kScriptID
+ 0x36, // push
+ 0x81, 0x00, // lag 00
+ 0x4a, 0x06, // send 06
+ 0x32, SIG_UINT16(0x0520), // jmp [end of fawaz::handleEvent]
+ SIG_END
+};
+
+static const uint16 camelotPatchPeepingTom[] = {
+ PATCH_ADDTOOFFSET(+576),
+ 0x32, PATCH_UINT16(0xfdbd), // jmp to fawaz::doit / properly init peepingTom code
PATCH_END
};
-// script, description, magic DWORD, adjust
-const SciScriptSignature camelotSignatures[] = {
- { 62, "fix peepingTom Sierra bug", 1, PATCH_MAGICDWORD(0x7e, 0x07, 0xa1, 0xb9), -1, camelotSignaturePeepingTom, camelotPatchPeepingTom },
+// script, description, signature patch
+static const SciScriptPatcherEntry camelotSignatures[] = {
+ { true, 62, "fix peepingTom Sierra bug", 1, camelotSignaturePeepingTom, camelotPatchPeepingTom },
SCI_SIGNATUREENTRY_TERMINATOR
};
@@ -115,64 +180,67 @@ const SciScriptSignature camelotSignatures[] = {
// boundaries of room 660. Normally a textbox is supposed to get on screen
// but the call is wrong, so not only do we get an error message the script
// is also hanging because the cue won't get sent out
-// This also happens in sierra sci - refer to bug #3038387
-const byte ecoquest1SignatureStayAndHelp[] = {
- 40,
- 0x3f, 0x01, // link 01
- 0x87, 0x01, // lap param[1]
- 0x65, 0x14, // aTop state
- 0x36, // push
- 0x3c, // dup
- 0x35, 0x00, // ldi 00
- 0x1a, // eq?
- 0x31, 0x1c, // bnt [next state]
- 0x76, // push0
- 0x45, 0x01, 0x00, // callb export1 from script 0 (switching control off)
- 0x38, 0x22, 0x01, // pushi 0122
- 0x78, // push1
- 0x76, // push0
- 0x81, 0x00, // lag global[0]
- 0x4a, 0x06, // send 06 - call ego::setMotion(0)
- 0x39, 0x6e, // pushi 6e (selector init)
- 0x39, 0x04, // pushi 04
- 0x76, // push0
- 0x76, // push0
- 0x39, 0x17, // pushi 17
- 0x7c, // pushSelf
- 0x51, 0x82, // class EcoNarrator
- 0x4a, 0x0c, // send 0c - call EcoNarrator::init(0, 0, 23, self) (BADLY BROKEN!)
- 0x33, // jmp [end]
- 0
-};
-
-const uint16 ecoquest1PatchStayAndHelp[] = {
- 0x87, 0x01, // lap param[1]
- 0x65, 0x14, // aTop state
- 0x36, // push
- 0x2f, 0x22, // bt [next state] (this optimization saves 6 bytes)
- 0x39, 0x00, // pushi 0 (wasting 1 byte here)
- 0x45, 0x01, 0x00, // callb export1 from script 0 (switching control off)
- 0x38, 0x22, 0x01, // pushi 0122
- 0x78, // push1
- 0x76, // push0
- 0x81, 0x00, // lag global[0]
- 0x4a, 0x06, // send 06 - call ego::setMotion(0)
- 0x39, 0x6e, // pushi 6e (selector init)
- 0x39, 0x06, // pushi 06
- 0x39, 0x02, // pushi 02 (additional 2 bytes)
- 0x76, // push0
- 0x76, // push0
- 0x39, 0x17, // pushi 17
- 0x7c, // pushSelf
- 0x38, 0x80, 0x02, // pushi 280 (additional 3 bytes)
- 0x51, 0x82, // class EcoNarrator
- 0x4a, 0x10, // send 10 - call EcoNarrator::init(2, 0, 0, 23, self, 640)
+// This also happens in sierra sci
+// Applies to at least: PC-CD
+// Responsible method: stayAndHelp::changeState
+// Fixes bug: #5107
+static const uint16 ecoquest1SignatureStayAndHelp[] = {
+ 0x3f, 0x01, // link 01
+ 0x87, 0x01, // lap param[1]
+ 0x65, 0x14, // aTop state
+ 0x36, // push
+ 0x3c, // dup
+ 0x35, 0x00, // ldi 00
+ 0x1a, // eq?
+ 0x31, 0x1c, // bnt [next state]
+ 0x76, // push0
+ 0x45, 0x01, 0x00, // callb export1 from script 0 (switching control off)
+ SIG_MAGICDWORD,
+ 0x38, SIG_UINT16(0x0122), // pushi 0122
+ 0x78, // push1
+ 0x76, // push0
+ 0x81, 0x00, // lag global[0]
+ 0x4a, 0x06, // send 06 - call ego::setMotion(0)
+ 0x39, SIG_SELECTOR8(init), // pushi "init"
+ 0x39, 0x04, // pushi 04
+ 0x76, // push0
+ 0x76, // push0
+ 0x39, 0x17, // pushi 17
+ 0x7c, // pushSelf
+ 0x51, 0x82, // class EcoNarrator
+ 0x4a, 0x0c, // send 0c - call EcoNarrator::init(0, 0, 23, self) (BADLY BROKEN!)
+ 0x33, // jmp [end]
+ SIG_END
+};
+
+static const uint16 ecoquest1PatchStayAndHelp[] = {
+ 0x87, 0x01, // lap param[1]
+ 0x65, 0x14, // aTop state
+ 0x36, // push
+ 0x2f, 0x22, // bt [next state] (this optimization saves 6 bytes)
+ 0x39, 0x00, // pushi 0 (wasting 1 byte here)
+ 0x45, 0x01, 0x00, // callb export1 from script 0 (switching control off)
+ 0x38, PATCH_UINT16(0x0122), // pushi 0122
+ 0x78, // push1
+ 0x76, // push0
+ 0x81, 0x00, // lag global[0]
+ 0x4a, 0x06, // send 06 - call ego::setMotion(0)
+ 0x39, PATCH_SELECTOR8(init), // pushi "init"
+ 0x39, 0x06, // pushi 06
+ 0x39, 0x02, // pushi 02 (additional 2 bytes)
+ 0x76, // push0
+ 0x76, // push0
+ 0x39, 0x17, // pushi 17
+ 0x7c, // pushSelf
+ 0x38, PATCH_UINT16(0x0280), // pushi 280 (additional 3 bytes)
+ 0x51, 0x82, // class EcoNarrator
+ 0x4a, 0x10, // send 10 - call EcoNarrator::init(2, 0, 0, 23, self, 640)
PATCH_END
};
-// script, description, magic DWORD, adjust
-const SciScriptSignature ecoquest1Signatures[] = {
- { 660, "CD: bad messagebox and freeze", 1, PATCH_MAGICDWORD(0x38, 0x22, 0x01, 0x78), -17, ecoquest1SignatureStayAndHelp, ecoquest1PatchStayAndHelp },
+// script, description, signature patch
+static const SciScriptPatcherEntry ecoquest1Signatures[] = {
+ { true, 660, "CD: bad messagebox and freeze", 1, ecoquest1SignatureStayAndHelp, ecoquest1PatchStayAndHelp },
SCI_SIGNATUREENTRY_TERMINATOR
};
@@ -181,122 +249,124 @@ const SciScriptSignature ecoquest1Signatures[] = {
// ecorder. This is done by reusing temp-space, that was filled on state 1.
// this worked in sierra sci just by accident. In our sci, the temp space
// is resetted every time, which means the previous text isn't available
-// anymore. We have to patch the code because of that - bug #3035386
-const byte ecoquest2SignatureEcorder[] = {
- 35,
- 0x31, 0x22, // bnt [next state]
- 0x39, 0x0a, // pushi 0a
- 0x5b, 0x04, 0x1e, // lea temp[1e]
- 0x36, // push
- 0x39, 0x64, // pushi 64
- 0x39, 0x7d, // pushi 7d
- 0x39, 0x32, // pushi 32
- 0x39, 0x66, // pushi 66
- 0x39, 0x17, // pushi 17
- 0x39, 0x69, // pushi 69
- 0x38, 0x31, 0x26, // pushi 2631
- 0x39, 0x6a, // pushi 6a
- 0x39, 0x64, // pushi 64
- 0x43, 0x1b, 0x14, // call kDisplay
- 0x35, 0x0a, // ldi 0a
- 0x65, 0x20, // aTop ticks
- 0x33, // jmp [end]
- +1, 5, // [skip 1 byte]
- 0x3c, // dup
- 0x35, 0x03, // ldi 03
- 0x1a, // eq?
- 0x31, // bnt [end]
- 0
-};
-
-const uint16 ecoquest2PatchEcorder[] = {
- 0x2f, 0x02, // bt [to pushi 07]
- 0x3a, // toss
- 0x48, // ret
- 0x38, 0x07, 0x00, // pushi 07 (parameter count) (waste 1 byte)
- 0x39, 0x0b, // push (FillBoxAny)
- 0x39, 0x1d, // pushi 29d
- 0x39, 0x73, // pushi 115d
- 0x39, 0x5e, // pushi 94d
- 0x38, 0xd7, 0x00, // pushi 215d
- 0x78, // push1 (visual screen)
- 0x38, 0x17, 0x00, // pushi 17 (color) (waste 1 byte)
- 0x43, 0x6c, 0x0e, // call kGraph
- 0x38, 0x05, 0x00, // pushi 05 (parameter count) (waste 1 byte)
- 0x39, 0x0c, // pushi 12d (UpdateBox)
- 0x39, 0x1d, // pushi 29d
- 0x39, 0x73, // pushi 115d
- 0x39, 0x5e, // pushi 94d
- 0x38, 0xd7, 0x00, // pushi 215d
- 0x43, 0x6c, 0x0a, // call kGraph
+// anymore. We have to patch the code because of that.
+// Fixes bug: #4993
+static const uint16 ecoquest2SignatureEcorder[] = {
+ 0x31, 0x22, // bnt [next state]
+ 0x39, 0x0a, // pushi 0a
+ 0x5b, 0x04, 0x1e, // lea temp[1e]
+ 0x36, // push
+ SIG_MAGICDWORD,
+ 0x39, 0x64, // pushi 64
+ 0x39, 0x7d, // pushi 7d
+ 0x39, 0x32, // pushi 32
+ 0x39, 0x66, // pushi 66
+ 0x39, 0x17, // pushi 17
+ 0x39, 0x69, // pushi 69
+ 0x38, PATCH_UINT16(0x2631), // pushi 2631
+ 0x39, 0x6a, // pushi 6a
+ 0x39, 0x64, // pushi 64
+ 0x43, 0x1b, 0x14, // call kDisplay
+ 0x35, 0x0a, // ldi 0a
+ 0x65, 0x20, // aTop ticks
+ 0x33, // jmp [end]
+ SIG_ADDTOOFFSET(+1), // [skip 1 byte]
+ 0x3c, // dup
+ 0x35, 0x03, // ldi 03
+ 0x1a, // eq?
+ 0x31, // bnt [end]
+ SIG_END
+};
+
+static const uint16 ecoquest2PatchEcorder[] = {
+ 0x2f, 0x02, // bt [to pushi 07]
+ 0x3a, // toss
+ 0x48, // ret
+ 0x38, PATCH_UINT16(0x0007), // pushi 07 (parameter count) (waste 1 byte)
+ 0x39, 0x0b, // push (FillBoxAny)
+ 0x39, 0x1d, // pushi 29d
+ 0x39, 0x73, // pushi 115d
+ 0x39, 0x5e, // pushi 94d
+ 0x38, PATCH_UINT16(0x00d7), // pushi 215d
+ 0x78, // push1 (visual screen)
+ 0x38, PATCH_UINT16(0x0017), // pushi 17 (color) (waste 1 byte)
+ 0x43, 0x6c, 0x0e, // call kGraph
+ 0x38, PATCH_UINT16(0x0005), // pushi 05 (parameter count) (waste 1 byte)
+ 0x39, 0x0c, // pushi 12d (UpdateBox)
+ 0x39, 0x1d, // pushi 29d
+ 0x39, 0x73, // pushi 115d
+ 0x39, 0x5e, // pushi 94d
+ 0x38, PATCH_UINT16(0x00d7), // pushi 215d
+ 0x43, 0x6c, 0x0a, // call kGraph
PATCH_END
};
// ===========================================================================
-// Same patch as above for the ecorder introduction. Fixes bug #3092115.
+// Same patch as above for the ecorder introduction.
// Two workarounds are needed for this patch in workarounds.cpp (when calling
// kGraphFillBoxAny and kGraphUpdateBox), as there isn't enough space to patch
// the function otherwise.
-const byte ecoquest2SignatureEcorderTutorial[] = {
- 36,
- 0x30, 0x23, 0x00, // bnt [next state]
- 0x39, 0x0a, // pushi 0a
- 0x5b, 0x04, 0x1f, // lea temp[1f]
- 0x36, // push
- 0x39, 0x64, // pushi 64
- 0x39, 0x7d, // pushi 7d
- 0x39, 0x32, // pushi 32
- 0x39, 0x66, // pushi 66
- 0x39, 0x17, // pushi 17
- 0x39, 0x69, // pushi 69
- 0x38, 0x31, 0x26, // pushi 2631
- 0x39, 0x6a, // pushi 6a
- 0x39, 0x64, // pushi 64
- 0x43, 0x1b, 0x14, // call kDisplay
- 0x35, 0x1e, // ldi 1e
- 0x65, 0x20, // aTop ticks
- 0x32, // jmp [end]
+// Fixes bug: #6467
+static const uint16 ecoquest2SignatureEcorderTutorial[] = {
+ 0x30, SIG_UINT16(0x0023), // bnt [next state]
+ 0x39, 0x0a, // pushi 0a
+ 0x5b, 0x04, 0x1f, // lea temp[1f]
+ 0x36, // push
+ SIG_MAGICDWORD,
+ 0x39, 0x64, // pushi 64
+ 0x39, 0x7d, // pushi 7d
+ 0x39, 0x32, // pushi 32
+ 0x39, 0x66, // pushi 66
+ 0x39, 0x17, // pushi 17
+ 0x39, 0x69, // pushi 69
+ 0x38, SIG_UINT16(0x2631), // pushi 2631
+ 0x39, 0x6a, // pushi 6a
+ 0x39, 0x64, // pushi 64
+ 0x43, 0x1b, 0x14, // call kDisplay
+ 0x35, 0x1e, // ldi 1e
+ 0x65, 0x20, // aTop ticks
+ 0x32, // jmp [end]
// 2 extra bytes, jmp offset
- 0
+ SIG_END
};
-const uint16 ecoquest2PatchEcorderTutorial[] = {
- 0x31, 0x23, // bnt [next state] (save 1 byte)
+static const uint16 ecoquest2PatchEcorderTutorial[] = {
+ 0x31, 0x23, // bnt [next state] (save 1 byte)
// The parameter count below should be 7, but we're out of bytes
// to patch! A workaround has been added because of this
- 0x78, // push1 (parameter count)
- //0x39, 0x07, // pushi 07 (parameter count)
- 0x39, 0x0b, // push (FillBoxAny)
- 0x39, 0x1d, // pushi 29d
- 0x39, 0x73, // pushi 115d
- 0x39, 0x5e, // pushi 94d
- 0x38, 0xd7, 0x00, // pushi 215d
- 0x78, // push1 (visual screen)
- 0x39, 0x17, // pushi 17 (color)
- 0x43, 0x6c, 0x0e, // call kGraph
+ 0x78, // push1 (parameter count)
+ //0x39, 0x07, // pushi 07 (parameter count)
+ 0x39, 0x0b, // push (FillBoxAny)
+ 0x39, 0x1d, // pushi 29d
+ 0x39, 0x73, // pushi 115d
+ 0x39, 0x5e, // pushi 94d
+ 0x38, PATCH_UINT16(0x00d7), // pushi 215d
+ 0x78, // push1 (visual screen)
+ 0x39, 0x17, // pushi 17 (color)
+ 0x43, 0x6c, 0x0e, // call kGraph
// The parameter count below should be 5, but we're out of bytes
// to patch! A workaround has been added because of this
- 0x78, // push1 (parameter count)
- //0x39, 0x05, // pushi 05 (parameter count)
- 0x39, 0x0c, // pushi 12d (UpdateBox)
- 0x39, 0x1d, // pushi 29d
- 0x39, 0x73, // pushi 115d
- 0x39, 0x5e, // pushi 94d
- 0x38, 0xd7, 0x00, // pushi 215d
- 0x43, 0x6c, 0x0a, // call kGraph
+ 0x78, // push1 (parameter count)
+ //0x39, 0x05, // pushi 05 (parameter count)
+ 0x39, 0x0c, // pushi 12d (UpdateBox)
+ 0x39, 0x1d, // pushi 29d
+ 0x39, 0x73, // pushi 115d
+ 0x39, 0x5e, // pushi 94d
+ 0x38, PATCH_UINT16(0x00d7), // pushi 215d
+ 0x43, 0x6c, 0x0a, // call kGraph
// We are out of bytes to patch at this point,
// so we skip 494 (0x1EE) bytes to reuse this code:
// ldi 1e
// aTop 20
// jmp 030e (jump to end)
- 0x32, 0xee, 0x01, // skip 494 (0x1EE) bytes
+ 0x32, PATCH_UINT16(0x01ee), // skip 494 (0x1EE) bytes
PATCH_END
};
-// script, description, magic DWORD, adjust
-const SciScriptSignature ecoquest2Signatures[] = {
- { 50, "initial text not removed on ecorder", 1, PATCH_MAGICDWORD(0x39, 0x64, 0x39, 0x7d), -8, ecoquest2SignatureEcorder, ecoquest2PatchEcorder },
- { 333, "initial text not removed on ecorder tutorial",1, PATCH_MAGICDWORD(0x39, 0x64, 0x39, 0x7d), -9, ecoquest2SignatureEcorderTutorial, ecoquest2PatchEcorderTutorial },
+// script, description, signature patch
+static const SciScriptPatcherEntry ecoquest2Signatures[] = {
+ { true, 50, "initial text not removed on ecorder", 1, ecoquest2SignatureEcorder, ecoquest2PatchEcorder },
+ { true, 333, "initial text not removed on ecorder tutorial", 1, ecoquest2SignatureEcorderTutorial, ecoquest2PatchEcorderTutorial },
SCI_SIGNATUREENTRY_TERMINATOR
};
@@ -305,27 +375,27 @@ const SciScriptSignature ecoquest2Signatures[] = {
// wrong address when an incorrect word is typed, therefore leading to an
// infinite loop. This script bug was not apparent in SSCI, probably because
// event handling was slightly different there, so it was never discovered.
-// Fixes bug #3038870.
-const byte fanmadeSignatureInfiniteLoop[] = {
- 13,
- 0x38, 0x4c, 0x00, // pushi 004c
- 0x39, 0x00, // pushi 00
- 0x87, 0x01, // lap 01
- 0x4b, 0x04, // send 04
- 0x18, // not
- 0x30, 0x2f, 0x00, // bnt 002f [06a5] --> jmp ffbc [0664] --> BUG! infinite loop
- 0
-};
-
-const uint16 fanmadePatchInfiniteLoop[] = {
- PATCH_ADDTOOFFSET | +10,
- 0x30, 0x32, 0x00, // bnt 0032 [06a8] --> pushi 004c
+// Fixes bug: #5120
+static const uint16 fanmadeSignatureInfiniteLoop[] = {
+ 0x38, SIG_UINT16(0x004c), // pushi 004c
+ 0x39, 0x00, // pushi 00
+ 0x87, 0x01, // lap 01
+ 0x4b, 0x04, // send 04
+ SIG_MAGICDWORD,
+ 0x18, // not
+ 0x30, SIG_UINT16(0x002f), // bnt 002f [06a5] --> jmp ffbc [0664] --> BUG! infinite loop
+ SIG_END
+};
+
+static const uint16 fanmadePatchInfiniteLoop[] = {
+ PATCH_ADDTOOFFSET(+10),
+ 0x30, SIG_UINT16(0x0032), // bnt 0032 [06a8] --> pushi 004c
PATCH_END
};
-// script, description, magic DWORD, adjust
-const SciScriptSignature fanmadeSignatures[] = {
- { 999, "infinite loop on typo", 1, PATCH_MAGICDWORD(0x18, 0x30, 0x2f, 0x00), -9, fanmadeSignatureInfiniteLoop, fanmadePatchInfiniteLoop },
+// script, description, signature patch
+static const SciScriptPatcherEntry fanmadeSignatures[] = {
+ { true, 999, "infinite loop on typo", 1, fanmadeSignatureInfiniteLoop, fanmadePatchInfiniteLoop },
SCI_SIGNATUREENTRY_TERMINATOR
};
@@ -337,21 +407,23 @@ const SciScriptSignature fanmadeSignatures[] = {
// was already playing in the sound driver. In our case we would also stop
// the sample from playing, so we patch it out
// The "score" code is already buggy and sets volume to 0 when playing
-const byte freddypharkasSignatureScoreDisposal[] = {
- 10,
- 0x67, 0x32, // pTos 32 (selector theAudCount)
- 0x78, // push1
- 0x39, 0x0d, // pushi 0d
- 0x43, 0x75, 0x02, // call kDoAudio
- 0x1c, // ne?
- 0x31, // bnt (-> to skip disposal)
- 0
-};
-
-const uint16 freddypharkasPatchScoreDisposal[] = {
- 0x34, 0x00, 0x00, // ldi 0000
- 0x34, 0x00, 0x00, // ldi 0000
- 0x34, 0x00, 0x00, // ldi 0000
+// Applies to at least: English PC-CD
+// Responsible method: unknown
+static const uint16 freddypharkasSignatureScoreDisposal[] = {
+ 0x67, 0x32, // pTos 32 (selector theAudCount)
+ 0x78, // push1
+ SIG_MAGICDWORD,
+ 0x39, 0x0d, // pushi 0d
+ 0x43, 0x75, 0x02, // call kDoAudio
+ 0x1c, // ne?
+ 0x31, // bnt (-> to skip disposal)
+ SIG_END
+};
+
+static const uint16 freddypharkasPatchScoreDisposal[] = {
+ 0x34, PATCH_UINT16(0x0000), // ldi 0000
+ 0x34, PATCH_UINT16(0x0000), // ldi 0000
+ 0x34, PATCH_UINT16(0x0000), // ldi 0000
PATCH_END
};
@@ -361,24 +433,26 @@ const uint16 freddypharkasPatchScoreDisposal[] = {
// in IconBar::disable doing endless loops even in sierra sci, because there
// is no enabled icon left. We remove disabling of icon 8 (which is help),
// this fixes the issue.
-const byte freddypharkasSignatureCanisterHang[] = {
- 12,
- 0x38, 0xf1, 0x00, // pushi f1 (selector disable)
- 0x7a, // push2
- 0x39, 0x07, // pushi 07
- 0x39, 0x08, // pushi 08
- 0x81, 0x45, // lag 45
- 0x4a, 0x08, // send 08 - call IconBar::disable(7, 8)
- 0
-};
-
-const uint16 freddypharkasPatchCanisterHang[] = {
- PATCH_ADDTOOFFSET | +3,
- 0x78, // push1
- PATCH_ADDTOOFFSET | +2,
- 0x33, 0x00, // ldi 00 (waste 2 bytes)
- PATCH_ADDTOOFFSET | +3,
- 0x06, // send 06 - call IconBar::disable(7)
+// Applies to at least: English PC-CD
+// Responsible method: rm235::init and sEnterFrom500::changeState
+static const uint16 freddypharkasSignatureCanisterHang[] = {
+ 0x38, SIG_SELECTOR16(disable), // pushi disable
+ 0x7a, // push2
+ SIG_MAGICDWORD,
+ 0x39, 0x07, // pushi 07
+ 0x39, 0x08, // pushi 08
+ 0x81, 0x45, // lag 45
+ 0x4a, 0x08, // send 08 - call IconBar::disable(7, 8)
+ SIG_END
+};
+
+static const uint16 freddypharkasPatchCanisterHang[] = {
+ PATCH_ADDTOOFFSET(+3),
+ 0x78, // push1
+ PATCH_ADDTOOFFSET(+2),
+ 0x33, 0x00, // ldi 00 (waste 2 bytes)
+ PATCH_ADDTOOFFSET(+3),
+ 0x06, // send 06 - call IconBar::disable(7)
PATCH_END
};
@@ -390,135 +464,132 @@ const uint16 freddypharkasPatchCanisterHang[] = {
// ego, sometimes clicks also won't get registered. Strangely it's not nearly
// as bad as in our sci, but these differences may be caused by timing.
// We just reuse the active event, thus removing the duplicate kGetEvent call.
-const byte freddypharkasSignatureLadderEvent[] = {
- 21,
- 0x39, 0x6d, // pushi 6d (selector new)
- 0x76, // push0
- 0x38, 0xf5, 0x00, // pushi f5 (selector curEvent)
- 0x76, // push0
- 0x81, 0x50, // lag global[50]
- 0x4a, 0x04, // send 04 - read User::curEvent
- 0x4a, 0x04, // send 04 - call curEvent::new
- 0xa5, 0x00, // sat temp[0]
- 0x38, 0x94, 0x00, // pushi 94 (selector localize)
- 0x76, // push0
- 0x4a, 0x04, // send 04 - call curEvent::localize
- 0
-};
-
-const uint16 freddypharkasPatchLadderEvent[] = {
- 0x34, 0x00, 0x00, // ldi 0000 (waste 3 bytes, overwrites first 2 pushes)
- PATCH_ADDTOOFFSET | +8,
- 0xa5, 0x00, // sat temp[0] (waste 2 bytes, overwrites 2nd send)
- PATCH_ADDTOOFFSET | +2,
- 0x34, 0x00, 0x00, // ldi 0000
- 0x34, 0x00, 0x00, // ldi 0000 (waste 6 bytes, overwrites last 3 opcodes)
+// Applies to at least: English PC-CD, German Floppy, English Mac
+// Responsible method: lowerLadder::doit and highLadder::doit
+static const uint16 freddypharkasSignatureLadderEvent[] = {
+ 0x39, SIG_MAGICDWORD,
+ SIG_SELECTOR8(new), // pushi new
+ 0x76, // push0
+ 0x38, SIG_SELECTOR16(curEvent), // pushi curEvent
+ 0x76, // push0
+ 0x81, 0x50, // lag global[50]
+ 0x4a, 0x04, // send 04 - read User::curEvent
+ 0x4a, 0x04, // send 04 - call curEvent::new
+ 0xa5, 0x00, // sat temp[0]
+ 0x38, SIG_SELECTOR16(localize),
+ 0x76, // push0
+ 0x4a, 0x04, // send 04 - call curEvent::localize
+ SIG_END
+};
+
+static const uint16 freddypharkasPatchLadderEvent[] = {
+ 0x34, 0x00, 0x00, // ldi 0000 (waste 3 bytes, overwrites first 2 pushes)
+ PATCH_ADDTOOFFSET(+8),
+ 0xa5, 0x00, // sat temp[0] (waste 2 bytes, overwrites 2nd send)
+ PATCH_ADDTOOFFSET(+2),
+ 0x34, 0x00, 0x00, // ldi 0000
+ 0x34, 0x00, 0x00, // ldi 0000 (waste 6 bytes, overwrites last 3 opcodes)
PATCH_END
};
// In the Macintosh version of Freddy Pharkas, kRespondsTo is broken for
// property selectors. They hacked the script to work around the issue,
// so we revert the script back to using the values of the DOS script.
-const byte freddypharkasSignatureMacInventory[] = {
- 10,
- 0x39, 0x23, // pushi 23
- 0x39, 0x74, // pushi 74
- 0x78, // push1
- 0x38, 0x01, 0x74, // pushi 0174
- 0x85, 0x15, // lat 15
- 0
-};
-
-const uint16 freddypharkasPatchMacInventory[] = {
- 0x39, 0x02, // pushi 02 (now matches the DOS version)
- 0x39, 0x74, // pushi 74
- 0x78, // push1
- 0x38, 0x01, 0x74, // pushi 0174
- 0x85, 0x15, // lat 15
- 0x4a, 0x06, // send 06
- 0x31, 0x08, // bnt 08
- 0x38, 0x01, 0x74, // pushi 0174
- 0x76, // push0
- 0x85, 0x15, // lat 15
- 0x4a, 0x04, // send 04
- 0x02, // add
- 0xa5, 0x12, // sat 12
- 0x39, 0x04, // pushi 04 (now matches the DOS version)
+// Applies to at least: English Mac
+// Responsible method: unknown
+static const uint16 freddypharkasSignatureMacInventory[] = {
+ SIG_MAGICDWORD,
+ 0x39, 0x23, // pushi 23
+ 0x39, 0x74, // pushi 74
+ 0x78, // push1
+ 0x38, SIG_UINT16(0x0174), // pushi 0174 (on mac it's actually 0x01, 0x74)
+ 0x85, 0x15, // lat 15
+ SIG_END
+};
+
+static const uint16 freddypharkasPatchMacInventory[] = {
+ 0x39, 0x02, // pushi 02 (now matches the DOS version)
+ PATCH_ADDTOOFFSET(+23),
+ 0x39, 0x04, // pushi 04 (now matches the DOS version)
PATCH_END
};
-// script, description, magic DWORD, adjust
-const SciScriptSignature freddypharkasSignatures[] = {
- { 0, "CD: score early disposal", 1, PATCH_MAGICDWORD(0x39, 0x0d, 0x43, 0x75), -3, freddypharkasSignatureScoreDisposal, freddypharkasPatchScoreDisposal },
- { 15, "Mac: broken inventory", 1, PATCH_MAGICDWORD(0x39, 0x23, 0x39, 0x74), 0, freddypharkasSignatureMacInventory, freddypharkasPatchMacInventory },
- { 235, "CD: canister pickup hang", 3, PATCH_MAGICDWORD(0x39, 0x07, 0x39, 0x08), -4, freddypharkasSignatureCanisterHang, freddypharkasPatchCanisterHang },
- { 320, "ladder event issue", 2, PATCH_MAGICDWORD(0x6d, 0x76, 0x38, 0xf5), -1, freddypharkasSignatureLadderEvent, freddypharkasPatchLadderEvent },
+// script, description, signature patch
+static const SciScriptPatcherEntry freddypharkasSignatures[] = {
+ { true, 0, "CD: score early disposal", 1, freddypharkasSignatureScoreDisposal, freddypharkasPatchScoreDisposal },
+ { true, 15, "Mac: broken inventory", 1, freddypharkasSignatureMacInventory, freddypharkasPatchMacInventory },
+ { true, 235, "CD: canister pickup hang", 3, freddypharkasSignatureCanisterHang, freddypharkasPatchCanisterHang },
+ { true, 320, "ladder event issue", 2, freddypharkasSignatureLadderEvent, freddypharkasPatchLadderEvent },
SCI_SIGNATUREENTRY_TERMINATOR
};
// ===========================================================================
// daySixBeignet::changeState (4) is called when the cop goes out and sets cycles to 220.
// this is not enough time to get to the door, so we patch that to 23 seconds
-const byte gk1SignatureDay6PoliceBeignet[] = {
- 4,
- 0x35, 0x04, // ldi 04
- 0x1a, // eq?
- 0x30, // bnt [next state check]
- +2, 5, // [skip 2 bytes, offset of bnt]
- 0x38, 0x93, 0x00, // pushi 93 (selector dispose)
- 0x76, // push0
- 0x72, // lofsa deskSarg
- +2, 9, // [skip 2 bytes, offset of lofsa]
- 0x4a, 0x04, 0x00, // send 04
- 0x34, 0xdc, 0x00, // ldi 220
- 0x65, 0x1a, // aTop cycles
- 0x32, // jmp [end]
- 0
-};
-
-const uint16 gk1PatchDay6PoliceBeignet[] = {
- PATCH_ADDTOOFFSET | +16,
- 0x34, 0x17, 0x00, // ldi 23
- 0x65, 0x1c, // aTop seconds
+// Applies to at least: English PC-CD, German PC-CD, English Mac
+// Responsible method: daySixBeignet::changeState
+static const uint16 gk1SignatureDay6PoliceBeignet[] = {
+ 0x35, 0x04, // ldi 04
+ 0x1a, // eq?
+ 0x30, SIG_ADDTOOFFSET(+2), // bnt [next state check]
+ 0x38, SIG_SELECTOR16(dispose), // pushi dispose
+ 0x76, // push0
+ 0x72, SIG_ADDTOOFFSET(+2), // lofsa deskSarg
+ 0x4a, SIG_UINT16(0x0004), // send 04
+ SIG_MAGICDWORD,
+ 0x34, SIG_UINT16(0x00dc), // ldi 220
+ 0x65, SIG_ADDTOOFFSET(+1), // aTop cycles (1a for PC, 1c for Mac)
+ 0x32, // jmp [end]
+ SIG_END
+};
+
+static const uint16 gk1PatchDay6PoliceBeignet[] = {
+ PATCH_ADDTOOFFSET(+16),
+ 0x34, PATCH_UINT16(0x0017), // ldi 23
+ 0x65, PATCH_GETORIGINALBYTEADJUST(+20, +2), // aTop seconds (1c for PC, 1e for Mac)
PATCH_END
};
// sargSleeping::changeState (8) is called when the cop falls asleep and sets cycles to 220.
// this is not enough time to get to the door, so we patch it to 42 seconds
-const byte gk1SignatureDay6PoliceSleep[] = {
- 4,
- 0x35, 0x08, // ldi 08
- 0x1a, // eq?
- 0x31, // bnt [next state check]
- +1, 6, // [skip 1 byte, offset of bnt]
- 0x34, 0xdc, 0x00, // ldi 220
- 0x65, 0x1a, // aTop cycles
- 0x32, // jmp [end]
+// Applies to at least: English PC-CD, German PC-CD, English Mac
+// Responsible method: sargSleeping::changeState
+static const uint16 gk1SignatureDay6PoliceSleep[] = {
+ 0x35, 0x08, // ldi 08
+ 0x1a, // eq?
+ 0x31, SIG_ADDTOOFFSET(+1), // bnt [next state check]
+ SIG_MAGICDWORD,
+ 0x34, SIG_UINT16(0x00dc), // ldi 220
+ 0x65, SIG_ADDTOOFFSET(+1), // aTop cycles (1a for PC, 1c for Mac)
+ 0x32, // jmp [end]
0
};
-const uint16 gk1PatchDay6PoliceSleep[] = {
- PATCH_ADDTOOFFSET | +5,
- 0x34, 0x2a, 0x00, // ldi 42
- 0x65, 0x1c, // aTop seconds
+static const uint16 gk1PatchDay6PoliceSleep[] = {
+ PATCH_ADDTOOFFSET(+5),
+ 0x34, SIG_UINT16(0x002a), // ldi 42
+ 0x65, PATCH_GETORIGINALBYTEADJUST(+9, +2), // aTop seconds (1c for PC, 1e for Mac)
PATCH_END
};
// startOfDay5::changeState (20h) - when gabriel goes to the phone the script will hang
-const byte gk1SignatureDay5PhoneFreeze[] = {
- 5,
- 0x35, 0x03, // ldi 03
- 0x65, 0x1a, // aTop cycles
- 0x32, // jmp [end]
- +2, 3, // [skip 2 bytes, offset of jmp]
- 0x3c, // dup
- 0x35, 0x21, // ldi 21
- 0
-};
-
-const uint16 gk1PatchDay5PhoneFreeze[] = {
- 0x35, 0x06, // ldi 06
- 0x65, 0x20, // aTop ticks
+// Applies to at least: English PC-CD, German PC-CD, English Mac
+// Responsible method: startOfDay5::changeState
+static const uint16 gk1SignatureDay5PhoneFreeze[] = {
+ 0x4a,
+ SIG_MAGICDWORD, SIG_UINT16(0x000c), // send 0c
+ 0x35, 0x03, // ldi 03
+ 0x65, SIG_ADDTOOFFSET(+1), // aTop cycles
+ 0x32, SIG_ADDTOOFFSET(+2), // jmp [end]
+ 0x3c, // dup
+ 0x35, 0x21, // ldi 21
+ SIG_END
+};
+
+static const uint16 gk1PatchDay5PhoneFreeze[] = {
+ PATCH_ADDTOOFFSET(+3),
+ 0x35, 0x06, // ldi 01
+ 0x65, PATCH_GETORIGINALBYTEADJUST(+6, +6), // aTop ticks
PATCH_END
};
@@ -530,63 +601,66 @@ const uint16 gk1PatchDay5PhoneFreeze[] = {
// comparison between a number an an object. In the CD version, the checks are
// in the correct order, thus the comparison is correct, thus we use the code
// from the CD version in the floppy one.
-const byte gk1SignatureInterrogationBug[] = {
- 43,
- 0x65, 0x4c, // aTop 4c
- 0x67, 0x50, // pTos 50
- 0x34, 0x10, 0x27, // ldi 2710
- 0x1e, // gt?
- 0x31, 0x08, // bnt 08 [05a0]
- 0x67, 0x50, // pTos 50
- 0x34, 0x10, 0x27, // ldi 2710
- 0x04, // sub
- 0x65, 0x50, // aTop 50
- 0x63, 0x50, // pToa 50
- 0x31, 0x15, // bnt 15 [05b9]
- 0x39, 0x0e, // pushi 0e
- 0x76, // push0
- 0x4a, 0x04, 0x00, // send 0004
- 0xa5, 0x00, // sat 00
- 0x38, 0x93, 0x00, // pushi 0093
- 0x76, // push0
- 0x63, 0x50, // pToa 50
- 0x4a, 0x04, 0x00, // send 0004
- 0x85, 0x00, // lat 00
- 0x65, 0x50, // aTop 50
- 0
-};
-
-const uint16 gk1PatchInterrogationBug[] = {
- 0x65, 0x4c, // aTop 4c
- 0x63, 0x50, // pToa 50
- 0x31, 0x15, // bnt 15 [05b9]
- 0x39, 0x0e, // pushi 0e
- 0x76, // push0
- 0x4a, 0x04, 0x00, // send 0004
- 0xa5, 0x00, // sat 00
- 0x38, 0x93, 0x00, // pushi 0093
- 0x76, // push0
- 0x63, 0x50, // pToa 50
- 0x4a, 0x04, 0x00, // send 0004
- 0x85, 0x00, // lat 00
- 0x65, 0x50, // aTop 50
- 0x67, 0x50, // pTos 50
- 0x34, 0x10, 0x27, // ldi 2710
- 0x1e, // gt?
- 0x31, 0x08, // bnt 08 [05b9]
- 0x67, 0x50, // pTos 50
- 0x34, 0x10, 0x27, // ldi 2710
- 0x04, // sub
- 0x65, 0x50, // aTop 50
+// Applies to at least: English Floppy
+// Responsible method: Interrogation::dispose
+// TODO: Check, if English Mac is affected too and if this patch applies
+static const uint16 gk1SignatureInterrogationBug[] = {
+ SIG_MAGICDWORD,
+ 0x65, 0x4c, // aTop 4c
+ 0x67, 0x50, // pTos 50
+ 0x34, SIG_UINT16(0x2710), // ldi 2710
+ 0x1e, // gt?
+ 0x31, 0x08, // bnt 08 [05a0]
+ 0x67, 0x50, // pTos 50
+ 0x34, SIG_UINT16(0x2710), // ldi 2710
+ 0x04, // sub
+ 0x65, 0x50, // aTop 50
+ 0x63, 0x50, // pToa 50
+ 0x31, 0x15, // bnt 15 [05b9]
+ 0x39, 0x0e, // pushi 0e
+ 0x76, // push0
+ 0x4a, SIG_UINT16(0x0004), // send 0004
+ 0xa5, 0x00, // sat 00
+ 0x38, SIG_SELECTOR16(dispose), // pushi dispose
+ 0x76, // push0
+ 0x63, 0x50, // pToa 50
+ 0x4a, SIG_UINT16(0x0004), // send 0004
+ 0x85, 0x00, // lat 00
+ 0x65, 0x50, // aTop 50
+ SIG_END
+};
+
+static const uint16 gk1PatchInterrogationBug[] = {
+ 0x65, 0x4c, // aTop 4c
+ 0x63, 0x50, // pToa 50
+ 0x31, 0x15, // bnt 15 [05b9]
+ 0x39, 0x0e, // pushi 0e
+ 0x76, // push0
+ 0x4a, 0x04, 0x00, // send 0004
+ 0xa5, 0x00, // sat 00
+ 0x38, SIG_SELECTOR16(dispose), // pushi dispose
+ 0x76, // push0
+ 0x63, 0x50, // pToa 50
+ 0x4a, 0x04, 0x00, // send 0004
+ 0x85, 0x00, // lat 00
+ 0x65, 0x50, // aTop 50
+ 0x67, 0x50, // pTos 50
+ 0x34, PATCH_UINT16(0x2710), // ldi 2710
+ 0x1e, // gt?
+ 0x31, 0x08, // bnt 08 [05b9]
+ 0x67, 0x50, // pTos 50
+ 0x34, PATCH_UINT16(0x2710), // ldi 2710
+ 0x04, // sub
+ 0x65, 0x50, // aTop 50
PATCH_END
};
-// script, description, magic DWORD, adjust
-const SciScriptSignature gk1Signatures[] = {
- { 51, "interrogation bug", 1, PATCH_MAGICDWORD(0x65, 0x4c, 0x67, 0x50), 0, gk1SignatureInterrogationBug, gk1PatchInterrogationBug },
- { 212, "day 5 phone freeze", 1, PATCH_MAGICDWORD(0x35, 0x03, 0x65, 0x1a), 0, gk1SignatureDay5PhoneFreeze, gk1PatchDay5PhoneFreeze },
- { 230, "day 6 police beignet timer issue", 1, PATCH_MAGICDWORD(0x34, 0xdc, 0x00, 0x65), -16, gk1SignatureDay6PoliceBeignet, gk1PatchDay6PoliceBeignet },
- { 230, "day 6 police sleep timer issue", 1, PATCH_MAGICDWORD(0x34, 0xdc, 0x00, 0x65), -5, gk1SignatureDay6PoliceSleep, gk1PatchDay6PoliceSleep },
+// script, description, signature patch
+static const SciScriptPatcherEntry gk1Signatures[] = {
+ { true, 51, "interrogation bug", 1, gk1SignatureInterrogationBug, gk1PatchInterrogationBug },
+ { true, 212, "day 5 phone freeze", 1, gk1SignatureDay5PhoneFreeze, gk1PatchDay5PhoneFreeze },
+ { true, 230, "day 6 police beignet timer issue", 1, gk1SignatureDay6PoliceBeignet, gk1PatchDay6PoliceBeignet },
+ { true, 230, "day 6 police sleep timer issue", 1, gk1SignatureDay6PoliceSleep, gk1PatchDay6PoliceSleep },
SCI_SIGNATUREENTRY_TERMINATOR
};
@@ -596,47 +670,47 @@ const SciScriptSignature gk1Signatures[] = {
// is later used to set master volume. This issue makes sierra sci set
// the volume to max. We fix the export, so volume won't get modified in
// those cases.
-const byte kq5SignatureCdHarpyVolume[] = {
- 34,
- 0x80, 0x91, 0x01, // lag global[191h]
- 0x18, // not
- 0x30, 0x2c, 0x00, // bnt [jump further] (jumping, if global 191h is 1)
- 0x35, 0x01, // ldi 01
- 0xa0, 0x91, 0x01, // sag global[191h] (setting global 191h to 1)
- 0x38, 0x7b, 0x01, // pushi 017b
- 0x76, // push0
- 0x81, 0x01, // lag global[1]
- 0x4a, 0x04, // send 04 - read KQ5::masterVolume
- 0xa5, 0x03, // sat temp[3] (store volume in temp 3)
- 0x38, 0x7b, 0x01, // pushi 017b
- 0x76, // push0
- 0x81, 0x01, // lag global[1]
- 0x4a, 0x04, // send 04 - read KQ5::masterVolume
- 0x36, // push
- 0x35, 0x04, // ldi 04
- 0x20, // ge? (followed by bnt)
- 0
-};
-
-const uint16 kq5PatchCdHarpyVolume[] = {
- 0x38, 0x2f, 0x02, // pushi 022f (selector theVol) (3 new bytes)
- 0x76, // push0 (1 new byte)
- 0x51, 0x88, // class SpeakTimer (2 new bytes)
- 0x4a, 0x04, // send 04 (2 new bytes) -> read SpeakTimer::theVol
- 0xa5, 0x03, // sat temp[3] (2 new bytes) -> write to temp 3
- 0x80, 0x91, 0x01, // lag global[191h]
+static const uint16 kq5SignatureCdHarpyVolume[] = {
+ SIG_MAGICDWORD,
+ 0x80, SIG_UINT16(0x0191), // lag global[191h]
+ 0x18, // not
+ 0x30, SIG_UINT16(0x002c), // bnt [jump further] (jumping, if global 191h is 1)
+ 0x35, 0x01, // ldi 01
+ 0xa0, SIG_UINT16(0x0191), // sag global[191h] (setting global 191h to 1)
+ 0x38, SIG_UINT16(0x017b), // pushi 017b
+ 0x76, // push0
+ 0x81, 0x01, // lag global[1]
+ 0x4a, 0x04, // send 04 - read KQ5::masterVolume
+ 0xa5, 0x03, // sat temp[3] (store volume in temp 3)
+ 0x38, SIG_UINT16(0x017b), // pushi 017b
+ 0x76, // push0
+ 0x81, 0x01, // lag global[1]
+ 0x4a, 0x04, // send 04 - read KQ5::masterVolume
+ 0x36, // push
+ 0x35, 0x04, // ldi 04
+ 0x20, // ge? (followed by bnt)
+ SIG_END
+};
+
+static const uint16 kq5PatchCdHarpyVolume[] = {
+ 0x38, PATCH_UINT16(0x022f), // pushi 022f (selector theVol) (3 new bytes)
+ 0x76, // push0 (1 new byte)
+ 0x51, 0x88, // class SpeakTimer (2 new bytes)
+ 0x4a, 0x04, // send 04 (2 new bytes) -> read SpeakTimer::theVol
+ 0xa5, 0x03, // sat temp[3] (2 new bytes) -> write to temp 3
+ 0x80, PATCH_UINT16(0x0191), // lag global[191h]
// saving 1 byte due optimization
- 0x2e, 0x23, 0x00, // bt [jump further] (jumping, if global 191h is 1)
- 0x35, 0x01, // ldi 01
- 0xa0, 0x91, 0x01, // sag global[191h] (setting global 191h to 1)
- 0x38, 0x7b, 0x01, // pushi 017b
- 0x76, // push0
- 0x81, 0x01, // lag global[1]
- 0x4a, 0x04, // send 04 - read KQ5::masterVolume
- 0xa5, 0x03, // sat temp[3] (store volume in temp 3)
+ 0x2e, PATCH_UINT16(0x0023), // bt [jump further] (jumping, if global 191h is 1)
+ 0x35, 0x01, // ldi 01
+ 0xa0, PATCH_UINT16(0x0191), // sag global[191h] (setting global 191h to 1)
+ 0x38, PATCH_UINT16(0x017b), // pushi 017b
+ 0x76, // push0
+ 0x81, 0x01, // lag global[1]
+ 0x4a, 0x04, // send 04 - read KQ5::masterVolume
+ 0xa5, 0x03, // sat temp[3] (store volume in temp 3)
// saving 8 bytes due removing of duplicate code
- 0x39, 0x04, // pushi 04 (saving 1 byte due swapping)
- 0x22, // lt? (because we switched values)
+ 0x39, 0x04, // pushi 04 (saving 1 byte due swapping)
+ 0x22, // lt? (because we switched values)
PATCH_END
};
@@ -648,30 +722,32 @@ const uint16 kq5PatchCdHarpyVolume[] = {
// Additionally its top,left,bottom,right properties are set to 0 rather
// than the right values. We fix the object by setting the right values.
// If they are all zero, this causes an impossible position check in
-// witch::cantBeHere and an infinite loop when entering room 22 (bug #3034714).
+// witch::cantBeHere and an infinite loop when entering room 22.
//
// This bug is accidentally not triggered in SSCI because the invalid number
// of variables effectively hides witchCage::doit, causing this position check
// to be bypassed entirely.
// See also the warning+comment in Object::initBaseObject
-const byte kq5SignatureWitchCageInit[] = {
- 16,
- 0x00, 0x00, // top
- 0x00, 0x00, // left
- 0x00, 0x00, // bottom
- 0x00, 0x00, // right
- 0x00, 0x00, // extra property #1
- 0x7a, 0x00, // extra property #2
- 0xc8, 0x00, // extra property #3
- 0xa3, 0x00, // extra property #4
- 0
-};
-
-const uint16 kq5PatchWitchCageInit[] = {
- 0x00, 0x00, // top
- 0x7a, 0x00, // left
- 0xc8, 0x00, // bottom
- 0xa3, 0x00, // right
+//
+// Fixes bug: #4964
+static const uint16 kq5SignatureWitchCageInit[] = {
+ SIG_UINT16(0x0000), // top
+ SIG_UINT16(0x0000), // left
+ SIG_UINT16(0x0000), // bottom
+ SIG_UINT16(0x0000), // right
+ SIG_UINT16(0x0000), // extra property #1
+ SIG_MAGICDWORD,
+ SIG_UINT16(0x007a), // extra property #2
+ SIG_UINT16(0x00c8), // extra property #3
+ SIG_UINT16(0x00a3), // extra property #4
+ SIG_END
+};
+
+static const uint16 kq5PatchWitchCageInit[] = {
+ PATCH_UINT16(0x0000), // top
+ PATCH_UINT16(0x007a), // left
+ PATCH_UINT16(0x00c8), // bottom
+ PATCH_UINT16(0x00a3), // right
PATCH_END
};
@@ -689,31 +765,25 @@ const uint16 kq5PatchWitchCageInit[] = {
// changes to GameFeatures::detectsetCursorType() ) and breaking savegame
// compatibilty between the DOS and Windows CD versions of KQ5.
// TODO: Investigate these side effects more closely.
-const byte kq5SignatureWinGMSignals[] = {
- 9,
- 0x80, 0x90, 0x01, // lag 0x190
- 0x18, // not
- 0x30, 0x1b, 0x00, // bnt +0x001B
- 0x89, 0x57, // lsg 0x57
- 0
+static const uint16 kq5SignatureWinGMSignals[] = {
+ SIG_MAGICDWORD,
+ 0x80, SIG_UINT16(0x0190), // lag 0x190
+ 0x18, // not
+ 0x30, SIG_UINT16(0x001b), // bnt +0x001B
+ 0x89, 0x57, // lsg 0x57
+ SIG_END
};
-const uint16 kq5PatchWinGMSignals[] = {
- 0x34, 0x01, 0x00, // ldi 0x0001
+static const uint16 kq5PatchWinGMSignals[] = {
+ 0x34, PATCH_UINT16(0x0001), // ldi 0x0001
PATCH_END
};
-// script, description, magic DWORD, adjust
-const SciScriptSignature kq5Signatures[] = {
- { 0, "CD: harpy volume change", 1, PATCH_MAGICDWORD(0x80, 0x91, 0x01, 0x18), 0, kq5SignatureCdHarpyVolume, kq5PatchCdHarpyVolume },
- { 200, "CD: witch cage init", 1, PATCH_MAGICDWORD(0x7a, 0x00, 0xc8, 0x00), -10, kq5SignatureWitchCageInit, kq5PatchWitchCageInit },
- SCI_SIGNATUREENTRY_TERMINATOR
-};
-
-const SciScriptSignature kq5WinGMSignatures[] = {
- { 0, "CD: harpy volume change", 1, PATCH_MAGICDWORD(0x80, 0x91, 0x01, 0x18), 0, kq5SignatureCdHarpyVolume, kq5PatchCdHarpyVolume },
- { 200, "CD: witch cage init", 1, PATCH_MAGICDWORD(0x7a, 0x00, 0xc8, 0x00), -10, kq5SignatureWitchCageInit, kq5PatchWitchCageInit },
- { 124, "Win: GM Music signal checks", 4, PATCH_MAGICDWORD(0x80, 0x90, 0x01, 0x18), 0, kq5SignatureWinGMSignals, kq5PatchWinGMSignals },
+// script, description, signature patch
+static const SciScriptPatcherEntry kq5Signatures[] = {
+ { true, 0, "CD: harpy volume change", 1, kq5SignatureCdHarpyVolume, kq5PatchCdHarpyVolume },
+ { true, 200, "CD: witch cage init", 1, kq5SignatureWitchCageInit, kq5PatchWitchCageInit },
+ { false, 124, "Win: GM Music signal checks", 4, kq5SignatureWinGMSignals, kq5PatchWinGMSignals },
SCI_SIGNATUREENTRY_TERMINATOR
};
@@ -725,25 +795,518 @@ const SciScriptSignature kq5WinGMSignatures[] = {
// sound is played twice, squelching all other sounds. We just rip the
// unnecessary cryMusic::check method out, thereby stopping the sound from
// constantly restarting (since it's being looped anyway), thus the normal
-// game speech can work while the baby cry sound is heard. Fixes bug #3034579.
-const byte kq6SignatureDuplicateBabyCry[] = {
- 10,
- 0x83, 0x00, // lal 00
- 0x31, 0x1e, // bnt 1e [07f4]
- 0x78, // push1
- 0x39, 0x04, // pushi 04
- 0x43, 0x75, 0x02, // callk DoAudio[75] 02
- 0
+// game speech can work while the baby cry sound is heard.
+// Fixes bug: #4955
+static const uint16 kq6SignatureDuplicateBabyCry[] = {
+ SIG_MAGICDWORD,
+ 0x83, 0x00, // lal 00
+ 0x31, 0x1e, // bnt 1e [07f4]
+ 0x78, // push1
+ 0x39, 0x04, // pushi 04
+ 0x43, 0x75, 0x02, // callk DoAudio[75] 02
+ SIG_END
+};
+
+static const uint16 kq6PatchDuplicateBabyCry[] = {
+ 0x48, // ret
+ PATCH_END
+};
+
+// The inventory of King's Quest 6 is buggy. When it grows too large,
+// it will get split into 2 pages. Switching between those pages will
+// grow the stack, because it's calling itself per switch.
+// Which means after a while ScummVM will bomb out because the stack frame
+// will be too large. This patch fixes the buggy script.
+// Applies to at least: PC-CD, English PC floppy, German PC floppy, English Mac
+// Responsible method: KqInv::showSelf
+// Fixes bug: #5681
+static const uint16 kq6SignatureInventoryStackFix[] = {
+ 0x67, 0x30, // pTos state
+ 0x34, SIG_UINT16(0x2000), // ldi 2000
+ 0x12, // and
+ 0x18, // not
+ 0x31, 0x04, // bnt [not first refresh]
+ 0x35, 0x00, // ldi 00
+ SIG_MAGICDWORD,
+ 0x65, 0x1e, // aTop curIcon
+ 0x67, 0x30, // pTos state
+ 0x34, SIG_UINT16(0xdfff), // ldi dfff
+ 0x12, // and
+ 0x65, 0x30, // aTop state
+ 0x38, SIG_SELECTOR16(show), // pushi "show" ("show" is e1h for KQ6CD)
+ 0x78, // push1
+ 0x87, 0x00, // lap param[0]
+ 0x31, 0x04, // bnt [use global for show]
+ 0x87, 0x01, // lap param[1]
+ 0x33, 0x02, // jmp [use param for show]
+ 0x81, 0x00, // lag global[0]
+ 0x36, // push
+ 0x54, 0x06, // self 06 (KqInv::show)
+ 0x31, SIG_ADDTOOFFSET(+1), // bnt [exit menu code] (0x08 for PC, 0x07 for mac)
+ 0x39, 0x39, // pushi 39
+ 0x76, // push0
+ 0x54, 0x04, // self 04 (KqInv::doit)
+ SIG_END // followed by jmp (0x32 for PC, 0x33 for mac)
+};
+
+static const uint16 kq6PatchInventoryStackFix[] = {
+ 0x67, 0x30, // pTos state
+ 0x3c, // dup (1 more byte, needed for patch)
+ 0x3c, // dup (1 more byte, saves 1 byte later)
+ 0x34, PATCH_UINT16(0x2000), // ldi 2000
+ 0x12, // and
+ 0x2f, 0x02, // bt [not first refresh] - saves 3 bytes in total
+ 0x65, 0x1e, // aTop curIcon
+ 0x00, // neg (either 2000 or 0000 in acc, this will create dfff or ffff) - saves 2 bytes
+ 0x12, // and
+ 0x65, 0x30, // aTop state
+ 0x38, // pushi "show"
+ PATCH_GETORIGINALBYTE(+22),
+ PATCH_GETORIGINALBYTE(+23),
+ 0x78, // push1
+ 0x87, 0x00, // lap param[0]
+ 0x31, 0x04, // bnt [call show using global 0]
+ 0x8f, 0x01, // lsp param[1], save 1 byte total with lsg global[0] combined
+ 0x33, 0x02, // jmp [call show using param 1]
+ 0x89, 0x00, // lsg global[0], save 1 byte total, see above
+ 0x54, 0x06, // self 06 (call x::show)
+ 0x31, // bnt [menu exit code]
+ PATCH_GETORIGINALBYTEADJUST(+39, +6),// dynamic offset must be 0x0E for PC and 0x0D for mac
+ 0x34, PATCH_UINT16(0x2000), // ldi 2000
+ 0x12, // and
+ 0x2f, 0x05, // bt [to return]
+ 0x39, 0x39, // pushi 39
+ 0x76, // push0
+ 0x54, 0x04, // self 04 (self::doit)
+ 0x48, // ret (saves 2 bytes for PC, 1 byte for mac)
+ PATCH_END
+};
+
+// The "Drink Me" bottle code doesn't repaint the AddToPics elements to the screen,
+// when Alexander returns back from the effect of the bottle.
+// It's pretty strange that Sierra didn't find this bug, because it occurs when
+// drinking the bottle right on the screen, where the bottle is found.
+// This bug also occurs in Sierra SCI.
+// Applies to at least: PC-CD, English PC floppy, German PC floppy, English Mac
+// Responsible method: drinkMeScript::changeState
+// Fixes bug: #5252
+static const uint16 kq6SignatureDrinkMeFix[] = {
+ SIG_MAGICDWORD,
+ 0x3c, // dup
+ 0x35, 0x0f, // ldi 0f
+ 0x1a, // eq?
+ 0x30, SIG_UINT16(0x00a4), // bnt [skip to next check]
+ SIG_ADDTOOFFSET(+161),
+ 0x32, SIG_UINT16(0x007f), // jmp [return]
+ 0x3c, // dup
+ 0x35, 0x10, // ldi 10
+ 0x1a, // eq?
+ 0x31, 0x07, // bnt [skip to next check]
+ 0x35, 0x03, // ldi 03
+ 0x65, 0x1a, // aTop (cycles)
+ 0x32, SIG_UINT16(0x0072), // jmp [return]
+ 0x3c, // dup
+ 0x35, 0x11, // ldi 11
+ 0x1a, // eq?
+ 0x31, 0x13, // bnt [skip to next check]
+ SIG_ADDTOOFFSET(+20),
+ 0x35, 0x12, // ldi 12
+ SIG_ADDTOOFFSET(+23),
+ 0x35, 0x13, // ldi 13
+ SIG_END
+};
+
+static const uint16 kq6PatchDrinkMeFix[] = {
+ PATCH_ADDTOOFFSET(+5), // skip to bnt offset
+ PATCH_GETORIGINALBYTEADJUST(+5, +13), // adjust jump to [check for 11h code]
+ PATCH_ADDTOOFFSET(+162),
+ 0x39, PATCH_SELECTOR8(doit), // pushi (doit)
+ 0x76, // push0
+ 0x81, 0x0a, // lag 0a
+ 0x4a, 0x04, // send 04 (call addToPics::doit)
+ 0x3a, // toss
+ 0x48, // ret
+ PATCH_ADDTOOFFSET(+8), // skip to check 11h code
+ 0x35, 0x10, // ldi 10 instead of 11
+ PATCH_ADDTOOFFSET(+23), // skip to check 12h code
+ 0x35, 0x11, // ldi 11 instead of 12
+ PATCH_ADDTOOFFSET(+23), // skip to check 13h code
+ 0x35, 0x12, // ldi 12 instead of 13
+ PATCH_END
+};
+
+// Audio + subtitles support - SHARED! - used for King's Quest 6 and Laura Bow 2
+// this patch gets enabled, when the user selects "both" in the ScummVM "Speech + Subtitles" menu
+// We currently use global 98d to hold a kMemory pointer.
+// Applies to at least: KQ6 PC-CD, LB2 PC-CD
+// Patched method: Messager::sayNext / lb2Messager::sayNext (always use text branch)
+static const uint16 kq6laurabow2CDSignatureAudioTextSupport1[] = {
+ 0x89, 0x5a, // lsg global[5a]
+ 0x35, 0x02, // ldi 02
+ 0x12, // and
+ SIG_MAGICDWORD,
+ 0x31, 0x13, // bnt [audio call]
+ 0x38, SIG_SELECTOR16(modNum), // pushi modNum
+ SIG_END
+};
+
+static const uint16 kq6laurabow2CDPatchAudioTextSupport1[] = {
+ PATCH_ADDTOOFFSET(+5),
+ 0x33, 0x13, // jmp [audio call]
+ PATCH_END
+};
+
+// Applies to at least: KQ6 PC-CD, LB2 PC-CD
+// Patched method: Messager::sayNext / lb2Messager::sayNext (allocate audio memory)
+static const uint16 kq6laurabow2CDSignatureAudioTextSupport2[] = {
+ 0x7a, // push2
+ 0x78, // push1
+ 0x39, 0x0c, // pushi 0c
+ 0x43, SIG_MAGICDWORD, 0x72, 0x04, // kMemory
+ 0xa5, 0xc9, // sat global[c9]
+ SIG_END
+};
+
+static const uint16 kq6laurabow2CDPatchAudioTextSupport2[] = {
+ PATCH_ADDTOOFFSET(+7),
+ 0xa1, 98, // sag global[98d]
+ PATCH_END
+};
+
+// Applies to at least: KQ6 PC-CD, LB2 PC-CD
+// Patched method: Messager::sayNext / lb2Messager::sayNext (release audio memory)
+static const uint16 kq6laurabow2CDSignatureAudioTextSupport3[] = {
+ 0x7a, // push2
+ 0x39, 0x03, // pushi 03
+ SIG_MAGICDWORD,
+ 0x8d, 0xc9, // lst temp[c9]
+ 0x43, 0x72, 0x04, // kMemory
+ SIG_END
+};
+
+static const uint16 kq6laurabow2CDPatchAudioTextSupport3[] = {
+ PATCH_ADDTOOFFSET(+3),
+ 0x89, 98, // lsg global[98d]
+ PATCH_END
+};
+
+// startText call gets acc = 0 for text-only and acc = 2 for audio+text
+// Applies to at least: KQ6 PC-CD, LB2 PC-CD
+// Patched method: Narrator::say (use audio memory)
+static const uint16 kq6laurabow2CDSignatureAudioTextSupport4[] = {
+ // set caller property code
+ 0x31, 0x08, // bnt [set acc to 0 for caller]
+ 0x87, 0x02, // lap param[2]
+ 0x31, 0x04, // bnt [set acc to 0 for caller]
+ 0x87, 0x02, // lap param[2]
+ 0x33, 0x02, // jmp [set caller]
+ 0x35, 0x00, // ldi 00
+ 0x65, 0x68, // aTop caller
+ // call startText + startAudio code
+ 0x89, 0x5a, // lsg global[5a]
+ 0x35, 0x01, // ldi 01
+ 0x12, // and
+ 0x31, 0x08, // bnt [skip code]
+ 0x38, SIG_SELECTOR16(startText), // pushi startText
+ 0x78, // push1
+ 0x8f, 0x01, // lsp param[1]
+ 0x54, 0x06, // self 06
+ 0x89, 0x5a, // lsg global[5a]
+ 0x35, 0x02, // ldi 02
+ 0x12, // and
+ 0x31, 0x08, // bnt [skip code]
+ SIG_MAGICDWORD,
+ 0x38, SIG_SELECTOR16(startAudio), // pushi startAudio
+ 0x78, // push1
+ 0x8f, 0x01, // lsp param[1]
+ 0x54, 0x06, // self 06
+ SIG_END
+};
+
+static const uint16 kq6laurabow2CDPatchAudioTextSupport4[] = {
+ 0x31, 0x02, // bnt [set caller]
+ 0x87, 0x02, // lap param[2]
+ 0x65, 0x68, // aTop caller
+ 0x81, 0x5a, // lag global[5a]
+ 0x78, // push1
+ 0x12, // and
+ 0x31, 0x11, // bnt [skip startText code]
+ 0x81, 0x5a, // lag global[5a]
+ 0x7a, // push2
+ 0x12, // and
+ 0x33, 0x03, // skip over 3 unused bytes
+ PATCH_ADDTOOFFSET(+22),
+ 0x89, 98, // lsp global[98d]
+ PATCH_END
+};
+
+// Applies to at least: KQ6 PC-CD, LB2 PC-CD
+// Patched method: Talker::display/Narrator::say (remove reset saved mouse cursor code)
+// code would screw over mouse cursor
+static const uint16 kq6laurabow2CDSignatureAudioTextSupport5[] = {
+ SIG_MAGICDWORD,
+ 0x35, 0x00, // ldi 00
+ 0x65, 0x82, // aTop saveCursor
+ SIG_END
+};
+
+static const uint16 kq6laurabow2CDPatchAudioTextSupport5[] = {
+ 0x18, 0x18, 0x18, 0x18, // waste bytes, do nothing
+ PATCH_END
+};
+
+// Additional patch specifically for King's Quest 6
+// Fixes text window placement, when in "dual" mode
+// Applies to at least: PC-CD
+// Patched method: Kq6Talker::init
+static const uint16 kq6CDSignatureAudioTextSupport1[] = {
+ SIG_MAGICDWORD,
+ 0x89, 0x5a, // lsg global[5a]
+ 0x35, 0x02, // ldi 02
+ 0x1a, // eq?
+ 0x31, SIG_ADDTOOFFSET(+1), // bnt [jump-to-text-code]
+ 0x78, // push1
+ SIG_END
+};
+
+static const uint16 kq6CDPatchAudioTextSupport1[] = {
+ PATCH_ADDTOOFFSET(+4),
+ 0x12, // and
+ PATCH_END
+};
+
+// Additional patch specifically for King's Quest 6
+// Fixes low-res portrait staying on screen for hi-res mode
+// Applies to at least: PC-CD
+// Patched method: Talker::startText
+// this method is called by Narrator::say and acc is 0 for text-only and 2 for dual mode (audio+text)
+static const uint16 kq6CDSignatureAudioTextSupport2[] = {
+ SIG_MAGICDWORD,
+ 0x3f, 0x01, // link 01
+ 0x63, 0x8a, // pToa viewInPrint
+ 0x18, // not
+ 0x31, 0x06, // bnt [skip following code]
+ 0x38, SIG_UINT16(0x00e1), // pushi 00e1
+ 0x76, // push0
+ 0x54, 0x04, // self 04
+ SIG_END
+};
+
+static const uint16 kq6CDPatchAudioTextSupport2[] = {
+ PATCH_ADDTOOFFSET(+2),
+ 0x67, 0x8a, // pTos viewInPrint
+ 0x14, // or
+ 0x2f, // bt [skip following code]
+ PATCH_END
+};
+
+// Additional patch specifically for King's Quest 6
+// Fixes special windows, used for example in the Pawn shop (room 280),
+// when the man in a robe complains about no more mints.
+// We have to change even more code, because the game uses PODialog class for
+// text windows and myDialog class for audio. Both are saved to KQ6Print::dialog
+// Sadly PODialog is created during KQ6Print::addText, myDialog is set during
+// KQ6Print::showSelf, which is called much later and KQ6Print::addText requires
+// KQ6Print::dialog to be set, which means we have to set it before calling addText
+// for audio mode, otherwise the user would have to click to get those windows disposed.
+// Applies to at least: PC-CD
+// Patched method: KQ6Print::say
+static const uint16 kq6CDSignatureAudioTextSupport3[] = {
+ 0x31, 0x6e, // bnt [to text code]
+ SIG_ADDTOOFFSET(+85),
+ SIG_MAGICDWORD,
+ 0x8f, 0x01, // lsp param[1]
+ 0x35, 0x01, // ldi 01
+ 0x1a, // eq?
+ 0x31, 0x0c, // bnt [code to set property repressText to 1]
+ 0x38, // pushi (selector addText)
+ SIG_ADDTOOFFSET(+9), // skip addText-calling code
+ 0x33, 0x10, // jmp [to ret]
+ 0x35, 0x01, // ldi 01
+ 0x65, 0x2e, // aTop repressText
+ 0x33, 0x0a, // jmp [to ret]
+ SIG_END
+};
+
+static const uint16 kq6CDPatchAudioTextSupport3[] = {
+ 0x31, 0x5c, // adjust jump to reuse audio mode addText-calling code
+ PATCH_ADDTOOFFSET(102),
+ 0x48, // ret
+ 0x48, // ret (waste byte)
+ 0x72, 0x0e, 0x00, // lofsa myDialog
+ 0x65, 0x12, // aTop dialog
+ 0x33, 0xed, // jump back to audio mode addText-calling code
+ PATCH_END
+};
+
+// Additional patch specifically for King's Quest 6
+// Fixes text-window size for hires portraits mode
+// Otherwise at least at the end some text-windows will be way too small
+// Applies to at least: PC-CD
+// Patched method: Talker::init
+static const uint16 kq6CDSignatureAudioTextSupport4[] = {
+ SIG_MAGICDWORD,
+ 0x63, 0x94, // pToa raving
+ 0x31, 0x0a, // bnt [no rave code]
+ 0x35, 0x00, // ldi 00
+ SIG_ADDTOOFFSET(6), // skip reset of bust, eyes and mouth
+ 0x33, 0x24, // jmp [to super class code]
+ SIG_END
+};
+
+static const uint16 kq6CDPatchAudioTextSupport4[] = {
+ PATCH_ADDTOOFFSET(+12),
+ 0x33, PATCH_GETORIGINALBYTEADJUST(+13, -6), // adjust jump to also include setSize call
+ PATCH_END
+};
+
+// Fixes text window placement, when dual mode is active (Guards in room 220)
+// Applies to at least: PC-CD
+// Patched method: tlkGateGuard1::init & tlkGateGuard2::init
+static const uint16 kq6CDSignatureAudioTextSupportGuards[] = {
+ SIG_MAGICDWORD,
+ 0x89, 0x5a, // lsg global[5a]
+ 0x35, 0x01, // ldi 01
+ 0x1a, // eq?
+ SIG_END // followed by bnt for Guard1 and bt for Guard2
};
-const uint16 kq6PatchDuplicateBabyCry[] = {
- 0x48, // ret
+static const uint16 kq6CDPatchAudioTextSupportGuards[] = {
+ PATCH_ADDTOOFFSET(+2),
+ 0x35, 0x02, // ldi 02
+ 0x1c, // ne?
PATCH_END
};
-// script, description, magic DWORD, adjust
-const SciScriptSignature kq6Signatures[] = {
- { 481, "duplicate baby cry", 1, PATCH_MAGICDWORD(0x83, 0x00, 0x31, 0x1e), 0, kq6SignatureDuplicateBabyCry, kq6PatchDuplicateBabyCry },
+// Fixes text window placement, when portrait+text is shown (Stepmother in room 250)
+// Applies to at least: PC-CD
+// Patched method: tlkStepmother::init
+static const uint16 kq6CDSignatureAudioTextSupportStepmother[] = {
+ SIG_MAGICDWORD,
+ 0x89, 0x5a, // lsg global[5a]
+ 0x35, 0x02, // ldi 02
+ 0x12, // and
+ 0x31, // bnt [jump-for-text-code]
+ SIG_END
+};
+
+static const uint16 kq6CDPatchAudioTextSupportJumpAlways[] = {
+ PATCH_ADDTOOFFSET(+4),
+ 0x1a, // eq?
+ PATCH_END
+};
+
+// Fixes "Girl In The Tower" to get played in dual mode as well
+// Applies to at least: PC-CD
+// Patched method: rm740::cue
+static const uint16 kq6CDSignatureAudioTextSupportGirlInTheTower[] = {
+ SIG_MAGICDWORD,
+ 0x89, 0x5a, // lsg global[5a]
+ 0x35, 0x02, // ldi 02
+ 0x1a, // eq?
+ 0x31, // bnt [jump-for-text-code]
+ SIG_END
+};
+
+static const uint16 kq6CDPatchAudioTextSupportGirlInTheTower[] = {
+ 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"
+// View 947, loop 8, cel 0+1 -> "speech"
+// View 947, loop 12, cel 0+1 -> "dual" (TODO: inject our own 2 views for the new "dual" mode)
+// Applies to at least: PC-CD
+// Patched method: iconTextSwitch::show, iconTextSwitch::doit
+static const uint16 kq6CDSignatureAudioTextMenuSupport[] = {
+ SIG_MAGICDWORD,
+ 0x89, 0x5a, // lsg global[5a]
+ 0x35, 0x02, // ldi 02
+ 0x1a, // eq?
+ 0x31, 0x06, // bnt [set text view]
+ 0x35, 0x08, // ldi 08
+ 0x65, 0x14, // aTop loop
+ 0x33, 0x04, // jmp [skip over text view]
+ 0x35, 0x09, // ldi 09
+ 0x65, 0x14, // aTop loop
+ SIG_ADDTOOFFSET(+102), // skip to iconTextSwitch::doit code
+ 0x89, 0x5a, // lsg global[5a]
+ 0x3c, // dup
+ 0x35, 0x01, // ldi 01
+ 0x1a, // eq?
+ 0x31, 0x06, // bnt [set text mode]
+ 0x35, 0x02, // ldi 02
+ 0xa1, 0x5a, // sag global[5a]
+ 0x33, 0x0a, // jmp [skip over text mode code]
+ 0x3c, // dup
+ 0x35, 0x02, // ldi 02
+ 0x1a, // eq?
+ 0x31, 0x04, // bnt [skip over text ode code]
+ 0x35, 0x01, // ldi 01
+ 0xa1, 0x5a, // sag global[5a]
+ 0x3a, // toss
+ 0x67, 0x14, // pTos loop
+ 0x35, 0x09, // ldi 09
+ 0x1a, // eq?
+ 0x31, 0x04, // bnt [set text view]
+ 0x35, 0x08, // ldi 08
+ 0x33, 0x02, // jmp [skip text view]
+ 0x35, 0x09, // ldi 09
+ 0x65, 0x14, // aTop loop
+ SIG_END
+};
+
+static const uint16 kq6CDPatchAudioTextMenuSupport[] = {
+ PATCH_ADDTOOFFSET(+13),
+ 0x33, 0x79, // jmp to new text+dual code
+ PATCH_ADDTOOFFSET(+104), // seek to iconTextSwitch::doit
+ 0x81, 0x5a, // lag global[5a]
+ 0x78, // push1
+ 0x02, // add
+ 0xa1, 0x5a, // sag global[5a]
+ 0x36, // push
+ 0x35, 0x03, // ldi 03
+ 0x1e, // gt?
+ 0x31, 0x03, // bnt [skip over]
+ 0x78, // push1
+ 0xa9, 0x5a, // ssg global[5a]
+ 0x33, 0x17, // jmp [iconTextSwitch::show call]
+ // additional code for iconTextSwitch::show
+ 0x89, 0x5a, // lsg global[5a]
+ 0x35, 0x01, // ldi 01
+ 0x1a, // eq?
+ 0x31, 0x04, // bnt [dual mode]
+ 0x35, 0x09, // ldi 09
+ 0x33, 0x02, // jmp [skip over dual mode]
+ 0x35, 0x0c, // ldi 0c (view 947, loop 12, cel 0+1 is our "dual" view, injected by view.cpp)
+ 0x65, 0x14, // aTop loop
+ 0x32, PATCH_UINT16(0xff75), // jmp [back to iconTextSwitch::show]
+ PATCH_END
+};
+
+// script, description, signature patch
+static const SciScriptPatcherEntry kq6Signatures[] = {
+ { true, 481, "duplicate baby cry", 1, kq6SignatureDuplicateBabyCry, kq6PatchDuplicateBabyCry },
+ { true, 907, "inventory stack fix", 1, kq6SignatureInventoryStackFix, kq6PatchInventoryStackFix },
+ { true, 87, "Drink Me bottle fix", 1, kq6SignatureDrinkMeFix, kq6PatchDrinkMeFix },
+ // King's Quest 6 and Laura Bow 2 share basic patches for audio + text support
+ // *** King's Quest 6 audio + text support ***
+ { false, 924, "CD: audio + text support KQ6&LB2 1", 1, kq6laurabow2CDSignatureAudioTextSupport1, kq6laurabow2CDPatchAudioTextSupport1 },
+ { false, 924, "CD: audio + text support KQ6&LB2 2", 1, kq6laurabow2CDSignatureAudioTextSupport2, kq6laurabow2CDPatchAudioTextSupport2 },
+ { false, 924, "CD: audio + text support KQ6&LB2 3", 1, kq6laurabow2CDSignatureAudioTextSupport3, kq6laurabow2CDPatchAudioTextSupport3 },
+ { false, 928, "CD: audio + text support KQ6&LB2 4", 1, kq6laurabow2CDSignatureAudioTextSupport4, kq6laurabow2CDPatchAudioTextSupport4 },
+ { false, 928, "CD: audio + text support KQ6&LB2 5", 2, kq6laurabow2CDSignatureAudioTextSupport5, kq6laurabow2CDPatchAudioTextSupport5 },
+ { false, 909, "CD: audio + text support KQ6 1", 2, kq6CDSignatureAudioTextSupport1, kq6CDPatchAudioTextSupport1 },
+ { false, 928, "CD: audio + text support KQ6 2", 1, kq6CDSignatureAudioTextSupport2, kq6CDPatchAudioTextSupport2 },
+ { false, 104, "CD: audio + text support KQ6 3", 1, kq6CDSignatureAudioTextSupport3, kq6CDPatchAudioTextSupport3 },
+ { false, 928, "CD: audio + text support KQ6 4", 1, kq6CDSignatureAudioTextSupport4, kq6CDPatchAudioTextSupport4 },
+ { 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, 903, "CD: audio + text support KQ6 menu", 1, kq6CDSignatureAudioTextMenuSupport, kq6CDPatchAudioTextMenuSupport },
SCI_SIGNATUREENTRY_TERMINATOR
};
@@ -756,40 +1319,40 @@ const SciScriptSignature kq6Signatures[] = {
// the function is undefined, thus kStrCat() that is called inside the function
// reads a random pointer and crashes. We patch all of the 5 function calls
// (one for each letter typed from "R", "O", "B", "I", "N") so that they are
-// the same as the English version. Fixes bug #3048054.
-const byte longbowSignatureShowHandCode[] = {
- 3,
- 0x78, // push1
- 0x78, // push1
- 0x72, // lofsa
- +2, 2, // skip 2 bytes, offset of lofsa (the letter typed)
- 0x36, // push
- 0x40, // call
- +2, 3, // skip 2 bytes, offset of call
- 0x02, // perform the call above with 2 parameters
- 0x36, // push
- 0x40, // call
- +2, 8, // skip 2 bytes, offset of call
- 0x02, // perform the call above with 2 parameters
- 0x38, 0x1c, 0x01, // pushi 011c (setMotion)
- 0x39, 0x04, // pushi 04 (x)
- 0x51, 0x1e, // class MoveTo
- 0
-};
-
-const uint16 longbowPatchShowHandCode[] = {
- 0x39, 0x01, // pushi 1 (combine the two push1's in one, like in the English version)
- PATCH_ADDTOOFFSET | +3, // leave the lofsa call untouched
+// the same as the English version.
+// Applies to at least: German floppy
+// Responsible method: unknown
+// Fixes bug: #5264
+static const uint16 longbowSignatureShowHandCode[] = {
+ 0x78, // push1
+ 0x78, // push1
+ 0x72, SIG_ADDTOOFFSET(+2), // lofsa (letter, that was typed)
+ 0x36, // push
+ 0x40, SIG_ADDTOOFFSET(+2), // call
+ 0x02, // perform the call above with 2 parameters
+ 0x36, // push
+ 0x40, SIG_ADDTOOFFSET(+2), // call
+ SIG_MAGICDWORD,
+ 0x02, // perform the call above with 2 parameters
+ 0x38, SIG_SELECTOR16(setMotion), // pushi "setMotion" (0x11c in Longbow German)
+ 0x39, SIG_SELECTOR8(x), // pushi "x" (0x04 in Longbow German)
+ 0x51, 0x1e, // class MoveTo
+ SIG_END
+};
+
+static const uint16 longbowPatchShowHandCode[] = {
+ 0x39, 0x01, // pushi 1 (combine the two push1's in one, like in the English version)
+ PATCH_ADDTOOFFSET(+3), // leave the lofsa call untouched
// The following will remove the duplicate call
- 0x32, 0x02, 0x00, // jmp 02 - skip 2 bytes (the remainder of the first call)
- 0x48, // ret (dummy, should never be reached)
- 0x48, // ret (dummy, should never be reached)
+ 0x32, PATCH_UINT16(0x0002), // jmp 02 - skip 2 bytes (the remainder of the first call)
+ 0x48, // ret (dummy, should never be reached)
+ 0x48, // ret (dummy, should never be reached)
PATCH_END
};
-// script, description, magic DWORD, adjust
-const SciScriptSignature longbowSignatures[] = {
- { 210, "hand code crash", 5, PATCH_MAGICDWORD(0x02, 0x38, 0x1c, 0x01), -14, longbowSignatureShowHandCode, longbowPatchShowHandCode },
+// script, description, signature patch
+static const SciScriptPatcherEntry longbowSignatures[] = {
+ { true, 210, "hand code crash", 5, longbowSignatureShowHandCode, longbowPatchShowHandCode },
SCI_SIGNATUREENTRY_TERMINATOR
};
@@ -807,31 +1370,60 @@ const SciScriptSignature longbowSignatures[] = {
// "worked" in SSCI, but ScummVM/SCI doesn't allow that.
// That's why those points weren't granted here at all.
// We patch the script to use global 90, which seems to be unused in the whole game.
+// Applies to at least: English floppy
// Responsible method: rm63Script::handleEvent
-// Fixes bug #3614419
-const byte larry2SignatureWearParachutePoints[] = {
- 16,
- 0x35, 0x01, // ldi 01
- 0xa1, 0x8e, // sag 8e
- 0x80, 0xe0, 0x01, // lag 1e0
- 0x18, // not
- 0x30, 0x0f, 0x00, // bnt [don't give points]
- 0x35, 0x01, // ldi 01
- 0xa0, 0xe0, 0x01, // sag 1e0
- 0
+// Fixes bug: #6346
+static const uint16 larry2SignatureWearParachutePoints[] = {
+ 0x35, 0x01, // ldi 01
+ 0xa1, SIG_MAGICDWORD, 0x8e, // sag 8e
+ 0x80, SIG_UINT16(0x01e0), // lag 1e0
+ 0x18, // not
+ 0x30, SIG_UINT16(0x000f), // bnt [don't give points]
+ 0x35, 0x01, // ldi 01
+ 0xa0, 0xe0, 0x01, // sag 1e0
+ SIG_END
+};
+
+static const uint16 larry2PatchWearParachutePoints[] = {
+ PATCH_ADDTOOFFSET(+4),
+ 0x80, PATCH_UINT16(0x005a), // lag 5a (global 90)
+ PATCH_ADDTOOFFSET(+6),
+ 0xa0, PATCH_UINT16(0x005a), // sag 5a (global 90)
+ PATCH_END
+};
+
+// script, description, signature patch
+static const SciScriptPatcherEntry larry2Signatures[] = {
+ { true, 63, "plane: no points for wearing plane", 1, larry2SignatureWearParachutePoints, larry2PatchWearParachutePoints },
+ SCI_SIGNATUREENTRY_TERMINATOR
};
-const uint16 larry2PatchWearParachutePoints[] = {
- PATCH_ADDTOOFFSET | +4,
- 0x80, 0x5a, 0x00, // lag 5a (global 90)
- PATCH_ADDTOOFFSET | +6,
- 0xa0, 0x5a, 0x00, // sag 5a (global 90)
+// ===========================================================================
+// Leisure Suit Larry 5
+// 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.
+// Because of that the talking head of Patti is drawn over the textbox. A translation oversight.
+// Applies to at least: German floppy
+// Responsible method: none, position of talker object on screen needs to get modified
+static const uint16 larry5SignatureGermanEndingPattiTalker[] = {
+ SIG_MAGICDWORD,
+ SIG_UINT16(0x006e), // object pattiTalker::x (110)
+ SIG_UINT16(0x00b4), // object pattiTalker::y (180)
+ SIG_ADDTOOFFSET(+469), // verify that it's really the German version
+ 0x59, 0x6f, 0x75, // (object name) "You"
+ 0x23, 0x47, 0x44, 0x75, // "#GDu"
+ SIG_END
+};
+
+static const uint16 larry5PatchGermanEndingPattiTalker[] = {
+ PATCH_UINT16(0x005a), // change pattiTalker::x to 90
PATCH_END
};
-// script, description, magic DWORD, adjust
-const SciScriptSignature larry2Signatures[] = {
- { 63, "plane: no points for wearing plane", 1, PATCH_MAGICDWORD(0x8e, 0x80, 0xe0, 0x01), -3, larry2SignatureWearParachutePoints, larry2PatchWearParachutePoints },
+// script, description, signature patch
+static const SciScriptPatcherEntry larry5Signatures[] = {
+ { true, 380, "German-only: Enlarge Patti Textbox", 1, larry5SignatureGermanEndingPattiTalker, larry5PatchGermanEndingPattiTalker },
SCI_SIGNATUREENTRY_TERMINATOR
};
@@ -843,77 +1435,265 @@ const SciScriptSignature larry2Signatures[] = {
// doesn't happen anymore. We would otherwise get a crash
// calling for invalid views (this happens of course also
// in sierra sci)
-const byte larry6SignatureDeathDialog[] = {
- 7,
- 0x3e, 0x33, 0x01, // link 0133 (offset 0x20)
- 0x35, 0xff, // ldi ff
- 0xa3, 0x00, // sal 00
- +255, 0,
- +255, 0,
- +170, 12, // [skip 680 bytes]
- 0x8f, 0x01, // lsp 01 (offset 0x2cf)
- 0x7a, // push2
- 0x5a, 0x04, 0x00, 0x0e, 0x01, // lea 0004 010e
- 0x36, // push
- 0x43, 0x7c, 0x0e, // kMessage[7c] 0e
- +90, 10, // [skip 90 bytes]
- 0x38, 0xd6, 0x00, // pushi 00d6 (offset 0x335)
- 0x78, // push1
- 0x5a, 0x04, 0x00, 0x0e, 0x01, // lea 0004 010e
- 0x36, // push
- +76, 11, // [skip 76 bytes]
- 0x38, 0xcd, 0x00, // pushi 00cd (offset 0x38b)
- 0x39, 0x03, // pushi 03
- 0x5a, 0x04, 0x00, 0x0e, 0x01, // lea 0004 010e
+// Applies to at least: German PC-CD
+// Responsible method: unknown
+static const uint16 larry6SignatureDeathDialog[] = {
+ SIG_MAGICDWORD,
+ 0x3e, SIG_UINT16(0x0133), // link 0133 (offset 0x20)
+ 0x35, 0xff, // ldi ff
+ 0xa3, 0x00, // sal 00
+ SIG_ADDTOOFFSET(+680), // [skip 680 bytes]
+ 0x8f, 0x01, // lsp 01 (offset 0x2cf)
+ 0x7a, // push2
+ 0x5a, SIG_UINT16(0x0004), SIG_UINT16(0x010e), // lea 0004 010e
+ 0x36, // push
+ 0x43, 0x7c, 0x0e, // kMessage[7c] 0e
+ SIG_ADDTOOFFSET(+90), // [skip 90 bytes]
+ 0x38, SIG_UINT16(0x00d6), // pushi 00d6 (offset 0x335)
+ 0x78, // push1
+ 0x5a, SIG_UINT16(0x0004), SIG_UINT16(0x010e), // lea 0004 010e
+ 0x36, // push
+ SIG_ADDTOOFFSET(+76), // [skip 76 bytes]
+ 0x38, SIG_UINT16(0x00cd), // pushi 00cd (offset 0x38b)
+ 0x39, 0x03, // pushi 03
+ 0x5a, SIG_UINT16(0x0004), SIG_UINT16(0x010e), // lea 0004 010e
0x36,
- 0
+ SIG_END
};
-const uint16 larry6PatchDeathDialog[] = {
- 0x3e, 0x00, 0x02, // link 0200
- PATCH_ADDTOOFFSET | +687,
- 0x5a, 0x04, 0x00, 0x40, 0x01, // lea 0004 0140
- PATCH_ADDTOOFFSET | +98,
- 0x5a, 0x04, 0x00, 0x40, 0x01, // lea 0004 0140
- PATCH_ADDTOOFFSET | +82,
- 0x5a, 0x04, 0x00, 0x40, 0x01, // lea 0004 0140
+static const uint16 larry6PatchDeathDialog[] = {
+ 0x3e, 0x00, 0x02, // link 0200
+ PATCH_ADDTOOFFSET(+687),
+ 0x5a, PATCH_UINT16(0x0004), PATCH_UINT16(0x0140), // lea 0004 0140
+ PATCH_ADDTOOFFSET(+98),
+ 0x5a, PATCH_UINT16(0x0004), PATCH_UINT16(0x0140), // lea 0004 0140
+ PATCH_ADDTOOFFSET(+82),
+ 0x5a, PATCH_UINT16(0x0004), PATCH_UINT16(0x0140), // lea 0004 0140
PATCH_END
};
-// script, description, magic DWORD, adjust
-const SciScriptSignature larry6Signatures[] = {
- { 82, "death dialog memory corruption", 1, PATCH_MAGICDWORD(0x3e, 0x33, 0x01, 0x35), 0, larry6SignatureDeathDialog, larry6PatchDeathDialog },
+// script, description, signature patch
+static const SciScriptPatcherEntry larry6Signatures[] = {
+ { true, 82, "death dialog memory corruption", 1, larry6SignatureDeathDialog, larry6PatchDeathDialog },
SCI_SIGNATUREENTRY_TERMINATOR
};
// ===========================================================================
-// rm560::doit was supposed to close the painting, when Heimlich enters the
-// room. The code is buggy, so it actually closes the painting, when heimlich
-// is not in the room. We fix that.
-const byte laurabow2SignaturePaintingClosing[] = {
- 17,
- 0x4a, 0x04, // send 04 - read aHeimlich::room
- 0x36, // push
- 0x81, 0x0b, // lag global[11d] -> current room
- 0x1c, // ne?
- 0x31, 0x0e, // bnt [don't close]
- 0x35, 0x00, // ldi 00
- 0xa3, 0x00, // sal local[0]
- 0x38, 0x92, 0x00, // pushi 0092
- 0x78, // push1
- 0x72, // lofsa sDumpSafe
- 0
+// Laura Bow 2
+//
+// Moving away the painting in the room with the hidden safe is problematic
+// for the CD version of the game. safePic::doVerb gets triggered by the mouse-click.
+// This method sets local 0 as signal, which is only meant to get handled, when
+// the player clicks again to move the painting back. This signal is processed by
+// the room doit-script.
+// That doit-script checks safePic::cel to be not equal 0 and would then skip over
+// the "close painting" trigger code. On very fast computers this script may
+// get called too early (which is the case when running under ScummVM and when
+// running the game using Sierra SCI in DOS-Box with cycles 15000) and thinks
+// that it's supposed to move the painting back. Which then results in the painting
+// getting moved to its original position immediately (which means it won't be possible
+// to access the safe behind it).
+//
+// We patch the script, so that we check for cel to be not equal 4 (the final cel) and
+// we also reset the safePic-signal immediately as well.
+//
+// In the floppy version Laura's coordinates are checked directly in rm560::doit
+// and as soon as she moves, the painting will automatically move to its original position.
+// This is not the case for the CD version of the game. The painting will only "move" back,
+// when the player actually exits the room and re-enters.
+//
+// Applies to at least: English PC-CD
+// Responsible method: rm560::doit
+// Fixes bug: #6460
+static const uint16 laurabow2CDSignaturePaintingClosing[] = {
+ 0x39, 0x04, // pushi 04 (cel)
+ 0x76, // push0
+ SIG_MAGICDWORD,
+ 0x7a, // push2
+ 0x38, SIG_UINT16(0x0231), // pushi 0231h (561)
+ 0x76, // push0
+ 0x43, 0x02, 0x04, // kScriptID (get export 0 of script 561)
+ 0x4a, 0x04, // send 04 (gets safePicture::cel)
+ 0x18, // not
+ 0x31, 0x21, // bnt [exit]
+ 0x38, SIG_UINT16(0x0283), // pushi 0283h
+ 0x76, // push0
+ 0x7a, // push2
+ 0x39, 0x20, // pushi 20
+ 0x76, // push0
+ 0x43, 0x02, 0x04, // kScriptID (get export 0 of script 32)
+ 0x4a, 0x04, // send 04 (get sHeimlich::room)
+ 0x36, // push
+ 0x81, 0x0b, // lag global[b] (current room)
+ 0x1c, // ne?
+ 0x31, 0x0e, // bnt [exit]
+ 0x35, 0x00, // ldi 00
+ 0xa3, 0x00, // sal local[0] -> reset safePic signal
+ SIG_END
+};
+
+static const uint16 laurabow2CDPatchPaintingClosing[] = {
+ PATCH_ADDTOOFFSET(+2),
+ 0x3c, // dup (1 additional byte)
+ 0x76, // push0
+ 0x3c, // dup (1 additional byte)
+ 0xab, 0x00, // ssl local[0] -> reset safePic signal
+ 0x7a, // push2
+ 0x38, PATCH_UINT16(0x0231), // pushi 0231h (561)
+ 0x76, // push0
+ 0x43, 0x02, 0x04, // kScriptID (get export 0 of script 561)
+ 0x4a, 0x04, // send 04 (gets safePicture::cel)
+ 0x1a, // eq?
+ 0x31, 0x1d, // bnt [exit]
+ 0x38, PATCH_UINT16(0x0283), // pushi 0283h
+ 0x76, // push0
+ 0x7a, // push2
+ 0x39, 0x20, // pushi 20
+ 0x76, // push0
+ 0x43, 0x02, 0x04, // kScriptID (get export 0 of script 32)
+ 0x4a, 0x04, // send 04 (get sHeimlich::room)
+ 0x36, // push
+ 0x81, 0x0b, // lag global[b] (current room)
+ 0x1a, // eq? (2 opcodes changed, to save 2 bytes)
+ 0x2f, 0x0a, // bt [exit]
+ PATCH_END
};
-const uint16 laurabow2PatchPaintingClosing[] = {
- PATCH_ADDTOOFFSET | +6,
- 0x2f, 0x0e, // bt [don't close]
+// In the CD version the system menu is disabled for certain rooms. LB2::handsOff is called,
+// when leaving the room (and in other cases as well). This method remembers the disabled
+// icons of the icon bar. In the new room LB2::handsOn will get called, which then enables
+// all icons, but also disabled the ones, that were disabled before.
+//
+// Because of this behaviour certain rooms, that should have the system menu enabled, have
+// it disabled, when entering those rooms from rooms, where the menu is supposed to be
+// disabled.
+//
+// We patch this by injecting code into LB2::newRoom (which is called right after a room change)
+// and reset the global variable there, that normally holds the disabled buttons.
+//
+// This patch may cause side-effects and it's difficult to test, because it affects every room
+// in the game. At least for the intro, the speakeasy and plenty of rooms in the beginning it
+// seems to work correctly.
+//
+// Applies to at least: English PC-CD
+// Responsible method: LB2::newRoom, LB2::handsOff, LB2::handsOn
+// Fixes bug: #6440
+static const uint16 laurabow2CDSignatureFixProblematicIconBar[] = {
+ SIG_MAGICDWORD,
+ 0x38, SIG_UINT16(0x00f1), // pushi 00f1 (disable) - hardcoded, we only want to patch the CD version
+ 0x76, // push0
+ 0x81, 0x45, // lag global[45]
+ 0x4a, 0x04, // send 04
+ SIG_END
+};
+
+static const uint16 laurabow2CDPatchFixProblematicIconBar[] = {
+ 0x35, 0x00, // ldi 00
+ 0xa1, 0x74, // sag 74h
+ 0x35, 0x00, // ldi 00 (waste bytes)
+ 0x35, 0x00, // ldi 00
PATCH_END
};
-// script, description, magic DWORD, adjust
-const SciScriptSignature laurabow2Signatures[] = {
- { 560, "painting closing immediately", 1, PATCH_MAGICDWORD(0x36, 0x81, 0x0b, 0x1c), -2, laurabow2SignaturePaintingClosing, laurabow2PatchPaintingClosing },
+// Laura Bow 2 CD resets the audio mode to speech on init/restart
+// We already sync the settings from ScummVM (see SciEngine::syncIngameAudioOptions())
+// and this script code would make it impossible to see the intro using "dual" mode w/o using debugger command
+// That's why we remove the corresponding code
+// Patched method: LB2::init, rm100::init
+static const uint16 laurabow2CDSignatureAudioTextSupportModeReset[] = {
+ SIG_MAGICDWORD,
+ 0x35, 0x02, // ldi 02
+ 0xa1, 0x5a, // sag global[5a]
+ SIG_END
+};
+
+static const uint16 laurabow2CDPatchAudioTextSupportModeReset[] = {
+ 0x34, PATCH_UINT16(0x0001), // ldi 0001 (waste bytes)
+ 0x18, // not (waste bytes)
+ PATCH_END
+};
+
+// Directly use global 5a for view-cel id
+// That way it's possible to use a new "dual" mode view in the game menu
+// View 995, loop 13, cel 0 -> "text"
+// View 995, loop 13, cel 1 -> "speech"
+// View 995, loop 13, cel 2 -> "dual" (TODO: inject our own view for the new "dual" mode)
+// Patched method: gcWin::open
+static const uint16 laurabow2CDSignatureAudioTextMenuSupport1[] = {
+ SIG_MAGICDWORD,
+ 0x89, 0x5a, // lsg global[5a]
+ 0x35, 0x02, // ldi 02
+ 0x1a, // eq?
+ 0x36, // push
+ SIG_END
+};
+
+static const uint16 laurabow2CDPatchAudioTextMenuSupport1[] = {
+ PATCH_ADDTOOFFSET(+2),
+ 0x35, 0x01, // ldi 01
+ 0x04, // sub
+ PATCH_END
+};
+
+// Adds another button state for the text/audio button. We currently use the "speech" view for "dual" mode.
+// TODO: inject our own 2 views for the new "dual" mode
+// Patched method: iconMode::doit
+static const uint16 laurabow2CDSignatureAudioTextMenuSupport2[] = {
+ SIG_MAGICDWORD,
+ 0x89, 0x5a, // lsg global[5a]
+ 0x3c, // dup
+ 0x1a, // eq?
+ 0x31, 0x0a, // bnt [set text mode]
+ 0x35, 0x02, // ldi 02
+ 0xa1, 0x5a, // sag global[5a]
+ 0x35, 0x01, // ldi 01
+ 0xa5, 0x00, // sat temp[0]
+ 0x33, 0x0e, // jmp [draw cel code]
+ 0x3c, // dup
+ 0x35, 0x02, // ldi 02
+ 0x1a, // eq?
+ 0x31, 0x08, // bnt [draw cel code]
+ 0x35, 0x01, // ldi 01
+ 0xa1, 0x5a, // sag global[5a]
+ 0x35, 0x00, // ldi 00
+ 0xa5, 0x00, // sat temp[0]
+ 0x3a, // toss
+ SIG_END
+};
+
+static const uint16 laurabow2CDPatchAudioTextMenuSupport2[] = {
+ 0x81, 0x5a, // lag global[5a]
+ 0x78, // push1
+ 0x02, // add
+ 0xa1, 0x5a, // sag global[5a]
+ 0x36, // push
+ 0x35, 0x03, // ldi 03
+ 0x1e, // gt?
+ 0x31, 0x03, // bnt [skip over]
+ 0x78, // push1
+ 0xa9, 0x5a, // ssg global[5a]
+ 0x89, 0x5a, // lsg global[5a]
+ 0x35, 0x01, // ldi 01
+ 0x04, // sub
+ 0xa5, 0x00, // sat temp[0] - calculate global[5a] - 1 to use as view cel id
+ 0x33, 0x07, // jmp [draw cel code, don't do toss]
+ PATCH_END
+};
+
+// script, description, signature patch
+static const SciScriptPatcherEntry laurabow2Signatures[] = {
+ { true, 560, "CD: painting closing immediately", 1, laurabow2CDSignaturePaintingClosing, laurabow2CDPatchPaintingClosing },
+ { true, 0, "CD: fix problematic icon bar", 1, laurabow2CDSignatureFixProblematicIconBar, laurabow2CDPatchFixProblematicIconBar },
+ // King's Quest 6 and Laura Bow 2 share basic patches for audio + text support
+ { false, 924, "CD: audio + text support 1", 1, kq6laurabow2CDSignatureAudioTextSupport1, kq6laurabow2CDPatchAudioTextSupport1 },
+ { false, 924, "CD: audio + text support 2", 1, kq6laurabow2CDSignatureAudioTextSupport2, kq6laurabow2CDPatchAudioTextSupport2 },
+ { false, 924, "CD: audio + text support 3", 1, kq6laurabow2CDSignatureAudioTextSupport3, kq6laurabow2CDPatchAudioTextSupport3 },
+ { false, 928, "CD: audio + text support 4", 1, kq6laurabow2CDSignatureAudioTextSupport4, kq6laurabow2CDPatchAudioTextSupport4 },
+ { false, 928, "CD: audio + text support 5", 2, kq6laurabow2CDSignatureAudioTextSupport5, kq6laurabow2CDPatchAudioTextSupport5 },
+ { false, 0, "CD: audio + text support disable mode reset", 1, laurabow2CDSignatureAudioTextSupportModeReset, laurabow2CDPatchAudioTextSupportModeReset },
+ { false, 100, "CD: audio + text support disable mode reset", 1, laurabow2CDSignatureAudioTextSupportModeReset, laurabow2CDPatchAudioTextSupportModeReset },
+ { false, 24, "CD: audio + text support LB2 menu 1", 1, laurabow2CDSignatureAudioTextMenuSupport1, laurabow2CDPatchAudioTextMenuSupport1 },
+ { false, 24, "CD: audio + text support LB2 menu 2", 1, laurabow2CDSignatureAudioTextMenuSupport2, laurabow2CDPatchAudioTextMenuSupport2 },
SCI_SIGNATUREENTRY_TERMINATOR
};
@@ -922,42 +1702,40 @@ const SciScriptSignature laurabow2Signatures[] = {
// MG::replay somewhat calculates the savedgame-id used when saving again
// this doesn't work right and we remove the code completely.
// We set the savedgame-id directly right after restoring in kRestoreGame.
-const byte mothergoose256SignatureReplay[] = {
- 6,
- 0x36, // push
- 0x35, 0x20, // ldi 20
- 0x04, // sub
- 0xa1, 0xb3, // sag global[b3]
- 0
+static const uint16 mothergoose256SignatureReplay[] = {
+ 0x36, // push
+ 0x35, SIG_MAGICDWORD, 0x20, // ldi 20
+ 0x04, // sub
+ 0xa1, 0xb3, // sag global[b3]
+ SIG_END
};
-const uint16 mothergoose256PatchReplay[] = {
- 0x34, 0x00, 0x00, // ldi 0000 (dummy)
- 0x34, 0x00, 0x00, // ldi 0000 (dummy)
+static const uint16 mothergoose256PatchReplay[] = {
+ 0x34, PATCH_UINT16(0x0000), // ldi 0000 (dummy)
+ 0x34, PATCH_UINT16(0x0000), // ldi 0000 (dummy)
PATCH_END
};
// when saving, it also checks if the savegame ID is below 13.
// we change this to check if below 113 instead
-const byte mothergoose256SignatureSaveLimit[] = {
- 5,
- 0x89, 0xb3, // lsg global[b3]
- 0x35, 0x0d, // ldi 0d
- 0x20, // ge?
- 0
+static const uint16 mothergoose256SignatureSaveLimit[] = {
+ 0x89, SIG_MAGICDWORD, 0xb3, // lsg global[b3]
+ 0x35, 0x0d, // ldi 0d
+ 0x20, // ge?
+ SIG_END
};
-const uint16 mothergoose256PatchSaveLimit[] = {
- PATCH_ADDTOOFFSET | +2,
+static const uint16 mothergoose256PatchSaveLimit[] = {
+ PATCH_ADDTOOFFSET(+2),
0x35, 0x0d + SAVEGAMEID_OFFICIALRANGE_START, // ldi 113d
PATCH_END
};
-// script, description, magic DWORD, adjust
-const SciScriptSignature mothergoose256Signatures[] = {
- { 0, "replay save issue", 1, PATCH_MAGICDWORD(0x20, 0x04, 0xa1, 0xb3), -2, mothergoose256SignatureReplay, mothergoose256PatchReplay },
- { 0, "save limit dialog (SCI1.1)", 1, PATCH_MAGICDWORD(0xb3, 0x35, 0x0d, 0x20), -1, mothergoose256SignatureSaveLimit, mothergoose256PatchSaveLimit },
- { 994, "save limit dialog (SCI1)", 1, PATCH_MAGICDWORD(0xb3, 0x35, 0x0d, 0x20), -1, mothergoose256SignatureSaveLimit, mothergoose256PatchSaveLimit },
+// script, description, signature patch
+static const SciScriptPatcherEntry mothergoose256Signatures[] = {
+ { true, 0, "replay save issue", 1, mothergoose256SignatureReplay, mothergoose256PatchReplay },
+ { true, 0, "save limit dialog (SCI1.1)", 1, mothergoose256SignatureSaveLimit, mothergoose256PatchSaveLimit },
+ { true, 994, "save limit dialog (SCI1)", 1, mothergoose256SignatureSaveLimit, mothergoose256PatchSaveLimit },
SCI_SIGNATUREENTRY_TERMINATOR
};
@@ -971,55 +1749,89 @@ const SciScriptSignature mothergoose256Signatures[] = {
// SSCI.
// This patch changes the code, so that the gun is actually given away
// when the 2 seconds have passed and the locker got closed.
+// Applies to at least: English floppy
// Responsible method: putGun::changeState (script 341)
-// Fixes bug #3036933 / #3303802
-const byte pq1vgaSignaturePutGunInLockerBug[] = {
- 5,
- 0x35, 0x00, // ldi 00
- 0x1a, // eq?
- 0x31, 0x25, // bnt [next state check]
- +22, 29, // [skip 22 bytes]
- 0x38, 0x5f, 0x01, // pushi 15fh
- 0x78, // push1
- 0x76, // push0
- 0x81, 0x00, // lag 00
- 0x4a, 0x06, // send 06 - ego::put(0)
- 0x35, 0x02, // ldi 02
- 0x65, 0x1c, // aTop 1c (set timer to 2 seconds)
- 0x33, 0x0e, // jmp [end of method]
- 0x3c, // dup --- next state check target
- 0x35, 0x01, // ldi 01
- 0x1a, // eq?
- 0x31, 0x08, // bnt [end of method]
- 0x39, 0x6f, // pushi 6fh
- 0x76, // push0
- 0x72, 0x88, 0x00, // lofsa 0088
- 0x4a, 0x04, // send 04 - locker::dispose
- 0
+// Fixes bug: #5705 / #6400
+static const uint16 pq1vgaSignaturePutGunInLockerBug[] = {
+ 0x35, 0x00, // ldi 00
+ 0x1a, // eq?
+ 0x31, 0x25, // bnt [next state check]
+ SIG_ADDTOOFFSET(+22), // [skip 22 bytes]
+ SIG_MAGICDWORD,
+ 0x38, SIG_SELECTOR16(put), // pushi "put"
+ 0x78, // push1
+ 0x76, // push0
+ 0x81, 0x00, // lag 00
+ 0x4a, 0x06, // send 06 - ego::put(0)
+ 0x35, 0x02, // ldi 02
+ 0x65, 0x1c, // aTop 1c (set timer to 2 seconds)
+ 0x33, 0x0e, // jmp [end of method]
+ 0x3c, // dup --- next state check target
+ 0x35, 0x01, // ldi 01
+ 0x1a, // eq?
+ 0x31, 0x08, // bnt [end of method]
+ 0x39, SIG_SELECTOR8(dispose), // pushi "dispose"
+ 0x76, // push0
+ 0x72, SIG_UINT16(0x0088), // lofsa 0088
+ 0x4a, 0x04, // send 04 - locker::dispose
+ SIG_END
+};
+
+static const uint16 pq1vgaPatchPutGunInLockerBug[] = {
+ PATCH_ADDTOOFFSET(+3),
+ 0x31, 0x1c, // bnt [next state check]
+ PATCH_ADDTOOFFSET(+22),
+ 0x35, 0x02, // ldi 02
+ 0x65, 0x1c, // aTop 1c (set timer to 2 seconds)
+ 0x33, 0x17, // jmp [end of method]
+ 0x3c, // dup --- next state check target
+ 0x35, 0x01, // ldi 01
+ 0x1a, // eq?
+ 0x31, 0x11, // bnt [end of method]
+ 0x38, PATCH_SELECTOR16(put), // pushi "put"
+ 0x78, // push1
+ 0x76, // push0
+ 0x81, 0x00, // lag 00
+ 0x4a, 0x06, // send 06 - ego::put(0)
+ PATCH_END
};
-const uint16 pq1vgaPatchPutGunInLockerBug[] = {
- PATCH_ADDTOOFFSET | +3,
- 0x31, 0x1c, // bnt [next state check]
- PATCH_ADDTOOFFSET | +22,
- 0x35, 0x02, // ldi 02
- 0x65, 0x1c, // aTop 1c (set timer to 2 seconds)
- 0x33, 0x17, // jmp [end of method]
- 0x3c, // dup --- next state check target
- 0x35, 0x01, // ldi 01
- 0x1a, // eq?
- 0x31, 0x11, // bnt [end of method]
- 0x38, 0x5f, 0x01, // pushi 15fh
- 0x78, // push1
- 0x76, // push0
- 0x81, 0x00, // lag 00
- 0x4a, 0x06, // send 06 - ego::put(0)
+// When restoring a saved game, which was made while driving around,
+// the game didn't redraw the map. This also happened in Sierra SCI.
+//
+// The map is a picture resource and drawn over the main picture.
+// This is called an "overlay" in SCI. This wasn't implemented properly.
+// We fix it by actually implementing it properly.
+//
+// Applies to at least: English floppy
+// Responsible method: rm500::init, changeOverlay::changeState (script 500)
+// Fixes bug: #5016
+static const uint16 pq1vgaSignatureMapSaveRestoreBug[] = {
+ 0x39, 0x04, // pushi 04
+ SIG_ADDTOOFFSET(+2), // skip either lsg global[f9] or pTos register
+ SIG_MAGICDWORD,
+ 0x38, 0x64, 0x80, // pushi 8064
+ 0x76, // push0
+ 0x89, 0x28, // lsg global[28]
+ 0x43, 0x08, 0x08, // kDrawPic (8)
+ SIG_END
+};
+
+static const uint16 pq1vgaPatchMapSaveRestoreBug[] = {
+ 0x38, PATCH_SELECTOR16(overlay), // pushi "overlay"
+ 0x7a, // push2
+ 0x89, 0xf9, // lsg global[f9]
+ 0x39, 0x64, // pushi 64 (no transition)
+ 0x81, 0x02, // lag global[02] (current room object)
+ 0x4a, 0x08, // send 08
+ 0x18, // not (waste byte)
PATCH_END
};
-// script, description, magic DWORD, adjust
-const SciScriptSignature pq1vgaSignatures[] = {
- { 341, "put gun in locker bug", 1, PATCH_MAGICDWORD(0x38, 0x5f, 0x01, 0x78), -27, pq1vgaSignaturePutGunInLockerBug, pq1vgaPatchPutGunInLockerBug },
+// script, description, signature patch
+static const SciScriptPatcherEntry pq1vgaSignatures[] = {
+ { true, 341, "put gun in locker bug", 1, pq1vgaSignaturePutGunInLockerBug, pq1vgaPatchPutGunInLockerBug },
+ { true, 500, "map save/restore bug", 2, pq1vgaSignatureMapSaveRestoreBug, pq1vgaPatchMapSaveRestoreBug },
SCI_SIGNATUREENTRY_TERMINATOR
};
@@ -1032,43 +1844,45 @@ const SciScriptSignature pq1vgaSignatures[] = {
// not nearly as bad as in our sci, but these differences may be caused by
// timing.
// We just reuse the active event, thus removing the duplicate kGetEvent call.
-const byte qfg1vgaSignatureFightEvents[] = {
- 25,
- 0x39, 0x6d, // pushi 6d (selector new)
- 0x76, // push0
- 0x51, 0x07, // class Event
- 0x4a, 0x04, // send 04 - call Event::new
- 0xa5, 0x00, // sat temp[0]
- 0x78, // push1
- 0x76, // push0
- 0x4a, 0x04, // send 04 - read Event::x
- 0xa5, 0x03, // sat temp[3]
- 0x76, // push0 (selector y)
- 0x76, // push0
- 0x85, 0x00, // lat temp[0]
- 0x4a, 0x04, // send 04 - read Event::y
- 0x36, // push
- 0x35, 0x0a, // ldi 0a
- 0x04, // sub (poor mans localization) ;-)
- 0
-};
-
-const uint16 qfg1vgaPatchFightEvents[] = {
- 0x38, 0x5a, 0x01, // pushi 15a (selector curEvent)
- 0x76, // push0
- 0x81, 0x50, // lag global[50]
- 0x4a, 0x04, // send 04 - read User::curEvent -> needs one byte more than previous code
- 0xa5, 0x00, // sat temp[0]
- 0x78, // push1
- 0x76, // push0
- 0x4a, 0x04, // send 04 - read Event::x
- 0xa5, 0x03, // sat temp[3]
- 0x76, // push0 (selector y)
- 0x76, // push0
- 0x85, 0x00, // lat temp[0]
- 0x4a, 0x04, // send 04 - read Event::y
- 0x39, 0x00, // pushi 00
- 0x02, // add (waste 3 bytes) - we don't need localization, User::doit has already done it
+// Applies to at least: English floppy
+// Responsible method: pointBox::doit
+static const uint16 qfg1vgaSignatureFightEvents[] = {
+ 0x39, SIG_MAGICDWORD,
+ SIG_SELECTOR8(new), // pushi "new"
+ 0x76, // push0
+ 0x51, 0x07, // class Event
+ 0x4a, 0x04, // send 04 - call Event::new
+ 0xa5, 0x00, // sat temp[0]
+ 0x78, // push1
+ 0x76, // push0
+ 0x4a, 0x04, // send 04 - read Event::x
+ 0xa5, 0x03, // sat temp[3]
+ 0x76, // push0 (selector y)
+ 0x76, // push0
+ 0x85, 0x00, // lat temp[0]
+ 0x4a, 0x04, // send 04 - read Event::y
+ 0x36, // push
+ 0x35, 0x0a, // ldi 0a
+ 0x04, // sub (poor mans localization) ;-)
+ SIG_END
+};
+
+static const uint16 qfg1vgaPatchFightEvents[] = {
+ 0x38, PATCH_SELECTOR16(curEvent), // pushi 15a (selector curEvent)
+ 0x76, // push0
+ 0x81, 0x50, // lag global[50]
+ 0x4a, 0x04, // send 04 - read User::curEvent -> needs one byte more than previous code
+ 0xa5, 0x00, // sat temp[0]
+ 0x78, // push1
+ 0x76, // push0
+ 0x4a, 0x04, // send 04 - read Event::x
+ 0xa5, 0x03, // sat temp[3]
+ 0x76, // push0 (selector y)
+ 0x76, // push0
+ 0x85, 0x00, // lat temp[0]
+ 0x4a, 0x04, // send 04 - read Event::y
+ 0x39, 0x00, // pushi 00
+ 0x02, // add (waste 3 bytes) - we don't need localization, User::doit has already done it
PATCH_END
};
@@ -1079,31 +1893,31 @@ const uint16 qfg1vgaPatchFightEvents[] = {
// window text, which erases the window header text because of its length. To
// fix that, we allocate more temp space and move the pointer used for the
// window header a little bit, wherever it's used in script 814.
-// Fixes bug #3568431.
+// Fixes bug: #6139.
// Patch 1: Increase temp space
-const byte qfg1vgaSignatureTempSpace[] = {
- 4,
- 0x3f, 0xba, // link 0xba
- 0x87, 0x00, // lap 0
- 0
+static const uint16 qfg1vgaSignatureTempSpace[] = {
+ SIG_MAGICDWORD,
+ 0x3f, 0xba, // link 0xba
+ 0x87, 0x00, // lap 0
+ SIG_END
};
-const uint16 qfg1vgaPatchTempSpace[] = {
- 0x3f, 0xca, // link 0xca
+static const uint16 qfg1vgaPatchTempSpace[] = {
+ 0x3f, 0xca, // link 0xca
PATCH_END
};
// Patch 2: Move the pointer used for the window header a little bit
-const byte qfg1vgaSignatureDialogHeader[] = {
- 4,
- 0x5b, 0x04, 0x80, // lea temp[0x80]
- 0x36, // push
- 0
+static const uint16 qfg1vgaSignatureDialogHeader[] = {
+ SIG_MAGICDWORD,
+ 0x5b, 0x04, 0x80, // lea temp[0x80]
+ 0x36, // push
+ SIG_END
};
-const uint16 qfg1vgaPatchDialogHeader[] = {
- 0x5b, 0x04, 0x90, // lea temp[0x90]
+static const uint16 qfg1vgaPatchDialogHeader[] = {
+ 0x5b, 0x04, 0x90, // lea temp[0x90]
PATCH_END
};
@@ -1115,63 +1929,65 @@ const uint16 qfg1vgaPatchDialogHeader[] = {
// edge case that can occur when Ego is set to sneak. Normally, when clicking on
// the crusher, ego is supposed to move close to position 79, 165. We change it
// to 85, 165, which is not an edge case thus the freeze is avoided.
-// Fixes bug #3585189.
-const byte qfg1vgaSignatureMoveToCrusher[] = {
- 9,
- 0x51, 0x1f, // class Motion
- 0x36, // push
- 0x39, 0x4f, // pushi 4f (79 - x)
- 0x38, 0xa5, 0x00, // pushi 00a5 (165 - y)
- 0x7c, // pushSelf
- 0
-};
-
-const uint16 qfg1vgaPatchMoveToCrusher[] = {
- PATCH_ADDTOOFFSET | +3,
- 0x39, 0x55, // pushi 55 (85 - x)
+// Fixes bug: #6180
+static const uint16 qfg1vgaSignatureMoveToCrusher[] = {
+ SIG_MAGICDWORD,
+ 0x51, 0x1f, // class Motion
+ 0x36, // push
+ 0x39, 0x4f, // pushi 4f (79 - x)
+ 0x38, SIG_UINT16(0x00a5), // pushi 00a5 (165 - y)
+ 0x7c, // pushSelf
+ SIG_END
+};
+
+static const uint16 qfg1vgaPatchMoveToCrusher[] = {
+ PATCH_ADDTOOFFSET(+3),
+ 0x39, 0x55, // pushi 55 (85 - x)
PATCH_END
};
// Same pathfinding bug as above, where Ego is set to move to an impossible
// spot when sneaking. In GuardsTrumpet::changeState, we change the final
-// location where Ego is moved from 111, 111 to 114, 114. Fixes bug #3604939.
-const byte qfg1vgaSignatureMoveToCastleGate[] = {
- 7,
- 0x51, 0x1f, // class MoveTo
- 0x36, // push
- 0x39, 0x6f, // pushi 6f (111 - x)
- 0x3c, // dup (111 - y)
- 0x7c, // pushSelf
- 0
-};
-
-const uint16 qfg1vgaPatchMoveToCastleGate[] = {
- PATCH_ADDTOOFFSET | +3,
- 0x39, 0x72, // pushi 72 (114 - x)
+// location where Ego is moved from 111, 111 to 114, 114.
+// Fixes bug: #6248
+static const uint16 qfg1vgaSignatureMoveToCastleGate[] = {
+ SIG_MAGICDWORD,
+ 0x51, 0x1f, // class MoveTo
+ 0x36, // push
+ 0x39, 0x6f, // pushi 6f (111 - x)
+ 0x3c, // dup (111 - y)
+ 0x7c, // pushSelf
+ SIG_END
+};
+
+static const uint16 qfg1vgaPatchMoveToCastleGate[] = {
+ PATCH_ADDTOOFFSET(+3),
+ 0x39, 0x72, // pushi 72 (114 - x)
PATCH_END
};
// Typo in the original Sierra scripts
// Looking at a cheetaur resulted in a text about a Saurus Rex
// The code treats both monster types the same.
+// Applies to at least: English floppy
// Responsible method: smallMonster::doVerb
-// Fixes bug #3604943.
-const byte qfg1vgaSignatureCheetaurDescription[] = {
- 16,
- 0x34, 0xb8, 0x01, // ldi 01b8
- 0x1a, // eq?
- 0x31, 0x16, // bnt 16
- 0x38, 0x27, 0x01, // pushi 0127
- 0x39, 0x06, // pushi 06
- 0x39, 0x03, // pushi 03
- 0x78, // push1
- 0x39, 0x12, // pushi 12 -> monster type Saurus Rex
- 0
-};
-
-const uint16 qfg1vgaPatchCheetaurDescription[] = {
- PATCH_ADDTOOFFSET | +14,
- 0x39, 0x11, // pushi 11 -> monster type cheetaur
+// Fixes bug #6249
+static const uint16 qfg1vgaSignatureCheetaurDescription[] = {
+ SIG_MAGICDWORD,
+ 0x34, SIG_UINT16(0x01b8), // ldi 01b8
+ 0x1a, // eq?
+ 0x31, 0x16, // bnt 16
+ 0x38, SIG_UINT16(0x0127), // pushi 0127
+ 0x39, 0x06, // pushi 06
+ 0x39, 0x03, // pushi 03
+ 0x78, // push1
+ 0x39, 0x12, // pushi 12 -> monster type Saurus Rex
+ SIG_END
+};
+
+static const uint16 qfg1vgaPatchCheetaurDescription[] = {
+ PATCH_ADDTOOFFSET(+14),
+ 0x39, 0x11, // pushi 11 -> monster type cheetaur
PATCH_END
};
@@ -1185,41 +2001,42 @@ 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 #3585793
-const byte qfg1vgaSignatureFunnyRoomFix[] = {
- 14,
- 0x65, 0x14, // aTop 14 (state)
- 0x36, // push
- 0x3c, // dup
- 0x35, 0x00, // ldi 00
- 0x1a, // eq?
- 0x30, 0x25, 0x00, // bnt 0025 [-> next state]
- 0x35, 0x01, // ldi 01
- 0xa3, 0x4e, // sal 4e
- 0
-};
-
-const uint16 qfg1vgaPatchFunnyRoomFix[] = {
- PATCH_ADDTOOFFSET | +3,
- 0x2e, 0x29, 0x00, // bt 0029 [-> next state] - saves 4 bytes
- 0x35, 0x01, // ldi 01
- 0xa3, 0x4e, // sal 4e
- 0xa3, 0x05, // sal 05 (sets local 5 to 1)
- 0xa3, 0x05, // and again to make absolutely sure (actually to waste 2 bytes)
+// Fixes bug #6181
+static const uint16 qfg1vgaSignatureFunnyRoomFix[] = {
+ 0x65, 0x14, // aTop 14 (state)
+ 0x36, // push
+ 0x3c, // dup
+ 0x35, 0x00, // ldi 00
+ 0x1a, // eq?
+ 0x30, SIG_UINT16(0x0025), // bnt 0025 [-> next state]
+ SIG_MAGICDWORD,
+ 0x35, 0x01, // ldi 01
+ 0xa3, 0x4e, // sal 4e
+ SIG_END
+};
+
+static const uint16 qfg1vgaPatchFunnyRoomFix[] = {
+ PATCH_ADDTOOFFSET(+3),
+ 0x2e, PATCH_UINT16(0x0029), // bt 0029 [-> next state] - saves 4 bytes
+ 0x35, 0x01, // ldi 01
+ 0xa3, 0x4e, // sal 4e
+ 0xa3, 0x05, // sal 05 (sets local 5 to 1)
+ 0xa3, 0x05, // and again to make absolutely sure (actually to waste 2 bytes)
PATCH_END
};
-// script, description, magic DWORD, adjust
-const SciScriptSignature qfg1vgaSignatures[] = {
- { 215, "fight event issue", 1, PATCH_MAGICDWORD(0x6d, 0x76, 0x51, 0x07), -1, qfg1vgaSignatureFightEvents, qfg1vgaPatchFightEvents },
- { 216, "weapon master event issue", 1, PATCH_MAGICDWORD(0x6d, 0x76, 0x51, 0x07), -1, qfg1vgaSignatureFightEvents, qfg1vgaPatchFightEvents },
- { 814, "window text temp space", 1, PATCH_MAGICDWORD(0x3f, 0xba, 0x87, 0x00), 0, qfg1vgaSignatureTempSpace, qfg1vgaPatchTempSpace },
- { 814, "dialog header offset", 3, PATCH_MAGICDWORD(0x5b, 0x04, 0x80, 0x36), 0, qfg1vgaSignatureDialogHeader, qfg1vgaPatchDialogHeader },
- { 331, "moving to crusher", 1, PATCH_MAGICDWORD(0x51, 0x1f, 0x36, 0x39), 0, qfg1vgaSignatureMoveToCrusher, qfg1vgaPatchMoveToCrusher },
- { 41, "moving to castle gate", 1, PATCH_MAGICDWORD(0x51, 0x1f, 0x36, 0x39), 0, qfg1vgaSignatureMoveToCastleGate, qfg1vgaPatchMoveToCastleGate },
- { 210, "cheetaur description fixed", 1, PATCH_MAGICDWORD(0x34, 0xb8, 0x01, 0x1a), 0, qfg1vgaSignatureCheetaurDescription, qfg1vgaPatchCheetaurDescription },
- { 96, "funny room script bug fixed", 1, PATCH_MAGICDWORD(0x35, 0x01, 0xa3, 0x4e), -10, qfg1vgaSignatureFunnyRoomFix, qfg1vgaPatchFunnyRoomFix },
+// script, description, signature patch
+static const SciScriptPatcherEntry qfg1vgaSignatures[] = {
+ { true, 215, "fight event issue", 1, qfg1vgaSignatureFightEvents, qfg1vgaPatchFightEvents },
+ { true, 216, "weapon master event issue", 1, qfg1vgaSignatureFightEvents, qfg1vgaPatchFightEvents },
+ { 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
};
@@ -1235,58 +2052,56 @@ const SciScriptSignature qfg1vgaSignatures[] = {
// deleted entries. We don't allow the user to change the directory, thus the
// contents of the file list are constant, so we can avoid the constant file
// and text entry refreshes whenever a button is pressed, and prevent possible
-// crashes because of these constant quick object reallocations. Fixes bug
-// #3037996.
-const byte qfg2SignatureImportDialog[] = {
- 16,
- 0x63, 0x20, // pToa text
- 0x30, 0x0b, 0x00, // bnt [next state]
- 0x7a, // push2
- 0x39, 0x03, // pushi 03
- 0x36, // push
- 0x43, 0x72, 0x04, // callk Memory 4
- 0x35, 0x00, // ldi 00
- 0x65, 0x20, // aTop text
- 0
-};
-
-const uint16 qfg2PatchImportDialog[] = {
- PATCH_ADDTOOFFSET | +5,
- 0x48, // ret
+// crashes because of these constant quick object reallocations.
+// Fixes bug: #5096
+static const uint16 qfg2SignatureImportDialog[] = {
+ 0x63, SIG_MAGICDWORD, 0x20, // pToa text
+ 0x30, SIG_UINT16(0x000b), // bnt [next state]
+ 0x7a, // push2
+ 0x39, 0x03, // pushi 03
+ 0x36, // push
+ 0x43, 0x72, 0x04, // callk Memory 4
+ 0x35, 0x00, // ldi 00
+ 0x65, 0x20, // aTop text
+ SIG_END
+};
+
+static const uint16 qfg2PatchImportDialog[] = {
+ PATCH_ADDTOOFFSET(+5),
+ 0x48, // ret
PATCH_END
};
-// script, description, magic DWORD, adjust
-const SciScriptSignature qfg2Signatures[] = {
- { 944, "import dialog continuous calls", 1, PATCH_MAGICDWORD(0x20, 0x30, 0x0b, 0x00), -1, qfg2SignatureImportDialog, qfg2PatchImportDialog },
+// script, description, signature patch
+static const SciScriptPatcherEntry qfg2Signatures[] = {
+ { true, 944, "import dialog continuous calls", 1, qfg2SignatureImportDialog, qfg2PatchImportDialog },
SCI_SIGNATUREENTRY_TERMINATOR
};
// ===========================================================================
// Patch for the import screen in QFG3, same as the one for QFG2 above
-const byte qfg3SignatureImportDialog[] = {
- 15,
- 0x63, 0x2a, // pToa text
- 0x31, 0x0b, // bnt [next state]
- 0x7a, // push2
- 0x39, 0x03, // pushi 03
- 0x36, // push
- 0x43, 0x72, 0x04, // callk Memory 4
- 0x35, 0x00, // ldi 00
- 0x65, 0x2a, // aTop text
- 0
-};
-
-const uint16 qfg3PatchImportDialog[] = {
- PATCH_ADDTOOFFSET | +4,
- 0x48, // ret
+static const uint16 qfg3SignatureImportDialog[] = {
+ 0x63, SIG_MAGICDWORD, 0x2a, // pToa text
+ 0x31, 0x0b, // bnt [next state]
+ 0x7a, // push2
+ 0x39, 0x03, // pushi 03
+ 0x36, // push
+ 0x43, 0x72, 0x04, // callk Memory 4
+ 0x35, 0x00, // ldi 00
+ 0x65, 0x2a, // aTop text
+ SIG_END
+};
+
+static const uint16 qfg3PatchImportDialog[] = {
+ PATCH_ADDTOOFFSET(+4),
+ 0x48, // ret
PATCH_END
};
// ===========================================================================
-// Patch for the Woo dialog option in Uhura's conversation. Bug #3040722
+// Patch for the Woo dialog option in Uhura's conversation.
// Problem: The Woo dialog option (0xffb5) is negative, and therefore
// treated as an option opening a submenu. This leads to uhuraTell::doChild
// being called, which calls hero::solvePuzzle and then proceeds with
@@ -1298,38 +2113,40 @@ const uint16 qfg3PatchImportDialog[] = {
// hero::solvePuzzle (0xfffc) which does a ret afterwards without going to
// Teller::doChild. We jump to this call of hero::solvePuzzle to get that same
// behaviour.
-
-const byte qfg3SignatureWooDialog[] = {
- 30,
- 0x67, 0x12, // pTos 12 (query)
- 0x35, 0xb6, // ldi b6
- 0x1a, // eq?
- 0x2f, 0x05, // bt 05
- 0x67, 0x12, // pTos 12 (query)
- 0x35, 0x9b, // ldi 9b
- 0x1a, // eq?
- 0x31, 0x0c, // bnt 0c
- 0x38, 0x97, 0x02, // pushi 0297
- 0x7a, // push2
- 0x38, 0x0c, 0x01, // pushi 010c
- 0x7a, // push2
- 0x81, 0x00, // lag 00
- 0x4a, 0x08, // send 08
- 0x67, 0x12, // pTos 12 (query)
- 0x35, 0xb5, // ldi b5
- 0
-};
-
-const uint16 qfg3PatchWooDialog[] = {
- PATCH_ADDTOOFFSET | +0x29,
- 0x33, 0x11, // jmp to 0x6a2, the call to hero::solvePuzzle for 0xFFFC
+// Applies to at least: English, German, Italian, French, Spanish Floppy
+// Responsible method: unknown
+// Fixes bug: #5172
+static const uint16 qfg3SignatureWooDialog[] = {
+ SIG_MAGICDWORD,
+ 0x67, 0x12, // pTos 12 (query)
+ 0x35, 0xb6, // ldi b6
+ 0x1a, // eq?
+ 0x2f, 0x05, // bt 05
+ 0x67, 0x12, // pTos 12 (query)
+ 0x35, 0x9b, // ldi 9b
+ 0x1a, // eq?
+ 0x31, 0x0c, // 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 qfg3PatchWooDialog[] = {
+ PATCH_ADDTOOFFSET(+0x29),
+ 0x33, 0x11, // jmp to 0x6a2, the call to hero::solvePuzzle for 0xFFFC
PATCH_END
};
-// script, description, magic DWORD, adjust
-const SciScriptSignature qfg3Signatures[] = {
- { 944, "import dialog continuous calls", 1, PATCH_MAGICDWORD(0x2a, 0x31, 0x0b, 0x7a), -1, qfg3SignatureImportDialog, qfg3PatchImportDialog },
- { 440, "dialog crash when asking about Woo", 1, PATCH_MAGICDWORD(0x67, 0x12, 0x35, 0xb5), -26, qfg3SignatureWooDialog, qfg3PatchWooDialog },
+// 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 },
SCI_SIGNATUREENTRY_TERMINATOR
};
@@ -1339,31 +2156,53 @@ const SciScriptSignature qfg3Signatures[] = {
// adds it to nest::x. The problem is that the script also checks if x exceeds
// we never reach that of course, so the pterodactyl-flight will go endlessly
// we could either calculate property count differently somehow fixing this
-// but I think just patching it out is cleaner (bug #3037938)
-const byte sq4FloppySignatureEndlessFlight[] = {
- 8,
- 0x39, 0x04, // pushi 04 (selector x)
- 0x78, // push1
- 0x67, 0x08, // pTos 08 (property x)
- 0x63, 0x44, // pToa 44 (invalid property)
- 0x02, // add
- 0
-};
-
-// Similar to the above, for the German version (bug #3110215)
-const byte sq4FloppySignatureEndlessFlightGerman[] = {
- 8,
- 0x39, 0x04, // pushi 04 (selector x)
- 0x78, // push1
- 0x67, 0x08, // pTos 08 (property x)
- 0x63, 0x4c, // pToa 4c (invalid property)
- 0x02, // add
- 0
+// but I think just patching it out is cleaner.
+// Fixes bug: #5093
+static const uint16 sq4FloppySignatureEndlessFlight[] = {
+ 0x39, 0x04, // pushi 04 (selector x)
+ SIG_MAGICDWORD,
+ 0x78, // push1
+ 0x67, 0x08, // pTos 08 (property x)
+ 0x63, SIG_ADDTOOFFSET(+1), // pToa (invalid property) - 44h for English floppy, 4ch for German floppy
+ 0x02, // add
+ SIG_END
+};
+
+static const uint16 sq4FloppyPatchEndlessFlight[] = {
+ PATCH_ADDTOOFFSET(+5),
+ 0x35, 0x03, // ldi 03 (which would be the content of the property)
+ PATCH_END
};
-const uint16 sq4FloppyPatchEndlessFlight[] = {
- PATCH_ADDTOOFFSET | +5,
- 0x35, 0x03, // ldi 03 (which would be the content of the property)
+// Floppy-only: When the player tries to throw something at the sequel police in Space Quest X (zero g zone),
+// the game will first show a textbox and then cause a signature mismatch in ScummVM/
+// crash the whole game in Sierra SCI/display garbage (the latter when the Sierra "patch" got applied).
+//
+// All of this is caused by a typo in the script. Right after the code for showing the textbox,
+// there is more similar code for showing another textbox, but without a pointer to the text.
+// This has to be a typo, because there is no unused text to be found within that script.
+//
+// Sierra's "patch" didn't include a proper fix (as in a modified script). Instead they shipped a dummy
+// text resource, which somewhat "solved" the issue in Sierra SCI, but it still showed another textbox
+// with garbage in it. Funnily Sierra must have known that, because that new text resource contains:
+// "Hi! This is a kludge!"
+//
+// We properly fix it by removing the faulty code.
+// Applies to at least: English Floppy
+// Responsible method: sp1::doVerb
+// Fixes bug: found by SCI developer
+static const uint16 sq4FloppySignatureThrowStuffAtSequelPoliceBug[] = {
+ 0x47, 0xff, 0x00, 0x02, // call export 255_0, 2
+ 0x3a, // toss
+ SIG_MAGICDWORD,
+ 0x36, // push
+ 0x47, 0xff, 0x00, 0x02, // call export 255_0, 2
+ SIG_END
+};
+
+static const uint16 sq4FloppyPatchThrowStuffAtSequelPoliceBug[] = {
+ PATCH_ADDTOOFFSET(+5),
+ 0x48, // ret
PATCH_END
};
@@ -1373,40 +2212,40 @@ const uint16 sq4FloppyPatchEndlessFlight[] = {
// Patch 1: iconTextSwitch::show, called when the text options button is shown.
// This is patched to add the "Both" text resource (i.e. we end up with
// "Speech", "Text" and "Both")
-const byte sq4CdSignatureTextOptionsButton[] = {
- 11,
- 0x35, 0x01, // ldi 0x01
- 0xa1, 0x53, // sag 0x53
- 0x39, 0x03, // pushi 0x03
- 0x78, // push1
- 0x39, 0x09, // pushi 0x09
- 0x54, 0x06, // self 0x06
- 0
-};
-
-const uint16 sq4CdPatchTextOptionsButton[] = {
- PATCH_ADDTOOFFSET | +7,
- 0x39, 0x0b, // pushi 0x0b
+static const uint16 sq4CdSignatureTextOptionsButton[] = {
+ SIG_MAGICDWORD,
+ 0x35, 0x01, // ldi 0x01
+ 0xa1, 0x53, // sag 0x53
+ 0x39, 0x03, // pushi 0x03
+ 0x78, // push1
+ 0x39, 0x09, // pushi 0x09
+ 0x54, 0x06, // self 0x06
+ SIG_END
+};
+
+static const uint16 sq4CdPatchTextOptionsButton[] = {
+ PATCH_ADDTOOFFSET(+7),
+ 0x39, 0x0b, // pushi 0x0b
PATCH_END
};
// Patch 2: Adjust a check in babbleIcon::init, which handles the babble icon
// (e.g. the two guys from Andromeda) shown when dying/quitting.
-// Fixes bug #3538418.
-const byte sq4CdSignatureBabbleIcon[] = {
- 7,
- 0x89, 0x5a, // lsg 5a
- 0x35, 0x02, // ldi 02
- 0x1a, // eq?
- 0x31, 0x26, // bnt 26 [02a7]
- 0
-};
-
-const uint16 sq4CdPatchBabbleIcon[] = {
- 0x89, 0x5a, // lsg 5a
- 0x35, 0x01, // ldi 01
- 0x1a, // eq?
- 0x2f, 0x26, // bt 26 [02a7]
+// Fixes bug: #6068
+static const uint16 sq4CdSignatureBabbleIcon[] = {
+ SIG_MAGICDWORD,
+ 0x89, 0x5a, // lsg 5a
+ 0x35, 0x02, // ldi 02
+ 0x1a, // eq?
+ 0x31, 0x26, // bnt 26 [02a7]
+ SIG_END
+};
+
+static const uint16 sq4CdPatchBabbleIcon[] = {
+ 0x89, 0x5a, // lsg 5a
+ 0x35, 0x01, // ldi 01
+ 0x1a, // eq?
+ 0x2f, 0x26, // bt 26 [02a7]
PATCH_END
};
@@ -1414,56 +2253,56 @@ const uint16 sq4CdPatchBabbleIcon[] = {
// when the text options button is clicked: "Speech", "Text" and "Both".
// Refer to the patch above for additional details.
// iconTextSwitch::doit (called when the text options button is clicked)
-const byte sq4CdSignatureTextOptions[] = {
- 32,
- 0x89, 0x5a, // lsg 0x5a (load global 90 to stack)
- 0x3c, // dup
- 0x35, 0x01, // ldi 0x01
- 0x1a, // eq? (global 90 == 1)
- 0x31, 0x06, // bnt 0x06 (0x0691)
- 0x35, 0x02, // ldi 0x02
- 0xa1, 0x5a, // sag 0x5a (save acc to global 90)
- 0x33, 0x0a, // jmp 0x0a (0x69b)
- 0x3c, // dup
- 0x35, 0x02, // ldi 0x02
- 0x1a, // eq? (global 90 == 2)
- 0x31, 0x04, // bnt 0x04 (0x069b)
- 0x35, 0x01, // ldi 0x01
- 0xa1, 0x5a, // sag 0x5a (save acc to global 90)
- 0x3a, // toss
- 0x38, 0xd9, 0x00, // pushi 0x00d9
- 0x76, // push0
- 0x54, 0x04, // self 0x04
- 0x48, // ret
- 0
-};
-
-const uint16 sq4CdPatchTextOptions[] = {
- 0x89, 0x5a, // lsg 0x5a (load global 90 to stack)
- 0x3c, // dup
- 0x35, 0x03, // ldi 0x03 (acc = 3)
- 0x1a, // eq? (global 90 == 3)
- 0x2f, 0x07, // bt 0x07
- 0x89, 0x5a, // lsg 0x5a (load global 90 to stack again)
- 0x35, 0x01, // ldi 0x01 (acc = 1)
- 0x02, // add: acc = global 90 (on stack) + 1 (previous acc value)
- 0x33, 0x02, // jmp 0x02
- 0x35, 0x01, // ldi 0x01 (reset acc to 1)
- 0xa1, 0x5a, // sag 0x5a (save acc to global 90)
- 0x33, 0x03, // jmp 0x03 (jump over the wasted bytes below)
- 0x34, 0x00, 0x00, // ldi 0x0000 (waste 3 bytes)
- 0x3a, // toss
+static const uint16 sq4CdSignatureTextOptions[] = {
+ SIG_MAGICDWORD,
+ 0x89, 0x5a, // lsg 0x5a (load global 90 to stack)
+ 0x3c, // dup
+ 0x35, 0x01, // ldi 0x01
+ 0x1a, // eq? (global 90 == 1)
+ 0x31, 0x06, // bnt 0x06 (0x0691)
+ 0x35, 0x02, // ldi 0x02
+ 0xa1, 0x5a, // sag 0x5a (save acc to global 90)
+ 0x33, 0x0a, // jmp 0x0a (0x69b)
+ 0x3c, // dup
+ 0x35, 0x02, // ldi 0x02
+ 0x1a, // eq? (global 90 == 2)
+ 0x31, 0x04, // bnt 0x04 (0x069b)
+ 0x35, 0x01, // ldi 0x01
+ 0xa1, 0x5a, // sag 0x5a (save acc to global 90)
+ 0x3a, // toss
+ 0x38, SIG_SELECTOR16(show), // pushi 0x00d9
+ 0x76, // push0
+ 0x54, 0x04, // self 0x04
+ 0x48, // ret
+ SIG_END
+};
+
+static const uint16 sq4CdPatchTextOptions[] = {
+ 0x89, 0x5a, // lsg 0x5a (load global 90 to stack)
+ 0x3c, // dup
+ 0x35, 0x03, // ldi 0x03 (acc = 3)
+ 0x1a, // eq? (global 90 == 3)
+ 0x2f, 0x07, // bt 0x07
+ 0x89, 0x5a, // lsg 0x5a (load global 90 to stack again)
+ 0x35, 0x01, // ldi 0x01 (acc = 1)
+ 0x02, // add: acc = global 90 (on stack) + 1 (previous acc value)
+ 0x33, 0x02, // jmp 0x02
+ 0x35, 0x01, // ldi 0x01 (reset acc to 1)
+ 0xa1, 0x5a, // sag 0x5a (save acc to global 90)
+ 0x33, 0x03, // jmp 0x03 (jump over the wasted bytes below)
+ 0x34, PATCH_UINT16(0x0000), // ldi 0x0000 (waste 3 bytes)
+ 0x3a, // toss
// (the rest of the code is the same)
PATCH_END
};
-// script, description, magic DWORD, adjust
-const SciScriptSignature sq4Signatures[] = {
- { 298, "Floppy: endless flight", 1, PATCH_MAGICDWORD(0x67, 0x08, 0x63, 0x44), -3, sq4FloppySignatureEndlessFlight, sq4FloppyPatchEndlessFlight },
- { 298, "Floppy (German): endless flight", 1, PATCH_MAGICDWORD(0x67, 0x08, 0x63, 0x4c), -3, sq4FloppySignatureEndlessFlightGerman, sq4FloppyPatchEndlessFlight },
- { 818, "CD: Speech and subtitles option", 1, PATCH_MAGICDWORD(0x89, 0x5a, 0x3c, 0x35), 0, sq4CdSignatureTextOptions, sq4CdPatchTextOptions },
- { 0, "CD: Babble icon speech and subtitles fix", 1, PATCH_MAGICDWORD(0x89, 0x5a, 0x35, 0x02), 0, sq4CdSignatureBabbleIcon, sq4CdPatchBabbleIcon },
- { 818, "CD: Speech and subtitles option button", 1, PATCH_MAGICDWORD(0x35, 0x01, 0xa1, 0x53), 0, sq4CdSignatureTextOptionsButton, sq4CdPatchTextOptionsButton },
+// script, description, signature patch
+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, 0, "CD: Babble icon speech and subtitles fix", 1, sq4CdSignatureBabbleIcon, sq4CdPatchBabbleIcon },
+ { true, 818, "CD: Speech and subtitles option button", 1, sq4CdSignatureTextOptionsButton, sq4CdPatchTextOptionsButton },
SCI_SIGNATUREENTRY_TERMINATOR
};
@@ -1478,75 +2317,154 @@ const SciScriptSignature sq4Signatures[] = {
// The same issue happens in Sierra SCI.
// We simply set the correct starting cel number to fix the bug.
// Responsible method: robotIntoShip::changeState(9)
-const byte sq1vgaSignatureUlenceFlatsTimepodGfxGlitch[] = {
- 8,
- 0x39, 0x07, // pushi 07 (ship::cel)
- 0x78, // push1
- 0x39, 0x0a, // pushi 0x0a (set ship::cel to 10)
- 0x38, 0xa0, 0x00, // pushi 0x00a0 (ship::setLoop)
- 0
-};
-
-const uint16 sq1vgaPatchUlenceFlatsTimepodGfxGlitch[] = {
- PATCH_ADDTOOFFSET | +3,
- 0x39, 0x09, // pushi 0x09 (set ship::cel to 9)
+static const uint16 sq1vgaSignatureUlenceFlatsTimepodGfxGlitch[] = {
+ 0x39,
+ SIG_MAGICDWORD, SIG_SELECTOR8(cel), // pushi "cel"
+ 0x78, // push1
+ 0x39, 0x0a, // pushi 0x0a (set ship::cel to 10)
+ 0x38, SIG_UINT16(0x00a0), // pushi 0x00a0 (ship::setLoop)
+ SIG_END
+};
+
+static const uint16 sq1vgaPatchUlenceFlatsTimepodGfxGlitch[] = {
+ PATCH_ADDTOOFFSET(+3),
+ 0x39, 0x09, // pushi 0x09 (set ship::cel to 9)
PATCH_END
};
-const byte sq1vgaSignatureEgoShowsCard[] = {
- 25,
- 0x38, 0x46, 0x02, // push 0x246 (set up send frame to set timesShownID)
- 0x78, // push1
- 0x38, 0x46, 0x02, // push 0x246 (set up send frame to get timesShownID)
- 0x76, // push0
- 0x51, 0x7c, // class DeltaurRegion
- 0x4a, 0x04, // send 0x04 (get timesShownID)
- 0x36, // push
- 0x35, 0x01, // ldi 1
- 0x02, // add
- 0x36, // push
- 0x51, 0x7c, // class DeltaurRegion
- 0x4a, 0x06, // send 0x06 (set timesShownID)
- 0x36, // push (wrong, acc clobbered by class, above)
- 0x35, 0x03, // ldi 0x03
- 0x22, // lt?
- 0
+static const uint16 sq1vgaSignatureEgoShowsCard[] = {
+ SIG_MAGICDWORD,
+ 0x38, SIG_SELECTOR16(timesShownID), // push "timesShownID"
+ 0x78, // push1
+ 0x38, SIG_SELECTOR16(timesShownID), // push "timesShownID"
+ 0x76, // push0
+ 0x51, 0x7c, // class DeltaurRegion
+ 0x4a, 0x04, // send 0x04 (get timesShownID)
+ 0x36, // push
+ 0x35, 0x01, // ldi 1
+ 0x02, // add
+ 0x36, // push
+ 0x51, 0x7c, // class DeltaurRegion
+ 0x4a, 0x06, // send 0x06 (set timesShownID)
+ 0x36, // push (wrong, acc clobbered by class, above)
+ 0x35, 0x03, // ldi 0x03
+ 0x22, // lt?
+ SIG_END
};
// Note that this script patch is merely a reordering of the
// instructions in the original script.
-const uint16 sq1vgaPatchEgoShowsCard[] = {
- 0x38, 0x46, 0x02, // push 0x246 (set up send frame to get timesShownID)
- 0x76, // push0
- 0x51, 0x7c, // class DeltaurRegion
- 0x4a, 0x04, // send 0x04 (get timesShownID)
- 0x36, // push
- 0x35, 0x01, // ldi 1
- 0x02, // add
- 0x36, // push (this push corresponds to the wrong one above)
- 0x38, 0x46, 0x02, // push 0x246 (set up send frame to set timesShownID)
- 0x78, // push1
- 0x36, // push
- 0x51, 0x7c, // class DeltaurRegion
- 0x4a, 0x06, // send 0x06 (set timesShownID)
- 0x35, 0x03, // ldi 0x03
- 0x22, // lt?
+static const uint16 sq1vgaPatchEgoShowsCard[] = {
+ 0x38, PATCH_SELECTOR16(timesShownID), // push "timesShownID"
+ 0x76, // push0
+ 0x51, 0x7c, // class DeltaurRegion
+ 0x4a, 0x04, // send 0x04 (get timesShownID)
+ 0x36, // push
+ 0x35, 0x01, // ldi 1
+ 0x02, // add
+ 0x36, // push (this push corresponds to the wrong one above)
+ 0x38, PATCH_SELECTOR16(timesShownID), // push "timesShownID"
+ 0x78, // push1
+ 0x36, // push
+ 0x51, 0x7c, // class DeltaurRegion
+ 0x4a, 0x06, // send 0x06 (set timesShownID)
+ 0x35, 0x03, // ldi 0x03
+ 0x22, // lt?
PATCH_END
};
-// script, description, magic DWORD, adjust
-const SciScriptSignature sq1vgaSignatures[] = {
- { 45, "Ulence Flats: timepod graphic glitch", 1, PATCH_MAGICDWORD( 0x07, 0x78, 0x39, 0x0a ), -1, sq1vgaSignatureUlenceFlatsTimepodGfxGlitch, sq1vgaPatchUlenceFlatsTimepodGfxGlitch },
- { 58, "Sarien armory droid zapping ego first time", 1, PATCH_MAGICDWORD( 0x72, 0x88, 0x15, 0x36 ), -70, sq1vgaSignatureEgoShowsCard, sq1vgaPatchEgoShowsCard },
+// script, description, signature patch
+static const SciScriptPatcherEntry sq1vgaSignatures[] = {
+ { true, 45, "Ulence Flats: timepod graphic glitch", 1, sq1vgaSignatureUlenceFlatsTimepodGfxGlitch, sq1vgaPatchUlenceFlatsTimepodGfxGlitch },
+ { true, 58, "Sarien armory droid zapping ego first time", 1, sq1vgaSignatureEgoShowsCard, sq1vgaPatchEgoShowsCard },
+ SCI_SIGNATUREENTRY_TERMINATOR
+};
+
+// ===========================================================================
+// The toolbox in sq5 is buggy. When you click on the upper part of the "put
+// in inventory"-button (some items only - for example the hole puncher - at the
+// upper left), points will get awarded correctly and the item will get put into
+// the player's inventory, but you will then get a "not here" message and the
+// item will also remain to be the current mouse cursor.
+// The bug report also says that items may get lost. I wasn't able to reproduce
+// that part.
+// This is caused by the mouse-click event getting reprocessed (which wouldn't
+// be a problem by itself) and during this reprocessing coordinates are not
+// processed the same as during the first click (script 226 includes a local
+// subroutine, which checks coordinates in a hardcoded way w/o port-adjustment).
+// Because of this, the hotspot for the button is lower than it should be, which
+// then results in the game thinking that the user didn't click on the button
+// and also results in the previously mentioned message.
+// This happened in Sierra SCI as well (of course).
+// We fix it by combining state 0 + 1 of takeTool::changeState and so stopping
+// the event to get reprocessed. This was the only way possible, because everything
+// else is done in SCI system scripts and I don't want to touch those.
+// Applies to at least: English/German/French PC floppy
+// Responsible method: takeTool::changeState
+// Fixes bug: #6457
+static const uint16 sq5SignatureToolboxFix[] = {
+ 0x31, 0x13, // bnt [check for state 1]
+ SIG_MAGICDWORD,
+ 0x38, SIG_UINT16(0x00aa), // pushi 00aa
+ 0x39, 0x05, // pushi 05
+ 0x39, 0x16, // pushi 16
+ 0x76, // push0
+ 0x39, 0x03, // pushi 03
+ 0x76, // push0
+ 0x7c, // pushSelf
+ 0x81, 0x5b, // lag 5b
+ 0x4a, 0x0e, // send 0e
+ 0x32, SIG_UINT16(0x0088), // jmp [end-of-method]
+ 0x3c, // dup
+ 0x35, 0x01, // ldi 01
+ 0x1a, // eq?
+ 0x31, 0x28, // bnt [check for state 2]
+ SIG_END
+};
+
+static const uint16 sq5PatchToolboxFix[] = {
+ 0x31, 0x41, // bnt [check for state 2]
+ PATCH_ADDTOOFFSET(+16), // skip to jmp offset
+ 0x35, 0x01, // ldi 01
+ 0x65, 0x14, // aTop [state]
+ 0x36, 0x00, 0x00, // ldi 0000 (waste 3 bytes)
+ 0x35, 0x00, // ldi 00 (waste 2 bytes)
+ PATCH_END
+};
+
+// script, description, signature patch
+static const SciScriptPatcherEntry sq5Signatures[] = {
+ { true, 226, "toolbox fix", 1, sq5SignatureToolboxFix, sq5PatchToolboxFix },
+ SCI_SIGNATUREENTRY_TERMINATOR
+};
+
+// =================================================================================
- SCI_SIGNATUREENTRY_TERMINATOR};
+ScriptPatcher::ScriptPatcher() {
+ int selectorCount = ARRAYSIZE(selectorNameTable);
+ int selectorNr;
+
+ // Allocate table for selector-IDs and initialize that table as well
+ _selectorIdTable = new Selector[ selectorCount ];
+ for (selectorNr = 0; selectorNr < selectorCount; selectorNr++)
+ _selectorIdTable[selectorNr] = -1;
+
+ _runtimeTable = NULL;
+}
+
+ScriptPatcher::~ScriptPatcher() {
+ delete[] _runtimeTable;
+ delete[] _selectorIdTable;
+}
// will actually patch previously found signature area
-void Script::applyPatch(const uint16 *patch, byte *scriptData, const uint32 scriptSize, int32 signatureOffset) {
+void ScriptPatcher::applyPatch(const SciScriptPatcherEntry *patchEntry, byte *scriptData, const uint32 scriptSize, int32 signatureOffset, const bool isMacSci11) {
+ const uint16 *patchData = patchEntry->patchData;
byte orgData[PATCH_VALUELIMIT];
int32 offset = signatureOffset;
- uint16 patchWord = *patch;
+ uint16 patchWord = *patchEntry->patchData;
+ uint16 patchSelector = 0;
// Copy over original bytes from script
uint32 orgDataSize = scriptSize - offset;
@@ -1555,74 +2473,179 @@ void Script::applyPatch(const uint16 *patch, byte *scriptData, const uint32 scri
memcpy(&orgData, &scriptData[offset], orgDataSize);
while (patchWord != PATCH_END) {
+ uint16 patchCommand = patchWord & PATCH_COMMANDMASK;
uint16 patchValue = patchWord & PATCH_VALUEMASK;
- switch (patchWord & PATCH_COMMANDMASK) {
- case PATCH_ADDTOOFFSET:
+ switch (patchCommand) {
+ case PATCH_CODE_ADDTOOFFSET: {
// add value to offset
- offset += patchValue & ~PATCH_ADDTOOFFSET;
+ offset += patchValue;
break;
- case PATCH_GETORIGINALBYTE:
+ }
+ case PATCH_CODE_GETORIGINALBYTE: {
// get original byte from script
if (patchValue >= orgDataSize)
- error("patching: can not get requested original byte from script");
+ error("Script-Patcher: can not get requested original byte from script");
scriptData[offset] = orgData[patchValue];
offset++;
break;
- case PATCH_ADJUSTWORD: {
- // Adjust word right before current position
- byte *adjustPtr = &scriptData[offset - 2];
- uint16 adjustWord = READ_LE_UINT16(adjustPtr);
- adjustWord += patchValue;
- WRITE_LE_UINT16(adjustPtr, adjustWord);
+ }
+ case PATCH_CODE_GETORIGINALBYTEADJUST: {
+ // get original byte from script and adjust it
+ if (patchValue >= orgDataSize)
+ error("Script-Patcher: can not get requested original byte from script");
+ byte orgByte = orgData[patchValue];
+ int16 adjustValue;
+ patchData++; adjustValue = (int16)(*patchData);
+ scriptData[offset] = orgByte + adjustValue;
+ offset++;
+ break;
+ }
+ case PATCH_CODE_UINT16:
+ case PATCH_CODE_SELECTOR16: {
+ byte byte1;
+ byte byte2;
+
+ switch (patchCommand) {
+ case PATCH_CODE_UINT16: {
+ byte1 = patchValue & PATCH_BYTEMASK;
+ patchData++; patchWord = *patchData;
+ if (patchWord & PATCH_COMMANDMASK)
+ error("Script-Patcher: Patch inconsistent");
+ byte2 = patchWord & PATCH_BYTEMASK;
+ break;
+ }
+ case PATCH_CODE_SELECTOR16: {
+ patchSelector = _selectorIdTable[patchValue];
+ byte1 = patchSelector & 0xFF;
+ byte2 = patchSelector >> 8;
+ break;
+ }
+ default:
+ byte1 = 0; byte2 = 0;
+ }
+ if (!isMacSci11) {
+ scriptData[offset++] = byte1;
+ scriptData[offset++] = byte2;
+ } else {
+ // SCI1.1+ on macintosh had uint16s in script in BE-order
+ scriptData[offset++] = byte2;
+ scriptData[offset++] = byte1;
+ }
break;
}
- case PATCH_ADJUSTWORD_NEG: {
- // Adjust word right before current position (negative way)
- byte *adjustPtr = &scriptData[offset - 2];
- uint16 adjustWord = READ_LE_UINT16(adjustPtr);
- adjustWord -= patchValue;
- WRITE_LE_UINT16(adjustPtr, adjustWord);
+ case PATCH_CODE_SELECTOR8: {
+ patchSelector = _selectorIdTable[patchValue];
+ if (patchSelector & 0xFF00)
+ error("Script-Patcher: 8 bit selector required, game uses 16 bit selector");
+ scriptData[offset] = patchSelector & 0xFF;
+ offset++;
break;
}
- default:
- scriptData[offset] = patchValue & 0xFF;
+ case PATCH_CODE_BYTE:
+ scriptData[offset] = patchValue & PATCH_BYTEMASK;
offset++;
}
- patch++;
- patchWord = *patch;
+ patchData++;
+ patchWord = *patchData;
}
}
// will return -1 if no match was found, otherwise an offset to the start of the signature match
-int32 Script::findSignature(const SciScriptSignature *signature, const byte *scriptData, const uint32 scriptSize) {
+int32 ScriptPatcher::findSignature(const SciScriptPatcherEntry *patchEntry, SciScriptPatcherRuntimeEntry *runtimeEntry, const byte *scriptData, const uint32 scriptSize, const bool isMacSci11) {
if (scriptSize < 4) // we need to find a DWORD, so less than 4 bytes is not okay
return -1;
- const uint32 magicDWord = signature->magicDWord; // is platform-specific BE/LE form, so that the later match will work
+ const uint32 magicDWord = runtimeEntry->magicDWord; // is platform-specific BE/LE form, so that the later match will work
const uint32 searchLimit = scriptSize - 3;
uint32 DWordOffset = 0;
// first search for the magic DWORD
while (DWordOffset < searchLimit) {
if (magicDWord == READ_UINT32(scriptData + DWordOffset)) {
// magic DWORD found, check if actual signature matches
- uint32 offset = DWordOffset + signature->magicOffset;
+ uint32 offset = DWordOffset + runtimeEntry->magicOffset;
uint32 byteOffset = offset;
- const byte *signatureData = signature->data;
- byte matchAdjust = 1;
- while (matchAdjust) {
- byte matchBytesCount = *signatureData++;
- if ((byteOffset + matchBytesCount) > scriptSize) // Out-Of-Bounds?
+ 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;
- if (memcmp(signatureData, &scriptData[byteOffset], matchBytesCount)) // Byte-Mismatch?
+ }
+ 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;
- // those bytes matched, adjust offsets accordingly
- signatureData += matchBytesCount;
- byteOffset += matchBytesCount;
- // get offset...
- matchAdjust = *signatureData++;
- byteOffset += matchAdjust;
+
+ signatureData++;
+ sigWord = *signatureData;
}
- if (!matchAdjust) // all matches worked?
+
+ if (sigWord == SIG_END) // signature fully matched?
return offset;
}
DWordOffset++;
@@ -1631,9 +2654,182 @@ int32 Script::findSignature(const SciScriptSignature *signature, const byte *scr
return -1;
}
-void Script::matchSignatureAndPatch(uint16 scriptNr, byte *scriptData, const uint32 scriptSize) {
- const SciScriptSignature *signatureTable = NULL;
- switch (g_sci->getGameId()) {
+// 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) {
+ const SciScriptPatcherEntry *curEntry = patchTable;
+ SciScriptPatcherRuntimeEntry *curRuntimeEntry;
+ Selector curSelector = -1;
+ int step;
+ int magicOffset;
+ byte magicDWord[4];
+ int magicDWordLeft = 0;
+ const uint16 *curData;
+ uint16 curWord;
+ uint16 curCommand;
+ uint32 curValue;
+ byte byte1;
+ byte byte2;
+ int patchEntryCount = 0;
+
+ // Count entries and allocate runtime data
+ while (curEntry->signatureData) {
+ patchEntryCount++; curEntry++;
+ }
+ _runtimeTable = new SciScriptPatcherRuntimeEntry[patchEntryCount];
+ memset(_runtimeTable, 0, sizeof(SciScriptPatcherRuntimeEntry) * patchEntryCount);
+
+ curEntry = patchTable;
+ curRuntimeEntry = _runtimeTable;
+ while (curEntry->signatureData) {
+ // process signature
+ memset(magicDWord, 0, sizeof(magicDWord));
+
+ curRuntimeEntry->active = curEntry->defaultActive;
+ curRuntimeEntry->magicDWord = 0;
+ curRuntimeEntry->magicOffset = 0;
+
+ for (step = 0; step < 2; step++) {
+ switch (step) {
+ case 0: curData = curEntry->signatureData; break;
+ case 1: curData = curEntry->patchData; break;
+ }
+
+ curWord = *curData;
+ magicOffset = 0;
+ while (curWord != SIG_END) {
+ curCommand = curWord & SIG_COMMANDMASK;
+ curValue = curWord & SIG_VALUEMASK;
+ switch (curCommand) {
+ case SIG_MAGICDWORD: {
+ if (step == 0) {
+ if ((curRuntimeEntry->magicDWord) || (magicDWordLeft))
+ error("Script-Patcher: Magic-DWORD specified multiple times in signature\nFaulty patch: '%s'", curEntry->description);
+ magicDWordLeft = 4;
+ curRuntimeEntry->magicOffset = magicOffset;
+ }
+ break;
+ }
+ case SIG_CODE_ADDTOOFFSET: {
+ magicOffset -= curValue;
+ if (magicDWordLeft)
+ error("Script-Patcher: Magic-DWORD contains AddToOffset command\nFaulty patch: '%s'", curEntry->description);
+ break;
+ }
+ case SIG_CODE_UINT16:
+ case SIG_CODE_SELECTOR16: {
+ // UINT16 or 1
+ switch (curCommand) {
+ case SIG_CODE_UINT16: {
+ curData++; curWord = *curData;
+ if (curWord & SIG_COMMANDMASK)
+ error("Script-Patcher: signature entry inconsistent\nFaulty patch: '%s'", curEntry->description);
+ if (!isMacSci11) {
+ byte1 = curValue;
+ byte2 = curWord & SIG_BYTEMASK;
+ } else {
+ byte1 = curWord & SIG_BYTEMASK;
+ byte2 = curValue;
+ }
+ break;
+ }
+ case SIG_CODE_SELECTOR16: {
+ curSelector = _selectorIdTable[curValue];
+ if (curSelector == -1) {
+ curSelector = g_sci->getKernel()->findSelector(selectorNameTable[curValue]);
+ _selectorIdTable[curValue] = curSelector;
+ }
+ if (!isMacSci11) {
+ byte1 = curSelector & 0x00FF;
+ byte2 = curSelector >> 8;
+ } else {
+ byte1 = curSelector >> 8;
+ byte2 = curSelector & 0x00FF;
+ }
+ break;
+ }
+ }
+ magicOffset -= 2;
+ if (magicDWordLeft) {
+ // Remember current word for Magic DWORD
+ magicDWord[4 - magicDWordLeft] = byte1;
+ magicDWordLeft--;
+ if (magicDWordLeft) {
+ magicDWord[4 - magicDWordLeft] = byte2;
+ magicDWordLeft--;
+ }
+ if (!magicDWordLeft) {
+ curRuntimeEntry->magicDWord = READ_LE_UINT32(magicDWord);
+ }
+ }
+ break;
+ }
+ case SIG_CODE_BYTE:
+ case SIG_CODE_SELECTOR8: {
+ if (curCommand == SIG_CODE_SELECTOR8) {
+ curSelector = _selectorIdTable[curValue];
+ if (curSelector == -1) {
+ curSelector = g_sci->getKernel()->findSelector(selectorNameTable[curValue]);
+ _selectorIdTable[curValue] = curSelector;
+ if (curSelector != -1) {
+ if (curSelector & 0xFF00)
+ error("Script-Patcher: 8 bit selector required, game uses 16 bit selector\nFaulty patch: '%s'", curEntry->description);
+ }
+ }
+ curValue = curSelector;
+ }
+ magicOffset--;
+ if (magicDWordLeft) {
+ // Remember current byte for Magic DWORD
+ magicDWord[4 - magicDWordLeft] = (byte)curValue;
+ magicDWordLeft--;
+ if (!magicDWordLeft) {
+ curRuntimeEntry->magicDWord = READ_LE_UINT32(magicDWord);
+ }
+ }
+ }
+ }
+ curData++;
+ curWord = *curData;
+ }
+ }
+ if (magicDWordLeft)
+ error("Script-Patcher: Magic-DWORD beyond End-Of-Signature\nFaulty patch: '%s'", curEntry->description);
+ if (!curRuntimeEntry->magicDWord)
+ error("Script-Patcher: Magic-DWORD not specified in signature\nFaulty patch: '%s'", curEntry->description);
+
+ curEntry++; curRuntimeEntry++;
+ }
+}
+
+// This method enables certain patches
+// It's used for patches, which are not meant to get applied all the time
+void ScriptPatcher::enablePatch(const SciScriptPatcherEntry *patchTable, const char *searchDescription) {
+ const SciScriptPatcherEntry *curEntry = patchTable;
+ SciScriptPatcherRuntimeEntry *runtimeEntry = _runtimeTable;
+ int searchDescriptionLen = strlen(searchDescription);
+ int matchCount = 0;
+
+ while (curEntry->signatureData) {
+ if (strncmp(curEntry->description, searchDescription, searchDescriptionLen) == 0) {
+ // match found, enable patch
+ runtimeEntry->active = true;
+ matchCount++;
+ }
+ curEntry++; runtimeEntry++;
+ }
+
+ if (!matchCount)
+ error("Script-Patcher: no patch found to enable");
+}
+
+void ScriptPatcher::processScript(uint16 scriptNr, byte *scriptData, const uint32 scriptSize) {
+ const SciScriptPatcherEntry *signatureTable = NULL;
+ const SciScriptPatcherEntry *curEntry = NULL;
+ SciScriptPatcherRuntimeEntry *curRuntimeEntry = NULL;
+ const Sci::SciGameId gameId = g_sci->getGameId();
+
+ switch (gameId) {
case GID_CAMELOT:
signatureTable = camelotSignatures;
break;
@@ -1653,11 +2849,7 @@ void Script::matchSignatureAndPatch(uint16 scriptNr, byte *scriptData, const uin
signatureTable = gk1Signatures;
break;
case GID_KQ5:
- // See the explanation in the kq5SignatureWinGMSignals comment
- if (g_sci->_features->useAltWinGMSound())
- signatureTable = kq5WinGMSignatures;
- else
- signatureTable = kq5Signatures;
+ signatureTable = kq5Signatures;
break;
case GID_KQ6:
signatureTable = kq6Signatures;
@@ -1671,6 +2863,9 @@ void Script::matchSignatureAndPatch(uint16 scriptNr, byte *scriptData, const uin
case GID_LSL2:
signatureTable = larry2Signatures;
break;
+ case GID_LSL5:
+ signatureTable = larry5Signatures;
+ break;
case GID_LSL6:
signatureTable = larry6Signatures;
break;
@@ -1695,26 +2890,67 @@ void Script::matchSignatureAndPatch(uint16 scriptNr, byte *scriptData, const uin
case GID_SQ4:
signatureTable = sq4Signatures;
break;
+ case GID_SQ5:
+ signatureTable = sq5Signatures;
+ break;
default:
break;
}
if (signatureTable) {
- while (signatureTable->data) {
- if (scriptNr == signatureTable->scriptNr) {
+ bool 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)
+ if (!g_sci->getKernel()->selectorNamesAvailable())
+ return;
+
+ // signature table needs to get initialized (Magic DWORD set, selector table set)
+ initSignature(signatureTable, isMacSci11);
+
+ // Do additional game-specific initialization
+ switch (gameId) {
+ case GID_KQ5:
+ if (g_sci->_features->useAltWinGMSound()) {
+ // See the explanation in the kq5SignatureWinGMSignals comment
+ enablePatch(signatureTable, "Win: GM Music signal checks");
+ }
+ break;
+ case GID_KQ6:
+ if (g_sci->isCD()) {
+ // Enables Dual mode patches (audio + subtitles at the same time) for King's Quest 6
+ enablePatch(signatureTable, "CD: audio + text support");
+ }
+ break;
+ case GID_LAURABOW2:
+ if (g_sci->isCD()) {
+ // Enables Dual mode patches (audio + subtitles at the same time) for Laura Bow 2
+ enablePatch(signatureTable, "CD: audio + text support");
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+ curEntry = signatureTable;
+ curRuntimeEntry = _runtimeTable;
+
+ while (curEntry->signatureData) {
+ if ((scriptNr == curEntry->scriptNr) && (curRuntimeEntry->active)) {
int32 foundOffset = 0;
- int16 applyCount = signatureTable->applyCount;
+ int16 applyCount = curEntry->applyCount;
do {
- foundOffset = findSignature(signatureTable, scriptData, scriptSize);
+ foundOffset = findSignature(curEntry, curRuntimeEntry, scriptData, scriptSize, isMacSci11);
if (foundOffset != -1) {
// found, so apply the patch
- debugC(kDebugLevelScripts, "matched and patched %s on script %d offset %d", signatureTable->description, scriptNr, foundOffset);
- applyPatch(signatureTable->patch, scriptData, scriptSize, foundOffset);
+ debugC(kDebugLevelScriptPatcher, "Script-Patcher: '%s' on script %d offset %d", curEntry->description, scriptNr, foundOffset);
+ applyPatch(curEntry, scriptData, scriptSize, foundOffset, isMacSci11);
}
applyCount--;
} while ((foundOffset != -1) && (applyCount));
}
- signatureTable++;
+ curEntry++; curRuntimeEntry++;
}
}
}
diff --git a/engines/sci/engine/script_patches.h b/engines/sci/engine/script_patches.h
new file mode 100644
index 0000000000..9e572f33fa
--- /dev/null
+++ b/engines/sci/engine/script_patches.h
@@ -0,0 +1,108 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef SCI_ENGINE_SCRIPT_PATCHES_H
+#define SCI_ENGINE_SCRIPT_PATCHES_H
+
+#include "sci/sci.h"
+
+namespace Sci {
+
+// Please do not use the #defines, that are called SIG_CODE_* / PATCH_CODE_* inside signature/patch-tables
+#define SIG_END 0xFFFF
+#define SIG_MISMATCH 0xFFFE
+#define SIG_COMMANDMASK 0xF000
+#define SIG_VALUEMASK 0x0FFF
+#define SIG_BYTEMASK 0x00FF
+#define SIG_MAGICDWORD 0xF000
+#define SIG_CODE_ADDTOOFFSET 0xE000
+#define SIG_ADDTOOFFSET(_offset_) SIG_CODE_ADDTOOFFSET | _offset_
+#define SIG_CODE_SELECTOR16 0x9000
+#define SIG_SELECTOR16(_selectorID_) SIG_CODE_SELECTOR16 | SELECTOR_##_selectorID_
+#define SIG_CODE_SELECTOR8 0x8000
+#define SIG_SELECTOR8(_selectorID_) SIG_CODE_SELECTOR8 | SELECTOR_##_selectorID_
+#define SIG_CODE_UINT16 0x1000
+#define SIG_UINT16(_value_) SIG_CODE_UINT16 | (_value_ & 0xFF), (_value_ >> 8)
+#define SIG_CODE_BYTE 0x0000
+
+#define PATCH_END SIG_END
+#define PATCH_COMMANDMASK SIG_COMMANDMASK
+#define PATCH_VALUEMASK SIG_VALUEMASK
+#define PATCH_BYTEMASK SIG_BYTEMASK
+#define PATCH_CODE_ADDTOOFFSET SIG_CODE_ADDTOOFFSET
+#define PATCH_ADDTOOFFSET(_offset_) SIG_CODE_ADDTOOFFSET | _offset_
+#define PATCH_CODE_GETORIGINALBYTE 0xD000
+#define PATCH_GETORIGINALBYTE(_offset_) PATCH_CODE_GETORIGINALBYTE | _offset_
+#define PATCH_CODE_GETORIGINALBYTEADJUST 0xC000
+#define PATCH_GETORIGINALBYTEADJUST(_offset_, _adjustValue_) PATCH_CODE_GETORIGINALBYTEADJUST | _offset_, (uint16)(_adjustValue_)
+#define PATCH_CODE_SELECTOR16 SIG_CODE_SELECTOR16
+#define PATCH_SELECTOR16(_selectorID_) SIG_CODE_SELECTOR16 | SELECTOR_##_selectorID_
+#define PATCH_CODE_SELECTOR8 SIG_CODE_SELECTOR8
+#define PATCH_SELECTOR8(_selectorID_) SIG_CODE_SELECTOR8 | SELECTOR_##_selectorID_
+#define PATCH_CODE_UINT16 SIG_CODE_UINT16
+#define PATCH_UINT16(_value_) SIG_CODE_UINT16 | (_value_ & 0xFF), (_value_ >> 8)
+#define PATCH_CODE_BYTE SIG_CODE_BYTE
+
+// defines maximum scratch area for getting original bytes from unpatched script data
+#define PATCH_VALUELIMIT 4096
+
+struct SciScriptPatcherEntry {
+ bool defaultActive;
+ uint16 scriptNr;
+ const char *description;
+ int16 applyCount;
+ const uint16 *signatureData;
+ 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 {
+ bool active;
+ uint32 magicDWord;
+ int magicOffset;
+};
+
+/**
+ * ScriptPatcher class, handles on-the-fly patching of script data
+ */
+class ScriptPatcher {
+public:
+ ScriptPatcher();
+ ~ScriptPatcher();
+
+ void processScript(uint16 scriptNr, byte *scriptData, const uint32 scriptSize);
+
+private:
+ void initSignature(const SciScriptPatcherEntry *patchTable, bool isMacSci11);
+ 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);
+
+ Selector *_selectorIdTable;
+ SciScriptPatcherRuntimeEntry *_runtimeTable;
+};
+
+} // End of namespace Sci
+
+#endif // SCI_ENGINE_WORKAROUNDS_H
diff --git a/engines/sci/engine/scriptdebug.cpp b/engines/sci/engine/scriptdebug.cpp
index 277437109c..37ec4e8850 100644
--- a/engines/sci/engine/scriptdebug.cpp
+++ b/engines/sci/engine/scriptdebug.cpp
@@ -737,37 +737,39 @@ void logKernelCall(const KernelFunction *kernelCall, const KernelSubFunction *ke
case SIG_TYPE_REFERENCE:
{
SegmentObj *mobj = s->_segMan->getSegmentObj(argv[parmNr].getSegment());
- switch (mobj->getType()) {
- case SEG_TYPE_HUNK:
- {
- HunkTable *ht = (HunkTable *)mobj;
- int index = argv[parmNr].getOffset();
- if (ht->isValidEntry(index)) {
- // NOTE: This ", deleted" isn't as useful as it could
- // be because it prints the status _after_ the kernel
- // call.
- debugN(" ('%s' hunk%s)", ht->_table[index].type, ht->_table[index].mem ? "" : ", deleted");
- } else
- debugN(" (INVALID hunk ref)");
- break;
- }
- default:
- // TODO: Any other segment types which could
- // use special handling?
-
- if (kernelCall->function == kSaid) {
- SegmentRef saidSpec = s->_segMan->dereference(argv[parmNr]);
- if (saidSpec.isRaw) {
- debugN(" ('");
- g_sci->getVocabulary()->debugDecipherSaidBlock(saidSpec.raw);
- debugN("')");
+ if (mobj) {
+ switch (mobj->getType()) {
+ case SEG_TYPE_HUNK:
+ {
+ HunkTable *ht = (HunkTable *)mobj;
+ int index = argv[parmNr].getOffset();
+ if (ht->isValidEntry(index)) {
+ // NOTE: This ", deleted" isn't as useful as it could
+ // be because it prints the status _after_ the kernel
+ // call.
+ debugN(" ('%s' hunk%s)", ht->_table[index].type, ht->_table[index].mem ? "" : ", deleted");
+ } else
+ debugN(" (INVALID hunk ref)");
+ break;
+ }
+ default:
+ // TODO: Any other segment types which could
+ // use special handling?
+
+ if (kernelCall->function == kSaid) {
+ SegmentRef saidSpec = s->_segMan->dereference(argv[parmNr]);
+ if (saidSpec.isRaw) {
+ debugN(" ('");
+ g_sci->getVocabulary()->debugDecipherSaidBlock(saidSpec.raw);
+ debugN("')");
+ } else {
+ debugN(" (non-raw said-spec)");
+ }
} else {
- debugN(" (non-raw said-spec)");
+ debugN(" ('%s')", s->_segMan->getString(argv[parmNr]).c_str());
}
- } else {
- debugN(" ('%s')", s->_segMan->getString(argv[parmNr]).c_str());
+ break;
}
- break;
}
}
default:
diff --git a/engines/sci/engine/seg_manager.cpp b/engines/sci/engine/seg_manager.cpp
index 97e33f256b..161a4f5c79 100644
--- a/engines/sci/engine/seg_manager.cpp
+++ b/engines/sci/engine/seg_manager.cpp
@@ -28,7 +28,8 @@
namespace Sci {
-SegManager::SegManager(ResourceManager *resMan) {
+SegManager::SegManager(ResourceManager *resMan, ScriptPatcher *scriptPatcher)
+ : _resMan(resMan), _scriptPatcher(scriptPatcher) {
_heap.push_back(0);
_clonesSegId = 0;
@@ -44,8 +45,6 @@ SegManager::SegManager(ResourceManager *resMan) {
_stringSegId = 0;
#endif
- _resMan = resMan;
-
createClassTable();
}
@@ -262,8 +261,14 @@ const char *SegManager::getObjectName(reg_t pos) {
const char *name = 0;
if (nameReg.getSegment())
name = derefString(nameReg);
- if (!name)
- return "<invalid name>";
+ if (!name) {
+ // Crazy Nick Laura Bow is missing some object names needed for the static
+ // selector vocabulary
+ if (g_sci->getGameId() == GID_CNICK_LAURABOW && pos == make_reg(1, 0x2267))
+ return "Character";
+ else
+ return "<invalid name>";
+ }
return name;
}
@@ -977,7 +982,7 @@ int SegManager::instantiateScript(int scriptNum) {
scr = allocateScript(scriptNum, &segmentId);
}
- scr->load(scriptNum, _resMan);
+ scr->load(scriptNum, _resMan, _scriptPatcher);
scr->initializeLocals(this);
scr->initializeClasses(this);
scr->initializeObjects(this, segmentId);
diff --git a/engines/sci/engine/seg_manager.h b/engines/sci/engine/seg_manager.h
index 074d3f6b0a..b587f4991a 100644
--- a/engines/sci/engine/seg_manager.h
+++ b/engines/sci/engine/seg_manager.h
@@ -49,7 +49,7 @@ public:
/**
* Initialize the segment manager.
*/
- SegManager(ResourceManager *resMan);
+ SegManager(ResourceManager *resMan, ScriptPatcher *scriptPatcher);
/**
* Deallocate all memory associated with the segment manager.
@@ -224,7 +224,7 @@ public:
* Allocate a fresh chunk of the hunk
* @param[in] size Number of bytes to allocate for the hunk entry
* @param[in] hunk_type A descriptive string for the hunk entry, for
- * debugging purposes
+ * debugging purposes
* @return The offset of the freshly allocated hunk entry
*/
reg_t allocateHunkEntry(const char *hunk_type, int size);
@@ -448,6 +448,7 @@ private:
Common::HashMap<int, SegmentId> _scriptSegMap;
ResourceManager *_resMan;
+ ScriptPatcher *_scriptPatcher;
SegmentId _clonesSegId; ///< ID of the (a) clones segment
SegmentId _listsSegId; ///< ID of the (a) list segment
diff --git a/engines/sci/engine/state.cpp b/engines/sci/engine/state.cpp
index 0f0c8dcd66..d26a519233 100644
--- a/engines/sci/engine/state.cpp
+++ b/engines/sci/engine/state.cpp
@@ -252,7 +252,7 @@ Common::String SciEngine::getSciLanguageString(const Common::String &str, kLangu
}
}
- if (seeker)
+ if (*seeker)
return Common::String(str.c_str(), seeker - str.c_str());
else
return str;
diff --git a/engines/sci/engine/vm.cpp b/engines/sci/engine/vm.cpp
index ef8f165084..d7c2fdc0eb 100644
--- a/engines/sci/engine/vm.cpp
+++ b/engines/sci/engine/vm.cpp
@@ -200,11 +200,18 @@ static void write_var(EngineState *s, int type, int index, reg_t value) {
s->variables[type][index] = value;
- // If the game is trying to change its speech/subtitle settings, apply the ScummVM audio
- // options first, if they haven't been applied yet
- if (type == VAR_GLOBAL && index == 90 && !g_sci->getEngineState()->_syncedAudioOptions) {
- g_sci->syncIngameAudioOptions();
- g_sci->getEngineState()->_syncedAudioOptions = true;
+ if (type == VAR_GLOBAL && index == 90) {
+ // The game is trying to change its speech/subtitle settings
+ if (!g_sci->getEngineState()->_syncedAudioOptions || s->variables[VAR_GLOBAL][4] == TRUE_REG) {
+ // ScummVM audio options haven't been applied yet, so apply them.
+ // We also force the ScummVM audio options when loading a game from
+ // the launcher.
+ g_sci->syncIngameAudioOptions();
+ g_sci->getEngineState()->_syncedAudioOptions = true;
+ } else {
+ // Update ScummVM's audio options
+ g_sci->updateScummVMAudioOptions();
+ }
}
}
}
diff --git a/engines/sci/engine/workarounds.cpp b/engines/sci/engine/workarounds.cpp
index 154ac8f8b4..4b8500bbcb 100644
--- a/engines/sci/engine/workarounds.cpp
+++ b/engines/sci/engine/workarounds.cpp
@@ -32,126 +32,137 @@ namespace Sci {
// gameID, room,script,lvl, object-name, method-name, call,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 #3044734
- { 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 #3034464
- { GID_ECOQUEST2, 100, 0, 0, "Rain", "points", 0xce0, 0, { WORKAROUND_FAKE, 0 } }, // Same as above, for the Spanish version - bug #3313962
- { GID_FANMADE, 516, 983, 0, "Wander", "setTarget", -1, 0, { WORKAROUND_FAKE, 0 } }, // op_mul: The Legend of the Lost Jewel Demo (fan made): called with object as second parameter when attacked by insects - bug #3038913
+ { GID_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 #3038228
+ { 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 #3039879
+ { 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_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
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 #3614968
- { 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 #3039656). 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 #3606025
+ { 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 #3038757
- { GID_FANMADE, 488, 1, 0, "RoomScript", "doit", 0x1f17, 1, { WORKAROUND_FAKE, 0 } }, // Happens in Ocean Battle while playing - bug #3059871
+ { 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 #3044218)
+ { 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 #3052359
- { GID_HOYLE1, -1, 997, 0, "MenuBar", "doit", -1, 0, { WORKAROUND_FAKE, 0 } }, // When changing game speed settings - bug #3108012
+ { 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 #3036918
- { GID_HOYLE4, -1, 0, 0, NULL, "open", -1, -1, { WORKAROUND_FAKE, 0 } }, // when selecting "Control" from the menu (temp vars 0-3) - bug #3039294
- { GID_HOYLE4, 910, 18, 0, NULL, "init", -1, 0, { WORKAROUND_FAKE, 0 } }, // during tutorial - bug #3042756
- { GID_HOYLE4, 910, 910, 0, NULL, "setup", -1, 3, { WORKAROUND_FAKE, 0 } }, // when selecting "Tutorial" from the main menu - bug #3039294
+ { GID_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 #3361925
+ { 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 #3292332 and #3361925
+ { 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, 300, 300, 0, "", "export 2", 0x1d4d, 0, { WORKAROUND_FAKE, 0 } }, // after passing around cards in hearts
- { GID_HOYLE4, 400, 400, 1, "GinHand", "calcRuns", -1, 4, { WORKAROUND_FAKE, 0 } }, // sometimes while playing Gin Rummy (e.g. when knocking and placing a card) - bug #3292334
- { GID_HOYLE4, 500, 17, 1, "Character", "say", -1, 504, { WORKAROUND_FAKE, 0 } }, // sometimes while playing Cribbage (e.g. when the opponent says "Last Card") - bug #3292327
- { GID_ISLANDBRAIN, 100, 937, 0, "IconBar", "dispatchEvent", -1, 58, { WORKAROUND_FAKE, 0 } }, // when using ENTER at the startup menu - bug #3045225
+ { 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_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 #3034700
+ //{ 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
// ^^ 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 #3041262
+ { 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 #3034597, #3035495, #3035824
- { GID_KQ6, 210, 210, 0, "rm210", "scriptCheck", -1, 0, { WORKAROUND_FAKE, 1 } }, // using inventory in that room - bug #3034565
+ { 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 #3059544
+ { 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 #3037694)
- { GID_LAURABOW, -1, 967, 0, "myIcon", "cycle", -1, 1, { WORKAROUND_FAKE, 0 } }, // having any portrait conversation coming up (initial bug #3034985)
+ { 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 #3035068, #3036274
- { GID_LAURABOW2, -1, 90, 1, "MuseumActor", "init", -1, 6, { WORKAROUND_FAKE, 0 } }, // Random actors in museum (bug #3041257)
- { GID_LAURABOW2, 240, 240, 0, "sSteveAnimates", "changeState", -1, 0, { WORKAROUND_FAKE, 0 } }, // Steve Dorian's idle animation at the docks - bug #3036291
- { GID_LONGBOW, -1, 0, 0, "Longbow", "restart", -1, 0, { WORKAROUND_FAKE, 0 } }, // When canceling a restart game - bug #3046200
+ { 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 #3036601
+ { 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 #3036483
+ { 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 #3038326
+ { 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 #3043955)
- { 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 #3049146
- { 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 #3268076
- { GID_MOTHERGOOSE256, 94, 94, 0, "sunrise", "changeState", -1, 367, { WORKAROUND_FAKE, 0 } }, // At the very end, after the game is completed - bug #3051163
+ { 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 #3040012
+ { 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 #3053268
- { GID_QFG1VGA, -1, 210, 0, "Encounter", "init", 0xcee, 0, { WORKAROUND_FAKE, 0 } }, // qfg1vga: going to the brigands hideout - bug #3109299
+ { 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 #3035835 & #3038367
+ { 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 #3039891, 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 #3040469, 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 #3148418
- { GID_QFG2, -1, 700, 0, NULL, "showSign", -1, 10, { WORKAROUND_FAKE, 0 } }, // Occurs sometimes when reading a sign in Raseir, Shapeir et al - bugs #3272735, #3275413
- { GID_QFG3, 510, 510, 0, "awardPrize", "changeState", -1, 0, { WORKAROUND_FAKE, 1 } }, // Simbani warrior challenge, after throwing the spears and retrieving the ring - bug #3049435. Must be non-zero, otherwise the prize is awarded twice - bug #3575570.
- { GID_QFG3, 140, 140, 0, "rm140", "init", 0x1008, 0, { WORKAROUND_FAKE, 0 } }, // when importing a character and selecting the previous profession - bug #3040460
- { GID_QFG3, 330, 330, -1, "Teller", "doChild", -1, -1, { WORKAROUND_FAKE, 0 } }, // when talking to King Rajah about "Rajah" (bug #3036390, temp 1) or "Tarna" (temp 0), or when clicking on yourself and saying "Greet" (bug #3039774, temp 1)
- { GID_QFG3, 700, 700, -1, "monsterIsDead", "changeState", -1, 0, { WORKAROUND_FAKE, 0 } }, // in the jungle, after winning any fight, bug #3040624
- { 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 #3040565
- { GID_QFG3, 490, 490, -1, "computersMove", "changeState", -1, 0, { WORKAROUND_FAKE, 0 } }, // when finishing awari game, bug #3040579
+ { 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 #3050122
+ { 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
@@ -171,7 +182,10 @@ const SciWorkaroundEntry uninitializedReadWorkarounds[] = {
{ 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_SQ5, 201, 201, 0, "buttonPanel", "doVerb", -1, 0, { WORKAROUND_FAKE, 1 } }, // when looking at the orange or red button - bug #3038563
+ { 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
@@ -185,25 +199,25 @@ const SciWorkaroundEntry kAbs_workarounds[] = {
{ 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 #3528416, #3528542)
+ { GID_QFG3 , -1, -1, 0, NULL, "doit", -1, 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
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 #3037003
+ { 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 #3035720
- { 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 #3039679
+ { 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
SCI_WORKAROUNDENTRY_TERMINATOR
};
// gameID, room,script,lvl, object-name, method-name, call,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 #3037003
+ { 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 #3035720
- { 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 #3039679
+ { 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
SCI_WORKAROUNDENTRY_TERMINATOR
};
@@ -212,6 +226,7 @@ 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)
@@ -224,9 +239,9 @@ const SciWorkaroundEntry kDeviceInfo_workarounds[] = {
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 #3043904)
+ { 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 #3044044)
+ { 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
SCI_WORKAROUNDENTRY_TERMINATOR
@@ -234,13 +249,13 @@ const SciWorkaroundEntry kDisplay_workarounds[] = {
// gameID, room,script,lvl, object-name, method-name, call,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 #3042964
+ { 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
SCI_WORKAROUNDENTRY_TERMINATOR
};
// gameID, room,script,lvl, object-name, method-name, call,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 #3034907
+ { 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
@@ -249,26 +264,26 @@ const SciWorkaroundEntry kDisposeScript_workarounds[] = {
// gameID, room,script,lvl, object-name, method-name, call,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 #3037594
+ { 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 #3034567
+ { 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 #3614145
+ { GID_SQ5, 800, 989, 0, "sq5Music1", "fade", -1, 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
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 #3034610 & #3041734
- { 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 #3513207
+ { 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
SCI_WORKAROUNDENTRY_TERMINATOR
};
// gameID, room,script,lvl, object-name, method-name, call,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 #3035186
- { 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 #3292333
+ { 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
SCI_WORKAROUNDENTRY_TERMINATOR
};
@@ -276,18 +291,18 @@ const SciWorkaroundEntry kFindKey_workarounds[] = {
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 #3040894
- { 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 #3040905
+ { 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
SCI_WORKAROUNDENTRY_TERMINATOR
};
// gameID, room,script,lvl, object-name, method-name, call,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 #3034485
+ { 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 #3038077
+ { GID_PQ3, 202, 202, 0, "MapEdit", "movePt", -1, 0, { WORKAROUND_STILLCALL, 0 } }, // when plotting crimes, gets called with 2 extra parameters - bug #5099
SCI_WORKAROUNDENTRY_TERMINATOR
};
@@ -317,12 +332,12 @@ const SciWorkaroundEntry kGraphRedrawBox_workarounds[] = {
{ 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 #3094235
- { GID_SQ4, 150, 150, 0, "laserScript", "changeState", 0x16, 0, { WORKAROUND_STILLCALL, 0 } }, // same as above, for the German version - bug #3116892
+ { 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 #3036331
+ { 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 #3039395
+ { 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
};
@@ -330,42 +345,49 @@ const SciWorkaroundEntry kGraphRedrawBox_workarounds[] = {
// gameID, room,script,lvl, object-name, method-name, call,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 #3038077
- { GID_PQ3, 202, 202, 0, "MapEdit", "movePt", -1, 0, { WORKAROUND_STILLCALL, 0 } }, // when plotting crimes, gets called with 2 extra parameters - bug #3038077
+ { 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
SCI_WORKAROUNDENTRY_TERMINATOR
};
// gameID, room,script,lvl, object-name, method-name, call,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 #3034519
- { 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 #3035262
+ { 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
SCI_WORKAROUNDENTRY_TERMINATOR
};
// gameID, room,script,lvl, object-name, method-name, call,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 #3034490
- { GID_SQ1, -1, 999, 0, "", "export 6", -1, 0, { WORKAROUND_FAKE, 0 } }, // during walking Roger around Ulence Flats - bug #3513765
+ { 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
SCI_WORKAROUNDENTRY_TERMINATOR
};
// gameID, room,script,lvl, object-name, method-name, call,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 #3156472
+ { 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
SCI_WORKAROUNDENTRY_TERMINATOR
};
// gameID, room,script,lvl, object-name, method-name, call,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 #3035057
+ { 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
+ SCI_WORKAROUNDENTRY_TERMINATOR
+};
+
+// gameID, room,script,lvl, object-name, method-name, call,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
SCI_WORKAROUNDENTRY_TERMINATOR
};
// gameID, room,script,lvl, object-name, method-name, call,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 #3034506
+ { 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
SCI_WORKAROUNDENTRY_TERMINATOR
};
@@ -378,28 +400,28 @@ const SciWorkaroundEntry kSetCursor_workarounds[] = {
// gameID, room,script,lvl, object-name, method-name, call,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 #3040844)
+ { 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
SCI_WORKAROUNDENTRY_TERMINATOR
};
// gameID, room,script,lvl, object-name, method-name, call,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 #3039036
- { 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 #3037835
+ { 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
SCI_WORKAROUNDENTRY_TERMINATOR
};
// gameID, room,script,lvl, object-name, method-name, call,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 #3100292
+ { 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
SCI_WORKAROUNDENTRY_TERMINATOR
};
// gameID, room,script,lvl, object-name, method-name, call,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 #3098353
- { GID_LAURABOW2, -1, -1, 0, "sCartoon", "changeState", -1, 0, { WORKAROUND_IGNORE, 0 } }, // DEMO: during the intro, a 3rd parameter is passed by accident - bug #3034902
+ { 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
@@ -465,7 +487,7 @@ SciWorkaroundSolution trackOriginAndFindWorkaround(int index, const SciWorkaroun
// 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 #3155550.
+ // 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;
diff --git a/engines/sci/engine/workarounds.h b/engines/sci/engine/workarounds.h
index 59054ae552..d5e91b70ec 100644
--- a/engines/sci/engine/workarounds.h
+++ b/engines/sci/engine/workarounds.h
@@ -88,6 +88,7 @@ extern const SciWorkaroundEntry kIsObject_workarounds[];
extern const SciWorkaroundEntry kMemory_workarounds[];
extern const SciWorkaroundEntry kMoveCursor_workarounds[];
extern const SciWorkaroundEntry kNewWindow_workarounds[];
+extern const SciWorkaroundEntry kReadNumber_workarounds[];
extern const SciWorkaroundEntry kPaletteUnsetFlag_workarounds[];
extern const SciWorkaroundEntry kSetCursor_workarounds[];
extern const SciWorkaroundEntry kSetPort_workarounds[];
diff --git a/engines/sci/graphics/picture.cpp b/engines/sci/graphics/picture.cpp
index 91c72456a8..caab1d80da 100644
--- a/engines/sci/graphics/picture.cpp
+++ b/engines/sci/graphics/picture.cpp
@@ -132,7 +132,7 @@ void GfxPicture::drawSci11Vga() {
_palette->createFromData(inbuffer + palette_data_ptr, size - palette_data_ptr, &palette);
_palette->set(&palette, true);
- drawCelData(inbuffer, size, cel_headerPos, cel_RlePos, cel_LiteralPos, 0, 0, 0, 0);
+ drawCelData(inbuffer, size, cel_headerPos, cel_RlePos, cel_LiteralPos, 0, 0, 0, 0, false);
}
// process vector data
@@ -224,14 +224,14 @@ void GfxPicture::drawSci32Vga(int16 celNo, int16 drawX, int16 drawY, int16 pictu
cel_RlePos = READ_SCI11ENDIAN_UINT32(inbuffer + cel_headerPos + 24);
cel_LiteralPos = READ_SCI11ENDIAN_UINT32(inbuffer + cel_headerPos + 28);
- drawCelData(inbuffer, size, cel_headerPos, cel_RlePos, cel_LiteralPos, drawX, drawY, pictureX, pictureY);
+ drawCelData(inbuffer, size, cel_headerPos, cel_RlePos, cel_LiteralPos, drawX, drawY, pictureX, pictureY, false);
cel_headerPos += 42;
}
#endif
extern void unpackCelData(byte *inBuffer, byte *celBitmap, byte clearColor, int pixelCount, int rlePos, int literalPos, ViewType viewType, uint16 width, bool isMacSci11ViewData);
-void GfxPicture::drawCelData(byte *inbuffer, int size, int headerPos, int rlePos, int literalPos, int16 drawX, int16 drawY, int16 pictureX, int16 pictureY) {
+void GfxPicture::drawCelData(byte *inbuffer, int size, int headerPos, int rlePos, int literalPos, int16 drawX, int16 drawY, int16 pictureX, int16 pictureY, bool isEGA) {
byte *celBitmap = NULL;
byte *ptr = NULL;
byte *headerPtr = inbuffer + headerPos;
@@ -239,13 +239,17 @@ void GfxPicture::drawCelData(byte *inbuffer, int size, int headerPos, int rlePos
// displaceX, displaceY fields are ignored, and may contain garbage
// (e.g. pic 261 in Dr. Brain 1 Spanish - bug #3614914)
//int16 displaceX, displaceY;
- byte priority = _addToFlag ? _priority : 0;
+ byte priority = _priority;
byte clearColor;
bool compression = true;
byte curByte;
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;
#ifdef ENABLE_SCI32
if (_resourceType != SCI_PICTURE_TYPE_SCI32) {
@@ -279,8 +283,6 @@ void GfxPicture::drawCelData(byte *inbuffer, int size, int headerPos, int rlePos
// That needs to be done cause a mirrored picture may be requested
pixelCount = width * height;
celBitmap = new byte[pixelCount];
- if (!celBitmap)
- error("Unable to allocate temporary memory for picture drawing");
if (g_sci->getPlatform() == Common::kPlatformMacintosh && getSciVersion() >= SCI_VERSION_2) {
// See GfxView::unpackCel() for why this black/white swap is done
@@ -360,37 +362,78 @@ void GfxPicture::drawCelData(byte *inbuffer, int size, int headerPos, int rlePos
ptr = celBitmap;
ptr += skipCelBitmapPixels;
ptr += skipCelBitmapLines * width;
- if (!_mirroredFlag) {
- // Draw bitmap to screen
- x = leftX;
- while (y < lastY) {
- curByte = *ptr++;
- if ((curByte != clearColor) && (priority >= _screen->getPriority(x, y)))
- _screen->putPixel(x, y, drawMask, curByte, priority, 0);
-
- x++;
-
- if (x >= rightX) {
- ptr += sourcePixelSkipPerRow;
- x = leftX;
- y++;
+
+ if ((!isEGA) || (priority < 16)) {
+ // VGA + EGA, EGA only checks priority, when given priority is below 16
+ if (!_mirroredFlag) {
+ // Draw bitmap to screen
+ x = leftX;
+ while (y < lastY) {
+ curByte = *ptr++;
+ if ((curByte != clearColor) && (priority >= _screen->getPriority(x, y)))
+ _screen->putPixel(x, y, drawMask, curByte, priority, 0);
+
+ x++;
+
+ if (x >= rightX) {
+ ptr += sourcePixelSkipPerRow;
+ x = leftX;
+ y++;
+ }
+ }
+ } else {
+ // Draw bitmap to screen (mirrored)
+ x = rightX - 1;
+ while (y < lastY) {
+ curByte = *ptr++;
+ if ((curByte != clearColor) && (priority >= _screen->getPriority(x, y)))
+ _screen->putPixel(x, y, drawMask, curByte, priority, 0);
+
+ if (x == leftX) {
+ ptr += sourcePixelSkipPerRow;
+ x = rightX;
+ y++;
+ }
+
+ x--;
}
}
} else {
- // Draw bitmap to screen (mirrored)
- x = rightX - 1;
- while (y < lastY) {
- curByte = *ptr++;
- if ((curByte != clearColor) && (priority >= _screen->getPriority(x, y)))
- _screen->putPixel(x, y, drawMask, curByte, priority, 0);
-
- if (x == leftX) {
- ptr += sourcePixelSkipPerRow;
- x = rightX;
- y++;
+ // EGA, when priority is above 15
+ // we don't check priority and also won't set priority at all
+ // fixes picture 48 of kq5 (island overview). Bug #5182
+ if (!_mirroredFlag) {
+ // EGA+priority>15: Draw bitmap to screen
+ x = leftX;
+ while (y < lastY) {
+ curByte = *ptr++;
+ if (curByte != clearColor)
+ _screen->putPixel(x, y, GFX_SCREEN_MASK_VISUAL, curByte, 0, 0);
+
+ x++;
+
+ if (x >= rightX) {
+ ptr += sourcePixelSkipPerRow;
+ x = leftX;
+ y++;
+ }
}
+ } else {
+ // EGA+priority>15: Draw bitmap to screen (mirrored)
+ x = rightX - 1;
+ while (y < lastY) {
+ curByte = *ptr++;
+ if (curByte != clearColor)
+ _screen->putPixel(x, y, GFX_SCREEN_MASK_VISUAL, curByte, 0, 0);
+
+ if (x == leftX) {
+ ptr += sourcePixelSkipPerRow;
+ x = rightX;
+ y++;
+ }
- x--;
+ x--;
+ }
}
}
}
@@ -540,22 +583,6 @@ void GfxPicture::drawVectorData(byte *data, int dataSize) {
if ((_screen->isUnditheringEnabled()) && ((_resourceId >= 53 && _resourceId <= 58) || (_resourceId == 61)))
icemanDrawFix = true;
}
- if (g_sci->getGameId() == GID_KQ5) {
- // WORKAROUND: ignore the seemingly broken priority of picture 48
- // (island overview). Fixes bug #3041044.
- if (_resourceId == 48)
- ignoreBrokenPriority = true;
- }
- if (g_sci->getGameId() == GID_SQ4) {
- // WORKAROUND: ignore the seemingly broken priority of pictures 546
- // and 547 (Vohaul's head and Roger Jr trapped). Fixes bug #3046543.
- if (_resourceId == 546 || _resourceId == 547)
- ignoreBrokenPriority = true;
- // WORKAROUND: ignore the seemingly broken priority of picture 631
- // (SQ1 view from the cockpit). Fixes bug #3046513.
- if (_resourceId == 631)
- ignoreBrokenPriority = true;
- }
}
// Drawing
@@ -658,6 +685,7 @@ void GfxPicture::drawVectorData(byte *data, int dataSize) {
case 35:
case 381:
case 376:
+ //case 390: // in the blacklisted NRS patch 1.2 (bug #3615060)
return;
default:
break;
@@ -739,8 +767,15 @@ void GfxPicture::drawVectorData(byte *data, int dataSize) {
case PIC_OPX_EGA_EMBEDDED_VIEW:
vectorGetAbsCoordsNoMirror(data, curPos, x, y);
size = READ_LE_UINT16(data + curPos); curPos += 2;
- _priority = pic_priority; // set global priority so the cel gets drawn using current priority as well
- drawCelData(data, _resource->size, curPos, curPos + 8, 0, x, y, 0, 0);
+ // hardcoded in SSCI, 16 for SCI1early excluding Space Quest 4, 0 for anything else
+ // fixes sq4 pictures 546+547 (Vohaul's head and Roger Jr trapped). Bug #5250
+ // fixes sq4 picture 631 (SQ1 view from cockpit). Bug 5249
+ if ((getSciVersion() <= SCI_VERSION_1_EARLY) && (g_sci->getGameId() != GID_SQ4)) {
+ _priority = 16;
+ } else {
+ _priority = 0;
+ }
+ drawCelData(data, _resource->size, curPos, curPos + 8, 0, x, y, 0, 0, true);
curPos += size;
break;
case PIC_OPX_EGA_SET_PRIORITY_TABLE:
@@ -782,8 +817,14 @@ void GfxPicture::drawVectorData(byte *data, int dataSize) {
case PIC_OPX_VGA_EMBEDDED_VIEW: // draw cel
vectorGetAbsCoordsNoMirror(data, curPos, x, y);
size = READ_LE_UINT16(data + curPos); curPos += 2;
- _priority = pic_priority; // set global priority so the cel gets drawn using current priority as well
- drawCelData(data, _resource->size, curPos, curPos + 8, 0, x, y, 0, 0);
+ if (getSciVersion() <= SCI_VERSION_1_EARLY) {
+ // During SCI1Early sierra always used 0 as priority for cels inside picture resources
+ // fixes Space Quest 4 orange ship lifting off (bug #6446)
+ _priority = 0;
+ } else {
+ _priority = pic_priority; // set global priority so the cel gets drawn using current priority as well
+ }
+ drawCelData(data, _resource->size, curPos, curPos + 8, 0, x, y, 0, 0, false);
curPos += size;
break;
case PIC_OPX_VGA_PRIORITY_TABLE_EQDIST:
@@ -966,6 +1007,12 @@ void GfxPicture::vectorFloodFill(int16 x, int16 y, byte color, byte priority, by
_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);
+#if 0
+ // debug code for floodfill
+ _screen->copyToScreen();
+ g_system->updateScreen();
+ g_system->delayMillis(100);
+#endif
// checking lines above and below for possible flood targets
a_set = b_set = 0;
while (w <= e) {
diff --git a/engines/sci/graphics/picture.h b/engines/sci/graphics/picture.h
index 4f075a6226..53f83bc09f 100644
--- a/engines/sci/graphics/picture.h
+++ b/engines/sci/graphics/picture.h
@@ -65,7 +65,7 @@ private:
void initData(GuiResourceId resourceId);
void reset();
void drawSci11Vga();
- void drawCelData(byte *inbuffer, int size, int headerPos, int rlePos, int literalPos, int16 drawX, int16 drawY, int16 pictureX, int16 pictureY);
+ void drawCelData(byte *inbuffer, int size, int headerPos, int rlePos, int literalPos, int16 drawX, int16 drawY, int16 pictureX, int16 pictureY, bool isEGA);
void drawVectorData(byte *data, int size);
bool vectorIsNonOpcode(byte pixel);
void vectorGetAbsCoords(byte *data, int &curPos, int16 &x, int16 &y);
diff --git a/engines/sci/graphics/portrait.cpp b/engines/sci/graphics/portrait.cpp
index d5227126e2..d589ee17f9 100644
--- a/engines/sci/graphics/portrait.cpp
+++ b/engines/sci/graphics/portrait.cpp
@@ -21,6 +21,7 @@
*/
#include "common/archive.h"
+#include "common/file.h" // for DumpFile
#include "common/system.h"
#include "sci/sci.h"
@@ -39,6 +40,7 @@ Portrait::Portrait(ResourceManager *resMan, EventManager *event, GfxScreen *scre
}
Portrait::~Portrait() {
+ delete[] _lipSyncDataOffsetTable;
delete[] _bitmaps;
delete[] _fileData;
}
@@ -51,7 +53,7 @@ void Portrait::init() {
// 2 bytes main height (should be the same as first bitmap header height)
// 2 bytes animation count
// 2 bytes unknown
- // 2 bytes unknown
+ // 2 bytes lip sync ID count
// 4 bytes paletteSize (base 1)
// -> 17 bytes
// paletteSize bytes paletteData
@@ -81,6 +83,8 @@ void Portrait::init() {
_width = READ_LE_UINT16(_fileData + 3);
_height = READ_LE_UINT16(_fileData + 5);
_bitmapCount = READ_LE_UINT16(_fileData + 7);
+ _lipSyncIDCount = READ_LE_UINT16(_fileData + 11);
+
_bitmaps = new PortraitBitmap[_bitmapCount];
uint16 portraitPaletteSize = READ_LE_UINT16(_fileData + 13);
@@ -128,17 +132,103 @@ void Portrait::init() {
}
data += offsetTableSize;
- // raw lip-sync data follows
+ // 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) ) {
+ // Either terminator (0xFF) or frame-data (1 byte tick count and 1 byte bitmap ID)
+ data++;
+ lipSyncData = *data++;
+ lipSyncCurOffset += 2;
+ }
+ lipSyncDataNr++;
+ }
+ _lipSyncDataOffsetTableEnd = data;
+ // last 4 bytes seem to be garbage
}
+// use this to print out kPortrait debug data
+//#define DEBUG_PORTRAIT
+// use this to use sync resources instead of rave resources (rave resources are better though)
+//#define DEBUG_PORTRAIT_USE_SYNC_RESOURCES
+
void Portrait::doit(Common::Point position, uint16 resourceId, uint16 noun, uint16 verb, uint16 cond, uint16 seq) {
_position = position;
// Now init audio and sync resource
uint32 audioNumber = ((noun & 0xff) << 24) | ((verb & 0xff) << 16) | ((cond & 0xff) << 8) | (seq & 0xff);
+#ifndef DEBUG_PORTRAIT_USE_SYNC_RESOURCES
+ ResourceId raveResourceId = ResourceId(kResourceTypeRave, resourceId, noun, verb, cond, seq);
+ Resource *raveResource = _resMan->findResource(raveResourceId, true);
+ uint raveOffset = 0;
+#else
ResourceId syncResourceId = ResourceId(kResourceTypeSync36, resourceId, noun, verb, cond, seq);
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 (noun %d, verb %d, cond %d, seq %d)", noun, verb, cond, seq);
+ debug("kPortrait: %s", debugPrint);
+ }
+#endif
+
+ // TODO: maybe try to create the missing sync resources for low-res KQ6 out of the rave resources
+
+#ifdef DEBUG_PORTRAIT_USE_SYNC_RESOURCES
+ // Dump the sync resources to disk
+ Common::DumpFile *outFile = new Common::DumpFile();
+ Common::String outName = syncResourceId.toPatchNameBase36() + ".sync36";
+ outFile->open(outName);
+ syncResource->writeToStream(outFile);
+ outFile->finalize();
+ outFile->close();
+
+ ResourceId raveResourceId = ResourceId(kResourceTypeRave, resourceId, noun, verb, cond, seq);
+ Resource *raveResource = _resMan->findResource(raveResourceId, true);
+ outName = raveResourceId.toPatchNameBase36() + ".rave";
+ outFile->open(outName);
+ raveResource->writeToStream(outFile);
+ outFile->finalize();
+ outFile->close();
+ _resMan->unlockResource(raveResource);
+
+ delete outFile;
+#endif
// Set the portrait palette
_palette->set(&_portraitPalette, false, true);
@@ -151,6 +241,90 @@ void Portrait::doit(Common::Point position, uint16 resourceId, uint16 noun, uint
_audio->stopAudio();
_audio->startAudio(resourceId, audioNumber);
+#ifndef DEBUG_PORTRAIT_USE_SYNC_RESOURCES
+ if (!raveResource) {
+ 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;
+ byte *raveLipSyncData;
+ byte raveLipSyncTicks;
+ byte raveLipSyncBitmapNr;
+ int timerPosition = 0;
+ int timerPositionWithin = 0;
+ int curPosition;
+ SciEvent curEvent;
+ bool userAbort = false;
+
+ while ((raveOffset < raveResource->size) && (!userAbort)) {
+ // rave string starts with tick count, followed by lipSyncID, tick count and so on
+ raveTicks = raveGetTicks(raveResource, &raveOffset);
+ if (raveTicks < 0)
+ break;
+
+ // get lipSyncID
+ raveID = raveGetID(raveResource, &raveOffset);
+ if (raveID) {
+ raveLipSyncData = raveGetLipSyncData(raveID);
+ } else {
+ raveLipSyncData = NULL;
+ }
+
+ timerPosition += raveTicks;
+
+ // Wait till syncTime passed, then show specific animation bitmap
+ if (timerPosition > 0) {
+ do {
+ g_sci->getEngineState()->wait(1);
+ 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)
+ userAbort = true;
+ curPosition = _audio->getAudioPosition();
+ } while ((curPosition != -1) && (curPosition < timerPosition) && (!userAbort));
+ }
+
+ if (raveLipSyncData) {
+ // lip sync data is
+ // Tick:Byte, Bitmap-Nr:BYTE
+ // Tick = 0xFF is the terminator for the data
+ timerPositionWithin = timerPosition;
+ raveLipSyncTicks = *raveLipSyncData++;
+ while ( (raveLipSyncData < _lipSyncDataOffsetTableEnd) && (raveLipSyncTicks != 0xFF) ) {
+ timerPositionWithin += raveLipSyncTicks;
+
+ do {
+ g_sci->getEngineState()->wait(1);
+ 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)
+ userAbort = true;
+ curPosition = _audio->getAudioPosition();
+ } while ((curPosition != -1) && (curPosition < timerPositionWithin) && (!userAbort));
+
+ raveLipSyncBitmapNr = *raveLipSyncData++;
+
+ // bitmap nr within sync data is base 1, we need base 0
+ raveLipSyncBitmapNr--;
+
+ if (raveLipSyncBitmapNr < _bitmapCount) {
+ drawBitmap(0);
+ drawBitmap(raveLipSyncBitmapNr);
+ bitsShow();
+ } else {
+ warning("kPortrait: rave lip sync data tried to draw non-existent bitmap %d", raveLipSyncBitmapNr);
+ }
+
+ raveLipSyncTicks = *raveLipSyncData++;
+ }
+ }
+ }
+#else
if (!syncResource) {
// Getting the book in the book shop calls kPortrait where no sync exists
// TODO: find out what to do then
@@ -197,15 +371,90 @@ 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();
if (userAbort) {
- // Reset the portrait bitmap to "closed mouth" state, when skipping dialogs
- drawBitmap(0);
- bitsShow();
_audio->stopAudio();
}
+#ifndef DEBUG_PORTRAIT_USE_SYNC_RESOURCES
+ _resMan->unlockResource(raveResource);
+#else
_resMan->unlockResource(syncResource);
+#endif
+}
+
+// returns ASCII ticks from lip sync string as uint16
+int16 Portrait::raveGetTicks(Resource *resource, uint *offset) {
+ uint curOffset = *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 == ' ' )
+ break;
+ if ( (curByte >= '0') && (curByte <= '9') ) {
+ curValue = curValue * 10 + ( curByte - '0' );
+ } else {
+ // no number -> assume there is an ID at current offset
+ return 0;
+ }
+ }
+ *offset = curOffset;
+ return curValue;
+}
+
+// returns ASCII ID from lip sync string as uint16
+uint16 Portrait::raveGetID(Resource *resource, uint *offset) {
+ uint curOffset = *offset;
+ byte *curData = resource->data + curOffset;
+ byte curByte = 0;
+ uint16 curValue = 0;
+
+ while (curOffset < resource->size) {
+ curByte = *curData++; curOffset++;
+ if ( curByte == ' ' )
+ break;
+ if (!curValue) {
+ curValue = curByte << 8;
+ } else {
+ curValue |= curByte;
+ }
+ }
+
+ *offset = curOffset;
+ return curValue;
+}
+
+// Searches for a specific lip sync ID and returns pointer to lip sync data or NULL in case ID was not found
+byte *Portrait::raveGetLipSyncData(uint16 raveID) {
+ uint lipSyncIDNr = 0;
+ 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
+ }
+ return NULL;
}
void Portrait::drawBitmap(uint16 bitmapNr) {
diff --git a/engines/sci/graphics/portrait.h b/engines/sci/graphics/portrait.h
index 75baa9a56b..de0dbffb3f 100644
--- a/engines/sci/graphics/portrait.h
+++ b/engines/sci/graphics/portrait.h
@@ -52,6 +52,10 @@ private:
void drawBitmap(uint16 bitmapNr);
void bitsShow();
+ int16 raveGetTicks(Resource *resource, uint *offset);
+ uint16 raveGetID(Resource *resource, uint *offset);
+ byte *raveGetLipSyncData(uint16 raveID);
+
ResourceManager *_resMan;
EventManager *_event;
GfxPalette *_palette;
@@ -68,6 +72,13 @@ private:
Common::String _resourceName;
byte *_fileData;
+
+ uint32 _lipSyncIDCount;
+ byte *_lipSyncIDTable;
+
+ byte *_lipSyncData;
+ uint16 *_lipSyncDataOffsetTable;
+ byte *_lipSyncDataOffsetTableEnd;
Common::Point _position;
};
diff --git a/engines/sci/graphics/ports.cpp b/engines/sci/graphics/ports.cpp
index 6d9dc03195..ed0013b491 100644
--- a/engines/sci/graphics/ports.cpp
+++ b/engines/sci/graphics/ports.cpp
@@ -300,11 +300,6 @@ Window *GfxPorts::addWindow(const Common::Rect &dims, const Common::Rect *restor
Window *pwnd = new Window(id);
Common::Rect r;
- if (!pwnd) {
- error("Can't open window");
- return 0;
- }
-
_windowsById[id] = pwnd;
// KQ1sci, KQ4, iceman, QfG2 always add windows to the back of the list.
diff --git a/engines/sci/graphics/view.cpp b/engines/sci/graphics/view.cpp
index 36aaae9232..3d72743ff4 100644
--- a/engines/sci/graphics/view.cpp
+++ b/engines/sci/graphics/view.cpp
@@ -55,6 +55,56 @@ static const byte EGAmappingStraight[SCI_VIEW_EGAMAPPING_SIZE] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
};
+static const byte ViewInject_LauraBow2_Dual[] = {
+ 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,0x37,0x37,0x37,0x37,0x37,0x00,0x00,0x37,0x37,0x00,0x00,0x37,0x37,0x00,0x00,0x00,0x37,0x37,0x37,0x00,0x00,0x37,0x37,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x37,0x08,0x08,0x08,0x08,0x37,0x00,0x37,0x08,0x32,0x00,0x37,0x08,0x32,0x00,0x37,0x08,0x08,0x08,0x37,0x00,0x37,0x08,0x32,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x37,0x08,0x33,0x32,0x37,0x08,0x00,0x37,0x08,0x32,0x00,0x37,0x08,0x32,0x37,0x08,0x32,0x32,0x33,0x08,0x32,0x37,0x08,0x32,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x37,0x08,0x32,0x00,0x37,0x08,0x32,0x37,0x08,0x32,0x00,0x37,0x08,0x32,0x37,0x08,0x33,0x37,0x37,0x08,0x32,0x37,0x08,0x32,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x37,0x08,0x32,0x00,0x37,0x08,0x32,0x37,0x08,0x32,0x00,0x37,0x08,0x32,0x37,0x08,0x08,0x08,0x08,0x08,0x32,0x37,0x08,0x32,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x37,0x08,0x32,0x00,0x37,0x08,0x32,0x37,0x08,0x32,0x00,0x37,0x08,0x32,0x37,0x08,0x32,0x32,0x33,0x08,0x32,0x37,0x08,0x32,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x37,0x08,0x33,0x37,0x37,0x08,0x32,0x37,0x08,0x33,0x37,0x37,0x08,0x32,0x37,0x08,0x32,0x00,0x37,0x08,0x32,0x37,0x08,0x33,0x37,0x37,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x37,0x08,0x08,0x08,0x08,0x32,0x00,0x00,0x37,0x08,0x08,0x08,0x32,0x00,0x37,0x08,0x32,0x00,0x37,0x08,0x32,0x37,0x08,0x08,0x08,0x08,0x32,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x32,0x32,0x32,0x32,0x00,0x00,0x00,0x00,0x32,0x32,0x32,0x00,0x00,0x00,0x32,0x32,0x00,0x00,0x32,0x32,0x00,0x32,0x32,0x32,0x32,0x32,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
+};
+
+static const byte ViewInject_KingsQuest6_Dual1[] = {
+ 0x17,0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x13,
+ 0x17,0x17,0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x13,0x11,
+ 0x16,0x17,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x11,0x11,
+ 0x16,0x16,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x17,0x16,0x16,0x16,0x16,0x13,0x13,0x17,0x16,0x13,0x13,0x17,0x16,0x13,0x13,0x13,0x17,0x16,0x16,0x13,0x13,0x17,0x16,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x11,0x11,
+ 0x16,0x16,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x16,0x10,0x10,0x10,0x10,0x16,0x13,0x16,0x10,0x11,0x13,0x16,0x10,0x11,0x13,0x16,0x10,0x10,0x10,0x16,0x13,0x16,0x10,0x11,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x11,0x11,
+ 0x16,0x16,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x16,0x10,0x11,0x11,0x16,0x10,0x11,0x16,0x10,0x11,0x13,0x16,0x10,0x11,0x16,0x10,0x11,0x11,0x13,0x10,0x11,0x16,0x10,0x11,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x11,0x11,
+ 0x16,0x16,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x16,0x10,0x11,0x13,0x16,0x10,0x11,0x16,0x10,0x11,0x13,0x16,0x10,0x11,0x16,0x10,0x13,0x16,0x16,0x10,0x11,0x16,0x10,0x11,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x11,0x11,
+ 0x16,0x16,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x16,0x10,0x11,0x13,0x16,0x10,0x11,0x16,0x10,0x11,0x13,0x16,0x10,0x11,0x16,0x10,0x10,0x10,0x10,0x10,0x11,0x16,0x10,0x11,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x11,0x11,
+ 0x16,0x16,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x16,0x10,0x11,0x13,0x16,0x10,0x11,0x16,0x10,0x11,0x13,0x16,0x10,0x11,0x16,0x10,0x11,0x11,0x13,0x10,0x11,0x16,0x10,0x11,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x11,0x11,
+ 0x16,0x16,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x16,0x10,0x13,0x16,0x16,0x10,0x11,0x16,0x10,0x13,0x16,0x16,0x10,0x11,0x16,0x10,0x11,0x13,0x16,0x10,0x11,0x16,0x10,0x13,0x16,0x16,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x11,0x11,
+ 0x16,0x16,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x16,0x10,0x10,0x10,0x10,0x11,0x11,0x13,0x16,0x10,0x10,0x10,0x11,0x13,0x16,0x10,0x11,0x13,0x16,0x10,0x11,0x13,0x10,0x10,0x10,0x10,0x11,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x11,0x11,
+ 0x16,0x16,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x11,0x11,0x11,0x11,0x11,0x13,0x13,0x13,0x11,0x11,0x11,0x13,0x13,0x13,0x11,0x11,0x13,0x13,0x11,0x11,0x13,0x11,0x11,0x11,0x11,0x11,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x11,0x11,
+ 0x16,0x16,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x11,0x11,
+ 0x16,0x13,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,
+ 0x13,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x11
+};
+
+static const byte ViewInject_KingsQuest6_Dual2[] = {
+ 0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
+ 0x10,0x16,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x11,0x10,
+ 0x10,0x13,0x16,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x11,0x10,0x10,
+ 0x10,0x13,0x13,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x16,0x13,0x13,0x13,0x13,0x11,0x11,0x16,0x13,0x11,0x11,0x16,0x13,0x11,0x11,0x11,0x16,0x13,0x13,0x11,0x11,0x16,0x13,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x10,0x10,
+ 0x10,0x13,0x13,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x13,0x16,0x16,0x16,0x16,0x13,0x11,0x13,0x16,0x10,0x11,0x13,0x16,0x10,0x11,0x13,0x16,0x16,0x16,0x13,0x11,0x13,0x16,0x10,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x10,0x10,
+ 0x10,0x13,0x13,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x13,0x16,0x10,0x10,0x13,0x16,0x10,0x13,0x16,0x10,0x11,0x13,0x16,0x10,0x13,0x16,0x10,0x10,0x11,0x16,0x10,0x13,0x16,0x10,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x10,0x10,
+ 0x10,0x13,0x13,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x13,0x16,0x10,0x11,0x13,0x16,0x10,0x13,0x16,0x10,0x11,0x13,0x16,0x10,0x13,0x16,0x11,0x13,0x13,0x16,0x10,0x13,0x16,0x10,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x10,0x10,
+ 0x10,0x13,0x13,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x13,0x16,0x10,0x11,0x13,0x16,0x10,0x13,0x16,0x10,0x11,0x13,0x16,0x10,0x13,0x16,0x16,0x16,0x16,0x16,0x10,0x13,0x16,0x10,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x10,0x10,
+ 0x10,0x13,0x13,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x13,0x16,0x10,0x11,0x13,0x16,0x10,0x13,0x16,0x10,0x11,0x13,0x16,0x10,0x13,0x16,0x10,0x10,0x11,0x16,0x10,0x13,0x16,0x10,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x10,0x10,
+ 0x10,0x13,0x13,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x13,0x16,0x11,0x13,0x13,0x16,0x10,0x13,0x16,0x11,0x13,0x13,0x16,0x10,0x13,0x16,0x10,0x11,0x13,0x16,0x10,0x13,0x16,0x11,0x13,0x13,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x10,0x10,
+ 0x10,0x13,0x13,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x13,0x16,0x16,0x16,0x16,0x10,0x10,0x11,0x13,0x16,0x16,0x16,0x10,0x11,0x13,0x16,0x10,0x11,0x13,0x16,0x10,0x11,0x16,0x16,0x16,0x16,0x10,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x10,0x10,
+ 0x10,0x13,0x13,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x10,0x10,0x10,0x10,0x10,0x11,0x11,0x11,0x10,0x10,0x10,0x11,0x11,0x11,0x10,0x10,0x11,0x11,0x10,0x10,0x11,0x10,0x10,0x10,0x10,0x10,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x10,0x10,
+ 0x10,0x13,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x10,0x10,
+ 0x10,0x11,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
+ 0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10
+};
+
void GfxView::initData(GuiResourceId resourceId) {
_resource = _resMan->findResource(ResourceId(kResourceTypeView, resourceId), true);
if (!_resource) {
@@ -316,6 +366,68 @@ 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
+ switch (g_sci->getGameId()) {
+ case GID_LAURABOW2:
+ // View 995, Loop 13, Cel 0 = "TEXT"
+ // View 995, Loop 13, Cel 1 = "SPEECH"
+ // View 995, Loop 13, Cel 2 = "DUAL" (<- our injected view)
+ if ((g_sci->isCD()) && (resourceId == 995)) {
+ // security checks
+ if (_loopCount >= 14) {
+ if ((_loop[13].celCount == 2) && (_loop[13].cel[0].width == 46) && (_loop[13].cel[0].height == 11)) {
+ // copy current cels over
+ CelInfo *newCels = new CelInfo[3];
+ memcpy(newCels, _loop[13].cel, sizeof(CelInfo) * 2);
+ delete[] _loop[13].cel;
+ _loop[13].celCount++;
+ _loop[13].cel = newCels;
+ // Duplicate cel 0 to cel 2
+ memcpy(&_loop[13].cel[2], &_loop[13].cel[0], sizeof(CelInfo));
+ // copy over our data (which is uncompressed bitmap data)
+ _loop[13].cel[2].rawBitmap = new byte[sizeof(ViewInject_LauraBow2_Dual)];
+ memcpy(_loop[13].cel[2].rawBitmap, ViewInject_LauraBow2_Dual, sizeof(ViewInject_LauraBow2_Dual));
+ }
+ }
+ }
+ break;
+ case GID_KQ6:
+ // View 947, Loop 8, Cel 0 = "SPEECH" (not pressed)
+ // View 947, Loop 8, Cel 1 = "SPEECH" (pressed)
+ // View 947, Loop 9, Cel 0 = "TEXT" (not pressed)
+ // View 947, Loop 9, Cel 1 = "TEXT" (pressed)
+ // View 947, Loop 12, Cel 0 = "DUAL" (not pressed) (<- our injected view)
+ // View 947, Loop 12, Cel 1 = "DUAL" (pressed) (<- our injected view)
+ if ((g_sci->isCD()) && (resourceId == 947)) {
+ // security checks
+ if (_loopCount == 12) {
+ if ((_loop[8].celCount == 2) && (_loop[8].cel[0].width == 50) && (_loop[8].cel[0].height == 15)) {
+ // add another loop
+ LoopInfo *newLoops = new LoopInfo[_loopCount + 1];
+ memcpy(newLoops, _loop, sizeof(LoopInfo) * _loopCount);
+ delete[] _loop;
+ _loop = newLoops;
+ _loopCount++;
+ // copy loop 8 to loop 12
+ memcpy(&_loop[12], &_loop[8], sizeof(LoopInfo));
+ _loop[12].cel = new CelInfo[2];
+ // duplicate all cels of loop 8 and into loop 12
+ memcpy(_loop[12].cel, _loop[8].cel, sizeof(CelInfo) * _loop[8].celCount);
+ // copy over our data (which is uncompressed bitmap data)
+ _loop[12].cel[0].rawBitmap = new byte[sizeof(ViewInject_KingsQuest6_Dual1)];
+ memcpy(_loop[12].cel[0].rawBitmap, ViewInject_KingsQuest6_Dual1, sizeof(ViewInject_KingsQuest6_Dual1));
+ _loop[12].cel[1].rawBitmap = new byte[sizeof(ViewInject_KingsQuest6_Dual2)];
+ memcpy(_loop[12].cel[1].rawBitmap, ViewInject_KingsQuest6_Dual2, sizeof(ViewInject_KingsQuest6_Dual2));
+ }
+ }
+ }
+ break;
+ default:
+ break;
+ }
}
GuiResourceId GfxView::getResourceId() const {
diff --git a/engines/sci/parser/vocabulary.cpp b/engines/sci/parser/vocabulary.cpp
index f5b79d6c5e..61659f864d 100644
--- a/engines/sci/parser/vocabulary.cpp
+++ b/engines/sci/parser/vocabulary.cpp
@@ -724,14 +724,13 @@ int Vocabulary::parseNodes(int *i, int *pos, int type, int nr, int argc, const c
newPos = parseNodes(i, pos, nextToken, nextValue, argc, argv);
+ if (newPos == -1)
+ return -1;
+
if (j == 0)
_parserNodes[oldPos].left = &_parserNodes[newPos];
else
_parserNodes[oldPos].right = &_parserNodes[newPos];
-
-
- if (newPos == -1)
- return -1;
}
const char *token = argv[(*i)++];
diff --git a/engines/sci/resource.cpp b/engines/sci/resource.cpp
index d14c965ebb..52155cd09a 100644
--- a/engines/sci/resource.cpp
+++ b/engines/sci/resource.cpp
@@ -112,11 +112,12 @@ static const char *const s_resourceTypeNames[] = {
"audio", "sync", "message", "map", "heap",
"audio36", "sync36", "xlate", "robot", "vmd",
"chunk", "animation", "etc", "duck", "clut",
- "tga", "zzz", "macibin", "macibis", "macpict"
+ "tga", "zzz", "macibin", "macibis", "macpict",
+ "rave"
};
// Resource type suffixes. Note that the
-// suffic of SCI3 scripts has been changed from
+// suffix of SCI3 scripts has been changed from
// scr to csc
static const char *const s_resourceTypeSuffixes[] = {
"v56", "p56", "scr", "tex", "snd",
@@ -125,7 +126,7 @@ static const char *const s_resourceTypeSuffixes[] = {
"msg", "map", "hep", "", "",
"trn", "rbt", "vmd", "chk", "",
"etc", "duk", "clu", "tga", "zzz",
- "", "", ""
+ "", "", "", ""
};
const char *getResourceTypeName(ResourceType restype) {
@@ -141,7 +142,7 @@ static const ResourceType s_resTypeMapSci0[] = {
kResourceTypeCursor, kResourceTypePatch, kResourceTypeBitmap, kResourceTypePalette, // 0x08-0x0B
kResourceTypeCdAudio, kResourceTypeAudio, kResourceTypeSync, kResourceTypeMessage, // 0x0C-0x0F
kResourceTypeMap, kResourceTypeHeap, kResourceTypeAudio36, kResourceTypeSync36, // 0x10-0x13
- kResourceTypeTranslation // 0x14
+ kResourceTypeTranslation, kResourceTypeRave // 0x14
};
// TODO: 12 should be "Wave", but SCI seems to just store it in Audio resources
@@ -207,7 +208,7 @@ void Resource::unalloc() {
}
void Resource::writeToStream(Common::WriteStream *stream) const {
- stream->writeByte(getType() | 0x80); // 0x80 is required by old sierra sci, otherwise it wont accept the patch file
+ stream->writeByte(getType() | 0x80); // 0x80 is required by old Sierra SCI, otherwise it wont accept the patch file
stream->writeByte(_headerSize);
if (_headerSize > 0)
stream->write(_header, _headerSize);
@@ -383,42 +384,13 @@ void PatchResourceSource::loadResource(ResourceManager *resMan, Resource *res) {
static Common::Array<uint32> resTypeToMacTags(ResourceType type);
-static Common::String intToBase36(uint32 number, int minChar) {
- // Convert from an integer to a base36 string
- Common::String string;
-
- while (minChar--) {
- int character = number % 36;
- string = ((character < 10) ? (character + '0') : (character + 'A' - 10)) + string;
- number /= 36;
- }
-
- return string;
-}
-
-static Common::String constructPatchNameBase36(ResourceId resId) {
- // Convert from a resource ID to a base36 patch name
- Common::String output;
-
- output += (resId.getType() == kResourceTypeAudio36) ? '@' : '#'; // Identifier
- output += intToBase36(resId.getNumber(), 3); // Map
- output += intToBase36(resId.getTuple() >> 24, 2); // Noun
- output += intToBase36((resId.getTuple() >> 16) & 0xff, 2); // Verb
- output += '.'; // Separator
- output += intToBase36((resId.getTuple() >> 8) & 0xff, 2); // Cond
- output += intToBase36(resId.getTuple() & 0xff, 1); // Seq
-
- assert(output.size() == 12); // We should always get 12 characters in the end
- return output;
-}
-
void MacResourceForkResourceSource::loadResource(ResourceManager *resMan, Resource *res) {
ResourceType type = res->getType();
Common::SeekableReadStream *stream = 0;
if (type == kResourceTypeAudio36 || type == kResourceTypeSync36) {
// Handle audio36/sync36, convert back to audio/sync
- stream = _macResMan->getResource(constructPatchNameBase36(res->_id));
+ stream = _macResMan->getResource(res->_id.toPatchNameBase36());
} else {
// Plain resource handling
Common::Array<uint32> tagArray = resTypeToMacTags(type);
diff --git a/engines/sci/resource.h b/engines/sci/resource.h
index 4baf39c67f..6a22f48086 100644
--- a/engines/sci/resource.h
+++ b/engines/sci/resource.h
@@ -112,6 +112,8 @@ enum ResourceType {
kResourceTypeMacIconBarPictS, // IBIS resources (icon bar, selected)
kResourceTypeMacPict, // PICT resources (inventory)
+ kResourceTypeRave, // KQ6 hires RAVE (special sync) resources
+
kResourceTypeInvalid
};
@@ -143,6 +145,19 @@ class ResourceId {
uint16 _number;
uint32 _tuple; // Only used for audio36 and sync36
+ static Common::String intToBase36(uint32 number, int minChar) {
+ // Convert from an integer to a base36 string
+ Common::String string;
+
+ while (minChar--) {
+ int character = number % 36;
+ string = ((character < 10) ? (character + '0') : (character + 'A' - 10)) + string;
+ number /= 36;
+ }
+
+ return string;
+ }
+
public:
ResourceId() : _type(kResourceTypeInvalid), _number(0), _tuple(0) { }
@@ -169,6 +184,22 @@ public:
return retStr;
}
+ // Convert from a resource ID to a base36 patch name
+ Common::String toPatchNameBase36() {
+ Common::String output;
+
+ output += (getType() == kResourceTypeAudio36) ? '@' : '#'; // Identifier
+ output += intToBase36(getNumber(), 3); // Map
+ output += intToBase36(getTuple() >> 24, 2); // Noun
+ output += intToBase36((getTuple() >> 16) & 0xff, 2); // Verb
+ output += '.'; // Separator
+ output += intToBase36((getTuple() >> 8) & 0xff, 2); // Cond
+ output += intToBase36(getTuple() & 0xff, 1); // Seq
+
+ assert(output.size() == 12); // We should always get 12 characters in the end
+ return output;
+ }
+
inline ResourceType getType() const { return _type; }
inline uint16 getNumber() const { return _number; }
inline uint32 getTuple() const { return _tuple; }
@@ -498,7 +529,7 @@ protected:
void readWaveAudioPatches();
void processWavePatch(ResourceId resourceId, Common::String name);
- /**
+ /**
* Applies to all versions before 0.000.395 (i.e. KQ4 old, XMAS 1988 and LSL2).
* Old SCI versions used two word header for script blocks (first word equal
* to 0x82, meaning of the second one unknown). New SCI versions used one
@@ -523,6 +554,7 @@ class SoundResource {
public:
struct Channel {
byte number;
+ byte flags;
byte poly;
uint16 prio;
uint16 size;
diff --git a/engines/sci/resource_audio.cpp b/engines/sci/resource_audio.cpp
index 744f05f2b9..8e1568f564 100644
--- a/engines/sci/resource_audio.cpp
+++ b/engines/sci/resource_audio.cpp
@@ -101,32 +101,34 @@ bool Resource::loadFromAudioVolumeSCI11(Common::SeekableReadStream *file) {
}
file->seek(-4, SEEK_CUR);
- ResourceType type = _resMan->convertResType(file->readByte());
- if (((getType() == kResourceTypeAudio || getType() == kResourceTypeAudio36) && (type != kResourceTypeAudio))
- || ((getType() == kResourceTypeSync || getType() == kResourceTypeSync36) && (type != kResourceTypeSync))) {
- warning("Resource type mismatch loading %s", _id.toString().c_str());
- unalloc();
- return false;
- }
-
- _headerSize = file->readByte();
-
- if (type == kResourceTypeAudio) {
- if (_headerSize != 7 && _headerSize != 11 && _headerSize != 12) {
- warning("Unsupported audio header");
+ // Rave-resources (King's Quest 6) don't have any header at all
+ if (getType() != kResourceTypeRave) {
+ ResourceType type = _resMan->convertResType(file->readByte());
+ if (((getType() == kResourceTypeAudio || getType() == kResourceTypeAudio36) && (type != kResourceTypeAudio))
+ || ((getType() == kResourceTypeSync || getType() == kResourceTypeSync36) && (type != kResourceTypeSync))) {
+ warning("Resource type mismatch loading %s", _id.toString().c_str());
unalloc();
return false;
}
+
+ _headerSize = file->readByte();
+
+ if (type == kResourceTypeAudio) {
+ if (_headerSize != 7 && _headerSize != 11 && _headerSize != 12) {
+ warning("Unsupported audio header");
+ unalloc();
+ return false;
+ }
- if (_headerSize != 7) { // Size is defined already from the map
- // Load sample size
- file->seek(7, SEEK_CUR);
- size = file->readUint32LE();
- // Adjust offset to point at the header data again
- file->seek(-11, SEEK_CUR);
+ if (_headerSize != 7) { // Size is defined already from the map
+ // Load sample size
+ file->seek(7, SEEK_CUR);
+ size = file->readUint32LE();
+ // Adjust offset to point at the header data again
+ file->seek(-11, SEEK_CUR);
+ }
}
}
-
return loadPatch(file);
}
@@ -395,15 +397,22 @@ int ResourceManager::readAudioMapSCI11(ResourceSource *map) {
syncSize = READ_LE_UINT16(ptr);
ptr += 2;
+ // FIXME: The sync36 resource seems to be two bytes too big in KQ6CD
+ // (bytes taken from the RAVE resource right after it)
if (syncSize > 0)
addResource(ResourceId(kResourceTypeSync36, map->_volumeNumber, n & 0xffffff3f), src, offset, syncSize);
}
if (n & 0x40) {
// This seems to define the size of raw lipsync data (at least
- // in kq6), may also just be general appended data.
- syncSize += READ_LE_UINT16(ptr);
+ // in KQ6 CD Windows).
+ int kq6HiresSyncSize = READ_LE_UINT16(ptr);
ptr += 2;
+
+ if (kq6HiresSyncSize > 0) {
+ addResource(ResourceId(kResourceTypeRave, map->_volumeNumber, n & 0xffffff3f), src, offset + syncSize, kq6HiresSyncSize);
+ syncSize += kq6HiresSyncSize;
+ }
}
addResource(ResourceId(kResourceTypeAudio36, map->_volumeNumber, n & 0xffffff3f), src, offset + syncSize);
@@ -590,6 +599,7 @@ SoundResource::SoundResource(uint32 resourceNr, ResourceManager *resMan, SciVers
_tracks->channels = new Channel[_tracks->channelCount];
memset(_tracks->channels, 0, sizeof(Channel) * _tracks->channelCount);
channel = &_tracks->channels[0];
+ channel->flags |= 2; // don't remap (SCI0 doesn't have remapping)
if (_soundVersion == SCI_VERSION_0_EARLY) {
channel->data = resource->data + 0x11;
channel->size = resource->size - 0x11;
@@ -667,33 +677,52 @@ SoundResource::SoundResource(uint32 resourceNr, ResourceManager *resMan, SciVers
channelNr = 0;
while (channelCount--) {
channel = &_tracks[trackNr].channels[channelNr];
- channel->prio = READ_LE_UINT16(data);
uint dataOffset = READ_LE_UINT16(data + 2);
- if (dataOffset < resource->size) {
- channel->data = resource->data + dataOffset;
- channel->size = READ_LE_UINT16(data + 4);
- channel->curPos = 0;
- // FIXME: number contains (low nibble) channel and (high nibble) flags
- // 0x20 is set on rhythm channels to prevent remapping
- channel->number = *channel->data;
- channel->poly = *(channel->data + 1);
- channel->time = channel->prev = 0;
- channel->data += 2; // skip over header
- channel->size -= 2; // remove header size
- if (channel->number == 0xFE) { // Digital channel
- _tracks[trackNr].digitalChannelNr = channelNr;
- _tracks[trackNr].digitalSampleRate = READ_LE_UINT16(channel->data);
- _tracks[trackNr].digitalSampleSize = READ_LE_UINT16(channel->data + 2);
- _tracks[trackNr].digitalSampleStart = READ_LE_UINT16(channel->data + 4);
- _tracks[trackNr].digitalSampleEnd = READ_LE_UINT16(channel->data + 6);
- channel->data += 8; // Skip over header
- channel->size -= 8;
- }
- _tracks[trackNr].channelCount++;
- channelNr++;
- } else {
+
+ if (dataOffset >= resource->size) {
warning("Invalid offset inside sound resource %d: track %d, channel %d", resourceNr, trackNr, channelNr);
+ data += 6;
+ continue;
+ }
+
+ channel->data = resource->data + dataOffset;
+ channel->size = READ_LE_UINT16(data + 4);
+ channel->curPos = 0;
+ channel->number = *channel->data;
+
+ channel->poly = *(channel->data + 1) & 0x0F;
+ channel->prio = *(channel->data + 1) >> 4;
+ channel->time = channel->prev = 0;
+ channel->data += 2; // skip over header
+ channel->size -= 2; // remove header size
+ if (channel->number == 0xFE) { // Digital channel
+ _tracks[trackNr].digitalChannelNr = channelNr;
+ _tracks[trackNr].digitalSampleRate = READ_LE_UINT16(channel->data);
+ _tracks[trackNr].digitalSampleSize = READ_LE_UINT16(channel->data + 2);
+ _tracks[trackNr].digitalSampleStart = READ_LE_UINT16(channel->data + 4);
+ _tracks[trackNr].digitalSampleEnd = READ_LE_UINT16(channel->data + 6);
+ channel->data += 8; // Skip over header
+ channel->size -= 8;
+ channel->flags = 0;
+ } else {
+ channel->flags = channel->number >> 4;
+ channel->number = channel->number & 0x0F;
+
+ // 0x20 is set on rhythm channels to prevent remapping
+ // CHECKME: Which SCI versions need that set manually?
+ channel->flags = (*channel->data) >> 4;
+ if (channel->number == 9)
+ channel->flags |= 2;
+ // Note: flag 1: channel start offset is 0 instead of 10
+ // (currently: everything 0)
+ // also: don't map the channel to device
+ // flag 2: don't remap
+ // flag 4: start muted
+ // QfG2 lacks flags 2 and 4, and uses (flags >= 1) as
+ // the condition for starting offset 0, without the "don't map"
}
+ _tracks[trackNr].channelCount++;
+ channelNr++;
data += 6;
}
} else {
@@ -856,6 +885,7 @@ void AudioVolumeResourceSource::loadResource(ResourceManager *resMan, Resource *
switch (res->getType()) {
case kResourceTypeSync:
case kResourceTypeSync36:
+ case kResourceTypeRave:
// we should already have a (valid) size
break;
default:
diff --git a/engines/sci/sci.cpp b/engines/sci/sci.cpp
index c1aadc3622..f32e0e16f9 100644
--- a/engines/sci/sci.cpp
+++ b/engines/sci/sci.cpp
@@ -38,6 +38,7 @@
#include "sci/engine/state.h"
#include "sci/engine/kernel.h"
#include "sci/engine/script.h" // for script_adjust_opcode_formats
+#include "sci/engine/script_patches.h"
#include "sci/engine/selector.h" // for SELECTOR
#include "sci/sound/audio.h"
@@ -112,6 +113,7 @@ SciEngine::SciEngine(OSystem *syst, const ADGameDescription *desc, SciGameId gam
DebugMan.addDebugChannel(kDebugLevelDclInflate, "DCL", "DCL inflate debugging");
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(kDebugLevelGC, "GC", "Garbage Collector debugging");
DebugMan.addDebugChannel(kDebugLevelResMan, "ResMan", "Resource manager debugging");
DebugMan.addDebugChannel(kDebugLevelOnStartup, "OnStartup", "Enter debugger at start of game");
@@ -135,7 +137,7 @@ SciEngine::SciEngine(OSystem *syst, const ADGameDescription *desc, SciGameId gam
SearchMan.addSubDirectoryMatching(gameDataDir, "duk"); // Duck movie files in Phantasmagoria 2
SearchMan.addSubDirectoryMatching(gameDataDir, "Robot Folder"); // Mac robot files
SearchMan.addSubDirectoryMatching(gameDataDir, "Sound Folder"); // Mac audio files
- SearchMan.addSubDirectoryMatching(gameDataDir, "Voices Folder"); // Mac audio36 files
+ SearchMan.addSubDirectoryMatching(gameDataDir, "Voices Folder", 0, 2, true); // Mac audio36 files (recursive for Torin)
SearchMan.addSubDirectoryMatching(gameDataDir, "Voices"); // Mac audio36 files
SearchMan.addSubDirectoryMatching(gameDataDir, "VMD Folder"); // Mac VMD files
@@ -183,6 +185,7 @@ SciEngine::~SciEngine() {
delete[] _opcode_formats;
+ delete _scriptPatcher;
delete _resMan; // should be deleted last
g_sci = 0;
}
@@ -216,14 +219,16 @@ Common::Error SciEngine::run() {
// Add the after market GM patches for the specified game, if they exist
_resMan->addNewGMPatch(_gameId);
_gameObjectAddress = _resMan->findGameObject();
-
- SegManager *segMan = new SegManager(_resMan);
+
+ _scriptPatcher = new ScriptPatcher();
+ SegManager *segMan = new SegManager(_resMan, _scriptPatcher);
// Initialize the game screen
_gfxScreen = new GfxScreen(_resMan);
_gfxScreen->enableUndithering(ConfMan.getBool("disable_dithering"));
_kernel = new Kernel(_resMan, segMan);
+ _kernel->init();
_features = new GameFeatures(segMan, _kernel);
// Only SCI0, SCI01 and SCI1 EGA games used a parser
@@ -881,8 +886,18 @@ void SciEngine::syncSoundSettings() {
}
}
+// used by Script Patcher. Used to find out, if Laura Bow 2/King's Quest 6 need patching for Speech+Subtitles - or not
+bool SciEngine::speechAndSubtitlesEnabled() {
+ bool subtitlesOn = ConfMan.getBool("subtitles");
+ bool speechOn = !ConfMan.getBool("speech_mute");
+
+ if (isCD() && subtitlesOn && speechOn)
+ return true;
+ return false;
+}
+
void SciEngine::syncIngameAudioOptions() {
- // Now, sync the in-game speech/subtitles settings for SCI1.1 CD games
+ // Sync the in-game speech/subtitles settings for SCI1.1 CD games
if (isCD() && getSciVersion() == SCI_VERSION_1_1) {
bool subtitlesOn = ConfMan.getBool("subtitles");
bool speechOn = !ConfMan.getBool("speech_mute");
@@ -893,16 +908,16 @@ void SciEngine::syncIngameAudioOptions() {
_gamestate->variables[VAR_GLOBAL][90] = make_reg(0, 2); // speech
} else if (subtitlesOn && speechOn) {
// Is it a game that supports simultaneous speech and subtitles?
- if (getGameId() == GID_SQ4
- || getGameId() == GID_FREDDYPHARKAS
- || getGameId() == GID_ECOQUEST
- || getGameId() == GID_LSL6
- // TODO: The following need script patches for simultaneous speech and subtitles
- //|| getGameId() == GID_KQ6
- //|| getGameId() == GID_LAURABOW2
- ) {
+ switch (_gameId) {
+ case GID_SQ4:
+ case GID_FREDDYPHARKAS:
+ case GID_ECOQUEST:
+ case GID_LSL6:
+ case GID_LAURABOW2:
+ case GID_KQ6:
_gamestate->variables[VAR_GLOBAL][90] = make_reg(0, 3); // speech + subtitles
- } else {
+ break;
+ default:
// Game does not support speech and subtitles, set it to speech
_gamestate->variables[VAR_GLOBAL][90] = make_reg(0, 2); // speech
}
@@ -910,6 +925,34 @@ void SciEngine::syncIngameAudioOptions() {
}
}
+void SciEngine::updateScummVMAudioOptions() {
+ // Update ScummVM's speech/subtitles settings for SCI1.1 CD games,
+ // 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
+ ConfMan.setBool("subtitles", true);
+ ConfMan.setBool("speech_mute", true);
+ break;
+ case 2:
+ // speech
+ ConfMan.setBool("subtitles", false);
+ ConfMan.setBool("speech_mute", false);
+ break;
+ case 3:
+ // speech + subtitles
+ ConfMan.setBool("subtitles", true);
+ ConfMan.setBool("speech_mute", false);
+ break;
+ default:
+ break;
+ }
+ }
+}
+
void SciEngine::loadMacExecutable() {
if (getPlatform() != Common::kPlatformMacintosh || getSciVersion() < SCI_VERSION_1_EARLY || getSciVersion() > SCI_VERSION_1_1)
return;
diff --git a/engines/sci/sci.h b/engines/sci/sci.h
index 0a75e115fd..418f8c5e50 100644
--- a/engines/sci/sci.h
+++ b/engines/sci/sci.h
@@ -55,6 +55,7 @@ class AudioPlayer;
class SoundCommandParser;
class EventManager;
class SegManager;
+class ScriptPatcher;
class GfxAnimate;
class GfxCache;
@@ -82,28 +83,29 @@ class GfxFrameout;
// our engine debug levels
enum kDebugLevels {
- kDebugLevelError = 1 << 0,
- kDebugLevelNodes = 1 << 1,
- kDebugLevelGraphics = 1 << 2,
- kDebugLevelStrings = 1 << 3,
- kDebugLevelMemory = 1 << 4,
- kDebugLevelFuncCheck = 1 << 5,
- kDebugLevelBresen = 1 << 6,
- kDebugLevelSound = 1 << 7,
- kDebugLevelBaseSetter = 1 << 8,
- kDebugLevelParser = 1 << 9,
- kDebugLevelSaid = 1 << 10,
- kDebugLevelFile = 1 << 11,
- kDebugLevelTime = 1 << 12,
- kDebugLevelRoom = 1 << 13,
- kDebugLevelAvoidPath = 1 << 14,
- kDebugLevelDclInflate = 1 << 15,
- kDebugLevelVM = 1 << 16,
- kDebugLevelScripts = 1 << 17,
- kDebugLevelGC = 1 << 18,
- kDebugLevelResMan = 1 << 19,
- kDebugLevelOnStartup = 1 << 20,
- kDebugLevelDebugMode = 1 << 21
+ kDebugLevelError = 1 << 0,
+ kDebugLevelNodes = 1 << 1,
+ kDebugLevelGraphics = 1 << 2,
+ kDebugLevelStrings = 1 << 3,
+ kDebugLevelMemory = 1 << 4,
+ kDebugLevelFuncCheck = 1 << 5,
+ kDebugLevelBresen = 1 << 6,
+ kDebugLevelSound = 1 << 7,
+ kDebugLevelBaseSetter = 1 << 8,
+ kDebugLevelParser = 1 << 9,
+ kDebugLevelSaid = 1 << 10,
+ kDebugLevelFile = 1 << 11,
+ kDebugLevelTime = 1 << 12,
+ kDebugLevelRoom = 1 << 13,
+ kDebugLevelAvoidPath = 1 << 14,
+ kDebugLevelDclInflate = 1 << 15,
+ kDebugLevelVM = 1 << 16,
+ kDebugLevelScripts = 1 << 17,
+ kDebugLevelGC = 1 << 18,
+ kDebugLevelResMan = 1 << 19,
+ kDebugLevelOnStartup = 1 << 20,
+ kDebugLevelDebugMode = 1 << 21,
+ kDebugLevelScriptPatcher = 1 << 22
};
enum SciGameId {
@@ -244,13 +246,15 @@ public:
* and we add this functionality in ScummVM:
* - Space Quest 4 CD
* - Freddy Pharkas CD
+ * - Laura Bow 2 CD
* SCI1.1 games which don't support simultaneous speech and subtitles,
* and we haven't added any extra functionality in ScummVM because extra
* script patches are needed:
- * - Laura Bow 2 CD
* - King's Quest 6 CD
*/
+ bool speechAndSubtitlesEnabled();
void syncIngameAudioOptions();
+ void updateScummVMAudioOptions();
const SciGameId &getGameId() const { return _gameId; }
const char *getGameIdStr() const;
@@ -266,6 +270,7 @@ public:
bool hasMacIconBar() const;
inline ResourceManager *getResMan() const { return _resMan; }
+ inline ScriptPatcher *getScriptPatcher() const { return _scriptPatcher; }
inline Kernel *getKernel() const { return _kernel; }
inline EngineState *getEngineState() const { return _gamestate; }
inline Vocabulary *getVocabulary() const { return _vocabulary; }
@@ -397,6 +402,7 @@ private:
const ADGameDescription *_gameDescription;
const SciGameId _gameId;
ResourceManager *_resMan; /**< The resource manager */
+ ScriptPatcher *_scriptPatcher; /**< The script patcher */
EngineState *_gamestate;
Kernel *_kernel;
Vocabulary *_vocabulary;
diff --git a/engines/sci/sound/midiparser_sci.cpp b/engines/sci/sound/midiparser_sci.cpp
index 186fc18a5c..f776eb9b8d 100644
--- a/engines/sci/sound/midiparser_sci.cpp
+++ b/engines/sci/sound/midiparser_sci.cpp
@@ -58,6 +58,10 @@ MidiParser_SCI::MidiParser_SCI(SciVersion soundVersion, SciMusic *music) :
_resetOnPause = false;
_pSnd = 0;
+
+ _mainThreadCalled = false;
+
+ resetStateTracking();
}
MidiParser_SCI::~MidiParser_SCI() {
@@ -68,10 +72,12 @@ MidiParser_SCI::~MidiParser_SCI() {
}
void MidiParser_SCI::mainThreadBegin() {
+ assert(!_mainThreadCalled);
_mainThreadCalled = true;
}
void MidiParser_SCI::mainThreadEnd() {
+ assert(_mainThreadCalled);
_mainThreadCalled = false;
}
@@ -83,12 +89,21 @@ bool MidiParser_SCI::loadMusic(SoundResource::Track *track, MusicEntry *psnd, in
for (int i = 0; i < 16; i++) {
_channelUsed[i] = false;
- _channelRemap[i] = -1;
_channelMuted[i] = false;
_channelVolume[i] = 127;
+
+ if (_soundVersion <= SCI_VERSION_0_LATE)
+ _channelRemap[i] = i;
+ else
+ _channelRemap[i] = -1;
}
- _channelRemap[9] = 9; // never map channel 9, because that's used for percussion
- _channelRemap[15] = 15; // never map channel 15, because thats used by sierra internally
+
+ // FIXME: SSCI does not always start playing a track at the first byte.
+ // By default it skips 10 (or 13?) bytes containing prio/voices, patch,
+ // volume, pan commands in fixed locations, and possibly a signal
+ // in channel 15. We should initialize state tracking to those values
+ // so that they automatically get set up properly when the channels get
+ // mapped. See also the related FIXME in MidiParser_SCI::processEvent.
if (channelFilterMask) {
// SCI0 only has 1 data stream, but we need to filter out channels depending on music hardware selection
@@ -314,31 +329,26 @@ byte *MidiParser_SCI::midiFilterChannels(int channelMask) {
return _mixedData;
}
-// This will get called right before actual playing and will try to own the used channels
-void MidiParser_SCI::tryToOwnChannels() {
- // We don't have SciMusic in case debug command show_instruments is used
- if (!_music)
- return;
- for (int curChannel = 0; curChannel < 15; curChannel++) {
- if (_channelUsed[curChannel]) {
- if (_channelRemap[curChannel] == -1) {
- _channelRemap[curChannel] = _music->tryToOwnChannel(_pSnd, curChannel);
- }
- }
- }
-}
+void MidiParser_SCI::resetStateTracking() {
+ for (int i = 0; i < 16; ++i) {
+ ChannelState &s = _channelState[i];
+ s._modWheel = 0;
+ s._pan = 64;
+ s._patch = 0; // TODO: Initialize properly (from data in LoadMusic?)
+ s._note = -1;
+ s._sustain = false;
+ s._pitchWheel = 0x2000;
+ s._voices = 0;
-void MidiParser_SCI::lostChannels() {
- for (int curChannel = 0; curChannel < 15; curChannel++)
- if ((_channelUsed[curChannel]) && (curChannel != 9))
- _channelRemap[curChannel] = -1;
+ _channelVolume[i] = 127;
+ }
}
void MidiParser_SCI::sendInitCommands() {
- // reset our "global" volume and channel volumes
+ resetStateTracking();
+
+ // reset our "global" volume
_volume = 127;
- for (int i = 0; i < 16; i++)
- _channelVolume[i] = 127;
// Set initial voice count
if (_pSnd) {
@@ -390,53 +400,119 @@ void MidiParser_SCI::sendFromScriptToDriver(uint32 midi) {
// this happens for cmdSendMidi at least in sq1vga right at the start, it's a script issue
return;
}
- if (_channelRemap[midiChannel] == -1) {
- // trying to send to an unmapped channel
- // this happens for cmdSendMidi at least in sq1vga right at the start, scripts are pausing the sound
- // and then sending manually. it's a script issue
- return;
- }
sendToDriver(midi);
}
void MidiParser_SCI::sendToDriver(uint32 midi) {
- byte midiChannel = midi & 0xf;
-
- if ((midi & 0xFFF0) == 0x4EB0) {
- // this is channel mute only for sci1
- // it's velocity control for sci0
- if (_soundVersion >= SCI_VERSION_1_EARLY) {
- _channelMuted[midiChannel] = midi & 0xFF0000 ? true : false;
- return; // don't send this to driver at all
- }
- }
+ // State tracking
+ trackState(midi);
- // Is channel muted? if so, don't send command
- if (_channelMuted[midiChannel])
+ if ((midi & 0xFFF0) == 0x4EB0 && _soundVersion >= SCI_VERSION_1_EARLY) {
+ // Mute. Handled in trackState().
+ // CHECKME: Should we send this on to the driver?
return;
+ }
if ((midi & 0xFFF0) == 0x07B0) {
// someone trying to set channel volume?
int channelVolume = (midi >> 16) & 0xFF;
- // Remember, if we need to set it ourselves
- _channelVolume[midiChannel] = channelVolume;
// Adjust volume accordingly to current local volume
channelVolume = channelVolume * _volume / 127;
- midi = (midi & 0xFFF0) | ((channelVolume & 0xFF) << 16);
+ midi = (midi & 0xFFFF) | ((channelVolume & 0xFF) << 16);
}
+
// Channel remapping
+ byte midiChannel = midi & 0xf;
int16 realChannel = _channelRemap[midiChannel];
if (realChannel == -1)
return;
midi = (midi & 0xFFFFFFF0) | realChannel;
+ sendToDriver_raw(midi);
+}
+
+void MidiParser_SCI::sendToDriver_raw(uint32 midi) {
if (_mainThreadCalled)
_music->putMidiCommandInQueue(midi);
else
_driver->send(midi);
}
+void MidiParser_SCI::trackState(uint32 b) {
+ // We keep track of most of the state of a midi channel, so we can
+ // at any time reset the device to the current state, even if the
+ // channel has been temporarily disabled due to remapping.
+
+ byte command = b & 0xf0;
+ byte channel = b & 0xf;
+ byte op1 = (b >> 8) & 0x7f;
+ byte op2 = (b >> 16) & 0x7f;
+
+ ChannelState &s = _channelState[channel];
+
+ switch (command) {
+ case 0x90:
+ if (op2 != 0) {
+ // note on
+ s._note = op1;
+ break;
+ }
+ // else, fall-through
+ case 0x80:
+ // note off
+ if (s._note == op1)
+ s._note = -1;
+ break;
+ case 0xB0:
+ // control change
+ switch (op1) {
+ case 0x01: // mod wheel
+ s._modWheel = op2;
+ break;
+ case 0x07: // channel volume
+ _channelVolume[channel] = op2;
+ break;
+ case 0x0A: // pan
+ s._pan = op2;
+ break;
+ case 0x40: // sustain
+ s._sustain = (op2 != 0);
+ break;
+ case 0x4B: // voices
+ 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) {
+ // 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);
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ break;
+ case 0xC0:
+ // program change
+ s._patch = op1;
+ break;
+ case 0xE0:
+ // pitchwheel
+ s._pitchWheel = (op2 << 7) | op1;
+ break;
+ default:
+ break;
+ }
+}
+
void MidiParser_SCI::parseNextEvent(EventInfo &info) {
info.start = _position._playPos;
info.delta = 0;
@@ -477,8 +553,10 @@ void MidiParser_SCI::parseNextEvent(EventInfo &info) {
case 0xE:
info.basic.param1 = *(_position._playPos++);
info.basic.param2 = *(_position._playPos++);
- if (info.command() == 0x9 && info.basic.param2 == 0)
+ if (info.command() == 0x9 && info.basic.param2 == 0) {
+ // NoteOn with param2==0 is a NoteOff
info.event = info.channel() | 0x80;
+ }
info.length = 0;
break;
@@ -523,11 +601,10 @@ void MidiParser_SCI::parseNextEvent(EventInfo &info) {
}// switch (info.command())
}
-void MidiParser_SCI::processEvent(const EventInfo &info, bool fireEvents) {
+bool MidiParser_SCI::processEvent(const EventInfo &info, bool fireEvents) {
if (!fireEvents) {
// We don't do any processing that should be done while skipping events
- MidiParser::processEvent(info, fireEvents);
- return;
+ return MidiParser::processEvent(info, fireEvents);
}
switch (info.command()) {
@@ -579,7 +656,7 @@ void MidiParser_SCI::processEvent(const EventInfo &info, bool fireEvents) {
}
// Done with this event.
- return;
+ return true;
}
// Break to let parent handle the rest.
@@ -606,7 +683,7 @@ void MidiParser_SCI::processEvent(const EventInfo &info, bool fireEvents) {
switch (info.basic.param1) {
case kSetReverb:
// Already handled above
- return;
+ return true;
case kMidiHold:
// Check if the hold ID marker is the same as the hold ID
// marker set for that song by cmdSetSoundHold.
@@ -614,9 +691,9 @@ void MidiParser_SCI::processEvent(const EventInfo &info, bool fireEvents) {
if (info.basic.param2 == _pSnd->hold) {
jumpToTick(_loopTick, false, false);
// Done with this event.
- return;
+ return true;
}
- return;
+ return true;
case kUpdateCue:
if (!_jumpingToTick) {
int inc;
@@ -637,17 +714,17 @@ void MidiParser_SCI::processEvent(const EventInfo &info, bool fireEvents) {
debugC(4, kDebugLevelSound, "datainc %04x", inc);
}
- return;
+ return true;
case kResetOnPause:
_resetOnPause = info.basic.param2;
- return;
+ return true;
// Unhandled SCI commands
case 0x46: // LSL3 - binoculars
case 0x61: // Iceman (AdLib?)
case 0x73: // Hoyle
case 0xD1: // KQ4, when riding the unicorn
// Obscure SCI commands - ignored
- return;
+ return true;
// Standard MIDI commands
case 0x01: // mod wheel
case 0x04: // foot controller
@@ -662,10 +739,10 @@ void MidiParser_SCI::processEvent(const EventInfo &info, bool fireEvents) {
case 0x4B: // voice mapping
// TODO: is any support for this needed at the MIDI parser level?
warning("Unhanded SCI MIDI command 0x%x - voice mapping (parameter %d)", info.basic.param1, info.basic.param2);
- return;
+ return true;
default:
warning("Unhandled SCI MIDI command 0x%x (parameter %d)", info.basic.param1, info.basic.param2);
- return;
+ return true;
}
}
@@ -684,7 +761,7 @@ void MidiParser_SCI::processEvent(const EventInfo &info, bool fireEvents) {
jumpToTick(_loopTick);
// Done with this event.
- return;
+ return true;
} else {
_pSnd->status = kSoundStopped;
@@ -704,7 +781,7 @@ void MidiParser_SCI::processEvent(const EventInfo &info, bool fireEvents) {
// Let parent handle the rest
- MidiParser::processEvent(info, fireEvents);
+ return MidiParser::processEvent(info, fireEvents);
}
byte MidiParser_SCI::getSongReverb() {
@@ -809,4 +886,44 @@ void MidiParser_SCI::setVolume(byte volume) {
}
}
+void MidiParser_SCI::remapChannel(int channel, int devChannel) {
+ if (_channelRemap[channel] == devChannel)
+ return;
+
+ _channelRemap[channel] = devChannel;
+
+ if (devChannel == -1)
+ return;
+
+// debug(" restoring state: channel %d on devChannel %d", channel, devChannel);
+
+ // restore state
+ ChannelState &s = _channelState[channel];
+
+ int channelVolume = _channelVolume[channel];
+ channelVolume = (channelVolume * _volume / 127) & 0xFF;
+ byte pitch1 = s._pitchWheel & 0x7F;
+ byte pitch2 = (s._pitchWheel >> 7) & 0x7F;
+
+ sendToDriver_raw(0x0040B0 | devChannel); // sustain off
+ sendToDriver_raw(0x004BB0 | devChannel | (s._voices << 16));
+ sendToDriver_raw(0x0000C0 | devChannel | (s._patch << 8));
+ sendToDriver_raw(0x0007B0 | devChannel | (channelVolume << 16));
+ sendToDriver_raw(0x000AB0 | devChannel | (s._pan << 16));
+ sendToDriver_raw(0x0001B0 | devChannel | (s._modWheel << 16));
+ sendToDriver_raw(0x0040B0 | devChannel | (s._sustain ? 0x7F0000 : 0));
+ sendToDriver_raw(0x0000E0 | devChannel | (pitch1 << 8) | (pitch2 << 16));
+
+ // CHECKME: Some SSCI version send a control change 0x4E with s._note as
+ // parameter.
+ // We need to investigate how (and if) drivers should act on this.
+ // Related: controller 0x4E is used for 'mute' in the midiparser.
+ // This could be a bug in SSCI that went unnoticed because few (or no?)
+ // drivers implement controller 0x4E
+
+ // NB: The line below is _not_ valid since s._note can be 0xFF.
+ // SSCI handles this out of band in the driver interface.
+ // sendToDriver_raw(0x004EB0 | devChannel | (s._note << 16);
+}
+
} // End of namespace Sci
diff --git a/engines/sci/sound/midiparser_sci.h b/engines/sci/sound/midiparser_sci.h
index 5784dca1ab..7c3c5c3483 100644
--- a/engines/sci/sound/midiparser_sci.h
+++ b/engines/sci/sound/midiparser_sci.h
@@ -79,20 +79,23 @@ public:
const byte *getMixedData() const { return _mixedData; }
byte getSongReverb();
- void tryToOwnChannels();
- void lostChannels();
void sendFromScriptToDriver(uint32 midi);
void sendToDriver(uint32 midi);
void sendToDriver(byte status, byte firstOp, byte secondOp) {
sendToDriver(status | ((uint32)firstOp << 8) | ((uint32)secondOp << 16));
}
+ void remapChannel(int channel, int devChannel);
+
protected:
void parseNextEvent(EventInfo &info);
- void processEvent(const EventInfo &info, bool fireEvents = true);
+ bool processEvent(const EventInfo &info, bool fireEvents = true);
byte *midiMixChannels();
byte *midiFilterChannels(int channelMask);
byte midiGetNextChannel(long ticker);
+ void resetStateTracking();
+ void trackState(uint32 midi);
+ void sendToDriver_raw(uint32 midi);
SciMusic *_music;
@@ -113,6 +116,19 @@ protected:
int16 _channelRemap[16];
bool _channelMuted[16];
byte _channelVolume[16];
+
+ struct ChannelState {
+ int8 _modWheel;
+ int8 _pan;
+ int8 _patch;
+ int8 _note;
+ bool _sustain;
+ int16 _pitchWheel;
+ int8 _voices;
+ };
+
+ ChannelState _channelState[16];
+
};
} // End of namespace Sci
diff --git a/engines/sci/sound/music.cpp b/engines/sci/sound/music.cpp
index 8c6d0d6431..f46c1dfbb0 100644
--- a/engines/sci/sound/music.cpp
+++ b/engines/sci/sound/music.cpp
@@ -33,7 +33,7 @@
#include "sci/sound/midiparser_sci.h"
#include "sci/sound/music.h"
-//#define DISABLE_REMAPPING
+//#define DEBUG_REMAP
namespace Sci {
@@ -47,6 +47,8 @@ SciMusic::SciMusic(SciVersion soundVersion, bool useDigitalSFX)
for (int i = 0; i < 16; i++) {
_usedChannel[i] = 0;
_channelRemap[i] = -1;
+ _channelMap[i]._song = 0;
+ _channelMap[i]._channel = -1;
}
_queuedCommands.reserve(1000);
@@ -291,6 +293,15 @@ void SciMusic::sortPlayList() {
}
void SciMusic::soundInitSnd(MusicEntry *pSnd) {
+ // Remove all currently mapped channels of this MusicEntry first,
+ // since they will no longer be valid.
+ for (int i = 0; i < 16; ++i) {
+ if (_channelMap[i]._song == pSnd) {
+ _channelMap[i]._song = 0;
+ _channelMap[i]._channel = -1;
+ }
+ }
+
int channelFilterMask = 0;
SoundResource::Track *track = pSnd->soundRes->getTrackByType(_pMidiDrv->getPlayId());
@@ -337,6 +348,27 @@ void SciMusic::soundInitSnd(MusicEntry *pSnd) {
// Find out what channels to filter for SCI0
channelFilterMask = pSnd->soundRes->getChannelFilterMask(_pMidiDrv->getPlayId(), _pMidiDrv->hasRhythmChannel());
+ for (int i = 0; i < 16; ++i)
+ pSnd->_usedChannels[i] = 0xFF;
+ for (int i = 0; i < track->channelCount; ++i) {
+ SoundResource::Channel &chan = track->channels[i];
+
+ pSnd->_usedChannels[i] = chan.number;
+ pSnd->_chan[chan.number]._dontRemap = (chan.flags & 2);
+ pSnd->_chan[chan.number]._prio = chan.prio;
+ pSnd->_chan[chan.number]._voices = chan.poly;
+
+ // CHECKME: Some SCI versions use chan.flags & 1 for this:
+ pSnd->_chan[chan.number]._dontMap = false;
+
+ // FIXME: Most MIDI tracks use the first 10 bytes for
+ // fixed MIDI commands. SSCI skips those the first iteration,
+ // but _does_ update channel state (including volume) with
+ // them. Specifically, prio/voices, patch, volume, pan.
+ // This should probably be implemented in
+ // MidiParser_SCI::loadMusic.
+ }
+
pSnd->pMidiParser->mainThreadBegin();
// loadMusic() below calls jumpToTick.
// Disable sound looping and hold before jumpToTick is called,
@@ -358,64 +390,6 @@ void SciMusic::soundInitSnd(MusicEntry *pSnd) {
}
}
-// This one checks, if requested channel is available -> in that case give
-// caller that channel. Otherwise look for an unused one
-int16 SciMusic::tryToOwnChannel(MusicEntry *caller, int16 bestChannel) {
-#ifdef DISABLE_REMAPPING
- return bestChannel;
-#endif
-
- // Don't even try this for SCI0
- if (_soundVersion <= SCI_VERSION_0_LATE)
- return bestChannel;
- if (!_usedChannel[bestChannel]) {
- // currently unused, so give it to caller directly
- _usedChannel[bestChannel] = caller;
- _channelRemap[bestChannel] = bestChannel;
- return bestChannel;
- }
- // otherwise look for unused channel
- for (int channelNr = _driverFirstChannel; channelNr < 15; channelNr++) {
- if (channelNr == 9) // never map to channel 9 (percussion)
- continue;
- if (!_usedChannel[channelNr]) {
- _usedChannel[channelNr] = caller;
- _channelRemap[bestChannel] = channelNr;
- return channelNr;
- }
- }
- // nothing found, don't map channel at all
- // sierra did this as well, although i'm not sure if we act exactly the same way
- // maybe they removed channels from previous playing music
- return -1;
-}
-
-void SciMusic::freeChannels(MusicEntry *caller) {
- // Remove used channels
- for (int i = 0; i < 15; i++) {
- if (_usedChannel[i] == caller) {
- if (_channelRemap[i] != -1) {
- // athrxx: The original handles this differently. It seems to be checking for (and effecting) necessary
- // remaps / resets etc. more or less all the time. There are several more tables to keep track of everything.
- // I don't know whether all of that is needed and to which SCI versions it applies, though.
- // At least it is necessary to release the allocated channels inside the driver. Otherwise these channels
- // won't be available any more (e.g. after half of the KQ5 FM-Towns intro there will be no more music
- // since the driver can't pick up any more channels). The channels also have to be reset to
- // default values, since the original does the same (although in a different manny) and the music will be wrong
- // otherwise (at least KQ5 FM-Towns).
-
- sendMidiCommand(0x4000e0 | _channelRemap[i]); // Reset pitch wheel
- sendMidiCommand(0x0040b0 | _channelRemap[i]); // Release pedal
- sendMidiCommand(0x004bb0 | _channelRemap[i]); // Release assigned driver channels
- }
- _usedChannel[i] = 0;
- _channelRemap[i] = -1;
- }
- }
- // Also tell midiparser, that he lost ownership
- caller->pMidiParser->lostChannels();
-}
-
void SciMusic::soundPlay(MusicEntry *pSnd) {
_mutex.lock();
@@ -481,28 +455,6 @@ void SciMusic::soundPlay(MusicEntry *pSnd) {
Common::StackLock lock(_mutex);
pSnd->pMidiParser->mainThreadBegin();
- if (pSnd->status != kSoundPaused) {
- // Stop any in progress music fading, as that will reset the
- // volume of the sound channels that the faded song occupies..
- // Fixes bug #3266480 and partially fixes bug #3041738.
- // CHECKME: Is this the right thing to do? Are these
- // overlapping channels not a deeper underlying problem?
- for (uint i = 0; i < playListCount; i++) {
- // Is another MIDI song being faded down? If yes, stop it
- // immediately instead
- if (_playList[i]->fadeStep < 0 && _playList[i]->pMidiParser) {
- _playList[i]->status = kSoundStopped;
- if (_soundVersion <= SCI_VERSION_0_LATE)
- _playList[i]->isQueued = false;
- _playList[i]->pMidiParser->stop();
- freeChannels(_playList[i]);
- _playList[i]->fadeStep = 0;
- _playList[i]->fadeCompleted = true;
- }
- }
- }
-
- pSnd->pMidiParser->tryToOwnChannels();
if (pSnd->status != kSoundPaused)
pSnd->pMidiParser->sendInitCommands();
pSnd->pMidiParser->setVolume(pSnd->volume);
@@ -532,6 +484,10 @@ void SciMusic::soundPlay(MusicEntry *pSnd) {
}
pSnd->status = kSoundPlaying;
+
+ _mutex.lock();
+ remapChannels();
+ _mutex.unlock();
}
void SciMusic::soundStop(MusicEntry *pSnd) {
@@ -549,8 +505,8 @@ void SciMusic::soundStop(MusicEntry *pSnd) {
// allNotesOff() again
if (previousStatus == kSoundPlaying)
pSnd->pMidiParser->stop();
- freeChannels(pSnd);
pSnd->pMidiParser->mainThreadEnd();
+ remapChannels();
}
pSnd->fadeStep = 0; // end fading, if fading was in progress
@@ -586,8 +542,10 @@ void SciMusic::soundSetPriority(MusicEntry *pSnd, byte prio) {
void SciMusic::soundKill(MusicEntry *pSnd) {
pSnd->status = kSoundStopped;
+ _mutex.lock();
+ remapChannels();
+
if (pSnd->pMidiParser) {
- Common::StackLock lock(_mutex);
pSnd->pMidiParser->mainThreadBegin();
pSnd->pMidiParser->unloadMusic();
pSnd->pMidiParser->mainThreadEnd();
@@ -595,6 +553,8 @@ void SciMusic::soundKill(MusicEntry *pSnd) {
pSnd->pMidiParser = NULL;
}
+ _mutex.unlock();
+
if (pSnd->pStreamAud) {
_pMixer->stopHandle(pSnd->hCurrentAud);
delete pSnd->pStreamAud;
@@ -603,7 +563,7 @@ void SciMusic::soundKill(MusicEntry *pSnd) {
pSnd->pLoopStream = 0;
}
- Common::StackLock lock(_mutex);
+ _mutex.lock();
uint sz = _playList.size(), i;
// Remove sound from playlist
for (i = 0; i < sz; i++) {
@@ -614,6 +574,7 @@ void SciMusic::soundKill(MusicEntry *pSnd) {
break;
}
}
+ _mutex.unlock();
}
void SciMusic::soundPause(MusicEntry *pSnd) {
@@ -639,8 +600,8 @@ void SciMusic::soundPause(MusicEntry *pSnd) {
Common::StackLock lock(_mutex);
pSnd->pMidiParser->mainThreadBegin();
pSnd->pMidiParser->pause();
- freeChannels(pSnd);
pSnd->pMidiParser->mainThreadEnd();
+ remapChannels();
}
}
}
@@ -789,6 +750,14 @@ MusicEntry::MusicEntry() {
pStreamAud = 0;
pLoopStream = 0;
pMidiParser = 0;
+
+ for (int i = 0; i < 16; ++i) {
+ _usedChannels[i] = 0xFF;
+ _chan[i]._prio = 127;
+ _chan[i]._voices = 0;
+ _chan[i]._dontRemap = false;
+ _chan[i]._mute = false;
+ }
}
MusicEntry::~MusicEntry() {
@@ -857,4 +826,447 @@ void MusicEntry::setSignal(int newSignal) {
}
}
+
+void ChannelRemapping::swap(int i, int j) {
+ DeviceChannelUsage t1;
+ int t2;
+ bool t3;
+
+ t1 = _map[i]; _map[i] = _map[j]; _map[j] = t1;
+ t2 = _prio[i]; _prio[i] = _prio[j]; _prio[j] = t2;
+ t2 = _voices[i]; _voices[i] = _voices[j]; _voices[j] = t2;
+ t3 = _dontRemap[i]; _dontRemap[i] = _dontRemap[j]; _dontRemap[j] = t3;
+}
+
+void ChannelRemapping::evict(int i) {
+ _freeVoices += _voices[i];
+
+ _map[i]._song = 0;
+ _map[i]._channel = -1;
+ _prio[i] = 0;
+ _voices[i] = 0;
+ _dontRemap[i] = false;
+}
+
+void ChannelRemapping::clear() {
+ for (int i = 0; i < 16; ++i) {
+ _map[i]._song = 0;
+ _map[i]._channel = -1;
+ _prio[i] = 0;
+ _voices[i] = 0;
+ _dontRemap[i] = false;
+ }
+}
+
+ChannelRemapping& ChannelRemapping::operator=(ChannelRemapping& other) {
+ for (int i = 0; i < 16; ++i) {
+ _map[i] = other._map[i];
+ _prio[i] = other._prio[i];
+ _voices[i] = other._voices[i];
+ _dontRemap[i] = other._dontRemap[i];
+ }
+ _freeVoices = other._freeVoices;
+
+ return *this;
+}
+
+int ChannelRemapping::lowestPrio() const {
+ int max = 0;
+ int channel = -1;
+ for (int i = 0; i < 16; ++i) {
+ if (_prio[i] > max) {
+ max = _prio[i];
+ channel = i;
+ }
+ }
+ return channel;
+}
+
+
+void SciMusic::remapChannels() {
+ if (_soundVersion <= SCI_VERSION_0_LATE)
+ return;
+
+ // NB: This function should only be called from the main thread,
+ // with _mutex locked
+
+
+ ChannelRemapping *map = determineChannelMap();
+
+ DeviceChannelUsage currentMap[16];
+
+#ifdef DEBUG_REMAP
+ debug("Remap results:");
+#endif
+
+ // Save current map, and then start from an empty map
+ for (int i = 0; i < 16; ++i) {
+ currentMap[i] = _channelMap[i];
+ _channelMap[i]._song = 0;
+ _channelMap[i]._channel = -1;
+ }
+
+ // Inform MidiParsers of any unmapped channels
+ const MusicList::iterator end = _playList.end();
+ int songIndex = -1;
+ for (MusicList::iterator i = _playList.begin(); i != end; ++i) {
+ MusicEntry *song = *i;
+ songIndex++;
+
+ if (!song || !song->pMidiParser)
+ continue;
+
+ bool channelMapped[16];
+#ifdef DEBUG_REMAP
+ bool channelUsed[16];
+#endif
+ for (int j = 0; j < 16; ++j) {
+ channelMapped[j] = false;
+#ifdef DEBUG_REMAP
+ channelUsed[j] = false;
+#endif
+ }
+
+ for (int j = 0; j < 16; ++j) {
+ if (map->_map[j]._song == song) {
+ int channel = map->_map[j]._channel;
+ assert(channel >= 0 && channel <= 0x0F);
+ channelMapped[channel] = true;
+ }
+#ifdef DEBUG_REMAP
+ if (song->_usedChannels[j] <= 0x0F)
+ channelUsed[song->_usedChannels[j]] = true;
+#endif
+ }
+
+ for (int j = 0; j < 16; ++j) {
+ if (!channelMapped[j]) {
+ song->pMidiParser->mainThreadBegin();
+ song->pMidiParser->remapChannel(j, -1);
+ song->pMidiParser->mainThreadEnd();
+#ifdef DEBUG_REMAP
+ if (channelUsed[j])
+ debug(" Unmapping song %d, channel %d", songIndex, j);
+#endif
+ }
+ }
+ }
+
+ // Now reshuffle the channels on the device.
+
+ // First, set up any dontRemap channels
+ for (int i = 0; i < 16; ++i) {
+
+ if (!map->_map[i]._song || !map->_map[i]._song->pMidiParser || !map->_dontRemap[i])
+ continue;
+
+ songIndex = -1;
+ for (MusicList::iterator iter = _playList.begin(); iter != end; ++iter) {
+ songIndex++;
+ if (map->_map[i]._song == *iter)
+ break;
+ }
+
+ _channelMap[i] = map->_map[i];
+ map->_map[i]._song = 0; // mark as done
+
+ // If this channel was not yet mapped to the device, reset it
+ if (currentMap[i] != _channelMap[i]) {
+#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();
+ _channelMap[i]._song->pMidiParser->remapChannel(_channelMap[i]._channel, i);
+ _channelMap[i]._song->pMidiParser->mainThreadEnd();
+ }
+
+ }
+
+ // Next, we look for channels which were already playing.
+ // We keep those on the same device channel as before.
+ for (int i = 0; i < 16; ++i) {
+
+ if (!map->_map[i]._song)
+ continue;
+
+ songIndex = -1;
+ for (MusicList::iterator iter = _playList.begin(); iter != end; ++iter) {
+ songIndex++;
+ if (map->_map[i]._song == *iter)
+ break;
+ }
+
+
+ for (int j = 0; j < 16; ++j) {
+ if (map->_map[i] == currentMap[j]) {
+ // found it
+ _channelMap[j] = map->_map[i];
+ map->_map[i]._song = 0; // mark as done
+#ifdef DEBUG_REMAP
+ debug(" Keeping song %d, channel %d on device channel %d", songIndex, _channelMap[j]._channel, j);
+#endif
+ break;
+ }
+ }
+ }
+
+ // Then, remap the rest.
+ for (int i = 0; i < 16; ++i) {
+
+ if (!map->_map[i]._song || !map->_map[i]._song->pMidiParser)
+ continue;
+
+ songIndex = -1;
+ for (MusicList::iterator iter = _playList.begin(); iter != end; ++iter) {
+ songIndex++;
+ if (map->_map[i]._song == *iter)
+ break;
+ }
+
+ for (int j = _driverLastChannel; j >= _driverFirstChannel; --j) {
+ if (_channelMap[j]._song == 0) {
+ _channelMap[j] = map->_map[i];
+ map->_map[i]._song = 0;
+#ifdef DEBUG_REMAP
+ debug(" Mapping song %d, channel %d to device channel %d", songIndex, _channelMap[j]._channel, j);
+#endif
+ _channelMap[j]._song->pMidiParser->mainThreadBegin();
+ _channelMap[j]._song->pMidiParser->remapChannel(_channelMap[j]._channel, j);
+ _channelMap[j]._song->pMidiParser->mainThreadEnd();
+ break;
+ }
+ }
+
+ }
+
+ // And finally, stop any empty channels
+ for (int i = _driverFirstChannel; i <= _driverLastChannel; ++i) {
+ if (!_channelMap[i]._song)
+ resetDeviceChannel(i);
+ }
+
+ delete map;
+}
+
+
+ChannelRemapping *SciMusic::determineChannelMap() {
+#ifdef DEBUG_REMAP
+ debug("Remap: avail chans: %d-%d", _driverFirstChannel, _driverLastChannel);
+#endif
+
+ ChannelRemapping *map = new ChannelRemapping;
+ ChannelRemapping backupMap;
+ map->clear();
+ map->_freeVoices = _pMidiDrv->getPolyphony();
+
+ if (_playList.empty())
+ return map;
+
+ // TODO: set reverb, either from first song, or from global???
+
+ MusicList::iterator songIter;
+ int songIndex = -1;
+ for (songIter = _playList.begin(); songIter != _playList.end(); ++songIter) {
+ songIndex++;
+ MusicEntry *song = *songIter;
+ if (song->status != kSoundPlaying)
+ continue;
+
+ // If song is digital, skip.
+ // CHECKME: Is this condition correct?
+ if (!song->pMidiParser) {
+#ifdef DEBUG_REMAP
+ debug(" Song %d (%p), digital?", songIndex, (void*)song);
+#endif
+ continue;
+ }
+
+
+#ifdef DEBUG_REMAP
+ debug(" Song %d (%p), prio %d", songIndex, (void*)song, song->priority);
+#endif
+
+ // Store backup. If we fail to map this song, we will revert to this.
+ backupMap = *map;
+
+ bool songMapped = true;
+
+ for (int i = 0; i < 16; ++i) {
+ int c = song->_usedChannels[i];
+ if (c == 0xFF || c == 0xFE || c == 0x0F)
+ continue;
+ const MusicEntryChannel &channel = song->_chan[c];
+ if (channel._dontMap)
+ continue;
+ if (channel._mute)
+ continue;
+
+#ifdef DEBUG_REMAP
+ debug(" Channel %d: prio %d, %d voice%s%s", c, channel._prio, channel._voices, channel._voices == 1 ? "" : "s", channel._dontRemap ? ", dontRemap" : "" );
+#endif
+
+ DeviceChannelUsage dc = { song, c };
+
+ // our target
+ int devChannel = -1;
+
+ if (channel._dontRemap && map->_map[c]._song == 0) {
+ // unremappable channel, with channel still free
+ devChannel = c;
+ }
+
+ // try to find a free channel
+ if (devChannel == -1) {
+ for (int j = 0; j < 16; ++j) {
+ if (map->_map[j] == dc) {
+ // already mapped?! (Can this happen?)
+ devChannel = j;
+ break;
+ }
+ if (map->_map[j]._song)
+ continue;
+
+ if (j >= _driverFirstChannel && j <= _driverLastChannel)
+ devChannel = j;
+ }
+ }
+
+ int prio = channel._prio;
+ if (prio > 0) {
+ // prio > 0 means non-essential
+ prio = (16 - prio) + 16*songIndex;
+ }
+
+ if (devChannel == -1 && prio > 0) {
+ // no empty channel, but this isn't an essential channel,
+ // so we just skip it.
+#ifdef DEBUG_REMAP
+ debug(" skipping non-essential");
+#endif
+ continue;
+ }
+
+ // try to empty a previous channel if this is an essential channel
+ if (devChannel == -1) {
+ devChannel = map->lowestPrio();
+ if (devChannel != -1)
+ map->evict(devChannel);
+ }
+
+ if (devChannel == -1) {
+ // failed to map this song.
+#ifdef DEBUG_REMAP
+ debug(" no free (or lower priority) channel found");
+#endif
+ songMapped = false;
+ break;
+ }
+
+ if (map->_map[devChannel] == dc) {
+ // already mapped?! (Can this happen?)
+ continue;
+ }
+
+ int neededVoices = channel._voices;
+ // do we have enough free voices?
+ // We only care for essential channels
+ if (map->_freeVoices < neededVoices && prio > 0) {
+ do {
+ int j = map->lowestPrio();
+ if (j == -1) {
+#ifdef DEBUG_REMAP
+ debug(" not enough voices; need %d, have %d", neededVoices, map->_freeVoices);
+#endif
+ // failed to free enough voices.
+ songMapped = false;
+ break;
+ }
+#ifdef DEBUG_REMAP
+ debug(" creating room for voices; evict %d", j);
+#endif
+ map->evict(j);
+ } while (map->_freeVoices < neededVoices);
+
+ if (!songMapped) {
+ // failed to map this song.
+ break;
+ }
+ }
+
+ // We have a channel and enough free voices now.
+#ifdef DEBUG_REMAP
+ debug(" trying to map to %d", devChannel);
+#endif
+
+ map->_map[devChannel] = dc;
+ map->_voices[devChannel] = neededVoices;
+ map->_prio[devChannel] = prio;
+ map->_dontRemap[devChannel] = channel._dontRemap;
+ map->_freeVoices -= neededVoices;
+
+ if (!channel._dontRemap || devChannel == c) {
+ // If this channel fits here, we're done.
+#ifdef DEBUG_REMAP
+ debug(" OK");
+#endif
+ continue;
+ }
+
+ // If this channel can't be remapped, we need to move it or fail.
+
+ if (!map->_dontRemap[c]) {
+ // Target channel can be remapped, so just swap
+ map->swap(devChannel, c);
+ continue;
+ }
+#ifdef DEBUG_REMAP
+ debug(" but %d is already dontRemap", c);
+#endif
+
+ if (prio > 0) {
+ // Channel collision, but this channel is non-essential,
+ // so drop it.
+ // TODO: Maybe we should have checked this before making room?
+ map->evict(devChannel);
+ continue;
+ }
+
+ if (map->_prio[c] > 0) {
+ // Channel collision, but the other channel is non-essential,
+ // so we take its place.
+ map->evict(c);
+ map->swap(devChannel, c);
+ continue;
+ }
+
+ // Otherwise, we have two essential channels claiming the same
+ // device channel.
+ songMapped = false;
+ break;
+ }
+
+ if (!songMapped) {
+ // We failed to map this song, so unmap all its channels.
+#ifdef DEBUG_REMAP
+ debug(" Failed song");
+#endif
+ *map = backupMap;
+ }
+ }
+
+ return map;
+}
+
+void SciMusic::resetDeviceChannel(int devChannel) {
+ // NB: This function should only be called from the main thread
+
+ assert(devChannel >= 0 && devChannel <= 0x0F);
+
+ putMidiCommandInQueue(0x0040B0 | devChannel); // sustain off
+ putMidiCommandInQueue(0x007BB0 | devChannel); // notes off
+ putMidiCommandInQueue(0x004BB0 | devChannel); // release voices
+}
+
+
+
} // End of namespace Sci
diff --git a/engines/sci/sound/music.h b/engines/sci/sound/music.h
index 40236c8445..23a072cb26 100644
--- a/engines/sci/sound/music.h
+++ b/engines/sci/sound/music.h
@@ -52,6 +52,17 @@ class SegManager;
typedef Common::Array<uint16> SignalQueue;
+
+struct MusicEntryChannel {
+ // Channel info
+ int8 _prio; // 0 = essential; lower is higher priority
+ int8 _voices;
+ bool _dontRemap;
+ bool _dontMap;
+ bool _mute;
+};
+
+
class MusicEntry : public Common::Serializable {
public:
// Do not get these directly for the sound objects!
@@ -90,6 +101,8 @@ public:
Audio::Mixer::SoundType soundType;
+ int _usedChannels[16];
+ MusicEntryChannel _chan[16];
MidiParser_SCI *pMidiParser;
// this is used for storing signals, when the current signal is not yet
@@ -114,6 +127,27 @@ public:
virtual void saveLoadWithSerializer(Common::Serializer &ser);
};
+struct DeviceChannelUsage {
+ MusicEntry *_song;
+ int _channel;
+ bool operator==(const DeviceChannelUsage& other) const { return _song == other._song && _channel == other._channel; }
+ bool operator!=(const DeviceChannelUsage& other) const { return !(*this == other); }
+};
+
+struct ChannelRemapping {
+ DeviceChannelUsage _map[16];
+ int _prio[16];
+ int _voices[16];
+ bool _dontRemap[16];
+ int _freeVoices;
+
+ void clear();
+ void swap(int i, int j);
+ void evict(int i);
+ ChannelRemapping& operator=(ChannelRemapping& other);
+ int lowestPrio() const;
+};
+
typedef Common::Array<MusicEntry *> MusicList;
typedef Common::Array<uint32> MidiCommandQueue;
@@ -198,9 +232,6 @@ public:
// where a deadlock can occur
Common::Mutex _mutex;
- int16 tryToOwnChannel(MusicEntry *caller, int16 bestChannel);
- void freeChannels(MusicEntry *caller);
-
protected:
void sortPlayList();
@@ -213,6 +244,11 @@ protected:
// If true and a sound has a digital track, the sound from the AdLib track is played
bool _useDigitalSFX;
+ // remapping:
+ void remapChannels();
+ ChannelRemapping *determineChannelMap();
+ void resetDeviceChannel(int devChannel);
+
private:
MusicList _playList;
bool _soundOn;
@@ -221,6 +257,8 @@ private:
int8 _channelRemap[16];
int8 _globalReverb;
+ DeviceChannelUsage _channelMap[16];
+
MidiCommandQueue _queuedCommands;
MusicType _musicType;
diff --git a/engines/sci/sound/soundcmd.cpp b/engines/sci/sound/soundcmd.cpp
index e36c5705ab..aa2a309f4d 100644
--- a/engines/sci/sound/soundcmd.cpp
+++ b/engines/sci/sound/soundcmd.cpp
@@ -508,9 +508,19 @@ void SoundCommandParser::processUpdateCues(reg_t obj) {
// fireworks).
// It is also needed in other games, e.g. LSL6 when talking to the
// receptionist (bug #3192166).
- // CHECKME: At least kq5cd/win and kq6 set signal to 0xFE here, but
- // kq5cd/dos does not set signal at all. Needs more investigation.
- writeSelectorValue(_segMan, obj, SELECTOR(signal), SIGNAL_OFFSET);
+ // TODO: More thorougly check the different SCI version:
+ // * SCI1late sets signal to 0xFE here. (With signal 0xFF
+ // duplicate music plays in LauraBow2CD - bug #6462)
+ // SCI1middle LSL1 1.000.510 does not have the 0xFE;
+ // SCI1late CastleDrBrain demo 1.000.005 does have the 0xFE.
+ // * Other SCI1 games seem to rely on processStopSound to set the signal
+ // * Need to check SCI0 behaviour.
+ uint16 sig;
+ if (getSciVersion() >= SCI_VERSION_1_LATE)
+ sig = 0xFFFE;
+ else
+ sig = SIGNAL_OFFSET;
+ writeSelectorValue(_segMan, obj, SELECTOR(signal), sig);
if (_soundVersion <= SCI_VERSION_0_LATE) {
processStopSound(obj, false);
} else {
diff --git a/engines/scumm/configure.engine b/engines/scumm/configure.engine
new file mode 100644
index 0000000000..e1de788061
--- /dev/null
+++ b/engines/scumm/configure.engine
@@ -0,0 +1,5 @@
+# This file is included from the main "configure" script
+# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps]
+add_engine scumm "SCUMM" yes "scumm_7_8 he" "v0-v6 games"
+add_engine scumm_7_8 "v7 & v8 games" yes
+add_engine he "HE71+ games" yes
diff --git a/engines/scumm/detection.cpp b/engines/scumm/detection.cpp
index 170ca0993c..aa7e60930a 100644
--- a/engines/scumm/detection.cpp
+++ b/engines/scumm/detection.cpp
@@ -1223,8 +1223,8 @@ const char *ScummMetaEngine::getOriginalCopyright() const {
}
namespace Scumm {
- extern bool getSavegameName(Common::InSaveFile *in, Common::String &desc, int heversion);
-}
+bool getSavegameName(Common::InSaveFile *in, Common::String &desc, int heversion);
+} // End of namespace Scumm
int ScummMetaEngine::getMaximumSaveSlot() const { return 99; }
@@ -1262,25 +1262,21 @@ void ScummMetaEngine::removeSaveState(const char *target, int slot) const {
}
SaveStateDescriptor ScummMetaEngine::querySaveMetaInfos(const char *target, int slot) const {
- Common::String filename = ScummEngine::makeSavegameName(target, slot, false);
- Common::InSaveFile *in = g_system->getSavefileManager()->openForLoading(filename);
-
- if (!in)
- return SaveStateDescriptor();
-
Common::String saveDesc;
- Scumm::getSavegameName(in, saveDesc, 0); // FIXME: heversion?!?
- delete in;
+ Graphics::Surface *thumbnail = nullptr;
+ SaveStateMetaInfos infos;
+ memset(&infos, 0, sizeof(infos));
+ SaveStateMetaInfos *infoPtr = &infos;
- // TODO: Cleanup
- Graphics::Surface *thumbnail = ScummEngine::loadThumbnailFromSlot(target, slot);
+ // FIXME: heversion?!?
+ if (!ScummEngine::querySaveMetaInfos(target, slot, 0, saveDesc, thumbnail, infoPtr)) {
+ return SaveStateDescriptor();
+ }
SaveStateDescriptor desc(slot, saveDesc);
desc.setThumbnail(thumbnail);
- SaveStateMetaInfos infos;
- memset(&infos, 0, sizeof(infos));
- if (ScummEngine::loadInfosFromSlot(target, slot, &infos)) {
+ if (infoPtr) {
int day = (infos.date >> 24) & 0xFF;
int month = (infos.date >> 16) & 0xFF;
int year = infos.date & 0xFFFF;
diff --git a/engines/scumm/he/animation_he.cpp b/engines/scumm/he/animation_he.cpp
index d01b456c8b..c736c6a04c 100644
--- a/engines/scumm/he/animation_he.cpp
+++ b/engines/scumm/he/animation_he.cpp
@@ -57,7 +57,7 @@ int MoviePlayer::getImageNum() {
return _wizResNum;
}
-int MoviePlayer::load(const char *filename, int flags, int image) {
+int MoviePlayer::load(const Common::String &filename, int flags, int image) {
if (_video->isVideoLoaded())
_video->close();
@@ -65,13 +65,13 @@ int MoviePlayer::load(const char *filename, int flags, int image) {
_video->setDefaultHighColorFormat(g_system->getScreenFormat());
if (!_video->loadFile(filename)) {
- warning("Failed to load video file %s", filename);
+ warning("Failed to load video file %s", filename.c_str());
return -1;
}
_video->start();
- debug(1, "Playing video %s", filename);
+ debug(1, "Playing video %s", filename.c_str());
if (flags & 2)
_vm->_wiz->createWizEmptyImage(image, 0, 0, _video->getWidth(), _video->getHeight());
diff --git a/engines/scumm/he/animation_he.h b/engines/scumm/he/animation_he.h
index e17c1b9a39..48234b8072 100644
--- a/engines/scumm/he/animation_he.h
+++ b/engines/scumm/he/animation_he.h
@@ -25,8 +25,12 @@
#include "audio/mixer.h"
+namespace Common {
+class String;
+}
+
namespace Video {
- class VideoDecoder;
+class VideoDecoder;
}
namespace Scumm {
@@ -39,7 +43,7 @@ public:
~MoviePlayer();
int getImageNum();
- int load(const char *filename, int flags, int image = 0);
+ int load(const Common::String &filename, int flags, int image = 0);
void copyFrameToBuffer(byte *dst, int dstType, uint x, uint y, uint pitch);
void handleNextFrame();
diff --git a/engines/scumm/he/intern_he.h b/engines/scumm/he/intern_he.h
index a674288775..067f508d2c 100644
--- a/engines/scumm/he/intern_he.h
+++ b/engines/scumm/he/intern_he.h
@@ -81,10 +81,23 @@ protected:
int virtScreenSave(byte *dst, int x1, int y1, int x2, int y2);
void virtScreenLoad(int resIdx, int x1, int y1, int x2, int y2);
- int convertFilePath(byte *dst, int dstSize);
virtual void decodeParseString(int a, int b);
void swapObjects(int object1, int object2);
+ Common::String convertFilePath(const byte *src);
+ Common::String convertSavePath(const byte *src);
+ Common::String convertSavePathOld(const byte *src);
+
+ Common::SeekableReadStream *openFileForReading(const byte *fileName);
+ Common::SeekableReadStream *openSaveFileForReading(const byte *fileName);
+ Common::WriteStream *openSaveFileForWriting(const byte *fileName);
+ Common::WriteStream *openSaveFileForAppending(const byte *fileName);
+ void deleteSaveFile(const byte *fileName);
+ void renameSaveFile(const byte *from, const byte *to);
+
+ Common::SeekableReadStream *openSaveFileForReading(int slot, bool compat, Common::String &fileName);
+ Common::WriteStream *openSaveFileForWriting(int slot, bool compat, Common::String &fileName);
+
/* HE version 60 script opcodes */
void o60_setState();
void o60_roomOps();
diff --git a/engines/scumm/he/logic/football.cpp b/engines/scumm/he/logic/football.cpp
index ea990ca86b..215fdf0179 100644
--- a/engines/scumm/he/logic/football.cpp
+++ b/engines/scumm/he/logic/football.cpp
@@ -449,25 +449,26 @@ int LogicHEfootball2002::initScreenTranslations() {
int LogicHEfootball2002::getPlaybookFiles(int32 *args) {
// Get the pattern and then skip over the directory prefix ("*\" or "*:")
- Common::String pattern = (const char *)_vm->getStringAddress(args[0] & ~0x33539000) + 2;
+ // Also prepend the target name
+ Common::String targetName = _vm->getTargetName();
+ Common::String basePattern = ((const char *)_vm->getStringAddress(args[0] & ~0x33539000) + 2);
+ Common::String pattern = targetName + '-' + basePattern;
// Prepare a buffer to hold the file names
- char buffer[1000];
- buffer[0] = 0;
+ Common::String output;
// Get the list of file names that match the pattern and iterate over it
Common::StringArray fileList = _vm->getSaveFileManager()->listSavefiles(pattern);
- for (uint32 i = 0; i < fileList.size() && strlen(buffer) < 970; i++) {
+ for (uint32 i = 0; i < fileList.size(); i++) {
// Isolate the base part of the filename and concatenate it to our buffer
- Common::String fileName = Common::String(fileList[i].c_str(), fileList[i].size() - (pattern.size() - 1));
- strcat(buffer, fileName.c_str());
- strcat(buffer, ">"); // names separated by '>'
+ Common::String fileName(fileList[i].c_str() + targetName.size() + 1, fileList[i].size() - (basePattern.size() - 1) - (targetName.size() + 1));
+ output += fileName + '>'; // names separated by '>'
}
// Now store the result in an array
- int array = _vm->setupStringArray(strlen(buffer));
- strcpy((char *)_vm->getStringAddress(array), buffer);
+ int array = _vm->setupStringArray(output.size());
+ strcpy((char *)_vm->getStringAddress(array), output.c_str());
// And store the array index in variable 108
writeScummVar(108, array);
diff --git a/engines/scumm/he/script_v100he.cpp b/engines/scumm/he/script_v100he.cpp
index 987f74957c..c26e3f57ea 100644
--- a/engines/scumm/he/script_v100he.cpp
+++ b/engines/scumm/he/script_v100he.cpp
@@ -1642,7 +1642,7 @@ void ScummEngine_v100he::o100_roomOps() {
copyScriptString((byte *)buffer, sizeof(buffer));
- _saveLoadFileName = (char *)buffer + convertFilePath(buffer, sizeof(buffer));
+ _saveLoadFileName = (char *)buffer;
debug(1, "o100_roomOps: case 137: filename %s", _saveLoadFileName.c_str());
_saveLoadFlag = pop();
@@ -2263,11 +2263,10 @@ void ScummEngine_v100he::o100_videoOps() {
if (_videoParams.flags == 0)
_videoParams.flags = 4;
- const char *filename = (char *)_videoParams.filename + convertFilePath(_videoParams.filename, sizeof(_videoParams.filename));
if (_videoParams.flags == 2) {
- VAR(119) = _moviePlay->load(filename, _videoParams.flags, _videoParams.wizResNum);
+ VAR(119) = _moviePlay->load(convertFilePath(_videoParams.filename), _videoParams.flags, _videoParams.wizResNum);
} else {
- VAR(119) = _moviePlay->load(filename, _videoParams.flags);
+ VAR(119) = _moviePlay->load(convertFilePath(_videoParams.filename), _videoParams.flags);
}
} else if (_videoParams.status == 19) {
// Stop video
diff --git a/engines/scumm/he/script_v60he.cpp b/engines/scumm/he/script_v60he.cpp
index bbd8725904..409fb7edf7 100644
--- a/engines/scumm/he/script_v60he.cpp
+++ b/engines/scumm/he/script_v60he.cpp
@@ -90,59 +90,214 @@ void ScummEngine_v60he::setupOpcodes() {
_opcodes[0xed].setProc(0, 0);
}
-int ScummEngine_v60he::convertFilePath(byte *dst, int dstSize) {
- debug(1, "convertFilePath: original filePath is %s", dst);
-
- int len = resStrLen(dst);
-
- // Switch all \ to / for portablity
- for (int i = 0; i < len; i++)
- if (dst[i] == '\\')
- dst[i] = '/';
-
- if (_game.platform == Common::kPlatformMacintosh) {
- // Remove : prefix in HE71 games
- if (dst[0] == ':') {
- len -= 1;
- memmove(dst, dst + 1, len);
- dst[len] = 0;
+Common::String ScummEngine_v60he::convertFilePath(const byte *src) {
+ debug(2, "convertFilePath in: '%s'", (const char *)src);
+
+ int srcSize = resStrLen(src);
+ int start = 0;
+
+ if (srcSize > 2) {
+ if (src[0] == ':') { // Game Data Path (Macintosh)
+ // The default game data path is set to ':' by ScummVM
+ start = 1;
+ } else if (src[0] == '.' && src[1] == '\\') { // Game Data Path (Windows)
+ // The default game data path is set to '.\\' by ScummVM
+ start = 2;
+ } else if (src[0] == '*' && src[1] == '\\') { // Save Game Path (Windows HE72 - HE100)
+ // The default save game path is set to '*\\' by ScummVM
+ start = 2;
+ } else if (src[0] == '*' && src[1] == ':') { // Save Game Path (Macintosh HE72 - HE100)
+ // The default save game path is set to '*:' by ScummVM
+ start = 2;
+ } else if (src[0] == 'c' && src[1] == ':') { // Save Game Path (HE60 - HE71)
+ // The default save path is game path (DOS) or 'c:\\hegames\\' (Windows)
+ for (start = srcSize; start != 0; start--)
+ if (src[start - 1] == '\\')
+ break;
+ } else if (src[0] == 'u' && src[1] == 's') { // Save Game Path (Moonbase Commander)
+ // The default save path is 'user\\'
+ start = 5;
}
+ }
- // Switch all : to / for portablity
- for (int i = 0; i < len; i++) {
- if (dst[i] == ':')
- dst[i] = '/';
- }
+ Common::String dst;
+
+ for (int i = start; i < srcSize; i++) {
+ // Convert path separators
+ if (src[i] == '\\' || src[i] == ':')
+ dst += '/';
+ else
+ dst += src[i];
}
- // Strip path
- int r = 0;
- if (dst[len - 3] == 's' && dst[len - 2] == 'g') { // Save Game File
- // Change filename prefix to target name, for save game files.
- const char c = dst[len - 1];
- snprintf((char *)dst, dstSize, "%s.sg%c", _targetName.c_str(), c);
- } else if (dst[0] == '.' && dst[1] == '/') { // Game Data Path
- // The default game data path is set to './' by ScummVM
- r = 2;
- } else if (dst[0] == '*' && dst[1] == '/') { // Save Game Path (Windows HE72 - HE100)
- // The default save game path is set to '*/' by ScummVM
- r = 2;
- } else if (dst[0] == '*' && dst[1] == ':') { // Save Game Path (Macintosh HE72 - HE100)
- // The default save game path is set to ':/' by ScummVM
- r = 2;
- } else if (dst[0] == 'c' && dst[1] == ':') { // Save Game Path (HE60 - HE71)
- // The default save path is game path (DOS) or 'c:/hegames/' (Windows)
- for (r = len; r != 0; r--) {
- if (dst[r - 1] == '/')
- break;
+ // Sanity check
+ if (dst.lastChar() == '/')
+ dst.deleteLastChar();
+
+ debug(2, "convertFilePath out: '%s'", dst.c_str());
+
+ return dst;
+}
+
+Common::String ScummEngine_v60he::convertSavePath(const byte *src) {
+ debug(2, "convertSavePath in: '%s'", (const char *)src);
+
+ Common::String filePath = convertFilePath(src);
+
+ // Strip us down to only the file
+ for (int32 i = filePath.size() - 1; i >= 0; i--) {
+ if (filePath[i] == '/') {
+ filePath = Common::String(filePath.c_str() + i + 1);
+ break;
}
- } else if (dst[0] == 'u' && dst[1] == 's') { // Save Game Path (Moonbase Commander)
+ }
+
+ // Prepend the target name
+ filePath = _targetName + '-' + filePath;
+
+ debug(2, "convertSavePath out: '%s'", filePath.c_str());
+
+ return filePath;
+}
+
+Common::String ScummEngine_v60he::convertSavePathOld(const byte *src) {
+ // This is provided solely for loading older saved games.
+ // No new saves should go through this function.
+
+ int srcSize = resStrLen(src);
+
+ // Old hacky target name insertion
+ // (This breaks the soccer and football games)
+ if (src[srcSize - 3] == 's' && src[srcSize - 2] == 'g')
+ return _targetName + ".sg" + (char)src[srcSize - 1];
+
+ if (src[0] == 'u' && src[1] == 's') {
+ // Save Game Path (Moonbase Commander)
// The default save path is 'user/'
- r = 5;
+ return (const char *)src + 5;
+ } else if (src[0] == '*' && (src[1] == '\\' || src[1] == ':')) {
+ // Save Game Path (HE72 - HE100)
+ // The default save game path is set to '*\\' by ScummVM for Windows
+ // and '*:' for Macintosh
+ return (const char *)src + 2;
+ } else if (src[0] == 'c' && src[1] == ':') {
+ // The default save path is game path (DOS) or 'c:\\hegames\\' (Windows)
+ for (int i = srcSize; i > 0; i--)
+ if (src[i] == '\\')
+ return (const char *)src + i + 1;
+ }
+
+ // Can't reach here
+ return "";
+}
+
+Common::SeekableReadStream *ScummEngine_v60he::openFileForReading(const byte *fileName) {
+ Common::SeekableReadStream *saveFile = openSaveFileForReading(fileName);
+
+ if (saveFile)
+ return saveFile;
+
+ return SearchMan.createReadStreamForMember(convertFilePath(fileName));
+}
+
+Common::SeekableReadStream *ScummEngine_v60he::openSaveFileForReading(const byte *fileName) {
+ Common::SeekableReadStream *file = _saveFileMan->openForLoading(convertSavePath(fileName));
+
+ if (file)
+ return file;
+
+ return _saveFileMan->openForLoading(convertSavePathOld(fileName));
+}
+
+Common::WriteStream *ScummEngine_v60he::openSaveFileForWriting(const byte *fileName) {
+ return _saveFileMan->openForSaving(convertSavePath(fileName));
+}
+
+void ScummEngine_v60he::deleteSaveFile(const byte *fileName) {
+ Common::String convertedName = convertSavePath(fileName);
+
+ if (!_saveFileMan->listSavefiles(convertedName).empty()) {
+ _saveFileMan->removeSavefile(convertedName);
+ return;
}
- debug(1, "convertFilePath: converted filePath is %s", dst + r);
- return r;
+ convertedName = convertSavePathOld(fileName);
+
+ if (!_saveFileMan->listSavefiles(convertedName).empty())
+ _saveFileMan->removeSavefile(convertedName);
+}
+
+void ScummEngine_v60he::renameSaveFile(const byte *from, const byte *to) {
+ Common::String toName = convertSavePath(to);
+
+ if (_saveFileMan->renameSavefile(convertSavePathOld(from), toName))
+ return;
+
+ _saveFileMan->renameSavefile(convertSavePath(from), toName);
+}
+
+Common::WriteStream *ScummEngine_v60he::openSaveFileForAppending(const byte *fileName) {
+ Common::SeekableReadStream *initialFile = openSaveFileForReading(fileName);
+ byte *initialData = 0;
+ uint32 initialDataSize = 0;
+
+ if (initialFile) {
+ initialDataSize = initialFile->size();
+
+ if (initialDataSize > 0) {
+ initialData = new byte[initialDataSize];
+ initialFile->read(initialData, initialDataSize);
+ }
+
+ delete initialFile;
+ }
+
+ Common::WriteStream *output = openSaveFileForWriting(fileName);
+
+ if (!output) {
+ delete[] initialData;
+ return nullptr;
+ }
+
+ if (initialData) {
+ output->write(initialData, initialDataSize);
+ delete[] initialData;
+ }
+
+ return output;
+}
+
+Common::SeekableReadStream *ScummEngine_v60he::openSaveFileForReading(int slot, bool compat, Common::String &fileName) {
+ if (slot == 255) {
+ // HACK: Allow custom filenames for save game system in HE Games
+ fileName = convertSavePath((const byte *)_saveLoadFileName.c_str());
+
+ Common::SeekableReadStream *stream = _saveFileMan->openForLoading(fileName);
+ if (stream)
+ return stream;
+
+ Common::String oldFileName = convertSavePathOld((const byte *)_saveLoadFileName.c_str());
+ stream = _saveFileMan->openForLoading(oldFileName);
+
+ if (stream) {
+ fileName = oldFileName;
+ return stream;
+ }
+
+ return 0;
+ }
+
+ return ScummEngine::openSaveFileForReading(slot, compat, fileName);
+}
+
+Common::WriteStream *ScummEngine_v60he::openSaveFileForWriting(int slot, bool compat, Common::String &fileName) {
+ if (slot == 255) {
+ // HACK: Allow custom filenames for save game system in HE Games
+ fileName = convertSavePath((const byte *)_saveLoadFileName.c_str());
+ return _saveFileMan->openForSaving(fileName);
+ }
+
+ return ScummEngine::openSaveFileForWriting(slot, compat, fileName);
}
void ScummEngine_v60he::o60_setState() {
@@ -284,7 +439,7 @@ void ScummEngine_v60he::o60_roomOps() {
len = resStrLen(_scriptPointer);
_scriptPointer += len + 1;
- _saveLoadFileName = (char *)buffer + convertFilePath(buffer, sizeof(buffer));
+ _saveLoadFileName = (char *)buffer;
debug(1, "o60_roomOps: case 221: filename %s", _saveLoadFileName.c_str());
_saveLoadFlag = pop();
@@ -692,14 +847,12 @@ void virtScreenSavePackByte(vsPackCtx *ctx, uint8 *&dst, int len, uint8 b) {
void ScummEngine_v60he::o60_openFile() {
int mode, len, slot, i;
byte buffer[100];
- const char *filename;
convertMessageToString(_scriptPointer, buffer, sizeof(buffer));
len = resStrLen(_scriptPointer);
_scriptPointer += len + 1;
- filename = (char *)buffer + convertFilePath(buffer, sizeof(buffer));
- debug(1, "Final filename to %s", filename);
+ debug(1, "Trying to open file '%s'", (char *)buffer);
mode = pop();
slot = -1;
@@ -713,14 +866,10 @@ void ScummEngine_v60he::o60_openFile() {
if (slot != -1) {
switch (mode) {
case 1:
- // TODO / FIXME: Consider using listSavefiles to avoid unneccessary openForLoading calls
- _hInFileTable[slot] = _saveFileMan->openForLoading(filename);
- if (_hInFileTable[slot] == 0) {
- _hInFileTable[slot] = SearchMan.createReadStreamForMember(filename);
- }
+ _hInFileTable[slot] = openFileForReading(buffer);
break;
case 2:
- _hOutFileTable[slot] = _saveFileMan->openForSaving(filename);
+ _hOutFileTable[slot] = openSaveFileForWriting(buffer);
break;
default:
error("o60_openFile(): wrong open file mode %d", mode);
@@ -750,25 +899,19 @@ void ScummEngine_v60he::o60_closeFile() {
void ScummEngine_v60he::o60_deleteFile() {
int len;
byte buffer[100];
- const char *filename;
convertMessageToString(_scriptPointer, buffer, sizeof(buffer));
len = resStrLen(_scriptPointer);
_scriptPointer += len + 1;
- filename = (char *)buffer + convertFilePath(buffer, sizeof(buffer));
-
- debug(1, "o60_deleteFile (\"%s\")", filename);
+ debug(1, "o60_deleteFile (\"%s\")", (char *)buffer);
- if (!_saveFileMan->listSavefiles(filename).empty()) {
- _saveFileMan->removeSavefile(filename);
- }
+ deleteSaveFile(buffer);
}
void ScummEngine_v60he::o60_rename() {
int len;
byte buffer1[100], buffer2[100];
- const char *newFilename, *oldFilename;
convertMessageToString(_scriptPointer, buffer1, sizeof(buffer1));
len = resStrLen(_scriptPointer);
@@ -778,12 +921,9 @@ void ScummEngine_v60he::o60_rename() {
len = resStrLen(_scriptPointer);
_scriptPointer += len + 1;
- oldFilename = (char *)buffer1 + convertFilePath(buffer1, sizeof(buffer1));
- newFilename = (char *)buffer2 + convertFilePath(buffer2, sizeof(buffer2));
-
- debug(1, "o60_rename (\"%s\" to \"%s\")", oldFilename, newFilename);
+ debug(1, "o60_rename (\"%s\" to \"%s\")", (char *)buffer1, (char *)buffer2);
- _saveFileMan->renameSavefile(oldFilename, newFilename);
+ renameSaveFile(buffer1, buffer2);
}
int ScummEngine_v60he::readFileToArray(int slot, int32 size) {
diff --git a/engines/scumm/he/script_v72he.cpp b/engines/scumm/he/script_v72he.cpp
index 42bf9a4bb6..cfa2be7275 100644
--- a/engines/scumm/he/script_v72he.cpp
+++ b/engines/scumm/he/script_v72he.cpp
@@ -710,7 +710,7 @@ void ScummEngine_v72he::o72_roomOps() {
copyScriptString((byte *)buffer, sizeof(buffer));
- _saveLoadFileName = (char *)buffer + convertFilePath(buffer, sizeof(buffer));
+ _saveLoadFileName = (char *)buffer;
debug(1, "o72_roomOps: case 221: filename %s", _saveLoadFileName.c_str());
_saveLoadFlag = pop();
@@ -1390,10 +1390,7 @@ void ScummEngine_v72he::o72_openFile() {
mode = pop();
copyScriptString(buffer, sizeof(buffer));
- debug(1, "Original filename %s", buffer);
-
- const char *filename = (char *)buffer + convertFilePath(buffer, sizeof(buffer));
- debug(1, "Final filename to %s", filename);
+ debug(1, "Trying to open file '%s'", (char *)buffer);
slot = -1;
for (i = 1; i < 17; i++) {
@@ -1406,48 +1403,17 @@ void ScummEngine_v72he::o72_openFile() {
if (slot != -1) {
switch (mode) {
case 1: // Read mode
- if (!_saveFileMan->listSavefiles(filename).empty()) {
- _hInFileTable[slot] = _saveFileMan->openForLoading(filename);
- } else {
- _hInFileTable[slot] = SearchMan.createReadStreamForMember(filename);
- }
+ _hInFileTable[slot] = openFileForReading(buffer);
break;
case 2: // Write mode
- if (!strchr(filename, '/')) {
- _hOutFileTable[slot] = _saveFileMan->openForSaving(filename);
+ if (!strchr((char *)buffer, '/')) {
+ _hOutFileTable[slot] = openSaveFileForWriting(buffer);
}
break;
- case 6: { // Append mode
- if (strchr(filename, '/'))
- break;
-
- // First check if the file already exists
- Common::InSaveFile *initialState = 0;
- if (!_saveFileMan->listSavefiles(filename).empty())
- initialState = _saveFileMan->openForLoading(filename);
- else
- initialState = SearchMan.createReadStreamForMember(filename);
-
- // Read in the data from the initial file
- uint32 initialSize = 0;
- byte *initialData = 0;
- if (initialState) {
- initialSize = initialState->size();
- initialData = new byte[initialSize];
- initialState->read(initialData, initialSize);
- delete initialState;
- }
-
- // Attempt to open a save file
- _hOutFileTable[slot] = _saveFileMan->openForSaving(filename);
-
- // Begin us off with the data from the previous file
- if (_hOutFileTable[slot] && initialData) {
- _hOutFileTable[slot]->write(initialData, initialSize);
- delete[] initialData;
- }
-
- } break;
+ case 6: // Append mode
+ if (!strchr((char *)buffer, '/'))
+ _hOutFileTable[slot] = openSaveFileForAppending(buffer);
+ break;
default:
error("o72_openFile(): wrong open file mode %d", mode);
}
@@ -1565,13 +1531,10 @@ void ScummEngine_v72he::o72_deleteFile() {
byte buffer[256];
copyScriptString(buffer, sizeof(buffer));
- const char *filename = (char *)buffer + convertFilePath(buffer, sizeof(buffer));
- debug(1, "o72_deleteFile(%s)", filename);
+ debug(1, "o72_deleteFile(%s)", (char *)buffer);
- if (!_saveFileMan->listSavefiles(filename).empty()) {
- _saveFileMan->removeSavefile(filename);
- }
+ deleteSaveFile(buffer);
}
void ScummEngine_v72he::o72_rename() {
@@ -1580,12 +1543,9 @@ void ScummEngine_v72he::o72_rename() {
copyScriptString(buffer1, sizeof(buffer1));
copyScriptString(buffer2, sizeof(buffer2));
- const char *newFilename = (char *)buffer1 + convertFilePath(buffer1, sizeof(buffer1));
- const char *oldFilename = (char *)buffer2 + convertFilePath(buffer2, sizeof(buffer2));
-
- _saveFileMan->renameSavefile(oldFilename, newFilename);
+ debug(1, "o72_rename(%s to %s)", (char *)buffer2, (char *)buffer1);
- debug(1, "o72_rename(%s to %s)", oldFilename, newFilename);
+ renameSaveFile(buffer2, buffer1);
}
void ScummEngine_v72he::o72_getPixel() {
diff --git a/engines/scumm/he/script_v80he.cpp b/engines/scumm/he/script_v80he.cpp
index ae43d714ad..7a8f230fc0 100644
--- a/engines/scumm/he/script_v80he.cpp
+++ b/engines/scumm/he/script_v80he.cpp
@@ -89,14 +89,8 @@ void ScummEngine_v80he::o80_getFileSize() {
byte buffer[256];
copyScriptString(buffer, sizeof(buffer));
- const char *filename = (char *)buffer + convertFilePath(buffer, sizeof(buffer));
- Common::SeekableReadStream *f = 0;
- if (!_saveFileMan->listSavefiles(filename).empty()) {
- f = _saveFileMan->openForLoading(filename);
- } else {
- f = SearchMan.createReadStreamForMember(filename);
- }
+ Common::SeekableReadStream *f = openFileForReading(buffer);
if (!f) {
push(-1);
@@ -143,14 +137,12 @@ void ScummEngine_v80he::o80_readConfigFile() {
byte option[128], section[128], filename[256];
byte *data;
Common::String entry;
- int len, r;
+ int len;
copyScriptString(option, sizeof(option));
copyScriptString(section, sizeof(section));
copyScriptString(filename, sizeof(filename));
- r = convertFilePath(filename, sizeof(filename));
-
if (_game.id == GID_TREASUREHUNT) {
// WORKAROUND: Remove invalid characters
if (!strcmp((char *)section, "Blue'sTreasureHunt-Disc1"))
@@ -159,13 +151,13 @@ void ScummEngine_v80he::o80_readConfigFile() {
memcpy(section, "BluesTreasureHunt-Disc2\0", 24);
}
- if (!strcmp((const char *)filename, "map (i)")) {
+ if (!strcmp((const char *)filename, ":map (i)")) {
// Mac resource fork config file
// (as used by only mustard mac for map data?)
Common::MacResManager resFork;
- if (!resFork.open((const char *)filename) || !resFork.hasResFork())
- error("Could not open '%s'", filename);
+ if (!resFork.open("map (i)") || !resFork.hasResFork())
+ error("Could not open 'map (i)'");
Common::String prefResName = Common::String::format("Pref:%s.%s", (const char *)section, (const char *)option);
Common::SeekableReadStream *res = resFork.getResource(prefResName);
@@ -180,13 +172,14 @@ void ScummEngine_v80he::o80_readConfigFile() {
}
} else {
// Normal Windows INI files
- Common::INIFile confFile;
- if (!strcmp((char *)filename + r, "map.ini"))
- confFile.loadFromFile((const char *)filename + r);
- else
- confFile.loadFromSaveFile((const char *)filename + r);
+ Common::SeekableReadStream *stream = openFileForReading(filename);
- confFile.getKey((const char *)option, (const char *)section, entry);
+ if (stream) {
+ Common::INIFile iniFile;
+ iniFile.loadFromStream(*stream);
+ iniFile.getKey((const char *)option, (const char *)section, entry);
+ delete stream;
+ }
}
byte subOp = fetchScriptByte();
@@ -216,7 +209,7 @@ void ScummEngine_v80he::o80_readConfigFile() {
void ScummEngine_v80he::o80_writeConfigFile() {
byte filename[256], section[256], option[256], string[1024];
- int r, value;
+ int value;
byte subOp = fetchScriptByte();
@@ -240,8 +233,6 @@ void ScummEngine_v80he::o80_writeConfigFile() {
error("o80_writeConfigFile: default type %d", subOp);
}
- r = convertFilePath(filename, sizeof(filename));
-
if (_game.id == GID_TREASUREHUNT) {
// WORKAROUND: Remove invalid characters
if (!strcmp((char *)section, "Blue'sTreasureHunt-Disc1"))
@@ -250,10 +241,16 @@ void ScummEngine_v80he::o80_writeConfigFile() {
memcpy(section, "BluesTreasureHunt-Disc2\0", 24);
}
- Common::INIFile ConfFile;
- ConfFile.loadFromSaveFile((const char *)filename + r);
- ConfFile.setKey((char *)option, (char *)section, (char *)string);
- ConfFile.saveToSaveFile((const char *)filename + r);
+ Common::INIFile iniFile;
+ Common::SeekableReadStream *iniStream = openSaveFileForReading(filename);
+
+ if (iniStream) {
+ iniFile.loadFromStream(*iniStream);
+ delete iniStream;
+ }
+
+ iniFile.setKey((char *)option, (char *)section, (char *)string);
+ iniFile.saveToSaveFile(convertSavePath(filename));
debug(1,"o80_writeConfigFile: Filename %s Section %s Option %s String %s", filename, section, option, string);
}
diff --git a/engines/scumm/he/script_v90he.cpp b/engines/scumm/he/script_v90he.cpp
index 1ea9960a18..f844c51cc6 100644
--- a/engines/scumm/he/script_v90he.cpp
+++ b/engines/scumm/he/script_v90he.cpp
@@ -1429,11 +1429,10 @@ void ScummEngine_v90he::o90_videoOps() {
if (_videoParams.flags == 0)
_videoParams.flags = 4;
- const char *filename = (char *)_videoParams.filename + convertFilePath(_videoParams.filename, sizeof(_videoParams.filename));
if (_videoParams.flags & 2) {
- VAR(119) = _moviePlay->load(filename, _videoParams.flags, _videoParams.wizResNum);
+ VAR(119) = _moviePlay->load(convertFilePath(_videoParams.filename), _videoParams.flags, _videoParams.wizResNum);
} else {
- VAR(119) = _moviePlay->load(filename, _videoParams.flags);
+ VAR(119) = _moviePlay->load(convertFilePath(_videoParams.filename), _videoParams.flags);
}
} else if (_videoParams.status == 165) {
// Stop video
diff --git a/engines/scumm/he/wiz_he.cpp b/engines/scumm/he/wiz_he.cpp
index ca360803bd..b3511648bd 100644
--- a/engines/scumm/he/wiz_he.cpp
+++ b/engines/scumm/he/wiz_he.cpp
@@ -2355,8 +2355,6 @@ void Wiz::remapWizImagePal(const WizParameters *params) {
}
void Wiz::processWizImage(const WizParameters *params) {
- byte buffer[260];
-
debug(3, "processWizImage: processMode %d", params->processMode);
switch (params->processMode) {
case 0:
@@ -2370,15 +2368,7 @@ void Wiz::processWizImage(const WizParameters *params) {
break;
case 3:
if (params->processFlags & kWPFUseFile) {
- Common::SeekableReadStream *f = NULL;
- memcpy(buffer, params->filename, 260);
- const char *filename = (char *)buffer + _vm->convertFilePath(buffer, sizeof(buffer));
-
- if (!_vm->_saveFileMan->listSavefiles(filename).empty()) {
- f = _vm->_saveFileMan->openForLoading(filename);
- } else {
- f = SearchMan.createReadStreamForMember(filename);
- }
+ Common::SeekableReadStream *f = _vm->openFileForReading(params->filename);
if (f) {
uint32 id = f->readUint32BE();
@@ -2388,7 +2378,7 @@ void Wiz::processWizImage(const WizParameters *params) {
byte *p = _vm->_res->createResource(rtImage, params->img.resNum, size);
if (f->read(p, size) != size) {
_vm->_res->nukeResource(rtImage, params->img.resNum);
- error("i/o error when reading '%s'", filename);
+ error("i/o error when reading '%s'", params->filename);
_vm->VAR(_vm->VAR_GAME_LOADED) = -2;
_vm->VAR(119) = -2;
} else {
@@ -2404,16 +2394,12 @@ void Wiz::processWizImage(const WizParameters *params) {
} else {
_vm->VAR(_vm->VAR_GAME_LOADED) = -3;
_vm->VAR(119) = -3;
- debug(0, "Unable to open for read '%s'", filename);
+ debug(0, "Unable to open for read '%s'", params->filename);
}
}
break;
case 4:
if (params->processFlags & kWPFUseFile) {
- Common::OutSaveFile *f;
- memcpy(buffer, params->filename, 260);
- const char *filename = (char *)buffer + _vm->convertFilePath(buffer, sizeof(buffer));
-
switch (params->fileWriteMode) {
case 2:
_vm->VAR(119) = -1;
@@ -2421,15 +2407,17 @@ void Wiz::processWizImage(const WizParameters *params) {
case 1:
// TODO Write image to file
break;
- case 0:
- if (!(f = _vm->_saveFileMan->openForSaving(filename))) {
- debug(0, "Unable to open for write '%s'", filename);
+ case 0: {
+ Common::WriteStream *f = _vm->openSaveFileForWriting(params->filename);
+
+ if (!f) {
+ debug(0, "Unable to open for write '%s'", params->filename);
_vm->VAR(119) = -3;
} else {
byte *p = _vm->getResourceAddress(rtImage, params->img.resNum);
uint32 size = READ_BE_UINT32(p + 4);
if (f->write(p, size) != size) {
- error("i/o error when writing '%s'", filename);
+ error("i/o error when writing '%s'", params->filename);
_vm->VAR(119) = -2;
} else {
_vm->VAR(119) = 0;
@@ -2438,6 +2426,7 @@ void Wiz::processWizImage(const WizParameters *params) {
delete f;
}
break;
+ }
default:
error("processWizImage: processMode 4 unhandled fileWriteMode %d", params->fileWriteMode);
}
diff --git a/engines/scumm/imuse_digi/dimuse_sndmgr.cpp b/engines/scumm/imuse_digi/dimuse_sndmgr.cpp
index abd0d68e56..26e248fbca 100644
--- a/engines/scumm/imuse_digi/dimuse_sndmgr.cpp
+++ b/engines/scumm/imuse_digi/dimuse_sndmgr.cpp
@@ -443,11 +443,13 @@ ImuseDigiSndMgr::SoundDesc *ImuseDigiSndMgr::openSound(int32 soundId, const char
} else if (soundName[0] == 0) {
if (sound->bundle->decompressSampleByIndex(soundId, 0, 0x2000, &ptr, 0, header_outside) == 0 || ptr == NULL) {
closeSound(sound);
+ free(ptr);
return NULL;
}
} else {
if (sound->bundle->decompressSampleByName(soundName, 0, 0x2000, &ptr, header_outside) == 0 || ptr == NULL) {
closeSound(sound);
+ free(ptr);
return NULL;
}
}
@@ -667,15 +669,18 @@ int32 ImuseDigiSndMgr::getDataFromRegion(SoundDesc *soundDesc, int region, byte
if (scumm_stricmp(fileName, soundDesc->lastFileName) != 0) {
int32 offs = 0, len = 0;
Common::SeekableReadStream *cmpFile;
+#if defined(USE_FLAC) || defined(USE_VORBIS) || defined(USE_MAD)
uint8 soundMode = 0;
+#endif
sprintf(fileName, "%s_reg%03d.fla", soundDesc->name, region);
cmpFile = soundDesc->bundle->getFile(fileName, offs, len);
if (len) {
#ifndef USE_FLAC
error("FLAC library compiled support needed");
-#endif
+#else
soundMode = 3;
+#endif
}
if (!len) {
sprintf(fileName, "%s_reg%03d.ogg", soundDesc->name, region);
@@ -683,8 +688,9 @@ int32 ImuseDigiSndMgr::getDataFromRegion(SoundDesc *soundDesc, int region, byte
if (len) {
#ifndef USE_VORBIS
error("Vorbis library compiled support needed");
-#endif
+#else
soundMode = 2;
+#endif
}
}
if (!len) {
@@ -693,8 +699,9 @@ int32 ImuseDigiSndMgr::getDataFromRegion(SoundDesc *soundDesc, int region, byte
if (len) {
#ifndef USE_MAD
error("Mad library compiled support needed");
-#endif
+#else
soundMode = 1;
+#endif
}
}
assert(len);
diff --git a/engines/scumm/module.mk b/engines/scumm/module.mk
index a377ad3dc4..d43db1e5f1 100644
--- a/engines/scumm/module.mk
+++ b/engines/scumm/module.mk
@@ -35,23 +35,23 @@ MODULE_OBJS := \
midiparser_ro.o \
object.o \
palette.o \
- player_ad.o \
- player_apple2.o \
- player_mac.o \
- player_mod.o \
- player_nes.o \
- player_pce.o \
- player_sid.o \
- player_towns.o \
- player_v1.o \
- player_v2.o \
- player_v2a.o \
- player_v2base.o \
- player_v2cms.o \
- player_v3a.o \
- player_v3m.o \
- player_v4a.o \
- player_v5m.o \
+ players/player_ad.o \
+ players/player_apple2.o \
+ players/player_mac.o \
+ players/player_mod.o \
+ players/player_nes.o \
+ players/player_pce.o \
+ players/player_sid.o \
+ players/player_towns.o \
+ players/player_v1.o \
+ players/player_v2.o \
+ players/player_v2a.o \
+ players/player_v2base.o \
+ players/player_v2cms.o \
+ players/player_v3a.o \
+ players/player_v3m.o \
+ players/player_v4a.o \
+ players/player_v5m.o \
resource_v2.o \
resource_v3.o \
resource_v4.o \
diff --git a/engines/scumm/player_ad.cpp b/engines/scumm/players/player_ad.cpp
index ed368afbf6..20630e1cb9 100644
--- a/engines/scumm/player_ad.cpp
+++ b/engines/scumm/players/player_ad.cpp
@@ -20,7 +20,7 @@
*
*/
-#include "scumm/player_ad.h"
+#include "scumm/players/player_ad.h"
#include "scumm/imuse/imuse.h"
#include "scumm/scumm.h"
#include "scumm/resource.h"
diff --git a/engines/scumm/player_ad.h b/engines/scumm/players/player_ad.h
index da6c7177ef..fbb65fbe24 100644
--- a/engines/scumm/player_ad.h
+++ b/engines/scumm/players/player_ad.h
@@ -20,8 +20,8 @@
*
*/
-#ifndef SCUMM_PLAYER_AD_H
-#define SCUMM_PLAYER_AD_H
+#ifndef SCUMM_PLAYERS_PLAYER_AD_H
+#define SCUMM_PLAYERS_PLAYER_AD_H
#include "scumm/music.h"
diff --git a/engines/scumm/player_apple2.cpp b/engines/scumm/players/player_apple2.cpp
index 58e4f78a94..87b8100f22 100644
--- a/engines/scumm/player_apple2.cpp
+++ b/engines/scumm/players/player_apple2.cpp
@@ -21,7 +21,7 @@
*/
#include "engines/engine.h"
-#include "scumm/player_apple2.h"
+#include "scumm/players/player_apple2.h"
#include "scumm/scumm.h"
namespace Scumm {
diff --git a/engines/scumm/player_apple2.h b/engines/scumm/players/player_apple2.h
index e1ec9d8946..9930a4f95d 100644
--- a/engines/scumm/player_apple2.h
+++ b/engines/scumm/players/player_apple2.h
@@ -20,8 +20,8 @@
*
*/
-#ifndef SCUMM_PLAYER_APPLEII_H
-#define SCUMM_PLAYER_APPLEII_H
+#ifndef SCUMM_PLAYERS_PLAYER_APPLEII_H
+#define SCUMM_PLAYERS_PLAYER_APPLEII_H
#include "common/mutex.h"
#include "common/scummsys.h"
diff --git a/engines/scumm/player_mac.cpp b/engines/scumm/players/player_mac.cpp
index a60736df5e..281eec5336 100644
--- a/engines/scumm/player_mac.cpp
+++ b/engines/scumm/players/player_mac.cpp
@@ -24,7 +24,7 @@
#include "common/translation.h"
#include "engines/engine.h"
#include "gui/message.h"
-#include "scumm/player_mac.h"
+#include "scumm/players/player_mac.h"
#include "scumm/resource.h"
#include "scumm/scumm.h"
#include "scumm/imuse/imuse.h"
diff --git a/engines/scumm/player_mac.h b/engines/scumm/players/player_mac.h
index 09307b4e57..7f9f42c34e 100644
--- a/engines/scumm/player_mac.h
+++ b/engines/scumm/players/player_mac.h
@@ -20,8 +20,8 @@
*
*/
-#ifndef SCUMM_PLAYER_MAC_H
-#define SCUMM_PLAYER_MAC_H
+#ifndef SCUMM_PLAYERS_PLAYER_MAC_H
+#define SCUMM_PLAYERS_PLAYER_MAC_H
#include "common/scummsys.h"
#include "common/util.h"
diff --git a/engines/scumm/player_mod.cpp b/engines/scumm/players/player_mod.cpp
index 6411f0a17a..abaa8c1fc5 100644
--- a/engines/scumm/player_mod.cpp
+++ b/engines/scumm/players/player_mod.cpp
@@ -21,7 +21,7 @@
*/
-#include "scumm/player_mod.h"
+#include "scumm/players/player_mod.h"
#include "audio/mixer.h"
#include "audio/rate.h"
#include "audio/decoders/raw.h"
diff --git a/engines/scumm/player_mod.h b/engines/scumm/players/player_mod.h
index 619d83541d..d4a5b16fca 100644
--- a/engines/scumm/player_mod.h
+++ b/engines/scumm/players/player_mod.h
@@ -20,8 +20,8 @@
*
*/
-#ifndef SCUMM_PLAYER_MOD_H
-#define SCUMM_PLAYER_MOD_H
+#ifndef SCUMM_PLAYERS_PLAYER_MOD_H
+#define SCUMM_PLAYERS_PLAYER_MOD_H
#include "scumm/scumm.h"
#include "audio/audiostream.h"
diff --git a/engines/scumm/player_nes.cpp b/engines/scumm/players/player_nes.cpp
index a6ffc9ed86..f55f1f9edd 100644
--- a/engines/scumm/player_nes.cpp
+++ b/engines/scumm/players/player_nes.cpp
@@ -23,7 +23,7 @@
#ifndef DISABLE_NES_APU
#include "engines/engine.h"
-#include "scumm/player_nes.h"
+#include "scumm/players/player_nes.h"
#include "scumm/scumm.h"
#include "audio/mixer.h"
diff --git a/engines/scumm/player_nes.h b/engines/scumm/players/player_nes.h
index be1617e0f6..f0b3e79aad 100644
--- a/engines/scumm/player_nes.h
+++ b/engines/scumm/players/player_nes.h
@@ -20,8 +20,8 @@
*
*/
-#ifndef SCUMM_PLAYER_NES_H
-#define SCUMM_PLAYER_NES_H
+#ifndef SCUMM_PLAYERS_PLAYER_NES_H
+#define SCUMM_PLAYERS_PLAYER_NES_H
#include "common/scummsys.h"
#include "scumm/music.h"
diff --git a/engines/scumm/player_pce.cpp b/engines/scumm/players/player_pce.cpp
index 8d886ee008..6d6e2fcde5 100644
--- a/engines/scumm/player_pce.cpp
+++ b/engines/scumm/players/player_pce.cpp
@@ -29,7 +29,7 @@
*/
#include <math.h>
-#include "player_pce.h"
+#include "scumm/players/player_pce.h"
#include "common/endian.h"
// PCE sound engine is only used by Loom, which requires 16bit color support
diff --git a/engines/scumm/player_pce.h b/engines/scumm/players/player_pce.h
index 427fb1ace6..ca2eddf58c 100644
--- a/engines/scumm/player_pce.h
+++ b/engines/scumm/players/player_pce.h
@@ -20,8 +20,8 @@
*
*/
-#ifndef SCUMM_PLAYER_PCE_H
-#define SCUMM_PLAYER_PCE_H
+#ifndef SCUMM_PLAYERS_PLAYER_PCE_H
+#define SCUMM_PLAYERS_PLAYER_PCE_H
#include "common/scummsys.h"
#include "common/mutex.h"
diff --git a/engines/scumm/player_sid.cpp b/engines/scumm/players/player_sid.cpp
index 7a609364e5..1b97ad16d4 100644
--- a/engines/scumm/player_sid.cpp
+++ b/engines/scumm/players/player_sid.cpp
@@ -23,7 +23,7 @@
#ifndef DISABLE_SID
#include "engines/engine.h"
-#include "scumm/player_sid.h"
+#include "scumm/players/player_sid.h"
#include "scumm/scumm.h"
#include "audio/mixer.h"
diff --git a/engines/scumm/player_sid.h b/engines/scumm/players/player_sid.h
index 12e3573575..a48ec793cd 100644
--- a/engines/scumm/player_sid.h
+++ b/engines/scumm/players/player_sid.h
@@ -20,8 +20,8 @@
*
*/
-#ifndef SCUMM_PLAYER_SID_H
-#define SCUMM_PLAYER_SID_H
+#ifndef SCUMM_PLAYERS_PLAYER_SID_H
+#define SCUMM_PLAYERS_PLAYER_SID_H
#include "common/mutex.h"
#include "common/scummsys.h"
diff --git a/engines/scumm/player_towns.cpp b/engines/scumm/players/player_towns.cpp
index 33e3e40e39..acbdbc7fb6 100644
--- a/engines/scumm/player_towns.cpp
+++ b/engines/scumm/players/player_towns.cpp
@@ -22,7 +22,7 @@
#include "scumm/sound.h"
-#include "scumm/player_towns.h"
+#include "scumm/players/player_towns.h"
namespace Scumm {
diff --git a/engines/scumm/player_towns.h b/engines/scumm/players/player_towns.h
index 5c76d7c6c7..2369b7da5f 100644
--- a/engines/scumm/player_towns.h
+++ b/engines/scumm/players/player_towns.h
@@ -20,8 +20,8 @@
*
*/
-#ifndef SCUMM_PLAYER_TOWNS_H
-#define SCUMM_PLAYER_TOWNS_H
+#ifndef SCUMM_PLAYERS_PLAYER_TOWNS_H
+#define SCUMM_PLAYERS_PLAYER_TOWNS_H
#include "scumm/scumm.h"
#include "scumm/imuse/imuse.h"
diff --git a/engines/scumm/player_v1.cpp b/engines/scumm/players/player_v1.cpp
index 8e784e9866..0fa1ee9361 100644
--- a/engines/scumm/player_v1.cpp
+++ b/engines/scumm/players/player_v1.cpp
@@ -22,7 +22,7 @@
#include "engines/engine.h"
-#include "scumm/player_v1.h"
+#include "scumm/players/player_v1.h"
#include "scumm/scumm.h"
namespace Scumm {
diff --git a/engines/scumm/player_v1.h b/engines/scumm/players/player_v1.h
index 9e6063adc9..ccd24c39df 100644
--- a/engines/scumm/player_v1.h
+++ b/engines/scumm/players/player_v1.h
@@ -20,10 +20,10 @@
*
*/
-#ifndef SCUMM_PLAYER_V1_H
-#define SCUMM_PLAYER_V1_H
+#ifndef SCUMM_PLAYERS_PLAYER_V1_H
+#define SCUMM_PLAYERS_PLAYER_V1_H
-#include "scumm/player_v2.h"
+#include "scumm/players/player_v2.h"
namespace Scumm {
diff --git a/engines/scumm/player_v2.cpp b/engines/scumm/players/player_v2.cpp
index 6910f5e0db..2429af2d8c 100644
--- a/engines/scumm/player_v2.cpp
+++ b/engines/scumm/players/player_v2.cpp
@@ -20,7 +20,7 @@
*
*/
-#include "scumm/player_v2.h"
+#include "scumm/players/player_v2.h"
#include "scumm/scumm.h"
namespace Scumm {
diff --git a/engines/scumm/player_v2.h b/engines/scumm/players/player_v2.h
index d932585b8e..33878ff08b 100644
--- a/engines/scumm/player_v2.h
+++ b/engines/scumm/players/player_v2.h
@@ -20,10 +20,10 @@
*
*/
-#ifndef SCUMM_PLAYER_V2_H
-#define SCUMM_PLAYER_V2_H
+#ifndef SCUMM_PLAYERS_PLAYER_V2_H
+#define SCUMM_PLAYERS_PLAYER_V2_H
-#include "scumm/player_v2base.h"
+#include "scumm/players/player_v2base.h"
namespace Scumm {
diff --git a/engines/scumm/player_v2a.cpp b/engines/scumm/players/player_v2a.cpp
index 07fc77b301..aeccb8b7cb 100644
--- a/engines/scumm/player_v2a.cpp
+++ b/engines/scumm/players/player_v2a.cpp
@@ -21,7 +21,7 @@
*/
#include "engines/engine.h"
-#include "scumm/player_v2a.h"
+#include "scumm/players/player_v2a.h"
#include "scumm/scumm.h"
namespace Scumm {
diff --git a/engines/scumm/player_v2a.h b/engines/scumm/players/player_v2a.h
index fe20b43846..12193635f2 100644
--- a/engines/scumm/player_v2a.h
+++ b/engines/scumm/players/player_v2a.h
@@ -20,12 +20,12 @@
*
*/
-#ifndef SCUMM_PLAYER_V2A_H
-#define SCUMM_PLAYER_V2A_H
+#ifndef SCUMM_PLAYERS_PLAYER_V2A_H
+#define SCUMM_PLAYERS_PLAYER_V2A_H
#include "common/scummsys.h"
#include "scumm/music.h"
-#include "scumm/player_mod.h"
+#include "scumm/players/player_mod.h"
class Mixer;
diff --git a/engines/scumm/player_v2base.cpp b/engines/scumm/players/player_v2base.cpp
index 0d3ad4b1b3..75f1518989 100644
--- a/engines/scumm/player_v2base.cpp
+++ b/engines/scumm/players/player_v2base.cpp
@@ -20,7 +20,7 @@
*
*/
-#include "scumm/player_v2base.h"
+#include "scumm/players/player_v2base.h"
#include "scumm/scumm.h"
#define FREQ_HZ 236 // Don't change!
diff --git a/engines/scumm/player_v2base.h b/engines/scumm/players/player_v2base.h
index eb9ed941ca..32bde95ddc 100644
--- a/engines/scumm/player_v2base.h
+++ b/engines/scumm/players/player_v2base.h
@@ -20,8 +20,8 @@
*
*/
-#ifndef SCUMM_PLAYER_V2BASE_H
-#define SCUMM_PLAYER_V2BASE_H
+#ifndef SCUMM_PLAYERS_PLAYER_V2BASE_H
+#define SCUMM_PLAYERS_PLAYER_V2BASE_H
#include "common/scummsys.h"
#include "common/mutex.h"
diff --git a/engines/scumm/player_v2cms.cpp b/engines/scumm/players/player_v2cms.cpp
index c1242e0645..8e903bf9d2 100644
--- a/engines/scumm/player_v2cms.cpp
+++ b/engines/scumm/players/player_v2cms.cpp
@@ -20,7 +20,7 @@
*
*/
-#include "scumm/player_v2cms.h"
+#include "scumm/players/player_v2cms.h"
#include "scumm/scumm.h"
#include "audio/mididrv.h"
#include "audio/mixer.h"
diff --git a/engines/scumm/player_v2cms.h b/engines/scumm/players/player_v2cms.h
index 905c7c141e..fe42720215 100644
--- a/engines/scumm/player_v2cms.h
+++ b/engines/scumm/players/player_v2cms.h
@@ -20,10 +20,10 @@
*
*/
-#ifndef SCUMM_PLAYER_V2CMS_H
-#define SCUMM_PLAYER_V2CMS_H
+#ifndef SCUMM_PLAYERS_PLAYER_V2CMS_H
+#define SCUMM_PLAYERS_PLAYER_V2CMS_H
-#include "scumm/player_v2base.h" // for channel_data
+#include "scumm/players/player_v2base.h" // for channel_data
class CMSEmulator;
diff --git a/engines/scumm/player_v3a.cpp b/engines/scumm/players/player_v3a.cpp
index 472cd1252b..ca0eedc90a 100644
--- a/engines/scumm/player_v3a.cpp
+++ b/engines/scumm/players/player_v3a.cpp
@@ -22,7 +22,7 @@
#include "engines/engine.h"
-#include "scumm/player_v3a.h"
+#include "scumm/players/player_v3a.h"
#include "scumm/scumm.h"
namespace Scumm {
diff --git a/engines/scumm/player_v3a.h b/engines/scumm/players/player_v3a.h
index 9449664e9b..3f84a74e51 100644
--- a/engines/scumm/player_v3a.h
+++ b/engines/scumm/players/player_v3a.h
@@ -20,12 +20,12 @@
*
*/
-#ifndef SCUMM_PLAYER_V3A_H
-#define SCUMM_PLAYER_V3A_H
+#ifndef SCUMM_PLAYERS_PLAYER_V3A_H
+#define SCUMM_PLAYERS_PLAYER_V3A_H
#include "common/scummsys.h"
#include "scumm/music.h"
-#include "scumm/player_mod.h"
+#include "scumm/players/player_mod.h"
class Mixer;
diff --git a/engines/scumm/player_v3m.cpp b/engines/scumm/players/player_v3m.cpp
index bf65ec797f..e30e31aff9 100644
--- a/engines/scumm/player_v3m.cpp
+++ b/engines/scumm/players/player_v3m.cpp
@@ -91,7 +91,7 @@
#include "common/translation.h"
#include "engines/engine.h"
#include "gui/message.h"
-#include "scumm/player_v3m.h"
+#include "scumm/players/player_v3m.h"
#include "scumm/scumm.h"
namespace Scumm {
diff --git a/engines/scumm/player_v3m.h b/engines/scumm/players/player_v3m.h
index 359bab32a9..615d736035 100644
--- a/engines/scumm/player_v3m.h
+++ b/engines/scumm/players/player_v3m.h
@@ -20,14 +20,14 @@
*
*/
-#ifndef SCUMM_PLAYER_V3M_H
-#define SCUMM_PLAYER_V3M_H
+#ifndef SCUMM_PLAYERS_PLAYER_V3M_H
+#define SCUMM_PLAYERS_PLAYER_V3M_H
#include "common/scummsys.h"
#include "common/util.h"
#include "common/mutex.h"
#include "scumm/music.h"
-#include "scumm/player_mac.h"
+#include "scumm/players/player_mac.h"
#include "audio/audiostream.h"
#include "audio/mixer.h"
diff --git a/engines/scumm/player_v4a.cpp b/engines/scumm/players/player_v4a.cpp
index e791736f0e..59f49625c3 100644
--- a/engines/scumm/player_v4a.cpp
+++ b/engines/scumm/players/player_v4a.cpp
@@ -21,7 +21,7 @@
*/
#include "engines/engine.h"
-#include "scumm/player_v4a.h"
+#include "scumm/players/player_v4a.h"
#include "scumm/scumm.h"
#include "common/file.h"
diff --git a/engines/scumm/player_v4a.h b/engines/scumm/players/player_v4a.h
index d01c70f295..c8c7b63ed2 100644
--- a/engines/scumm/player_v4a.h
+++ b/engines/scumm/players/player_v4a.h
@@ -20,8 +20,8 @@
*
*/
-#ifndef SCUMM_PLAYER_V4A_H
-#define SCUMM_PLAYER_V4A_H
+#ifndef SCUMM_PLAYERS_PLAYER_V4A_H
+#define SCUMM_PLAYERS_PLAYER_V4A_H
#include "common/scummsys.h"
#include "common/util.h"
diff --git a/engines/scumm/player_v5m.cpp b/engines/scumm/players/player_v5m.cpp
index 500f3bbc40..77b6d52a3c 100644
--- a/engines/scumm/player_v5m.cpp
+++ b/engines/scumm/players/player_v5m.cpp
@@ -76,7 +76,7 @@
#include "common/translation.h"
#include "engines/engine.h"
#include "gui/message.h"
-#include "scumm/player_v5m.h"
+#include "scumm/players/player_v5m.h"
#include "scumm/scumm.h"
namespace Scumm {
diff --git a/engines/scumm/player_v5m.h b/engines/scumm/players/player_v5m.h
index b2079ee331..e3a457f8af 100644
--- a/engines/scumm/player_v5m.h
+++ b/engines/scumm/players/player_v5m.h
@@ -20,14 +20,14 @@
*
*/
-#ifndef SCUMM_PLAYER_V5M_H
-#define SCUMM_PLAYER_V5M_H
+#ifndef SCUMM_PLAYERS_PLAYER_V5M_H
+#define SCUMM_PLAYERS_PLAYER_V5M_H
#include "common/scummsys.h"
#include "common/util.h"
#include "common/mutex.h"
#include "scumm/music.h"
-#include "scumm/player_mac.h"
+#include "scumm/players/player_mac.h"
#include "audio/audiostream.h"
#include "audio/mixer.h"
diff --git a/engines/scumm/saveload.cpp b/engines/scumm/saveload.cpp
index 3453e53a18..848e288589 100644
--- a/engines/scumm/saveload.cpp
+++ b/engines/scumm/saveload.cpp
@@ -30,7 +30,7 @@
#include "scumm/charset.h"
#include "scumm/imuse_digi/dimuse.h"
#include "scumm/imuse/imuse.h"
-#include "scumm/player_towns.h"
+#include "scumm/players/player_towns.h"
#include "scumm/he/intern_he.h"
#include "scumm/object.h"
#include "scumm/resource.h"
@@ -148,7 +148,17 @@ void ScummEngine::requestLoad(int slot) {
_saveLoadFlag = 2; // 2 for load
}
-static bool saveSaveGameHeader(Common::OutSaveFile *out, SaveGameHeader &hdr) {
+Common::SeekableReadStream *ScummEngine::openSaveFileForReading(int slot, bool compat, Common::String &fileName) {
+ fileName = makeSavegameName(slot, compat);
+ return _saveFileMan->openForLoading(fileName);
+}
+
+Common::WriteStream *ScummEngine::openSaveFileForWriting(int slot, bool compat, Common::String &fileName) {
+ fileName = makeSavegameName(slot, compat);
+ return _saveFileMan->openForSaving(fileName);
+}
+
+static bool saveSaveGameHeader(Common::WriteStream *out, SaveGameHeader &hdr) {
hdr.type = MKTAG('S','C','V','M');
hdr.size = 0;
hdr.ver = CURRENT_VER;
@@ -160,7 +170,7 @@ static bool saveSaveGameHeader(Common::OutSaveFile *out, SaveGameHeader &hdr) {
return true;
}
-bool ScummEngine::saveState(Common::OutSaveFile *out, bool writeHeader) {
+bool ScummEngine::saveState(Common::WriteStream *out, bool writeHeader) {
SaveGameHeader hdr;
if (writeHeader) {
@@ -177,20 +187,13 @@ bool ScummEngine::saveState(Common::OutSaveFile *out, bool writeHeader) {
return true;
}
-bool ScummEngine::saveState(int slot, bool compat) {
+bool ScummEngine::saveState(int slot, bool compat, Common::String &filename) {
bool saveFailed;
- Common::String filename;
- Common::OutSaveFile *out;
pauseEngine(true);
- if (_saveLoadSlot == 255) {
- // Allow custom filenames for save game system in HE Games
- filename = _saveLoadFileName;
- } else {
- filename = makeSavegameName(slot, compat);
- }
- if (!(out = _saveFileMan->openForSaving(filename)))
+ Common::WriteStream *out = openSaveFileForWriting(slot, compat, filename);
+ if (!out)
return false;
saveFailed = false;
@@ -307,18 +310,17 @@ static bool loadSaveGameHeader(Common::SeekableReadStream *in, SaveGameHeader &h
}
bool ScummEngine::loadState(int slot, bool compat) {
+ // Wrapper around the other variant
Common::String filename;
- Common::SeekableReadStream *in;
+ return loadState(slot, compat, filename);
+}
+
+bool ScummEngine::loadState(int slot, bool compat, Common::String &filename) {
SaveGameHeader hdr;
int sb, sh;
- if (_saveLoadSlot == 255) {
- // Allow custom filenames for save game system in HE Games
- filename = _saveLoadFileName;
- } else {
- filename = makeSavegameName(slot, compat);
- }
- if (!(in = _saveFileMan->openForLoading(filename)))
+ Common::SeekableReadStream *in = openSaveFileForReading(slot, compat, filename);
+ if (!in)
return false;
if (!loadSaveGameHeader(in, hdr)) {
@@ -634,100 +636,83 @@ bool ScummEngine::getSavegameName(int slot, Common::String &desc) {
return result;
}
-bool getSavegameName(Common::InSaveFile *in, Common::String &desc, int heversion) {
- SaveGameHeader hdr;
-
+namespace {
+bool loadAndCheckSaveGameHeader(Common::InSaveFile *in, int heversion, SaveGameHeader &hdr, Common::String *error = nullptr) {
if (!loadSaveGameHeader(in, hdr)) {
- desc = "Invalid savegame";
+ if (error) {
+ *error = "Invalid savegame";
+ }
return false;
}
- if (hdr.ver > CURRENT_VER)
+ if (hdr.ver > CURRENT_VER) {
hdr.ver = TO_LE_32(hdr.ver);
+ }
+
if (hdr.ver < VER(7) || hdr.ver > CURRENT_VER) {
- desc = "Invalid version";
+ if (error) {
+ *error = "Invalid version";
+ }
return false;
}
// We (deliberately) broke HE savegame compatibility at some point.
if (hdr.ver < VER(57) && heversion >= 60) {
- desc = "Unsupported version";
+ if (error) {
+ *error = "Unsupported version";
+ }
return false;
}
hdr.name[sizeof(hdr.name) - 1] = 0;
- desc = hdr.name;
return true;
}
+} // End of anonymous namespace
-Graphics::Surface *ScummEngine::loadThumbnailFromSlot(const char *target, int slot) {
- Common::SeekableReadStream *in;
+bool getSavegameName(Common::InSaveFile *in, Common::String &desc, int heversion) {
SaveGameHeader hdr;
- if (slot < 0)
- return 0;
-
- Common::String filename = ScummEngine::makeSavegameName(target, slot, false);
- if (!(in = g_system->getSavefileManager()->openForLoading(filename))) {
- return 0;
- }
-
- if (!loadSaveGameHeader(in, hdr)) {
- delete in;
- return 0;
+ if (!loadAndCheckSaveGameHeader(in, heversion, hdr, &desc)) {
+ return false;
}
- if (hdr.ver > CURRENT_VER)
- hdr.ver = TO_LE_32(hdr.ver);
- if (hdr.ver < VER(52)) {
- delete in;
- return 0;
- }
+ desc = hdr.name;
+ return true;
+}
- Graphics::Surface *thumb = 0;
- if (Graphics::checkThumbnailHeader(*in)) {
- thumb = Graphics::loadThumbnail(*in);
+bool ScummEngine::querySaveMetaInfos(const char *target, int slot, int heversion, Common::String &desc, Graphics::Surface *&thumbnail, SaveStateMetaInfos *&timeInfos) {
+ if (slot < 0) {
+ return false;
}
- delete in;
- return thumb;
-}
-
-bool ScummEngine::loadInfosFromSlot(const char *target, int slot, SaveStateMetaInfos *stuff) {
- Common::SeekableReadStream *in;
SaveGameHeader hdr;
+ const Common::String filename = ScummEngine::makeSavegameName(target, slot, false);
+ Common::ScopedPtr<Common::SeekableReadStream> in(g_system->getSavefileManager()->openForLoading(filename));
- if (slot < 0)
- return 0;
-
- Common::String filename = makeSavegameName(target, slot, false);
- if (!(in = g_system->getSavefileManager()->openForLoading(filename))) {
+ if (!in) {
return false;
}
- if (!loadSaveGameHeader(in, hdr)) {
- delete in;
+ if (!loadAndCheckSaveGameHeader(in.get(), heversion, hdr)) {
return false;
}
- if (hdr.ver > CURRENT_VER)
- hdr.ver = TO_LE_32(hdr.ver);
- if (hdr.ver < VER(56)) {
- delete in;
- return false;
- }
+ desc = hdr.name;
- if (!Graphics::skipThumbnail(*in)) {
- delete in;
- return false;
- }
+ if (hdr.ver > VER(52)) {
+ if (Graphics::checkThumbnailHeader(*in)) {
+ thumbnail = Graphics::loadThumbnail(*in);
+ }
- if (!loadInfos(in, stuff)) {
- delete in;
- return false;
+ if (hdr.ver > VER(57)) {
+ if (!loadInfos(in.get(), timeInfos)) {
+ return false;
+ }
+ } else {
+ timeInfos = nullptr;
+ }
}
- delete in;
return true;
}
@@ -781,7 +766,7 @@ bool ScummEngine::loadInfos(Common::SeekableReadStream *file, SaveStateMetaInfos
return true;
}
-void ScummEngine::saveInfos(Common::WriteStream* file) {
+void ScummEngine::saveInfos(Common::WriteStream *file) {
SaveInfoSection section;
section.type = MKTAG('I','N','F','O');
section.version = INFOSECTION_VERSION;
diff --git a/engines/scumm/script_v5.cpp b/engines/scumm/script_v5.cpp
index 2d4c326b68..3da7000ae9 100644
--- a/engines/scumm/script_v5.cpp
+++ b/engines/scumm/script_v5.cpp
@@ -27,7 +27,7 @@
#include "scumm/scumm_v3.h"
#include "scumm/scumm_v5.h"
#include "scumm/sound.h"
-#include "scumm/player_towns.h"
+#include "scumm/players/player_towns.h"
#include "scumm/util.h"
#include "scumm/verbs.h"
diff --git a/engines/scumm/scumm-md5.h b/engines/scumm/scumm-md5.h
index 979573c5f5..ae80f306af 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 Thu Aug 15 12:47:39 2013
+ This file was generated by the md5table tool on Fri Sep 27 05:44:12 2013
DO NOT EDIT MANUALLY!
*/
@@ -121,6 +121,7 @@ static const MD5Table md5table[] = {
{ "2723fea3dae0cb47768c424b145ae0e7", "tentacle", "Floppy", "Floppy", 7932, Common::EN_ANY, Common::kPlatformDOS },
{ "27b2ef1653089fe5b897d9cc89ce784f", "balloon", "HE 80", "", -1, Common::RU_RUS, Common::kPlatformWindows },
{ "27b3a4224ad63d5b04627595c1c1a025", "zak", "V2", "V2", -1, Common::IT_ITA, Common::kPlatformAmiga },
+ { "288fb75b24389733c29fa107fe8d44e8", "catalog", "HE CUP", "Preview", 10795148, Common::EN_USA, Common::kPlatformUnknown },
{ "28d24a33448fab6795850bc9f159a4a2", "atlantis", "FM-TOWNS", "Demo", 11170, Common::JA_JPN, Common::kPlatformFMTowns },
{ "28ef68ee3ed76d7e2ee8ee13c15fbd5b", "loom", "EGA", "EGA", 5748, Common::EN_ANY, Common::kPlatformDOS },
{ "28f07458f1b6c24e118a1ea056827701", "lost", "HE 99", "", -1, Common::NL_NLD, Common::kPlatformUnknown },
diff --git a/engines/scumm/scumm.cpp b/engines/scumm/scumm.cpp
index d1a3de94b8..39fbae8147 100644
--- a/engines/scumm/scumm.cpp
+++ b/engines/scumm/scumm.cpp
@@ -45,26 +45,26 @@
#include "scumm/imuse_digi/dimuse.h"
#include "scumm/smush/smush_mixer.h"
#include "scumm/smush/smush_player.h"
-#include "scumm/player_towns.h"
+#include "scumm/players/player_towns.h"
#include "scumm/insane/insane.h"
#include "scumm/he/animation_he.h"
#include "scumm/he/intern_he.h"
#include "scumm/he/logic_he.h"
#include "scumm/he/sound_he.h"
#include "scumm/object.h"
-#include "scumm/player_ad.h"
-#include "scumm/player_nes.h"
-#include "scumm/player_sid.h"
-#include "scumm/player_pce.h"
-#include "scumm/player_apple2.h"
-#include "scumm/player_v1.h"
-#include "scumm/player_v2.h"
-#include "scumm/player_v2cms.h"
-#include "scumm/player_v2a.h"
-#include "scumm/player_v3a.h"
-#include "scumm/player_v3m.h"
-#include "scumm/player_v4a.h"
-#include "scumm/player_v5m.h"
+#include "scumm/players/player_ad.h"
+#include "scumm/players/player_nes.h"
+#include "scumm/players/player_sid.h"
+#include "scumm/players/player_pce.h"
+#include "scumm/players/player_apple2.h"
+#include "scumm/players/player_v1.h"
+#include "scumm/players/player_v2.h"
+#include "scumm/players/player_v2cms.h"
+#include "scumm/players/player_v2a.h"
+#include "scumm/players/player_v3a.h"
+#include "scumm/players/player_v3m.h"
+#include "scumm/players/player_v4a.h"
+#include "scumm/players/player_v5m.h"
#include "scumm/resource.h"
#include "scumm/he/resource_he.h"
#include "scumm/scumm_v0.h"
@@ -2307,15 +2307,16 @@ void ScummEngine::scummLoop_handleSaveLoad() {
if (_game.version == 8 && _saveTemporaryState)
VAR(VAR_GAME_LOADED) = 0;
+ Common::String filename;
if (_saveLoadFlag == 1) {
- success = saveState(_saveLoadSlot, _saveTemporaryState);
+ success = saveState(_saveLoadSlot, _saveTemporaryState, filename);
if (!success)
errMsg = _("Failed to save game state to file:\n\n%s");
if (success && _saveTemporaryState && VAR_GAME_LOADED != 0xFF && _game.version <= 7)
VAR(VAR_GAME_LOADED) = 201;
} else {
- success = loadState(_saveLoadSlot, _saveTemporaryState);
+ success = loadState(_saveLoadSlot, _saveTemporaryState, filename);
if (!success)
errMsg = _("Failed to load game state from file:\n\n%s");
@@ -2323,7 +2324,6 @@ void ScummEngine::scummLoop_handleSaveLoad() {
VAR(VAR_GAME_LOADED) = (_game.version == 8) ? 1 : 203;
}
- Common::String filename = makeSavegameName(_saveLoadSlot, _saveTemporaryState);
if (!success) {
displayMessage(0, errMsg, filename.c_str());
} else if (_saveLoadFlag == 1 && _saveLoadSlot != 0 && !_saveTemporaryState) {
diff --git a/engines/scumm/scumm.h b/engines/scumm/scumm.h
index ca05c90936..7d3a01b895 100644
--- a/engines/scumm/scumm.h
+++ b/engines/scumm/scumm.h
@@ -595,14 +595,18 @@ protected:
Common::String _saveLoadFileName;
Common::String _saveLoadDescription;
- bool saveState(Common::OutSaveFile *out, bool writeHeader = true);
- bool saveState(int slot, bool compat);
+ bool saveState(Common::WriteStream *out, bool writeHeader = true);
+ bool saveState(int slot, bool compat, Common::String &fileName);
bool loadState(int slot, bool compat);
+ bool loadState(int slot, bool compat, Common::String &fileName);
virtual void saveOrLoad(Serializer *s);
void saveResource(Serializer *ser, ResType type, ResId idx);
void loadResource(Serializer *ser, ResType type, ResId idx);
void loadResourceOLD(Serializer *ser, ResType type, ResId idx); // "Obsolete"
+ virtual Common::SeekableReadStream *openSaveFileForReading(int slot, bool compat, Common::String &fileName);
+ virtual Common::WriteStream *openSaveFileForWriting(int slot, bool compat, Common::String &fileName);
+
Common::String makeSavegameName(int slot, bool temporary) const {
return makeSavegameName(_targetName, slot, temporary);
}
@@ -618,17 +622,14 @@ public:
void requestSave(int slot, const Common::String &name);
void requestLoad(int slot);
+ Common::String getTargetName() const { return _targetName; }
+
// thumbnail + info stuff
public:
- Graphics::Surface *loadThumbnailFromSlot(int slot) {
- return loadThumbnailFromSlot(_targetName.c_str(), slot);
- }
- static Graphics::Surface *loadThumbnailFromSlot(const char *target, int slot);
-
- static bool loadInfosFromSlot(const char *target, int slot, SaveStateMetaInfos *stuff);
+ static bool querySaveMetaInfos(const char *target, int slot, int heversion, Common::String &desc, Graphics::Surface *&thumbnail, SaveStateMetaInfos *&timeInfos);
protected:
- void saveInfos(Common::WriteStream* file);
+ void saveInfos(Common::WriteStream *file);
static bool loadInfos(Common::SeekableReadStream *file, SaveStateMetaInfos *stuff);
protected:
diff --git a/engines/scumm/sound.cpp b/engines/scumm/sound.cpp
index 5e5e8045b5..071805752b 100644
--- a/engines/scumm/sound.cpp
+++ b/engines/scumm/sound.cpp
@@ -30,7 +30,7 @@
#include "scumm/file.h"
#include "scumm/imuse/imuse.h"
#include "scumm/imuse_digi/dimuse.h"
-#include "scumm/player_towns.h"
+#include "scumm/players/player_towns.h"
#include "scumm/resource.h"
#include "scumm/scumm.h"
#include "scumm/sound.h"
@@ -470,8 +470,10 @@ static int compareMP3OffsetTable(const void *a, const void *b) {
void Sound::startTalkSound(uint32 offset, uint32 b, int mode, Audio::SoundHandle *handle) {
int num = 0, i;
- int size = 0;
int id = -1;
+#if defined(USE_FLAC) || defined(USE_VORBIS) || defined(USE_MAD)
+ int size = 0;
+#endif
Common::ScopedPtr<ScummFile> file;
if (_vm->_game.id == GID_CMI) {
@@ -562,10 +564,14 @@ void Sound::startTalkSound(uint32 offset, uint32 b, int mode, Audio::SoundHandle
num = result->num_tags;
}
offset = result->new_offset;
+#if defined(USE_FLAC) || defined(USE_VORBIS) || defined(USE_MAD)
size = result->compressed_size;
+#endif
} else {
offset += 8;
+#if defined(USE_FLAC) || defined(USE_VORBIS) || defined(USE_MAD)
size = -1;
+#endif
}
file.reset(new ScummFile());
diff --git a/engines/sky/configure.engine b/engines/sky/configure.engine
new file mode 100644
index 0000000000..32b84849cb
--- /dev/null
+++ b/engines/sky/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 sky "Beneath a Steel Sky" yes
diff --git a/engines/sword1/configure.engine b/engines/sword1/configure.engine
new file mode 100644
index 0000000000..0578d176a9
--- /dev/null
+++ b/engines/sword1/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 sword1 "Broken Sword" yes
diff --git a/engines/sword1/music.cpp b/engines/sword1/music.cpp
index c34630aceb..f31faffd5e 100644
--- a/engines/sword1/music.cpp
+++ b/engines/sword1/music.cpp
@@ -110,7 +110,7 @@ bool MusicHandle::play(const Common::String &filename, bool loop) {
return true;
}
-bool MusicHandle::playPSX(uint16 id) {
+bool MusicHandle::playPSX(uint16 id, bool loop) {
stop();
if (!_file.isOpen())
@@ -131,7 +131,7 @@ bool MusicHandle::playPSX(uint16 id) {
// not over file size
if ((size != 0) && (size != 0xffffffff) && ((int32)(offset + size) <= _file.size())) {
_file.seek(offset, SEEK_SET);
- _audioSource = Audio::makeXAStream(_file.readStream(size), 11025);
+ _audioSource = Audio::makeLoopingAudioStream(Audio::makeXAStream(_file.readStream(size), 11025), loop ? 0 : 1);
fadeUp();
} else {
_audioSource = NULL;
@@ -297,7 +297,7 @@ void Music::startMusic(int32 tuneId, int32 loopFlag) {
the mutex before, to have the soundthread playing normally.
As the corresponding _converter is NULL, the handle will be ignored by the playing thread */
if (SwordEngine::isPsx()) {
- if (_handles[newStream].playPSX(tuneId)) {
+ if (_handles[newStream].playPSX(tuneId, loopFlag != 0)) {
_mutex.lock();
_converter[newStream] = Audio::makeRateConverter(_handles[newStream].getRate(), _mixer->getOutputRate(), _handles[newStream].isStereo(), false);
_mutex.unlock();
diff --git a/engines/sword1/music.h b/engines/sword1/music.h
index f1366202d7..4207019c13 100644
--- a/engines/sword1/music.h
+++ b/engines/sword1/music.h
@@ -44,7 +44,7 @@ public:
MusicHandle() : _fading(0), _audioSource(NULL) {}
virtual int readBuffer(int16 *buffer, const int numSamples);
bool play(const Common::String &filename, bool loop);
- bool playPSX(uint16 id);
+ bool playPSX(uint16 id, bool loop);
void stop();
void fadeUp();
void fadeDown();
diff --git a/engines/sword1/screen.cpp b/engines/sword1/screen.cpp
index ae128b8c05..76957e0a70 100644
--- a/engines/sword1/screen.cpp
+++ b/engines/sword1/screen.cpp
@@ -57,6 +57,30 @@ Screen::Screen(OSystem *system, ResMan *pResMan, ObjectMan *pObjMan) {
_psxCache.extPlxCache = NULL;
_oldScrollX = 0;
_oldScrollY = 0;
+
+ _textMan = 0;
+
+ for (int i = 0; i < 4; i++)
+ _layerGrid[i] = 0;
+
+ for (int i = 0; i < 4; i++)
+ _layerBlocks[i] = 0;
+
+ _parallax[0] = 0;
+ _parallax[1] = 0;
+
+ _fullRefresh = 0;
+
+ for (int i = 0; i < MAX_SORT; i++) {
+ _sortList[i].id = 0;
+ _sortList[i].y = 0;
+ }
+ _scrnSizeX = 0;
+ _scrnSizeY = 0;
+ _gridSizeX = 0;
+ _gridSizeY = 0;
+ _fadingDirection = 0;
+ _isBlack = 0;
}
Screen::~Screen() {
diff --git a/engines/sword1/sound.cpp b/engines/sword1/sound.cpp
index 268da74508..643657c71f 100644
--- a/engines/sword1/sound.cpp
+++ b/engines/sword1/sound.cpp
@@ -269,9 +269,8 @@ void Sound::playSample(QueueElement *elem) {
uint8 volume = (volR + volL) / 2;
if (SwordEngine::isPsx()) {
- // We ignore FX_LOOP as XA has its own looping mechanism
uint32 size = READ_LE_UINT32(sampleData);
- Audio::AudioStream *audStream = Audio::makeXAStream(new Common::MemoryReadStream(sampleData + 4, size - 4), 11025);
+ Audio::AudioStream *audStream = Audio::makeLoopingAudioStream(Audio::makeXAStream(new Common::MemoryReadStream(sampleData + 4, size - 4), 11025), (_fxList[elem->id].type == FX_LOOP) ? 0 : 1);
_mixer->playStream(Audio::Mixer::kSFXSoundType, &elem->handle, audStream, elem->id, volume, pan);
} else {
uint32 size = READ_LE_UINT32(sampleData + 0x28);
diff --git a/engines/sword1/sword1.cpp b/engines/sword1/sword1.cpp
index 2d5452778d..5738431dce 100644
--- a/engines/sword1/sword1.cpp
+++ b/engines/sword1/sword1.cpp
@@ -67,6 +67,17 @@ SwordEngine::SwordEngine(OSystem *syst)
SearchMan.addSubDirectoryMatching(gameDataDir, "italian"); // PSX Demo
_console = new SwordConsole(this);
+
+ _mouseState = 0;
+ _resMan = 0;
+ _objectMan = 0;
+ _screen = 0;
+ _mouse = 0;
+ _logic = 0;
+ _sound = 0;
+ _menu = 0;
+ _music = 0;
+ _control = 0;
}
SwordEngine::~SwordEngine() {
diff --git a/engines/sword2/configure.engine b/engines/sword2/configure.engine
new file mode 100644
index 0000000000..7153605433
--- /dev/null
+++ b/engines/sword2/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 sword2 "Broken Sword II" yes
diff --git a/engines/sword25/configure.engine b/engines/sword25/configure.engine
new file mode 100644
index 0000000000..1729bbeb33
--- /dev/null
+++ b/engines/sword25/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 sword25 "Broken Sword 2.5" no "" "" "png zlib 16bit"
diff --git a/engines/sword25/gfx/animation.cpp b/engines/sword25/gfx/animation.cpp
index 1660c393c0..37207c967b 100644
--- a/engines/sword25/gfx/animation.cpp
+++ b/engines/sword25/gfx/animation.cpp
@@ -553,15 +553,15 @@ bool Animation::persist(OutputPersistenceBlock &writer) {
writer.write(_currentFrameTime);
writer.write(_running);
writer.write(_finished);
- writer.write(static_cast<uint>(_direction));
+ writer.write(static_cast<uint32>(_direction));
// Je nach Animationstyp entweder das Template oder die Ressource speichern.
if (_animationResourcePtr) {
- uint marker = 0;
+ uint32 marker = 0;
writer.write(marker);
writer.writeString(_animationResourcePtr->getFileName());
} else if (_animationTemplateHandle) {
- uint marker = 1;
+ uint32 marker = 1;
writer.write(marker);
writer.write(_animationTemplateHandle);
} else {
@@ -574,13 +574,13 @@ bool Animation::persist(OutputPersistenceBlock &writer) {
// The following is only there to for compatibility with older saves
// resp. the original engine.
- writer.write((uint)1);
+ writer.write((uint32)1);
writer.writeString("LuaLoopPointCB");
writer.write(getHandle());
- writer.write((uint)1);
+ writer.write((uint32)1);
writer.writeString("LuaActionCB");
writer.write(getHandle());
- writer.write((uint)1);
+ writer.write((uint32)1);
writer.writeString("LuaDeleteCB");
writer.write(getHandle());
@@ -605,12 +605,12 @@ bool Animation::unpersist(InputPersistenceBlock &reader) {
reader.read(_currentFrameTime);
reader.read(_running);
reader.read(_finished);
- uint direction;
+ uint32 direction;
reader.read(direction);
_direction = static_cast<Direction>(direction);
// Animationstyp einlesen.
- uint marker;
+ uint32 marker;
reader.read(marker);
if (marker == 0) {
Common::String resourceFilename;
@@ -629,9 +629,9 @@ bool Animation::unpersist(InputPersistenceBlock &reader) {
// The following is only there to for compatibility with older saves
// resp. the original engine.
- uint callbackCount;
+ uint32 callbackCount;
Common::String callbackFunctionName;
- uint callbackData;
+ uint32 callbackData;
// loop point callback
reader.read(callbackCount);
diff --git a/engines/sword25/gfx/animation.h b/engines/sword25/gfx/animation.h
index 44255e3b64..ced1995ae9 100644
--- a/engines/sword25/gfx/animation.h
+++ b/engines/sword25/gfx/animation.h
@@ -159,18 +159,18 @@ private:
BACKWARD
};
- int _relX;
- int _relY;
+ int32 _relX;
+ int32 _relY;
float _scaleFactorX;
float _scaleFactorY;
- uint _modulationColor;
- uint _currentFrame;
- int _currentFrameTime;
+ uint32 _modulationColor;
+ uint32 _currentFrame;
+ int32 _currentFrameTime;
bool _running;
bool _finished;
Direction _direction;
AnimationResource *_animationResourcePtr;
- uint _animationTemplateHandle;
+ uint32 _animationTemplateHandle;
bool _framesLocked;
ANIMATION_CALLBACK _loopPointCallback;
diff --git a/engines/sword25/gfx/animationdescription.cpp b/engines/sword25/gfx/animationdescription.cpp
index da0a660df9..164206bbc2 100644
--- a/engines/sword25/gfx/animationdescription.cpp
+++ b/engines/sword25/gfx/animationdescription.cpp
@@ -36,7 +36,7 @@
namespace Sword25 {
bool AnimationDescription::persist(OutputPersistenceBlock &writer) {
- writer.write(static_cast<uint>(_animationType));
+ writer.write(static_cast<uint32>(_animationType));
writer.write(_FPS);
writer.write(_millisPerFrame);
writer.write(_scalingAllowed);
@@ -47,7 +47,7 @@ bool AnimationDescription::persist(OutputPersistenceBlock &writer) {
}
bool AnimationDescription::unpersist(InputPersistenceBlock &reader) {
- uint animationType;
+ uint32 animationType;
reader.read(animationType);
_animationType = static_cast<Animation::ANIMATION_TYPES>(animationType);
reader.read(_FPS);
diff --git a/engines/sword25/gfx/animationdescription.h b/engines/sword25/gfx/animationdescription.h
index 3b11686bb9..009d83dcc7 100644
--- a/engines/sword25/gfx/animationdescription.h
+++ b/engines/sword25/gfx/animationdescription.h
@@ -52,8 +52,8 @@ protected:
public:
struct Frame {
// Die Hotspot-Angabe bezieht sich auf das ungeflippte Bild!!
- int hotspotX;
- int hotspotY;
+ int32 hotspotX;
+ int32 hotspotY;
bool flipV;
bool flipH;
Common::String fileName;
@@ -88,8 +88,8 @@ public:
protected:
Animation::ANIMATION_TYPES _animationType;
- int _FPS;
- int _millisPerFrame;
+ int32 _FPS;
+ int32 _millisPerFrame;
bool _scalingAllowed;
bool _alphaAllowed;
bool _colorModulationAllowed;
diff --git a/engines/sword25/gfx/animationtemplate.cpp b/engines/sword25/gfx/animationtemplate.cpp
index 19924302b9..a1d2bf5d1a 100644
--- a/engines/sword25/gfx/animationtemplate.cpp
+++ b/engines/sword25/gfx/animationtemplate.cpp
@@ -181,7 +181,7 @@ bool AnimationTemplate::persist(OutputPersistenceBlock &writer) {
Result &= AnimationDescription::persist(writer);
// Frameanzahl schreiben.
- writer.write(_frames.size());
+ writer.write((uint32)_frames.size());
// Frames einzeln persistieren.
Common::Array<const Frame>::const_iterator Iter = _frames.begin();
@@ -209,7 +209,7 @@ bool AnimationTemplate::unpersist(InputPersistenceBlock &reader) {
result &= AnimationDescription::unpersist(reader);
// Frameanzahl lesen.
- uint frameCount;
+ uint32 frameCount;
reader.read(frameCount);
// Frames einzeln wieder herstellen.
diff --git a/engines/sword25/gfx/animationtemplateregistry.cpp b/engines/sword25/gfx/animationtemplateregistry.cpp
index 8184b49eba..4cefe24b18 100644
--- a/engines/sword25/gfx/animationtemplateregistry.cpp
+++ b/engines/sword25/gfx/animationtemplateregistry.cpp
@@ -47,7 +47,7 @@ bool AnimationTemplateRegistry::persist(OutputPersistenceBlock &writer) {
writer.write(_nextHandle);
// Anzahl an BS_AnimationTemplates schreiben.
- writer.write(_handle2PtrMap.size());
+ writer.write((uint32)_handle2PtrMap.size());
// Alle BS_AnimationTemplates persistieren.
HANDLE2PTR_MAP::const_iterator iter = _handle2PtrMap.begin();
@@ -77,13 +77,13 @@ bool AnimationTemplateRegistry::unpersist(InputPersistenceBlock &reader) {
delete _handle2PtrMap.begin()->_value;
// Anzahl an BS_AnimationTemplates einlesen.
- uint animationTemplateCount;
+ uint32 animationTemplateCount;
reader.read(animationTemplateCount);
// Alle gespeicherten BS_AnimationTemplates wieder herstellen.
for (uint i = 0; i < animationTemplateCount; ++i) {
// Handle lesen.
- uint handle;
+ uint32 handle;
reader.read(handle);
// BS_AnimationTemplate wieder herstellen.
diff --git a/engines/sword25/gfx/bitmap.h b/engines/sword25/gfx/bitmap.h
index caa1238558..f22c5d7fc9 100644
--- a/engines/sword25/gfx/bitmap.h
+++ b/engines/sword25/gfx/bitmap.h
@@ -176,9 +176,9 @@ protected:
bool _flipV;
float _scaleFactorX;
float _scaleFactorY;
- uint _modulationColor;
- int _originalWidth;
- int _originalHeight;
+ uint32 _modulationColor;
+ int32 _originalWidth;
+ int32 _originalHeight;
};
} // End of namespace Sword25
diff --git a/engines/sword25/gfx/image/art.cpp b/engines/sword25/gfx/image/art.cpp
index 9c4b9fe8bd..e2eeaca33f 100644
--- a/engines/sword25/gfx/image/art.cpp
+++ b/engines/sword25/gfx/image/art.cpp
@@ -424,8 +424,7 @@ static void art_vpath_render_bez(ArtVpath **p_vpath, int *pn, int *pn_max,
x_m, y_m, xb1, yb1, xb2, yb2, x3, y3, flatness);
} else {
// don't subdivide
- art_vpath_add_point(p_vpath, pn, pn_max,
- ART_LINETO, x3, y3);
+ art_vpath_add_point(p_vpath, pn, pn_max, ART_LINETO, x3, y3);
}
}
diff --git a/engines/sword25/gfx/image/renderedimage.cpp b/engines/sword25/gfx/image/renderedimage.cpp
index 346b46f3b4..b359fc6a3e 100644
--- a/engines/sword25/gfx/image/renderedimage.cpp
+++ b/engines/sword25/gfx/image/renderedimage.cpp
@@ -240,14 +240,6 @@ bool RenderedImage::blit(int posX, int posY, int flipping, Common::Rect *pPartRe
int cg = (color >> 8) & 0xff;
int cb = (color >> 0) & 0xff;
- // Compensate for transparency. Since we're coming
- // down to 255 alpha, we just compensate for the colors here
- if (ca != 255) {
- cr = cr * ca >> 8;
- cg = cg * ca >> 8;
- cb = cb * ca >> 8;
- }
-
// Create an encapsulating surface for the data
Graphics::Surface srcImage;
// TODO: Is the data really in the screen format?
@@ -400,52 +392,52 @@ bool RenderedImage::blit(int posX, int posY, int flipping, Common::Rect *pPartRe
} else {
#if defined(SCUMM_LITTLE_ENDIAN)
pix = *(uint32 *)out;
- int outb = (pix >> 0) & 0xff;
- int outg = (pix >> 8) & 0xff;
- int outr = (pix >> 16) & 0xff;
+ int outb = ((pix >> 0) & 0xff) * (255 - a);
+ int outg = ((pix >> 8) & 0xff) * (255 - a);
+ int outr = ((pix >> 16) & 0xff) * (255 - a);
if (cb == 0)
- outb = 0;
+ outb = outb >> 8;
else if (cb != 255)
- outb += ((b - outb) * a * cb) >> 16;
+ outb = ((outb << 8) + b * a * cb) >> 16;
else
- outb += ((b - outb) * a) >> 8;
+ outb = (outb + b * a) >> 8;
if (cg == 0)
- outg = 0;
+ outg = outg >> 8;
else if (cg != 255)
- outg += ((g - outg) * a * cg) >> 16;
+ outg = ((outg << 8) + g * a * cg) >> 16;
else
- outg += ((g - outg) * a) >> 8;
+ outg = (outg + g * a) >> 8;
if (cr == 0)
- outr = 0;
+ outr = outr >> 8;
else if (cr != 255)
- outr += ((r - outr) * a * cr) >> 16;
+ outr = ((outr << 8) + r * a * cr) >> 16;
else
- outr += ((r - outr) * a) >> 8;
+ outr = (outr + r * a) >> 8;
*(uint32 *)out = (255 << 24) | (outr << 16) | (outg << 8) | outb;
out += 4;
#else
*out = 255;
out++;
if (cr == 0)
- *out = 0;
+ *out = (*out * (255-a)) >> 8;
else if (cr != 255)
- *out += ((r - *out) * a * cr) >> 16;
+ *out = (((*out * (255-a)) << 8) + r * a * cr) >> 16;
else
- *out += ((r - *out) * a) >> 8;
+ *out = ((*out * (255-a)) + r * a) >> 8;
out++;
if (cg == 0)
- *out = 0;
+ *out = (*out * (255-a)) >> 8;
else if (cg != 255)
- *out += ((g - *out) * a * cg) >> 16;
+ *out = (((*out * (255-a)) << 8) + g * a * cg) >> 16;
else
- *out += ((g - *out) * a) >> 8;
+ *out = ((*out * (255-a)) + g * a) >> 8;
out++;
if (cb == 0)
- *out = 0;
+ *out = (*out * (255-a)) >> 8;
else if (cb != 255)
- *out += ((b - *out) * a * cb) >> 16;
+ *out = (((*out * (255-a)) << 8) + b * a * cb) >> 16;
else
- *out += ((b - *out) * a) >> 8;
+ *out = ((*out * (255-a)) + b * a) >> 8;
out++;
#endif
}
diff --git a/engines/sword25/gfx/panel.cpp b/engines/sword25/gfx/panel.cpp
index b9bb8b087d..9b7fe82914 100644
--- a/engines/sword25/gfx/panel.cpp
+++ b/engines/sword25/gfx/panel.cpp
@@ -104,7 +104,7 @@ bool Panel::unpersist(InputPersistenceBlock &reader) {
result &= RenderObject::unpersist(reader);
- uint color;
+ uint32 color;
reader.read(color);
setColor(color);
diff --git a/engines/sword25/gfx/panel.h b/engines/sword25/gfx/panel.h
index 74a93247b6..d372b4e0fc 100644
--- a/engines/sword25/gfx/panel.h
+++ b/engines/sword25/gfx/panel.h
@@ -64,7 +64,7 @@ protected:
virtual bool doRender(RectangleList *updateRects);
private:
- uint _color;
+ uint32 _color;
};
} // End of namespace Sword25
diff --git a/engines/sword25/gfx/renderobject.cpp b/engines/sword25/gfx/renderobject.cpp
index 1dd6f4590f..e9e11aae4e 100644
--- a/engines/sword25/gfx/renderobject.cpp
+++ b/engines/sword25/gfx/renderobject.cpp
@@ -219,27 +219,27 @@ Common::Rect RenderObject::calcBoundingBox() const {
return bbox;
}
-void RenderObject::calcAbsolutePos(int &x, int &y, int &z) const {
+void RenderObject::calcAbsolutePos(int32 &x, int32 &y, int32 &z) const {
x = calcAbsoluteX();
y = calcAbsoluteY();
z = calcAbsoluteZ();
}
-int RenderObject::calcAbsoluteX() const {
+int32 RenderObject::calcAbsoluteX() const {
if (_parentPtr.isValid())
return _parentPtr->getAbsoluteX() + _x;
else
return _x;
}
-int RenderObject::calcAbsoluteY() const {
+int32 RenderObject::calcAbsoluteY() const {
if (_parentPtr.isValid())
return _parentPtr->getAbsoluteY() + _y;
else
return _y;
}
-int RenderObject::calcAbsoluteZ() const {
+int32 RenderObject::calcAbsoluteZ() const {
if (_parentPtr.isValid())
return _parentPtr->getAbsoluteZ() + _z;
else
@@ -399,7 +399,7 @@ RenderObjectPtr<Text> RenderObject::addText(const Common::String &font, const Co
bool RenderObject::persist(OutputPersistenceBlock &writer) {
// Typ und Handle werden als erstes gespeichert, damit beim Laden ein Objekt vom richtigen Typ mit dem richtigen Handle erzeugt werden kann.
- writer.write(static_cast<uint>(_type));
+ writer.write(static_cast<uint32>(_type));
writer.write(_handle);
// Restliche Objekteigenschaften speichern.
@@ -413,14 +413,14 @@ bool RenderObject::persist(OutputPersistenceBlock &writer) {
writer.write(_visible);
writer.write(_childChanged);
writer.write(_initSuccess);
- writer.write(_bbox.left);
- writer.write(_bbox.top);
- writer.write(_bbox.right);
- writer.write(_bbox.bottom);
- writer.write(_oldBbox.left);
- writer.write(_oldBbox.top);
- writer.write(_oldBbox.right);
- writer.write(_oldBbox.bottom);
+ writer.write((int32)_bbox.left);
+ writer.write((int32)_bbox.top);
+ writer.write((int32)_bbox.right);
+ writer.write((int32)_bbox.bottom);
+ writer.write((int32)_oldBbox.left);
+ writer.write((int32)_oldBbox.top);
+ writer.write((int32)_oldBbox.right);
+ writer.write((int32)_oldBbox.bottom);
writer.write(_oldX);
writer.write(_oldY);
writer.write(_oldZ);
@@ -455,7 +455,7 @@ bool RenderObject::unpersist(InputPersistenceBlock &reader) {
reader.read(_oldY);
reader.read(_oldZ);
reader.read(_oldVisible);
- uint parentHandle;
+ uint32 parentHandle;
reader.read(parentHandle);
_parentPtr = RenderObjectPtr<RenderObject>(parentHandle);
reader.read(_refreshForced);
@@ -470,7 +470,7 @@ bool RenderObject::persistChildren(OutputPersistenceBlock &writer) {
bool result = true;
// Kinderanzahl speichern.
- writer.write(_children.size());
+ writer.write((uint32)_children.size());
// Rekursiv alle Kinder speichern.
RENDEROBJECT_LIST::iterator it = _children.begin();
@@ -486,13 +486,13 @@ bool RenderObject::unpersistChildren(InputPersistenceBlock &reader) {
bool result = true;
// Kinderanzahl einlesen.
- uint childrenCount;
+ uint32 childrenCount;
reader.read(childrenCount);
if (!reader.isGood())
return false;
// Alle Kinder rekursiv wieder herstellen.
- for (uint i = 0; i < childrenCount; ++i) {
+ for (uint32 i = 0; i < childrenCount; ++i) {
if (!recreatePersistedRenderObject(reader).isValid())
return false;
}
@@ -504,8 +504,8 @@ RenderObjectPtr<RenderObject> RenderObject::recreatePersistedRenderObject(InputP
RenderObjectPtr<RenderObject> result;
// Typ und Handle auslesen.
- uint type;
- uint handle;
+ uint32 type;
+ uint32 handle;
reader.read(type);
reader.read(handle);
if (!reader.isGood())
diff --git a/engines/sword25/gfx/renderobject.h b/engines/sword25/gfx/renderobject.h
index 1116c3284c..7fcd3a87a3 100644
--- a/engines/sword25/gfx/renderobject.h
+++ b/engines/sword25/gfx/renderobject.h
@@ -359,7 +359,7 @@ public:
/**
@brief Gibt das Handle des Objekte zurück.
*/
- uint getHandle() const {
+ uint32 getHandle() const {
return _handle;
}
@@ -388,14 +388,14 @@ protected:
typedef Common::List<RenderObjectPtr<RenderObject> > RENDEROBJECT_LIST;
typedef Common::List<RenderObjectPtr<RenderObject> >::iterator RENDEROBJECT_ITER;
- int _x; ///< Die X-Position des Objektes relativ zum Eltern-Objekt
- int _y; ///< Die Y-Position des Objektes relativ zum Eltern-Objekt
- int _z; ///< Der Z-Wert des Objektes relativ zum Eltern-Objekt
- int _absoluteX; ///< Die absolute X-Position des Objektes
- int _absoluteY; ///< Die absolute Y-Position des Objektes
- int _absoluteZ;
- int _width; ///< Die Breite des Objektes
- int _height; ///< Die Höhe des Objektes
+ int32 _x; ///< Die X-Position des Objektes relativ zum Eltern-Objekt
+ int32 _y; ///< Die Y-Position des Objektes relativ zum Eltern-Objekt
+ int32 _z; ///< Der Z-Wert des Objektes relativ zum Eltern-Objekt
+ int32 _absoluteX; ///< Die absolute X-Position des Objektes
+ int32 _absoluteY; ///< Die absolute Y-Position des Objektes
+ int32 _absoluteZ;
+ int32 _width; ///< Die Breite des Objektes
+ int32 _height; ///< Die Höhe des Objektes
bool _visible; ///< Ist true, wenn das Objekt sichtbar ist
bool _childChanged; ///< Ist true, wenn sich ein Kinderobjekt verändert hat
TYPES _type; ///< Der Objekttyp
@@ -404,14 +404,14 @@ protected:
// Kopien der Variablen, die für die Errechnung des Dirty-Rects und zur Bestimmung der Objektveränderung notwendig sind
Common::Rect _oldBbox;
- int _oldX;
- int _oldY;
- int _oldZ;
+ int32 _oldX;
+ int32 _oldY;
+ int32 _oldZ;
bool _oldVisible;
static int _nextGlobalVersion;
- int _version;
+ int32 _version;
// This should be set to true if the RenderObject is NOT alpha-blended to optimize drawing
bool _isSolid;
@@ -475,7 +475,7 @@ private:
/// Ist true, wenn das Objekt in nächsten Frame neu gezeichnet werden soll
bool _refreshForced;
- uint _handle;
+ uint32 _handle;
/**
@brief Entfernt ein Objekt aus der Kinderliste.
@@ -500,17 +500,17 @@ private:
/**
@brief Berechnet die absolute Position des Objektes.
*/
- void calcAbsolutePos(int &x, int &y, int &z) const;
+ void calcAbsolutePos(int32 &x, int32 &y, int32 &z) const;
/**
@brief Berechnet die absolute Position des Objektes auf der X-Achse.
*/
- int calcAbsoluteX() const;
+ int32 calcAbsoluteX() const;
/**
@brief Berechnet die absolute Position des Objektes.
*/
- int calcAbsoluteY() const;
+ int32 calcAbsoluteY() const;
- int calcAbsoluteZ() const;
+ int32 calcAbsoluteZ() const;
/**
@brief Sortiert alle Kinderobjekte nach ihrem Renderang.
diff --git a/engines/sword25/gfx/renderobjectmanager.cpp b/engines/sword25/gfx/renderobjectmanager.cpp
index 77f944c9e0..bc7dd02636 100644
--- a/engines/sword25/gfx/renderobjectmanager.cpp
+++ b/engines/sword25/gfx/renderobjectmanager.cpp
@@ -103,13 +103,16 @@ bool RenderObjectManager::render() {
_uta->clear();
// Add rectangles of objects which don't exist in this frame any more
- for (RenderObjectQueue::iterator it = _prevQueue->begin(); it != _prevQueue->end(); ++it)
- 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))
- _uta->addRect((*it)._bbox);
+ for (RenderObjectQueue::iterator it = _prevQueue->begin(); it != _prevQueue->end(); ++it) {
+ 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))
+ _uta->addRect((*it)._bbox);
+ }
RectangleList *updateRects = _uta->getRectangles();
Common::Array<int> updateRectsMinZ;
@@ -171,7 +174,7 @@ bool RenderObjectManager::persist(OutputPersistenceBlock &writer) {
writer.write(_frameStarted);
// Referenzen auf die TimedRenderObjects persistieren.
- writer.write(_timedRenderObjects.size());
+ writer.write((uint32)_timedRenderObjects.size());
RenderObjectList::const_iterator iter = _timedRenderObjects.begin();
while (iter != _timedRenderObjects.end()) {
writer.write((*iter)->getHandle());
@@ -200,10 +203,10 @@ bool RenderObjectManager::unpersist(InputPersistenceBlock &reader) {
_timedRenderObjects.resize(0);
// Referenzen auf die TimedRenderObjects wieder herstellen.
- uint timedObjectCount;
+ uint32 timedObjectCount;
reader.read(timedObjectCount);
- for (uint i = 0; i < timedObjectCount; ++i) {
- uint handle;
+ for (uint32 i = 0; i < timedObjectCount; ++i) {
+ uint32 handle;
reader.read(handle);
_timedRenderObjects.push_back(handle);
}
diff --git a/engines/sword25/gfx/text.cpp b/engines/sword25/gfx/text.cpp
index d4aaa90682..8c33fa8d61 100644
--- a/engines/sword25/gfx/text.cpp
+++ b/engines/sword25/gfx/text.cpp
@@ -45,7 +45,7 @@
namespace Sword25 {
namespace {
-const uint AUTO_WRAP_THRESHOLD_DEFAULT = 300;
+const uint32 AUTO_WRAP_THRESHOLD_DEFAULT = 300;
}
Text::Text(RenderObjectPtr<RenderObject> parentPtr) :
@@ -98,8 +98,8 @@ void Text::setText(const Common::String &text) {
}
}
-void Text::setColor(uint modulationColor) {
- uint newModulationColor = (modulationColor & 0x00ffffff) | (_modulationColor & 0xff000000);
+void Text::setColor(uint32 modulationColor) {
+ uint32 newModulationColor = (modulationColor & 0x00ffffff) | (_modulationColor & 0xff000000);
if (newModulationColor != _modulationColor) {
_modulationColor = newModulationColor;
forceRefresh();
@@ -108,7 +108,7 @@ void Text::setColor(uint modulationColor) {
void Text::setAlpha(int alpha) {
assert(alpha >= 0 && alpha < 256);
- uint newModulationColor = (_modulationColor & 0x00ffffff) | alpha << 24;
+ uint32 newModulationColor = (_modulationColor & 0x00ffffff) | alpha << 24;
if (newModulationColor != _modulationColor) {
_modulationColor = newModulationColor;
forceRefresh();
@@ -123,7 +123,7 @@ void Text::setAutoWrap(bool autoWrap) {
}
}
-void Text::setAutoWrapThreshold(uint autoWrapThreshold) {
+void Text::setAutoWrapThreshold(uint32 autoWrapThreshold) {
if (autoWrapThreshold != _autoWrapThreshold) {
_autoWrapThreshold = autoWrapThreshold;
updateFormat();
@@ -351,7 +351,7 @@ bool Text::unpersist(InputPersistenceBlock &reader) {
reader.read(autoWrap);
setAutoWrap(autoWrap);
- uint autoWrapThreshold;
+ uint32 autoWrapThreshold;
reader.read(autoWrapThreshold);
setAutoWrapThreshold(autoWrapThreshold);
diff --git a/engines/sword25/gfx/text.h b/engines/sword25/gfx/text.h
index 94e7a30865..873eb33380 100644
--- a/engines/sword25/gfx/text.h
+++ b/engines/sword25/gfx/text.h
@@ -80,7 +80,7 @@ public:
@remark Dieses Attribut wird mit dem Wert 300 initialisiert.
@remark Eine automatische Formatierung wird nur vorgenommen, wenn diese durch einen Aufruf von SetAutoWrap() aktiviert wurde.
*/
- void setAutoWrapThreshold(uint autoWrapThreshold);
+ void setAutoWrapThreshold(uint32 autoWrapThreshold);
/**
@brief Gibt den dargestellten Text zurück.
@@ -100,7 +100,7 @@ public:
@brief Setzt die Farbe des Textes.
@param Color eine 24-Bit RGB Farbe, die die Farbe des Textes festlegt.
*/
- void setColor(uint modulationColor);
+ void setColor(uint32 modulationColor);
/**
@brief Gibt den Alphawert des Textes zurück.
@@ -128,7 +128,7 @@ public:
/**
@brief Gibt die Längengrenze des Textes in Pixeln zurück, ab der eine automatische Formatierung vorgenommen wird.
*/
- uint getAutoWrapThreshold() const {
+ uint32 getAutoWrapThreshold() const {
return _autoWrapThreshold;
}
@@ -142,11 +142,11 @@ private:
Text(RenderObjectPtr<RenderObject> parentPtr);
Text(InputPersistenceBlock &reader, RenderObjectPtr<RenderObject> parentPtr, uint handle);
- uint _modulationColor;
+ uint32 _modulationColor;
Common::String _font;
Common::String _text;
bool _autoWrap;
- uint _autoWrapThreshold;
+ uint32 _autoWrapThreshold;
struct Line {
Common::Rect bbox;
diff --git a/engines/sword25/input/inputengine.cpp b/engines/sword25/input/inputengine.cpp
index bb9c2c8b40..0d1c449805 100644
--- a/engines/sword25/input/inputengine.cpp
+++ b/engines/sword25/input/inputengine.cpp
@@ -235,13 +235,13 @@ bool InputEngine::persist(OutputPersistenceBlock &writer) {
// Write out the number of command callbacks and their names.
// Note: We do this only for compatibility with older engines resp.
// the original engine.
- writer.write((uint)1);
+ writer.write((uint32)1);
writer.writeString("LuaCommandCB");
// Write out the number of command callbacks and their names.
// Note: We do this only for compatibility with older engines resp.
// the original engine.
- writer.write((uint)1);
+ writer.write((uint32)1);
writer.writeString("LuaCharacterCB");
return true;
@@ -253,7 +253,7 @@ bool InputEngine::unpersist(InputPersistenceBlock &reader) {
// Read number of command callbacks and their names.
// Note: We do this only for compatibility with older engines resp.
// the original engine.
- uint commandCallbackCount;
+ uint32 commandCallbackCount;
reader.read(commandCallbackCount);
assert(commandCallbackCount == 1);
@@ -263,7 +263,7 @@ bool InputEngine::unpersist(InputPersistenceBlock &reader) {
// Read number of character callbacks and their names.
// Note: We do this only for compatibility with older engines resp.
// the original engine.
- uint characterCallbackCount;
+ uint32 characterCallbackCount;
reader.read(characterCallbackCount);
assert(characterCallbackCount == 1);
diff --git a/engines/sword25/kernel/inputpersistenceblock.cpp b/engines/sword25/kernel/inputpersistenceblock.cpp
index 0fe5d88b80..aa3a759756 100644
--- a/engines/sword25/kernel/inputpersistenceblock.cpp
+++ b/engines/sword25/kernel/inputpersistenceblock.cpp
@@ -48,12 +48,12 @@ InputPersistenceBlock::~InputPersistenceBlock() {
}
void InputPersistenceBlock::read(int16 &value) {
- signed int v;
+ int32 v;
read(v);
value = static_cast<int16>(v);
}
-void InputPersistenceBlock::read(signed int &value) {
+void InputPersistenceBlock::read(int32 &value) {
if (checkMarker(SINT_MARKER)) {
value = (int32)READ_LE_UINT32(_iter);
_iter += 4;
@@ -62,7 +62,7 @@ void InputPersistenceBlock::read(signed int &value) {
}
}
-void InputPersistenceBlock::read(uint &value) {
+void InputPersistenceBlock::read(uint32 &value) {
if (checkMarker(UINT_MARKER)) {
value = READ_LE_UINT32(_iter);
_iter += 4;
@@ -96,7 +96,7 @@ void InputPersistenceBlock::readString(Common::String &value) {
value = "";
if (checkMarker(STRING_MARKER)) {
- uint size;
+ uint32 size;
read(size);
if (checkBlockSize(size)) {
@@ -108,7 +108,7 @@ void InputPersistenceBlock::readString(Common::String &value) {
void InputPersistenceBlock::readByteArray(Common::Array<byte> &value) {
if (checkMarker(BLOCK_MARKER)) {
- uint size;
+ uint32 size;
read(size);
if (checkBlockSize(size)) {
diff --git a/engines/sword25/kernel/inputpersistenceblock.h b/engines/sword25/kernel/inputpersistenceblock.h
index 2518d7e32c..02a944ff1b 100644
--- a/engines/sword25/kernel/inputpersistenceblock.h
+++ b/engines/sword25/kernel/inputpersistenceblock.h
@@ -50,8 +50,8 @@ public:
virtual ~InputPersistenceBlock();
void read(int16 &value);
- void read(signed int &value);
- void read(uint &value);
+ void read(int32 &value);
+ void read(uint32 &value);
void read(float &value);
void read(bool &value);
void readString(Common::String &value);
diff --git a/engines/sword25/kernel/objectregistry.h b/engines/sword25/kernel/objectregistry.h
index d9a7c353f7..449b1b60a3 100644
--- a/engines/sword25/kernel/objectregistry.h
+++ b/engines/sword25/kernel/objectregistry.h
@@ -139,12 +139,12 @@ protected:
}
};
- typedef Common::HashMap<uint, T *> HANDLE2PTR_MAP;
- typedef Common::HashMap<T *, uint, ClassPointer_Hash, ClassPointer_EqualTo> PTR2HANDLE_MAP;
+ typedef Common::HashMap<uint32, T *> HANDLE2PTR_MAP;
+ typedef Common::HashMap<T *, uint32, ClassPointer_Hash, ClassPointer_EqualTo> PTR2HANDLE_MAP;
HANDLE2PTR_MAP _handle2PtrMap;
PTR2HANDLE_MAP _ptr2HandleMap;
- uint _nextHandle;
+ uint32 _nextHandle;
T *findPtrByHandle(uint handle) {
// Zum Handle gehörigen Pointer finden.
diff --git a/engines/sword25/kernel/outputpersistenceblock.cpp b/engines/sword25/kernel/outputpersistenceblock.cpp
index e29d956e5f..53fb624767 100644
--- a/engines/sword25/kernel/outputpersistenceblock.cpp
+++ b/engines/sword25/kernel/outputpersistenceblock.cpp
@@ -41,13 +41,13 @@ OutputPersistenceBlock::OutputPersistenceBlock() {
_data.reserve(INITIAL_BUFFER_SIZE);
}
-void OutputPersistenceBlock::write(signed int value) {
+void OutputPersistenceBlock::write(int32 value) {
writeMarker(SINT_MARKER);
value = TO_LE_32(value);
rawWrite(&value, sizeof(value));
}
-void OutputPersistenceBlock::write(uint value) {
+void OutputPersistenceBlock::write(uint32 value) {
writeMarker(UINT_MARKER);
value = TO_LE_32(value);
rawWrite(&value, sizeof(value));
@@ -74,14 +74,14 @@ void OutputPersistenceBlock::write(bool value) {
void OutputPersistenceBlock::writeString(const Common::String &string) {
writeMarker(STRING_MARKER);
- write(string.size());
+ write((uint32)string.size());
rawWrite(string.c_str(), string.size());
}
void OutputPersistenceBlock::writeByteArray(Common::Array<byte> &value) {
writeMarker(BLOCK_MARKER);
- write((uint)value.size());
+ write((uint32)value.size());
rawWrite(&value[0], value.size());
}
diff --git a/engines/sword25/kernel/outputpersistenceblock.h b/engines/sword25/kernel/outputpersistenceblock.h
index 12351d22e2..17f018a106 100644
--- a/engines/sword25/kernel/outputpersistenceblock.h
+++ b/engines/sword25/kernel/outputpersistenceblock.h
@@ -41,8 +41,8 @@ class OutputPersistenceBlock : public PersistenceBlock {
public:
OutputPersistenceBlock();
- void write(signed int value);
- void write(uint value);
+ void write(int32 value);
+ void write(uint32 value);
void write(float value);
void write(bool value);
void writeString(const Common::String &string);
diff --git a/engines/sword25/kernel/persistenceservice.cpp b/engines/sword25/kernel/persistenceservice.cpp
index 27d669caa1..df26da7800 100644
--- a/engines/sword25/kernel/persistenceservice.cpp
+++ b/engines/sword25/kernel/persistenceservice.cpp
@@ -59,7 +59,7 @@ static const int VERSIONNUM = 2;
char gameTarget[MAX_SAVEGAME_SIZE];
void setGameTarget(const char *target) {
- strncpy(gameTarget, target, MAX_SAVEGAME_SIZE);
+ strncpy(gameTarget, target, MAX_SAVEGAME_SIZE - 1);
}
static Common::String generateSavegameFilename(uint slotID) {
diff --git a/engines/sword25/math/polygon.cpp b/engines/sword25/math/polygon.cpp
index 2e7836ff77..99d947df87 100644
--- a/engines/sword25/math/polygon.cpp
+++ b/engines/sword25/math/polygon.cpp
@@ -364,20 +364,20 @@ bool Polygon::isPointInPolygon(const Vertex &point, bool edgesBelongToPolygon) c
bool Polygon::persist(OutputPersistenceBlock &writer) {
writer.write(vertexCount);
for (int i = 0; i < vertexCount; ++i) {
- writer.write(vertices[i].x);
- writer.write(vertices[i].y);
+ writer.write((int32)vertices[i].x);
+ writer.write((int32)vertices[i].y);
}
return true;
}
bool Polygon::unpersist(InputPersistenceBlock &reader) {
- int storedvertexCount;
+ int32 storedvertexCount;
reader.read(storedvertexCount);
Common::Array<Vertex> storedvertices;
for (int i = 0; i < storedvertexCount; ++i) {
- int x, y;
+ int32 x, y;
reader.read(x);
reader.read(y);
storedvertices.push_back(Vertex(x, y));
diff --git a/engines/sword25/math/polygon.h b/engines/sword25/math/polygon.h
index ffdbf14f6b..f81e165621 100644
--- a/engines/sword25/math/polygon.h
+++ b/engines/sword25/math/polygon.h
@@ -169,7 +169,7 @@ public:
//
/// Specifies the number of Vertecies in the Vertecies array.
- int vertexCount;
+ int32 vertexCount;
/// COntains the Vertecies of the polygon
Vertex *vertices;
diff --git a/engines/sword25/math/region.cpp b/engines/sword25/math/region.cpp
index 7681ef6d9f..db888e432a 100644
--- a/engines/sword25/math/region.cpp
+++ b/engines/sword25/math/region.cpp
@@ -67,7 +67,7 @@ uint Region::create(REGION_TYPE type) {
uint Region::create(InputPersistenceBlock &reader, uint handle) {
// Read type
- uint type;
+ uint32 type;
reader.read(type);
// Depending on the type, create a new BS_Region or BS_WalkRegion object
@@ -299,22 +299,22 @@ bool Region::isLineOfSight(const Vertex &a, const Vertex &b) const {
bool Region::persist(OutputPersistenceBlock &writer) {
bool Result = true;
- writer.write(static_cast<uint>(_type));
+ writer.write(static_cast<uint32>(_type));
writer.write(_valid);
- writer.write(_position.x);
- writer.write(_position.y);
+ writer.write((int32)_position.x);
+ writer.write((int32)_position.y);
- writer.write(_polygons.size());
+ writer.write((uint32)_polygons.size());
Common::Array<Polygon>::iterator It = _polygons.begin();
while (It != _polygons.end()) {
Result &= It->persist(writer);
++It;
}
- writer.write(_boundingBox.left);
- writer.write(_boundingBox.top);
- writer.write(_boundingBox.right);
- writer.write(_boundingBox.bottom);
+ writer.write((int32)_boundingBox.left);
+ writer.write((int32)_boundingBox.top);
+ writer.write((int32)_boundingBox.right);
+ writer.write((int32)_boundingBox.bottom);
return Result;
}
@@ -325,7 +325,7 @@ bool Region::unpersist(InputPersistenceBlock &reader) {
reader.read(_position.y);
_polygons.clear();
- uint PolygonCount;
+ uint32 PolygonCount;
reader.read(PolygonCount);
for (uint i = 0; i < PolygonCount; ++i) {
_polygons.push_back(Polygon(reader));
diff --git a/engines/sword25/math/regionregistry.cpp b/engines/sword25/math/regionregistry.cpp
index 68c360a5ee..e4925f7baf 100644
--- a/engines/sword25/math/regionregistry.cpp
+++ b/engines/sword25/math/regionregistry.cpp
@@ -47,7 +47,7 @@ bool RegionRegistry::persist(OutputPersistenceBlock &writer) {
writer.write(_nextHandle);
// Number of regions to write
- writer.write(_handle2PtrMap.size());
+ writer.write((uint32)_handle2PtrMap.size());
// Persist all the BS_Regions
HANDLE2PTR_MAP::const_iterator iter = _handle2PtrMap.begin();
@@ -76,13 +76,13 @@ bool RegionRegistry::unpersist(InputPersistenceBlock &reader) {
delete _handle2PtrMap.begin()->_value;
// read in the number of BS_Regions
- uint regionCount;
+ uint32 regionCount;
reader.read(regionCount);
// Restore all the BS_Regions objects
for (uint i = 0; i < regionCount; ++i) {
// Handle read
- uint handle;
+ uint32 handle;
reader.read(handle);
// BS_Region restore
diff --git a/engines/sword25/math/walkregion.cpp b/engines/sword25/math/walkregion.cpp
index bace4d54bc..0ba7e8ec3d 100644
--- a/engines/sword25/math/walkregion.cpp
+++ b/engines/sword25/math/walkregion.cpp
@@ -328,22 +328,22 @@ bool WalkRegion::persist(OutputPersistenceBlock &writer) {
result &= Region::persist(writer);
// Persist the nodes
- writer.write(_nodes.size());
+ writer.write((uint32)_nodes.size());
Common::Array<Vertex>::const_iterator it = _nodes.begin();
while (it != _nodes.end()) {
- writer.write(it->x);
- writer.write(it->y);
+ writer.write((int32)it->x);
+ writer.write((int32)it->y);
++it;
}
// Persist the visibility matrix
- writer.write(_visibilityMatrix.size());
+ writer.write((uint32)_visibilityMatrix.size());
Common::Array< Common::Array<int> >::const_iterator rowIter = _visibilityMatrix.begin();
while (rowIter != _visibilityMatrix.end()) {
- writer.write(rowIter->size());
+ writer.write((uint32)rowIter->size());
Common::Array<int>::const_iterator colIter = rowIter->begin();
while (colIter != rowIter->end()) {
- writer.write(*colIter);
+ writer.write((int32)*colIter);
++colIter;
}
@@ -360,7 +360,7 @@ bool WalkRegion::unpersist(InputPersistenceBlock &reader) {
// this point only the additional data from BS_WalkRegion needs to be loaded
// Node load
- uint nodeCount;
+ uint32 nodeCount;
reader.read(nodeCount);
_nodes.clear();
_nodes.resize(nodeCount);
@@ -372,18 +372,20 @@ bool WalkRegion::unpersist(InputPersistenceBlock &reader) {
}
// Visibility matrix load
- uint rowCount;
+ uint32 rowCount;
reader.read(rowCount);
_visibilityMatrix.clear();
_visibilityMatrix.resize(rowCount);
Common::Array< Common::Array<int> >::iterator rowIter = _visibilityMatrix.begin();
while (rowIter != _visibilityMatrix.end()) {
- uint colCount;
+ uint32 colCount;
reader.read(colCount);
rowIter->resize(colCount);
Common::Array<int>::iterator colIter = rowIter->begin();
while (colIter != rowIter->end()) {
- reader.read(*colIter);
+ int32 t;
+ reader.read(t);
+ *colIter = t;
++colIter;
}
diff --git a/engines/sword25/sfx/soundengine.cpp b/engines/sword25/sfx/soundengine.cpp
index 61d53c89a7..8ff1b0cf2a 100644
--- a/engines/sword25/sfx/soundengine.cpp
+++ b/engines/sword25/sfx/soundengine.cpp
@@ -339,7 +339,10 @@ bool SoundEngine::persist(OutputPersistenceBlock &writer) {
_handles[i].type = kFreeHandle;
writer.writeString(_handles[i].fileName);
- writer.write((int)_handles[i].sndType);
+ if (_handles[i].type == kFreeHandle)
+ writer.write((int32)-1);
+ else
+ writer.write(_handles[i].sndType);
writer.write(_handles[i].volume);
writer.write(_handles[i].pan);
writer.write(_handles[i].loop);
@@ -363,13 +366,13 @@ bool SoundEngine::unpersist(InputPersistenceBlock &reader) {
reader.read(_handles[i].id);
Common::String fileName;
- int sndType;
+ int32 sndType;
float volume;
float pan;
bool loop;
- int loopStart;
- int loopEnd;
- uint layer;
+ int32 loopStart;
+ int32 loopEnd;
+ uint32 layer;
reader.readString(fileName);
reader.read(sndType);
@@ -381,7 +384,7 @@ bool SoundEngine::unpersist(InputPersistenceBlock &reader) {
reader.read(layer);
if (reader.isGood()) {
- if (sndType != kFreeHandle)
+ if (sndType != -1)
playSoundEx(fileName, (SOUND_TYPES)sndType, volume, pan, loop, loopStart, loopEnd, layer, i);
} else
return false;
diff --git a/engines/sword25/sfx/soundengine.h b/engines/sword25/sfx/soundengine.h
index 8132ec556e..8974ee69e5 100644
--- a/engines/sword25/sfx/soundengine.h
+++ b/engines/sword25/sfx/soundengine.h
@@ -67,13 +67,13 @@ struct SndHandle {
uint32 id;
Common::String fileName;
- int sndType;
+ int32 sndType;
float volume;
float pan;
bool loop;
- int loopStart;
- int loopEnd;
- uint layer;
+ int32 loopStart;
+ int32 loopEnd;
+ uint32 layer;
};
diff --git a/engines/sword25/util/lua/lcode.cpp b/engines/sword25/util/lua/lcode.cpp
index ead780d359..93188b37e2 100644
--- a/engines/sword25/util/lua/lcode.cpp
+++ b/engines/sword25/util/lua/lcode.cpp
@@ -5,8 +5,6 @@
*/
-#include <stdlib.h>
-
#define lcode_c
#define LUA_CORE
diff --git a/engines/sword25/util/lua/ldebug.cpp b/engines/sword25/util/lua/ldebug.cpp
index e89ae9cad5..396c5df18b 100644
--- a/engines/sword25/util/lua/ldebug.cpp
+++ b/engines/sword25/util/lua/ldebug.cpp
@@ -5,11 +5,6 @@
*/
-#include <stdarg.h>
-#include <stddef.h>
-#include <string.h>
-
-
#define ldebug_c
#define LUA_CORE
diff --git a/engines/sword25/util/lua/lfunc.cpp b/engines/sword25/util/lua/lfunc.cpp
index f8fa19e25a..95e616cc7e 100644
--- a/engines/sword25/util/lua/lfunc.cpp
+++ b/engines/sword25/util/lua/lfunc.cpp
@@ -5,8 +5,6 @@
*/
-#include <stddef.h>
-
#define lfunc_c
#define LUA_CORE
diff --git a/engines/sword25/util/lua/lgc.cpp b/engines/sword25/util/lua/lgc.cpp
index 54f7b548dd..53f512280a 100644
--- a/engines/sword25/util/lua/lgc.cpp
+++ b/engines/sword25/util/lua/lgc.cpp
@@ -4,8 +4,6 @@
** See Copyright Notice in lua.h
*/
-#include <string.h>
-
#define lgc_c
#define LUA_CORE
diff --git a/engines/sword25/util/lua/llimits.h b/engines/sword25/util/lua/llimits.h
index 0925231350..ce6dbc980c 100644
--- a/engines/sword25/util/lua/llimits.h
+++ b/engines/sword25/util/lua/llimits.h
@@ -8,9 +8,6 @@
#define llimits_h
-#include <limits.h>
-#include <stddef.h>
-
#include "lua.h"
diff --git a/engines/sword25/util/lua/lmem.cpp b/engines/sword25/util/lua/lmem.cpp
index 004a467dc8..8cd220308c 100644
--- a/engines/sword25/util/lua/lmem.cpp
+++ b/engines/sword25/util/lua/lmem.cpp
@@ -5,8 +5,6 @@
*/
-#include <stddef.h>
-
#define lmem_c
#define LUA_CORE
diff --git a/engines/sword25/util/lua/lopcodes.cpp b/engines/sword25/util/lua/lopcodes.cpp
index 255b2029e9..8b0a3ab330 100644
--- a/engines/sword25/util/lua/lopcodes.cpp
+++ b/engines/sword25/util/lua/lopcodes.cpp
@@ -8,6 +8,7 @@
#define LUA_CORE
+#include "lua.h"
#include "lopcodes.h"
@@ -60,7 +61,7 @@ const char *const luaP_opnames[NUM_OPCODES+1] = {
const lu_byte luaP_opmodes[NUM_OPCODES] = {
/* T A B C mode opcode */
- opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_MOVE */
+ opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_MOVE */
,opmode(0, 1, OpArgK, OpArgN, iABx) /* OP_LOADK */
,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_LOADBOOL */
,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_LOADNIL */
diff --git a/engines/sword25/util/lua/lparser.cpp b/engines/sword25/util/lua/lparser.cpp
index 03ea333315..0c88992e79 100644
--- a/engines/sword25/util/lua/lparser.cpp
+++ b/engines/sword25/util/lua/lparser.cpp
@@ -5,8 +5,6 @@
*/
-#include <string.h>
-
#define lparser_c
#define LUA_CORE
diff --git a/engines/sword25/util/lua/lstate.cpp b/engines/sword25/util/lua/lstate.cpp
index 26bed7bec2..c0ea29de01 100644
--- a/engines/sword25/util/lua/lstate.cpp
+++ b/engines/sword25/util/lua/lstate.cpp
@@ -5,8 +5,6 @@
*/
-#include <stddef.h>
-
#define lstate_c
#define LUA_CORE
diff --git a/engines/sword25/util/lua/lstring.cpp b/engines/sword25/util/lua/lstring.cpp
index 046b87ee1c..5cfc72539a 100644
--- a/engines/sword25/util/lua/lstring.cpp
+++ b/engines/sword25/util/lua/lstring.cpp
@@ -5,8 +5,6 @@
*/
-#include <string.h>
-
#define lstring_c
#define LUA_CORE
diff --git a/engines/sword25/util/lua/lstrlib.cpp b/engines/sword25/util/lua/lstrlib.cpp
index ed68a2fa00..5da45e1fea 100644
--- a/engines/sword25/util/lua/lstrlib.cpp
+++ b/engines/sword25/util/lua/lstrlib.cpp
@@ -7,12 +7,6 @@
#define FORBIDDEN_SYMBOL_EXCEPTION_ctype_h
-#include <ctype.h>
-#include <stddef.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
#define lstrlib_c
#define LUA_LIB
diff --git a/engines/sword25/util/lua/ltablib.cpp b/engines/sword25/util/lua/ltablib.cpp
index 93be9e6077..064c33c005 100644
--- a/engines/sword25/util/lua/ltablib.cpp
+++ b/engines/sword25/util/lua/ltablib.cpp
@@ -5,8 +5,6 @@
*/
-#include <stddef.h>
-
#define ltablib_c
#define LUA_LIB
diff --git a/engines/sword25/util/lua/lua.h b/engines/sword25/util/lua/lua.h
index a3b7573ca5..4f557e462b 100644
--- a/engines/sword25/util/lua/lua.h
+++ b/engines/sword25/util/lua/lua.h
@@ -22,7 +22,7 @@
#define LUA_RELEASE "Lua 5.1.3"
#define LUA_VERSION_NUM 501
#define LUA_COPYRIGHT "Copyright (C) 1994-2008 Lua.org, PUC-Rio"
-#define LUA_AUTHORS "R. Ierusalimschy, L. H. de Figueiredo & W. Celes"
+#define LUA_AUTHORS "R. Ierusalimschy, L. H. de Figueiredo & W. Celes"
/* mark for precompiled code (`<esc>Lua') */
diff --git a/engines/sword25/util/pluto/pluto.cpp b/engines/sword25/util/pluto/pluto.cpp
index b7a8fd3c8b..fb477c1687 100644
--- a/engines/sword25/util/pluto/pluto.cpp
+++ b/engines/sword25/util/pluto/pluto.cpp
@@ -19,7 +19,6 @@
* for Mobile Lua (http://luaos.net/pages/mobile-lua.php)
*/
-#include "config.h"
#include "sword25/util/lua/lua.h"
#include "pluto.h"
diff --git a/engines/teenagent/callbacks.cpp b/engines/teenagent/callbacks.cpp
index 3e6e40a8fa..9fe9e68a76 100644
--- a/engines/teenagent/callbacks.cpp
+++ b/engines/teenagent/callbacks.cpp
@@ -1808,6 +1808,10 @@ bool TeenAgentEngine::processCallback(uint16 addr) {
displayMessage(dsAddr_uninterestingHaystackMsg); // "I don't see anything interesting about this haystack"
break;
+ case 0x6663:
+ displayMessage(dsAddr_uninterestingHaystackMsg); // "I don't see anything interesting about this haystack"
+ break;
+
case 0x666a:
displayMessage(dsAddr_moreComplicatedMsg); // "It's more complicated than that"
break;
@@ -2382,6 +2386,10 @@ bool TeenAgentEngine::processCallback(uint16 addr) {
fnEgoDefaultPosition();
break;
+ case 0x5634:
+ displayMessage(dsAddr_pullObjMsg2); // "I can't reach it"
+ break;
+
case 0x563b:
playSound(5, 10);
setOns(1, 0);
@@ -3322,6 +3330,10 @@ bool TeenAgentEngine::processCallback(uint16 addr) {
fnMansionIntrusionAttempt();
break;
+ case 0x830b:
+ displayMessage(dsAddr_noChainsawFuelMsg); // "There's no fuel in the chainsaw"
+ break;
+
case 0x8312: // hedgehog + plastic apple
dialog->showMark(76, scene);
setLan(1, 0);
diff --git a/engines/teenagent/configure.engine b/engines/teenagent/configure.engine
new file mode 100644
index 0000000000..223a0e884c
--- /dev/null
+++ b/engines/teenagent/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 teenagent "Teen Agent" yes
diff --git a/engines/teenagent/teenagent.h b/engines/teenagent/teenagent.h
index d6a2c0d3c6..3c3bc25e56 100644
--- a/engines/teenagent/teenagent.h
+++ b/engines/teenagent/teenagent.h
@@ -31,6 +31,9 @@
#include "common/rect.h"
#include "common/array.h"
+#include "gui/debugger.h"
+
+#include "teenagent/console.h"
#include "teenagent/dialog.h"
struct ADGameDescription;
@@ -50,7 +53,6 @@ struct UseHotspot;
class Scene;
class MusicPlayer;
class Dialog;
-class Console;
class Resources;
class Inventory;
@@ -84,6 +86,8 @@ public:
virtual bool canSaveGameStateCurrently() { return !_sceneBusy; }
virtual bool hasFeature(EngineFeature f) const;
+ GUI::Debugger *getDebugger() { return console; }
+
void init();
enum Action { kActionNone, kActionExamine, kActionUse };
diff --git a/engines/testbed/config-params.cpp b/engines/testbed/config-params.cpp
index e89da0b07f..47e5dfa933 100644
--- a/engines/testbed/config-params.cpp
+++ b/engines/testbed/config-params.cpp
@@ -38,6 +38,8 @@ ConfigParams::ConfigParams() {
_isInteractive = true;
_isGameDataFound = true;
_rerunTests = false;
+
+ _testbedConfMan = 0;
}
void ConfigParams::initLogging(const char *dirname, const char *filename, bool enable) {
diff --git a/engines/testbed/config.h b/engines/testbed/config.h
index d611ae4ec3..7d479a74fd 100644
--- a/engines/testbed/config.h
+++ b/engines/testbed/config.h
@@ -113,7 +113,7 @@ private:
class TestbedInteractionDialog : public GUI::Dialog {
public:
- TestbedInteractionDialog(uint x, uint y, uint w, uint h) : GUI::Dialog(x, y, w, h) {}
+ TestbedInteractionDialog(uint x, uint y, uint w, uint h) : GUI::Dialog(x, y, w, h), _xOffset(0), _yOffset(0) {}
~TestbedInteractionDialog() {}
virtual void handleCommand(GUI::CommandSender *sender, uint32 cmd, uint32 data);
void addButton(uint w, uint h, const Common::String name, uint32 cmd, uint xOffset = 0, uint yPadding = 8);
diff --git a/engines/testbed/configure.engine b/engines/testbed/configure.engine
new file mode 100644
index 0000000000..c0a68c8eb8
--- /dev/null
+++ b/engines/testbed/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 testbed "TestBed: the Testing framework" no
diff --git a/engines/testbed/events.cpp b/engines/testbed/events.cpp
index 78de87e133..4b9ced2a53 100644
--- a/engines/testbed/events.cpp
+++ b/engines/testbed/events.cpp
@@ -83,11 +83,10 @@ struct keycodeToChar {
char EventTests::keystrokeToChar() {
Common::EventManager *eventMan = g_system->getEventManager();
- bool quitLoop = false;
Common::Event event;
// handle all keybd events
- while (!quitLoop) {
+ while (true) {
while (eventMan->pollEvent(event)) {
// Quit if explicitly requested!
if (Engine::shouldQuit()) {
@@ -110,8 +109,6 @@ char EventTests::keystrokeToChar() {
}
}
}
-
- return 0;
}
Common::Rect EventTests::drawFinishZone() {
diff --git a/engines/tinsel/configure.engine b/engines/tinsel/configure.engine
new file mode 100644
index 0000000000..c0f3e0a18d
--- /dev/null
+++ b/engines/tinsel/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 tinsel "Tinsel" yes
diff --git a/engines/tinsel/detection_tables.h b/engines/tinsel/detection_tables.h
index cc8166f295..6e83fce3b1 100644
--- a/engines/tinsel/detection_tables.h
+++ b/engines/tinsel/detection_tables.h
@@ -319,7 +319,7 @@ static const TinselGameDescription gameDescriptions[] = {
},
Common::DE_DEU,
Common::kPlatformDOS,
- ADGF_DROPLANGUAGE,
+ ADGF_DROPLANGUAGE | ADGF_CD,
GUIO0()
},
GID_DW1,
diff --git a/engines/tinsel/music.cpp b/engines/tinsel/music.cpp
index 3144ea7f94..bf7257f876 100644
--- a/engines/tinsel/music.cpp
+++ b/engines/tinsel/music.cpp
@@ -91,28 +91,29 @@ static const int enhancedAudioGRAVersion[] = {
};
static const int enhancedAudioSCNVersion[] = {
- 301, 302, 2, 1, 1, 301, 302, 3, 3, 4, // 1-10
- 4, 5, 6, 1, 7, 8, 9, 10, 8, 11, // 11-20
- 11, 12, 13, 13, 13, 13, 13, 14, 13, 13, // 21-30
- 15, 16, 17, 15, 18, 19, 20, 338, 21, 21, // 31-40
- 341, 342, 22, 22, 23, 24, 25, 26, 27, 28, // 41-50
- 29, 30, 31, 32, 33, 34, 35, 35, 36, 37, // 51-60
- 38, 39, 39, 39, 39, 40, 39, 41, 41, 42, // 61-70
- 43, 42, 44, 45, 41, 46, 48, 47, 48, 49, // 71-80
- 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, // 81-90
- 60, 61, 62, 63, 61, 64, 65, 66, 67, 68, // 91-100
- 69, 70, 68, 71, 72, 73, 74, 75, 12, 76, // 101-110
- 77, 78, 79, 80, 4, 4, 82, 83, 77, 4, // 111-120
- 84, 85, 86, 3124, 88, 89, 90, 88, 2, 2, // 121-130
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // 131-140
- 3142, 91, 92, 93, 94, 94, 95, 96, 52, 4, // 141-150
- 97, 98, 99, 99 // 151-154
+ 301, 302, 2, 1, 1, 301, 302, 3, 3, 4, // 1-10
+ 4, 5, 6, 1, 7, 8, 9, 10, 8, 11, // 11-20
+ 11, 12, 13, 13, 13, 13, 13, 14, 13, 13, // 21-30
+ 15, 16, 17, 15, 18, 19, 20, 338, 21, 21, // 31-40
+ 341, 342, 22, 22, 23, 24, 25, 26, 27, 28, // 41-50
+ 29, 30, 31, 32, 33, 34, 35, 35, 36, 37, // 51-60
+ 38, 39, 39, 39, 39, 40, 39, 41, 41, 42, // 61-70
+ 43, 42, 44, 45, 41, 46, 48, 47, 48, 49, // 71-80
+ 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, // 81-90
+ 60, 61, 62, 63, 61, 64, 65, 66, 67, 68, // 91-100
+ 69, 70, 68, 71, 72, 73, 74, 75, 12, 76, // 101-110
+ 77, 78, 79, 80, 4, 4, 82, 83, 77, 4, // 111-120
+ 84, 85, 86, 3124, 88, 89, 90, 88, 2, 2, // 121-130
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // 131-140
+ 3142, 91, 92, 93, 94, 94, 95, 96, 52, 4, // 141-150
+ 97, 98, 99, 99 // 151-154
};
int GetTrackNumber(SCNHANDLE hMidi) {
- for (int i = 0; i < ARRAYSIZE(g_midiOffsets); i++)
+ for (int i = 0; i < ARRAYSIZE(g_midiOffsets); i++) {
if (g_midiOffsets[i] == hMidi)
return i;
+ }
return -1;
}
diff --git a/engines/tinsel/scene.cpp b/engines/tinsel/scene.cpp
index 43654fc3af..6b6f4a5cd3 100644
--- a/engines/tinsel/scene.cpp
+++ b/engines/tinsel/scene.cpp
@@ -130,14 +130,14 @@ const SCENE_STRUC *GetSceneStruc(const byte *pStruc) {
const byte *p = pStruc;
memset(&g_tempStruc, 0, sizeof(SCENE_STRUC));
- g_tempStruc.numEntrance = READ_32(p); p += sizeof(uint32);
- g_tempStruc.numPoly = READ_32(p); p += sizeof(uint32);
- g_tempStruc.numTaggedActor = READ_32(p); p += sizeof(uint32);
- g_tempStruc.defRefer = READ_32(p); p += sizeof(uint32);
- g_tempStruc.hSceneScript = READ_32(p); p += sizeof(uint32);
- g_tempStruc.hEntrance = READ_32(p); p += sizeof(uint32);
- g_tempStruc.hPoly = READ_32(p); p += sizeof(uint32);
- g_tempStruc.hTaggedActor = READ_32(p); p += sizeof(uint32);
+ g_tempStruc.numEntrance = READ_UINT32(p); p += sizeof(uint32);
+ g_tempStruc.numPoly = READ_UINT32(p); p += sizeof(uint32);
+ g_tempStruc.numTaggedActor = READ_UINT32(p); p += sizeof(uint32);
+ g_tempStruc.defRefer = READ_UINT32(p); p += sizeof(uint32);
+ g_tempStruc.hSceneScript = READ_UINT32(p); p += sizeof(uint32);
+ g_tempStruc.hEntrance = READ_UINT32(p); p += sizeof(uint32);
+ g_tempStruc.hPoly = READ_UINT32(p); p += sizeof(uint32);
+ g_tempStruc.hTaggedActor = READ_UINT32(p); p += sizeof(uint32);
return &g_tempStruc;
}
@@ -168,7 +168,7 @@ static void SceneTinselProcess(CORO_PARAM, const void *param) {
assert(_ctx->pInit->hTinselCode); // Must have some code to run
_ctx->pic = InitInterpretContext(GS_SCENE,
- _ctx->pInit->hTinselCode,
+ FROM_32(_ctx->pInit->hTinselCode),
TinselV2 ? _ctx->pInit->event : NOEVENT,
NOPOLY, // No polygon
0, // No actor
@@ -186,7 +186,7 @@ static void SceneTinselProcess(CORO_PARAM, const void *param) {
void SendSceneTinselProcess(TINSEL_EVENT event) {
SCENE_STRUC *ss;
- if (g_SceneHandle != (SCNHANDLE)NULL) {
+ if (g_SceneHandle != 0) {
ss = (SCENE_STRUC *) FindChunk(g_SceneHandle, CHUNK_SCENE);
if (ss->hSceneScript) {
@@ -210,7 +210,7 @@ void SendSceneTinselProcess(TINSEL_EVENT event) {
*/
static void LoadScene(SCNHANDLE scene, int entry) {
- int32 i;
+ uint32 i;
TP_INIT init;
const SCENE_STRUC *ss;
const ENTRANCE_STRUC *es;
@@ -239,17 +239,17 @@ static void LoadScene(SCNHANDLE scene, int entry) {
// Music stuff
char *cptr = (char *)FindChunk(scene, CHUNK_MUSIC_FILENAME);
assert(cptr);
- _vm->_pcmMusic->setMusicSceneDetails(ss->hMusicScript, ss->hMusicSegment, cptr);
+ _vm->_pcmMusic->setMusicSceneDetails(FROM_32(ss->hMusicScript), FROM_32(ss->hMusicSegment), cptr);
}
if (entry == NO_ENTRY_NUM) {
// Restoring scene
// Initialize all the polygons for this scene
- InitPolygons(ss->hPoly, ss->numPoly, true);
+ InitPolygons(FROM_32(ss->hPoly), FROM_32(ss->numPoly), true);
// Initialize the actors for this scene
- StartTaggedActors(ss->hTaggedActor, ss->numTaggedActor, false);
+ StartTaggedActors(FROM_32(ss->hTaggedActor), FROM_32(ss->numTaggedActor), false);
if (TinselV2)
// Returning from cutscene
@@ -259,18 +259,18 @@ static void LoadScene(SCNHANDLE scene, int entry) {
// Genuine new scene
// Initialize all the polygons for this scene
- InitPolygons(ss->hPoly, ss->numPoly, false);
+ InitPolygons(FROM_32(ss->hPoly), FROM_32(ss->numPoly), false);
// Initialize the actors for this scene
- StartTaggedActors(ss->hTaggedActor, ss->numTaggedActor, true);
+ StartTaggedActors(FROM_32(ss->hTaggedActor), FROM_32(ss->numTaggedActor), true);
// Run the appropriate entrance code (if any)
- es = (const ENTRANCE_STRUC *)LockMem(ss->hEntrance);
- for (i = 0; i < ss->numEntrance; i++) {
+ es = (const ENTRANCE_STRUC *)LockMem(FROM_32(ss->hEntrance));
+ for (i = 0; i < FROM_32(ss->numEntrance); i++) {
if (FROM_32(es->eNumber) == (uint)entry) {
if (es->hScript) {
init.event = STARTUP;
- init.hTinselCode = FROM_32(es->hScript);
+ init.hTinselCode = es->hScript;
CoroScheduler.createProcess(PID_TCODE, SceneTinselProcess, &init, sizeof(init));
}
@@ -285,7 +285,7 @@ static void LoadScene(SCNHANDLE scene, int entry) {
}
- if (i == ss->numEntrance)
+ if (i == FROM_32(ss->numEntrance))
error("Non-existent scene entry number");
if (ss->hSceneScript) {
@@ -297,10 +297,10 @@ static void LoadScene(SCNHANDLE scene, int entry) {
}
// Default refer type
- SetDefaultRefer(ss->defRefer);
+ SetDefaultRefer(FROM_32(ss->defRefer));
// Scene's processes
- SceneProcesses(ss->numProcess, ss->hProcess);
+ SceneProcesses(FROM_32(ss->numProcess), FROM_32(ss->hProcess));
}
diff --git a/engines/tinsel/tinsel.cpp b/engines/tinsel/tinsel.cpp
index 5d410e62c7..5ba3c5e80a 100644
--- a/engines/tinsel/tinsel.cpp
+++ b/engines/tinsel/tinsel.cpp
@@ -835,14 +835,6 @@ TinselEngine::TinselEngine(OSystem *syst, const TinselGameDescription *gameDesc)
// Setup mixer
syncSoundSettings();
- // Add DW2 subfolder to search path in case user is running directly from the CDs
- const Common::FSNode gameDataDir(ConfMan.get("path"));
- SearchMan.addSubDirectoryMatching(gameDataDir, "dw2");
-
- // Add subfolders needed for psx versions of Discworld 1
- if (TinselV1PSX)
- SearchMan.addDirectory(gameDataDir.getPath(), gameDataDir, 0, 3, true);
-
const GameSettings *g;
const char *gameid = ConfMan.get("gameid").c_str();
@@ -892,6 +884,17 @@ Common::String TinselEngine::getSavegameFilename(int16 saveNum) const {
return Common::String::format("%s.%03d", getTargetName().c_str(), saveNum);
}
+void TinselEngine::initializePath(const Common::FSNode &gamePath) {
+ if (TinselV1PSX) {
+ // Add subfolders needed for psx versions of Discworld 1
+ SearchMan.addDirectory(gamePath.getPath(), gamePath, 0, 3, true);
+ } else {
+ // Add DW2 subfolder to search path in case user is running directly from the CDs
+ SearchMan.addSubDirectoryMatching(gamePath, "dw2");
+ Engine::initializePath(gamePath);
+ }
+}
+
Common::Error TinselEngine::run() {
// Initialize backend
if (getGameID() == GID_DW2) {
diff --git a/engines/tinsel/tinsel.h b/engines/tinsel/tinsel.h
index 5eb3b7d7b8..efa9355dd5 100644
--- a/engines/tinsel/tinsel.h
+++ b/engines/tinsel/tinsel.h
@@ -32,6 +32,8 @@
#include "common/util.h"
#include "engines/engine.h"
+#include "gui/debugger.h"
+
#include "tinsel/debugger.h"
#include "tinsel/graphics.h"
#include "tinsel/sound.h"
@@ -150,6 +152,7 @@ class TinselEngine : public Engine {
Common::Point _mousePos;
uint8 _dosPlayerDir;
Console *_console;
+ GUI::Debugger *getDebugger() { return _console; }
static const char *const _sampleIndices[][3];
static const char *const _sampleFiles[][3];
@@ -158,6 +161,7 @@ class TinselEngine : public Engine {
protected:
// Engine APIs
+ virtual void initializePath(const Common::FSNode &gamePath);
virtual Common::Error run();
virtual bool hasFeature(EngineFeature f) const;
Common::Error loadGameState(int slot);
diff --git a/engines/toltecs/configure.engine b/engines/toltecs/configure.engine
new file mode 100644
index 0000000000..be5533efa2
--- /dev/null
+++ b/engines/toltecs/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 toltecs "3 Skulls of the Toltecs" yes
diff --git a/engines/toltecs/render.cpp b/engines/toltecs/render.cpp
index 4c41e6ce00..ae458d40a3 100644
--- a/engines/toltecs/render.cpp
+++ b/engines/toltecs/render.cpp
@@ -156,7 +156,7 @@ void RenderQueue::update() {
byte *srcp = _vm->_screen->_backScreen + _vm->_cameraX + _vm->_cameraY * _vm->_sceneWidth;
int16 w = MIN<int16>(640, _vm->_sceneWidth);
int16 h = MIN<int16>(400, _vm->_cameraHeight);
- while (h--) {
+ while (h--) {
memcpy(destp, srcp, w);
destp += 640;
srcp += _vm->_sceneWidth;
diff --git a/engines/toltecs/saveload.cpp b/engines/toltecs/saveload.cpp
index 6c195a34c2..4edcc601b8 100644
--- a/engines/toltecs/saveload.cpp
+++ b/engines/toltecs/saveload.cpp
@@ -183,7 +183,7 @@ void ToltecsEngine::loadgame(const char *filename) {
_mouseDisabled = in->readUint16LE();
_system->warpMouse(_mouseX, _mouseY);
- _system->showMouse(_mouseDisabled == 0);
+ _system->showMouse(_mouseDisabled == 0);
_palette->loadState(in);
_script->loadState(in);
diff --git a/engines/toltecs/screen.cpp b/engines/toltecs/screen.cpp
index 1eb2f41fd2..dd418be71f 100644
--- a/engines/toltecs/screen.cpp
+++ b/engines/toltecs/screen.cpp
@@ -599,7 +599,7 @@ int16 Screen::drawString(int16 x, int16 y, byte color, uint fontResIndex, const
if (ywobble)
yadd = *ywobble;
- while (len--) {
+ while (len--) {
byte ch = *text++;
if (ch <= 0x20) {
x += font.getWidth();
@@ -634,7 +634,7 @@ void Screen::drawChar(const Font &font, byte *dest, int16 x, int16 y, byte ch, b
byte flags = charData[0] & 0xF0;
charData++;
if ((flags & 0x80) == 0) {
- if (flags & 0x10) {
+ if (flags & 0x10) {
memset(dest, color, count);
} else if (outline) {
memset(dest, 0, count);
diff --git a/engines/toltecs/script.cpp b/engines/toltecs/script.cpp
index 476c3a4fcf..83c4ef15fe 100644
--- a/engines/toltecs/script.cpp
+++ b/engines/toltecs/script.cpp
@@ -65,7 +65,7 @@ ScriptInterpreter::ScriptInterpreter(ToltecsEngine *vm) : _vm(vm) {
_savedSp = 0;
_slots[kMaxScriptSlots - 1].size = 1024;
- _slots[kMaxScriptSlots - 1].data = new byte[_slots[kMaxScriptSlots - 1].size];
+ _slots[kMaxScriptSlots - 1].data = new byte[_slots[kMaxScriptSlots - 1].size];
setupScriptFunctions();
@@ -184,11 +184,11 @@ void ScriptInterpreter::loadScript(uint resIndex, uint slotIndex) {
delete[] _slots[slotIndex].data;
- _slots[slotIndex].resIndex = resIndex;
+ _slots[slotIndex].resIndex = resIndex;
Resource *scriptResource = _vm->_res->load(resIndex);
_slots[slotIndex].size = scriptResource->size;
- _slots[slotIndex].data = new byte[_slots[slotIndex].size];
- memcpy(_slots[slotIndex].data, scriptResource->data, _slots[slotIndex].size);
+ _slots[slotIndex].data = new byte[_slots[slotIndex].size];
+ memcpy(_slots[slotIndex].data, scriptResource->data, _slots[slotIndex].size);
}
void ScriptInterpreter::setMainScript(uint slotIndex) {
@@ -852,7 +852,7 @@ void ScriptInterpreter::sfFindMouseInRectIndex2() {
}
void ScriptInterpreter::sfDrawGuiImage() {
- _vm->_screen->drawGuiImage(arg16(5), arg16(3), arg16(7));
+ _vm->_screen->drawGuiImage(arg16(5), arg16(3), arg16(7));
}
void ScriptInterpreter::sfAddAnimatedSpriteNoLoop() {
diff --git a/engines/toltecs/toltecs.cpp b/engines/toltecs/toltecs.cpp
index 188facd63c..8bd824cfee 100644
--- a/engines/toltecs/toltecs.cpp
+++ b/engines/toltecs/toltecs.cpp
@@ -235,7 +235,7 @@ void ToltecsEngine::loadScene(uint resIndex) {
byte *source = scene + 392;
byte *destp = _screen->_backScreen;
byte *destEnd = destp + _sceneWidth * _sceneHeight;
- while (destp < destEnd) {
+ while (destp < destEnd) {
int count = 1;
byte pixel = *source++;
if (pixel & 0x80) {
@@ -250,7 +250,7 @@ void ToltecsEngine::loadScene(uint resIndex) {
debug(0, "_sceneWidth = %d; _sceneHeight = %d", _sceneWidth, _sceneHeight);
// Load scene segmap
- _segmap->load(scene + imageSize + 4);
+ _segmap->load(scene + imageSize + 4);
_screen->_fullRefresh = true;
_screen->_renderQueue->clear();
@@ -574,9 +574,9 @@ void ToltecsEngine::walk(byte *walkData) {
if (ydelta > ABS(walkInfo.x1 - walkInfo.x2) * _walkSpeedX) {
v10 = 100 - walkInfo.scaling;
v11 = v8;
- } else {
+ } else {
v10 = v8;
- v11 = 100 - walkInfo.scaling;
+ v11 = 100 - walkInfo.scaling;
}
walkInfo.yerror += walkInfo.mulValue * v10;
diff --git a/engines/toltecs/toltecs.h b/engines/toltecs/toltecs.h
index 0be2d2a646..b405d099c4 100644
--- a/engines/toltecs/toltecs.h
+++ b/engines/toltecs/toltecs.h
@@ -36,13 +36,16 @@
#include "graphics/surface.h"
+#include "gui/debugger.h"
+
+#include "toltecs/console.h"
+
namespace Toltecs {
struct ToltecsGameDescription;
class AnimationPlayer;
class ArchiveReader;
-class Console;
class Input;
class MenuSystem;
class MoviePlayer;
@@ -110,6 +113,8 @@ public:
const Common::String& getTargetName() const { return _targetName; }
void syncSoundSettings();
+ GUI::Debugger *getDebugger() { return _console; }
+
void setupSysStrings();
void requestSavegame(int slotNum, Common::String &description);
void requestLoadgame(int slotNum);
diff --git a/engines/tony/configure.engine b/engines/tony/configure.engine
new file mode 100644
index 0000000000..f85f45d158
--- /dev/null
+++ b/engines/tony/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 tony "Tony Tough and the Night of Roasted Moths" yes "" "" "16bit"
diff --git a/engines/tony/gfxcore.cpp b/engines/tony/gfxcore.cpp
index 410f9b8971..3433ad3024 100644
--- a/engines/tony/gfxcore.cpp
+++ b/engines/tony/gfxcore.cpp
@@ -117,6 +117,7 @@ RMGfxBuffer::operator void *() {
}
RMGfxBuffer::RMGfxBuffer(int dimx, int dimy, int nBpp) {
+ _origBuf = _buf = NULL;
create(dimx, dimy, nBpp);
}
diff --git a/engines/tony/mpal/mpal.cpp b/engines/tony/mpal/mpal.cpp
index 5e6d44f0a3..19e3d43df4 100644
--- a/engines/tony/mpal/mpal.cpp
+++ b/engines/tony/mpal/mpal.cpp
@@ -409,7 +409,7 @@ static uint32 *getSelectList(uint32 i) {
sl[k++] = dialog->_choice[i]._select[j]._dwData;
}
- sl[k] = (uint32)NULL;
+ sl[k] = 0;
return sl;
}
@@ -436,7 +436,7 @@ static uint32 *GetItemList(uint32 nLoc) {
}
}
- il[j] = (uint32)NULL;
+ il[j] = 0;
return il;
}
@@ -832,7 +832,7 @@ void LocationPollThread(CORO_PARAM, const void *param) {
if (_ctx->k == 0)
// We can remove this item from the list
- _ctx->il[_ctx->i] = (uint32)NULL;
+ _ctx->il[_ctx->i] = 0;
else
_ctx->nRealItems++;
}
@@ -963,7 +963,7 @@ void LocationPollThread(CORO_PARAM, const void *param) {
// Ok, we can perform the action. For convenience, we do it in a new process
_ctx->newItem = (LpMpalItem)globalAlloc(GMEM_FIXED | GMEM_ZEROINIT, sizeof(MpalItem));
- if (_ctx->newItem == false) {
+ if (!_ctx->newItem) {
globalDestroy(_ctx->myThreads);
globalDestroy(_ctx->myActions);
@@ -1935,7 +1935,7 @@ bool mpalExecuteScript(int nScript) {
// !!! New process management
if (CoroScheduler.createProcess(ScriptThread, &s, sizeof(LpMpalScript)) == CORO_INVALID_PID_VALUE)
- return false;
+ return false;
return true;
}
diff --git a/engines/tony/sound.cpp b/engines/tony/sound.cpp
index 547f31906e..74d32c7c0f 100644
--- a/engines/tony/sound.cpp
+++ b/engines/tony/sound.cpp
@@ -88,7 +88,7 @@ FPSound::~FPSound() {
bool FPSound::createStream(FPStream **streamPtr) {
(*streamPtr) = new FPStream(_soundSupported);
- return (*streamPtr != NULL);
+ return true;
}
/**
diff --git a/engines/tony/tony.h b/engines/tony/tony.h
index 750673061d..cdc7d7e20a 100644
--- a/engines/tony/tony.h
+++ b/engines/tony/tony.h
@@ -31,6 +31,7 @@
#include "common/random.h"
#include "common/util.h"
#include "engines/engine.h"
+#include "gui/debugger.h"
#include "tony/mpal/mpal.h"
#include "tony/mpal/memory.h"
@@ -108,6 +109,7 @@ public:
Common::List<FPSfx *> _activeSfx;
Globals _globals;
Debugger *_debugger;
+ GUI::Debugger *getDebugger() { return _debugger; }
int16 _cTableDialog[256];
int16 _lTableDialog[256];
diff --git a/engines/tony/window.cpp b/engines/tony/window.cpp
index a732862854..02991975ce 100644
--- a/engines/tony/window.cpp
+++ b/engines/tony/window.cpp
@@ -40,7 +40,7 @@ namespace Tony {
\****************************************************************************/
RMWindow::RMWindow() {
- _showDirtyRects = false;
+ reset();
}
RMWindow::~RMWindow() {
@@ -55,11 +55,21 @@ RMWindow::~RMWindow() {
void RMWindow::init() {
Graphics::PixelFormat pixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0);
initGraphics(RM_SX, RM_SY, true, &pixelFormat);
+
+ reset();
+}
+/**
+ * Reset the variables
+ */
+void RMWindow::reset() {
+ _showDirtyRects = false;
_bGrabScreenshot = false;
_bGrabThumbnail = false;
_bGrabMovie = false;
_wiping = false;
+
+ _wThumbBuf = nullptr;
}
void RMWindow::copyRectToScreen(const byte *buf, int pitch, int x, int y, int w, int h) {
diff --git a/engines/tony/window.h b/engines/tony/window.h
index 3874652f64..2cc9bfd37c 100644
--- a/engines/tony/window.h
+++ b/engines/tony/window.h
@@ -72,6 +72,7 @@ public:
* Initialization
*/
void init();
+ void reset();
void close();
/**
diff --git a/engines/toon/anim.cpp b/engines/toon/anim.cpp
index 78d3954325..19e997af34 100644
--- a/engines/toon/anim.cpp
+++ b/engines/toon/anim.cpp
@@ -41,7 +41,7 @@ bool Animation::loadAnimation(const Common::String &file) {
if (strncmp((char *)fileData, "KevinAguilar", 12))
return false;
- strcpy(_name, file.c_str());
+ Common::strlcpy(_name, file.c_str(), 32);
uint32 headerSize = READ_LE_UINT32(fileData + 16);
uint32 uncompressedBytes = READ_LE_UINT32(fileData + 20);
@@ -52,6 +52,7 @@ bool Animation::loadAnimation(const Common::String &file) {
_x2 = READ_LE_UINT32(fileData + 40);
_y2 = READ_LE_UINT32(fileData + 44);
_paletteEntries = READ_LE_UINT32(fileData + 56);
+ // CHECKME: Useless variable _fps
_fps = READ_LE_UINT32(fileData + 60);
uint32 paletteSize = READ_LE_UINT32(fileData + 64);
@@ -119,6 +120,10 @@ Animation::Animation(ToonEngine *vm) : _vm(vm) {
_palette = NULL;
_numFrames = 0;
_frames = NULL;
+
+ _x1 = _y1 = _x2 = _y2 = 0;
+ _fps = 0;
+ _paletteEntries = 0;
}
Animation::~Animation() {
@@ -448,6 +453,7 @@ AnimationInstance::AnimationInstance(ToonEngine *vm, AnimationInstanceType type)
_y = 0;
_z = 0;
_layerZ = 0;
+ _visible = false;
}
void AnimationInstance::render() {
diff --git a/engines/toon/audio.cpp b/engines/toon/audio.cpp
index bc0e051057..303f6774fa 100644
--- a/engines/toon/audio.cpp
+++ b/engines/toon/audio.cpp
@@ -228,6 +228,7 @@ void AudioManager::stopMusic() {
AudioStreamInstance::AudioStreamInstance(AudioManager *man, Audio::Mixer *mixer, Common::SeekableReadStream *stream , bool looping, bool deleteFileStreamAtEnd) {
_compBufferSize = 0;
_buffer = NULL;
+ _bufferSize = 0;
_bufferMaxSize = 0;
_mixer = mixer;
_compBuffer = NULL;
@@ -255,6 +256,8 @@ AudioStreamInstance::AudioStreamInstance(AudioManager *man, Audio::Mixer *mixer,
} else {
stopNow();
}
+
+ _soundType = Audio::Mixer::kPlainSoundType;
}
AudioStreamInstance::~AudioStreamInstance() {
diff --git a/engines/toon/character.cpp b/engines/toon/character.cpp
index 83c9e3ec70..baab8888cf 100644
--- a/engines/toon/character.cpp
+++ b/engines/toon/character.cpp
@@ -65,6 +65,7 @@ Character::Character(ToonEngine *vm) : _vm(vm) {
_numPixelToWalk = 0;
_nextIdleTime = _vm->_system->getMillis() + (_vm->randRange(0, 600) + 300) * _vm->getTickLength();
_lineToSayId = 0;
+ _time = 0;
}
Character::~Character(void) {
diff --git a/engines/toon/configure.engine b/engines/toon/configure.engine
new file mode 100644
index 0000000000..00c98f7d8a
--- /dev/null
+++ b/engines/toon/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 toon "Toonstruck" yes
diff --git a/engines/toon/font.cpp b/engines/toon/font.cpp
index e26ed92f83..2ba4eff652 100644
--- a/engines/toon/font.cpp
+++ b/engines/toon/font.cpp
@@ -32,6 +32,8 @@ FontRenderer::FontRenderer(ToonEngine *vm) : _vm(vm) {
_currentFontColor[1] = 0xc8;
_currentFontColor[2] = 0xcb;
_currentFontColor[3] = 0xce;
+
+ _currentFont = nullptr;
}
FontRenderer::~FontRenderer() {
@@ -195,8 +197,7 @@ void FontRenderer::renderMultiLineText(int16 x, int16 y, const Common::String &o
// divide the text in several lines
// based on number of characters or size of lines.
byte text[1024];
- strncpy((char *)text, origText.c_str(), 1023);
- text[1023] = 0;
+ Common::strlcpy((char *)text, origText.c_str(), 1024);
byte *lines[16];
int32 lineSize[16];
diff --git a/engines/toon/movie.cpp b/engines/toon/movie.cpp
index f0463a52e1..9e8514d0a8 100644
--- a/engines/toon/movie.cpp
+++ b/engines/toon/movie.cpp
@@ -85,7 +85,8 @@ void Movie::play(const Common::String &video, int32 flags) {
_playing = true;
if (flags & 1)
_vm->getAudioManager()->setMusicVolume(0);
- _decoder->loadFile(video.c_str());
+ if (!_decoder->loadFile(video.c_str()))
+ error("Unable to play video %s", video.c_str());
playVideo(isFirstIntroVideo);
_vm->flushPalette(true);
if (flags & 1)
@@ -94,7 +95,7 @@ void Movie::play(const Common::String &video, int32 flags) {
_playing = false;
}
-bool Movie::playVideo(bool isFirstIntroVideo) {
+void Movie::playVideo(bool isFirstIntroVideo) {
debugC(1, kDebugMovie, "playVideo(isFirstIntroVideo: %d)", isFirstIntroVideo);
_decoder->start();
@@ -135,13 +136,13 @@ bool Movie::playVideo(bool isFirstIntroVideo) {
while (_vm->_system->getEventManager()->pollEvent(event))
if ((event.type == Common::EVENT_KEYDOWN && event.kbd.keycode == Common::KEYCODE_ESCAPE)) {
_vm->dirtyAllScreen();
- return false;
+ return;
}
_vm->_system->delayMillis(10);
}
_vm->dirtyAllScreen();
- return !_vm->shouldQuit();
+ return;
}
} // End of namespace Toon
diff --git a/engines/toon/movie.h b/engines/toon/movie.h
index 4dd6583bf6..14287d87fd 100644
--- a/engines/toon/movie.h
+++ b/engines/toon/movie.h
@@ -53,9 +53,8 @@ public:
bool isPlaying() { return _playing; }
protected:
- bool playVideo(bool isFirstIntroVideo);
+ void playVideo(bool isFirstIntroVideo);
ToonEngine *_vm;
- Audio::Mixer *_mixer;
ToonstruckSmackerDecoder *_decoder;
bool _playing;
};
diff --git a/engines/toon/path.cpp b/engines/toon/path.cpp
index 7914aed595..336847e73c 100644
--- a/engines/toon/path.cpp
+++ b/engines/toon/path.cpp
@@ -152,6 +152,8 @@ PathFinding::PathFinding() {
_heap = new PathFindingHeap();
_sq = NULL;
_numBlockingRects = 0;
+
+ _currentMask = nullptr;
}
PathFinding::~PathFinding(void) {
diff --git a/engines/toon/picture.cpp b/engines/toon/picture.cpp
index 65cc3a70e1..4927f50e08 100644
--- a/engines/toon/picture.cpp
+++ b/engines/toon/picture.cpp
@@ -134,6 +134,11 @@ bool Picture::loadPicture(const Common::String &file) {
Picture::Picture(ToonEngine *vm) : _vm(vm) {
_data = NULL;
_palette = NULL;
+
+ _width = 0;
+ _height = 0;
+ _paletteEntries = 0;
+ _useFullPalette = false;
}
Picture::~Picture() {
diff --git a/engines/toon/resource.cpp b/engines/toon/resource.cpp
index 2d419ec027..ffcabbd348 100644
--- a/engines/toon/resource.cpp
+++ b/engines/toon/resource.cpp
@@ -285,6 +285,7 @@ void PakFile::close() {
}
PakFile::PakFile() {
+ _numFiles = 0;
}
PakFile::~PakFile() {
diff --git a/engines/toon/resource.h b/engines/toon/resource.h
index c80ac2216e..b432a1d335 100644
--- a/engines/toon/resource.h
+++ b/engines/toon/resource.h
@@ -53,7 +53,6 @@ protected:
uint32 _numFiles;
Common::Array<File> _files;
- Common::File *_fileHandle;
};
class ToonEngine;
diff --git a/engines/toon/script.cpp b/engines/toon/script.cpp
index 69ae727bb5..d752c277db 100644
--- a/engines/toon/script.cpp
+++ b/engines/toon/script.cpp
@@ -59,6 +59,8 @@ EMCInterpreter::EMCInterpreter(ToonEngine *vm) : _vm(vm), _scriptData(0), _filen
};
_opcodes = opcodes;
#undef OPCODE
+
+ _parameter = 0;
}
EMCInterpreter::~EMCInterpreter() {
@@ -132,8 +134,7 @@ bool EMCInterpreter::load(const char *filename, EMCData *scriptData, const Commo
_scriptData->sysFuncs = opcodes;
- strncpy(_scriptData->filename, filename, 13);
- _scriptData->filename[12] = 0;
+ Common::strlcpy(_scriptData->filename, filename, 13);
_scriptData = 0;
_filename = 0;
diff --git a/engines/toon/script_func.cpp b/engines/toon/script_func.cpp
index 1fa4058114..70baaaef22 100644
--- a/engines/toon/script_func.cpp
+++ b/engines/toon/script_func.cpp
@@ -1060,9 +1060,9 @@ int32 ScriptFunc::sys_Cmd_Set_Location_Data(EMCState *state) {
// initial setup of locations
int32 locationId = stackPos(0);
debugC(0, 0, "setlocationdata(%d) %s %x %s %s %d %d", locationId, GetText(1, state), stackPos(2), GetText(3, state), GetText(4, state), stackPos(5), stackPos(6));
- strcpy(_vm->state()->_locations[locationId]._name, GetText(1, state));
- strcpy(_vm->state()->_locations[locationId]._music, GetText(3, state));
- strcpy(_vm->state()->_locations[locationId]._cutaway, GetText(4, state));
+ Common::strlcpy(_vm->state()->_locations[locationId]._name, GetText(1, state), 64);
+ Common::strlcpy(_vm->state()->_locations[locationId]._music, GetText(3, state), 64);
+ Common::strlcpy(_vm->state()->_locations[locationId]._cutaway, GetText(4, state), 64);
_vm->state()->_locations[locationId]._flags = stackPos(2);
_vm->state()->_locations[locationId]._visited = false;
_vm->state()->_locations[locationId]._numSceneAnimations = stackPos(5);
diff --git a/engines/toon/state.cpp b/engines/toon/state.cpp
index 8e4abbd709..fffa8cf529 100644
--- a/engines/toon/state.cpp
+++ b/engines/toon/state.cpp
@@ -115,6 +115,10 @@ State::State(void) {
#endif
memset(_conversationState, 0, sizeof(Conversation) * 60);
+
+ _conversationData = nullptr;
+ _currentConversationId = -1;
+ _exitConversation = true;
}
State::~State(void) {
diff --git a/engines/toon/tools.cpp b/engines/toon/tools.cpp
index added39940..f5c77aca69 100644
--- a/engines/toon/tools.cpp
+++ b/engines/toon/tools.cpp
@@ -136,6 +136,13 @@ uint32 decompressSPCN(byte *src, byte *dst, uint32 dstsize) {
RncDecoder::RncDecoder() {
initCrc();
+
+ _bitBuffl = 0;
+ _bitBuffh = 0;
+ _bitCount = 0;
+ _srcPtr = nullptr;
+ _dstPtr = nullptr;
+ _inputByteLeft = 0;
}
RncDecoder::~RncDecoder() { }
diff --git a/engines/toon/toon.cpp b/engines/toon/toon.cpp
index 286bcf1941..7b1456b05c 100644
--- a/engines/toon/toon.cpp
+++ b/engines/toon/toon.cpp
@@ -922,6 +922,48 @@ ToonEngine::ToonEngine(OSystem *syst, const ADGameDescription *gameDescription)
_gameVariant = 0;
break;
}
+
+ for (int i = 0; i < 64; i++) {
+ _sceneAnimationScripts[i]._lastTimer = 0;
+ _sceneAnimationScripts[i]._frozen = false;
+ _sceneAnimationScripts[i]._frozenForConversation = false;
+ _sceneAnimationScripts[i]._active = false;
+ }
+
+ _lastProcessedSceneScript = 0;
+ _animationSceneScriptRunFlag = false;
+ _updatingSceneScriptRunFlag = false;
+ _dirtyAll = false;
+ _cursorOffsetX = 0;
+ _cursorOffsetY = 0;
+ _currentTextLine = 0;
+ _currentTextLineId = 0;
+ _currentTextLineX = 0;
+ _currentTextLineY = 0;
+ _currentTextLineCharacterId = -1;
+ _oldScrollValue = 0;
+ _drew = nullptr;
+ _flux = nullptr;
+ _currentHotspotItem = 0;
+ _shouldQuit = false;
+ _scriptStep = 0;
+ _oldTimer = 0;
+ _oldTimer2 = 0;
+ _lastRenderTime = 0;
+ _firstFrame = false;
+ _needPaletteFlush = true;
+
+ _numVariant = 0;
+ _currentCutaway = nullptr;
+ for (int i = 0; i < 4; i++) {
+ _scriptState[i].ip = nullptr;
+ _scriptState[i].dataPtr = nullptr;
+ _scriptState[i].retValue = 0;
+ _scriptState[i].bp = 0;
+ _scriptState[i].sp = 0;
+ _scriptState[i].running = false;
+ }
+ _currentScriptRegion = 0;
}
ToonEngine::~ToonEngine() {
diff --git a/engines/touche/configure.engine b/engines/touche/configure.engine
new file mode 100644
index 0000000000..777578e623
--- /dev/null
+++ b/engines/touche/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 touche "Touche: The Adventures of the Fifth Musketeer" yes
diff --git a/engines/touche/touche.cpp b/engines/touche/touche.cpp
index 5c133ccbc6..b3e3ca5b50 100644
--- a/engines/touche/touche.cpp
+++ b/engines/touche/touche.cpp
@@ -51,6 +51,28 @@ ToucheEngine::ToucheEngine(OSystem *system, Common::Language language)
_saveLoadCurrentSlot = 0;
_hideInventoryTexts = false;
+ _numOpcodes = 0;
+ _compressedSpeechData = 0;
+ _textData = 0;
+ _backdropBuffer = 0;
+ _menuKitData = 0;
+ _convKitData = 0;
+
+ for (int i = 0; i < NUM_SEQUENCES; i++)
+ _sequenceDataTable[i] = 0;
+
+ _programData = 0;
+ _programDataSize = 0;
+ _mouseData = 0;
+ _iconData = 0;
+ _currentBitmapWidth = 0;
+ _currentBitmapHeight = 0;
+ _currentImageWidth = 0;
+ _currentImageHeight = 0;
+ _roomWidth = 0;
+ _programTextDataPtr = 0;
+ _offscreenBuffer = 0;
+
_screenRect = Common::Rect(kScreenWidth, kScreenHeight);
_roomAreaRect = Common::Rect(kScreenWidth, kRoomHeight);
@@ -88,6 +110,63 @@ ToucheEngine::ToucheEngine(OSystem *system, Common::Language language)
DebugMan.addDebugChannel(kDebugCharset, "Charset", "Charset debug level");
_console = new ToucheConsole(this);
+
+ _newEpisodeNum = 0;
+ _currentEpisodeNum = 0;
+ _currentAmountOfMoney = 0;
+ _giveItemToKeyCharNum = 0;
+ _giveItemToObjectNum = 0;
+ _giveItemToCounter = 0;
+ _currentRoomNum = 0;
+ _waitingSetKeyCharNum1 = 0;
+ _waitingSetKeyCharNum2 = 0;
+ _waitingSetKeyCharNum3 = 0;
+ _script.opcodeNum = 0;
+ _script.dataOffset = 0;
+ _script.keyCharNum = 0;
+ _script.dataPtr = 0;
+ _script.stackDataPtr = 0;
+ _script.stackDataBasePtr = 0;
+ _script.quitFlag = 0;
+ _opcodesTable = 0;
+
+ for (uint i = 0; i < NUM_SPRITES; i++)
+ memset(&_spritesTable[i], 0, sizeof(SpriteData));
+
+ for (uint i = 0; i < NUM_SEQUENCES; i++)
+ memset(&_sequenceEntryTable[i], 0, sizeof(SequenceEntry));
+
+ _talkListEnd = 0;
+ _talkListCurrent = 0;
+ _talkTextRectDefined = 0;
+ _talkTextDisplayed = 0;
+ _talkTextInitialized = 0;
+ _skipTalkText = 0;
+ _talkTextSpeed = 0;
+ _keyCharTalkCounter = 0;
+ _talkTableLastTalkingKeyChar = 0;
+ _talkTableLastOtherKeyChar = 0;
+ _talkTableLastStringNum = 0;
+
+ for (uint i = 0; i < NUM_TALK_ENTRIES; i++)
+ memset(&_talkTable[i], 0, sizeof(TalkEntry));
+
+ _conversationChoicesUpdated = 0;
+ _conversationReplyNum = 0;
+ _conversationEnded = 0;
+ _conversationNum = 0;
+ _scrollConversationChoiceOffset = 0;
+ _currentConversation = 0;
+ _disableConversationScript = 0;
+ _conversationAreaCleared = 0;
+
+ for (uint i = 0; i < NUM_CONVERSATION_CHOICES; i++)
+ memset(&_conversationChoicesTable[i], 0, sizeof(ConversationChoice));
+
+ for (uint i = 0; i < NUM_KEYCHARS; i++)
+ _sortedKeyCharsTable[i] = 0;
+
+ _currentKeyCharNum = 0;
}
ToucheEngine::~ToucheEngine() {
diff --git a/engines/touche/touche.h b/engines/touche/touche.h
index 6ac43e7dfe..9cc42b0c68 100644
--- a/engines/touche/touche.h
+++ b/engines/touche/touche.h
@@ -102,7 +102,7 @@ struct KeyChar {
int16 zPosPrev;
int16 prevWalkDataNum;
uint16 textColor;
- int16 inventoryItems[4];
+ int16 inventoryItems[5];
int16 money;
int16 pointsDataNum;
int16 currentWalkBox;
diff --git a/engines/tsage/blue_force/blueforce_logic.cpp b/engines/tsage/blue_force/blueforce_logic.cpp
index 63f84d25e1..c8a0117bcf 100644
--- a/engines/tsage/blue_force/blueforce_logic.cpp
+++ b/engines/tsage/blue_force/blueforce_logic.cpp
@@ -454,9 +454,10 @@ void Timer::dispatch() {
if (_endFrame) {
uint32 frameNumber = BF_GLOBALS._events.getFrameNumber();
- if (frameNumber > _endFrame)
+ if (frameNumber > _endFrame) {
// Timer has expired
signal();
+ }
}
}
@@ -472,7 +473,8 @@ void Timer::set(uint32 delay, EventHandler *endHandler) {
/*--------------------------------------------------------------------------*/
TimerExt::TimerExt(): Timer() {
- _action = NULL;
+ _action = nullptr;
+ _newAction = nullptr;
}
void TimerExt::set(uint32 delay, EventHandler *endHandler, Action *newAction) {
@@ -646,8 +648,6 @@ void FocusObject::postInit(SceneObjectList *OwnerList) {
_lookLineNum = 43;
_talkLineNum = 44;
_useLineNum = -1;
- _v90 = 0;
- _v92 = 1;
SceneExt *scene = (SceneExt *)BF_GLOBALS._sceneManager._scene;
scene->_focusObject = this;
@@ -656,8 +656,11 @@ void FocusObject::postInit(SceneObjectList *OwnerList) {
void FocusObject::synchronize(Serializer &s) {
NamedObject::synchronize(s);
- s.syncAsSint16LE(_v90);
- s.syncAsSint16LE(_v92);
+ if (s.getVersion() < 12) {
+ int useless = 0;
+ s.syncAsSint16LE(useless);
+ s.syncAsSint16LE(useless);
+ }
}
void FocusObject::remove() {
@@ -703,7 +706,6 @@ SceneExt::SceneExt(): Scene() {
_stripManager._onBegin = SceneExt::startStrip;
_stripManager._onEnd = SceneExt::endStrip;
- _field372 = _field37A = 0;
_savedPlayerEnabled = false;
_savedUiEnabled = false;
_savedCanWalk = false;
@@ -746,6 +748,7 @@ void SceneExt::process(Event &event) {
void SceneExt::dispatch() {
_timerList.dispatch();
+ /*
if (_field37A) {
if ((--_field37A == 0) && BF_GLOBALS._dayNumber) {
if (T2_GLOBALS._uiElements._active && BF_GLOBALS._player._enabled) {
@@ -755,6 +758,7 @@ void SceneExt::dispatch() {
_field37A = 0;
}
}
+ */
Scene::dispatch();
}
@@ -762,8 +766,6 @@ void SceneExt::dispatch() {
void SceneExt::loadScene(int sceneNum) {
Scene::loadScene(sceneNum);
- _v51C34.top = 0;
- _v51C34.bottom = 300;
BF_GLOBALS._sceneHandler->_delayTicks = 1;
}
@@ -831,7 +833,6 @@ void SceneExt::gunDisplay() {
void SceneExt::startStrip() {
SceneExt *scene = (SceneExt *)BF_GLOBALS._sceneManager._scene;
- scene->_field372 = 1;
scene->_savedPlayerEnabled = BF_GLOBALS._player._enabled;
if (scene->_savedPlayerEnabled) {
@@ -839,21 +840,20 @@ void SceneExt::startStrip() {
scene->_savedCanWalk = BF_GLOBALS._player._canWalk;
BF_GLOBALS._player.disableControl();
- if (!BF_GLOBALS._v50696 && T2_GLOBALS._uiElements._active)
+ if (T2_GLOBALS._uiElements._active)
T2_GLOBALS._uiElements.hide();
}
}
void SceneExt::endStrip() {
SceneExt *scene = (SceneExt *)BF_GLOBALS._sceneManager._scene;
- scene->_field372 = 0;
if (scene->_savedPlayerEnabled) {
BF_GLOBALS._player.enableControl();
BF_GLOBALS._player._uiEnabled = scene->_savedUiEnabled;
BF_GLOBALS._player._canWalk = scene->_savedCanWalk;
- if (!BF_GLOBALS._v50696 && T2_GLOBALS._uiElements._active)
+ if (T2_GLOBALS._uiElements._active)
T2_GLOBALS._uiElements.show();
}
}
@@ -865,38 +865,34 @@ void SceneExt::clearScreen() {
/*--------------------------------------------------------------------------*/
PalettedScene::PalettedScene(): SceneExt() {
- _field794 = 0;
+ _hasFader = false;
}
void PalettedScene::synchronize(Serializer &s) {
SceneExt::synchronize(s);
- s.syncAsSint16LE(_field794);
+ s.syncAsSint16LE(_hasFader);
}
void PalettedScene::postInit(SceneObjectList *OwnerList) {
- _field794 = 0;
- _palette._field412 = 1;
+ _hasFader = false;
SceneExt::postInit(OwnerList);
}
void PalettedScene::remove() {
SceneExt::remove();
- if (_field794 == 1) {
+ if (_hasFader) {
for (SynchronizedList<SceneObject *>::iterator i = BF_GLOBALS._sceneObjects->begin();
i != BF_GLOBALS._sceneObjects->end(); ++i)
(*i)->remove();
BF_GLOBALS._sceneObjects->draw();
BF_GLOBALS._scenePalette.loadPalette(2);
- BF_GLOBALS._v51C44 = 1;
BF_GLOBALS._sceneManager._hasPalette = true;
}
-
- BF_GLOBALS._scenePalette._field412 = 0;
}
PaletteFader *PalettedScene::addFader(const byte *arrBufferRGB, int step, Action *action) {
- _field794 = 1;
+ _hasFader = true;
return BF_GLOBALS._scenePalette.addFader(arrBufferRGB, 1, step, action);
}
@@ -909,6 +905,7 @@ void PalettedScene::add2Faders(const byte *arrBufferRGB, int step, int paletteNu
void PalettedScene::transition(const byte *arrBufferRGB, int percent, int paletteNum, Action *action, int fromColor1, int fromColor2, int toColor1, int toColor2, bool flag) {
byte tmpPalette[768];
+ memset(tmpPalette, 0, 768);
_palette.loadPalette(paletteNum);
_palette.loadPalette(2);
@@ -1260,8 +1257,6 @@ void BlueForceInvObjectList::alterInventory(int mode) {
setObjectScene(INV_TICKET_BOOK, 60);
setObjectScene(INV_MIRANDA_CARD, 60);
- BF_GLOBALS._v4CEC4 = 0;
-
switch (mode) {
case 2:
if (hasPrintout)
diff --git a/engines/tsage/blue_force/blueforce_logic.h b/engines/tsage/blue_force/blueforce_logic.h
index 59bc2b7a51..0045980820 100644
--- a/engines/tsage/blue_force/blueforce_logic.h
+++ b/engines/tsage/blue_force/blueforce_logic.h
@@ -139,14 +139,17 @@ public:
class NamedObject2: public NamedObject {
public:
- int _v1, _v2;
+ int _talkCount;
- NamedObject2() { _v1 = _v2 = 0; }
+ NamedObject2() { _talkCount = 0; }
virtual Common::String getClassName() { return "NamedObject2"; }
virtual void synchronize(Serializer &s) {
NamedObject::synchronize(s);
- s.syncAsSint16LE(_v1);
- s.syncAsSint16LE(_v2);
+ if (s.getVersion() < 12) {
+ int useless = 0;
+ s.syncAsSint16LE(useless);
+ }
+ s.syncAsSint16LE(_talkCount);
}
};
@@ -177,7 +180,6 @@ public:
class FocusObject: public NamedObject {
public:
- int _v90, _v92;
GfxSurface _img;
FocusObject();
@@ -196,16 +198,12 @@ private:
static void endStrip();
public:
AObjectArray _timerList, _objArray2;
- int _field372;
bool _savedPlayerEnabled;
bool _savedUiEnabled;
bool _savedCanWalk;
- int _field37A;
EventHandler *_focusObject;
Visage _cursorVisage;
-
- Rect _v51C34;
public:
SceneExt();
@@ -228,7 +226,7 @@ public:
class PalettedScene: public SceneExt {
public:
ScenePalette _palette;
- int _field794;
+ bool _hasFader;
public:
PalettedScene();
diff --git a/engines/tsage/blue_force/blueforce_scenes0.cpp b/engines/tsage/blue_force/blueforce_scenes0.cpp
index f1f00599e0..06be605c1a 100644
--- a/engines/tsage/blue_force/blueforce_scenes0.cpp
+++ b/engines/tsage/blue_force/blueforce_scenes0.cpp
@@ -343,7 +343,7 @@ void Scene50::synchronize(Serializer &s) {
void Scene50::postInit(SceneObjectList *OwnerList) {
SceneExt::postInit();
- BF_GLOBALS._interfaceY = 200;
+ BF_GLOBALS._interfaceY = SCREEN_HEIGHT;
T2_GLOBALS._uiElements._active = false;
BF_GLOBALS._player.postInit();
BF_GLOBALS._player.setVisage(830);
@@ -419,6 +419,8 @@ void Scene50::postInit(SceneObjectList *OwnerList) {
tooltip = &_location8;
xp = 75;
break;
+ default:
+ error("Unexpected tooltip value %d", selectedTooltip);
}
_timer.set(240, this);
@@ -940,7 +942,6 @@ void Scene60::Action3::signal() {
scene->_stripManager.start(71, this);
break;
case 2:
- scene->_field1222 = true;
BF_GLOBALS._player.enableControl();
remove();
break;
@@ -954,7 +955,6 @@ Scene60::Scene60(): SceneExt() {
_sceneNumber = 0;
_visage = 0;
_cursorId = CURSOR_NONE;
- _field1222 = false;
}
void Scene60::synchronize(Serializer &s) {
@@ -964,7 +964,10 @@ void Scene60::synchronize(Serializer &s) {
s.syncAsSint16LE(_sceneNumber);
s.syncAsSint16LE(_visage);
s.syncAsSint16LE(_cursorId);
- s.syncAsSint16LE(_field1222);
+ if (s.getVersion() < 11) {
+ int useless = 0;
+ s.syncAsSint16LE(useless);
+ }
}
void Scene60::postInit(SceneObjectList *OwnerList) {
diff --git a/engines/tsage/blue_force/blueforce_scenes0.h b/engines/tsage/blue_force/blueforce_scenes0.h
index dd502c5f30..e7ee06e779 100644
--- a/engines/tsage/blue_force/blueforce_scenes0.h
+++ b/engines/tsage/blue_force/blueforce_scenes0.h
@@ -174,8 +174,6 @@ public:
int _sceneNumber;
int _visage;
CursorType _cursorId;
- // TODO: Check if really useless in original
- bool _field1222;
Scene60();
virtual void synchronize(Serializer &s);
diff --git a/engines/tsage/blue_force/blueforce_scenes1.cpp b/engines/tsage/blue_force/blueforce_scenes1.cpp
index d26e34ae23..fa877ea6c9 100644
--- a/engines/tsage/blue_force/blueforce_scenes1.cpp
+++ b/engines/tsage/blue_force/blueforce_scenes1.cpp
@@ -176,7 +176,6 @@ void Scene100::postInit(SceneObjectList *OwnerList) {
loadScene(101);
}
BF_GLOBALS._scenePalette.loadPalette(2);
- BF_GLOBALS._v51C44 = 1;
BF_GLOBALS._interfaceY = SCREEN_HEIGHT;
g_globals->_player.postInit();
@@ -232,7 +231,6 @@ void Scene109::Action1::signal() {
scene->_text.setup(BF_19840515, this);
break;
case 3:
- BF_GLOBALS._v51C44 = 1;
scene->loadScene(115);
scene->_protaginist2.show();
@@ -246,7 +244,6 @@ void Scene109::Action1::signal() {
scene->_beerSign.show();
scene->_beerSign.setAction(&scene->_action2);
- BF_GLOBALS._v501FC = 170;
setDelay(60);
break;
case 4:
@@ -401,12 +398,10 @@ void Scene110::Action1::signal() {
scene->_object6.show();
scene->_object9.show();
scene->_object10.show();
- BF_GLOBALS._v51C44 = 1;
scene->loadScene(110);
setDelay(10);
break;
case 2:
- BF_GLOBALS._v51C44 = 1;
scene->_object1.animate(ANIM_MODE_5, this);
break;
case 3: {
@@ -1833,8 +1828,6 @@ void Scene125::Action2::signal() {
setDelay(20);
break;
case 2: {
- BF_GLOBALS._v501FA = 10;
- BF_GLOBALS._v51C44 = 1;
Common::Point destPos(202, 94);
NpcMover *mover = new NpcMover();
BF_GLOBALS._player.addMover(mover, &destPos, this);
@@ -2311,7 +2304,6 @@ void Scene140::Action1::signal() {
setDelay(60);
// No break on purpose
case 13:
- BF_GLOBALS._v51C44 = 1;
BF_GLOBALS._sceneManager.changeScene(150);
default:
break;
@@ -2337,9 +2329,6 @@ void Scene140::postInit(SceneObjectList *OwnerList) {
_object1.changeZoom(100);
_object1.hide();
- BF_GLOBALS._v5020C = 0;
- BF_GLOBALS._v501F8 = 300;
- BF_GLOBALS._v501FC = 90;
BF_GLOBALS._sound1.play(7);
_object2.setAction(&_action1);
@@ -2640,7 +2629,6 @@ void Scene160::Action2::signal() {
BF_GLOBALS._sound1.stop();
// End of hack
- BF_GLOBALS._v51C44 = 1;
BF_GLOBALS._sceneManager.changeScene(200);
break;
default:
@@ -2788,9 +2776,6 @@ void Scene180::postInit(SceneObjectList *OwnerList) {
setZoomPercents(121, 60, 125, 70);
if ((BF_GLOBALS._bookmark == bLyleStoppedBy) && (BF_GLOBALS._dayNumber == 1)) {
- BF_GLOBALS._v501FC = 87;
- BF_GLOBALS._v501FA = _sceneBounds.left + 10;
- // CHECKME: BF_GLOBALS._v50206 = 18; ??
_sceneMessage.setup(THE_NEXT_DAY);
_sceneMode = 6;
setAction(&_sceneMessage, this);
@@ -2799,9 +2784,6 @@ void Scene180::postInit(SceneObjectList *OwnerList) {
BF_GLOBALS._mapLocationId = 4;
} else if (((BF_GLOBALS._bookmark == bDroppedOffLyle) && (BF_GLOBALS._dayNumber == 3)) ||
((BF_GLOBALS._bookmark == bDoneAtLyles) && (BF_GLOBALS._dayNumber == 4))) {
- BF_GLOBALS._v501FC = 87;
- BF_GLOBALS._v501FA = _sceneBounds.left + 10;
- // CHECKME: BF_GLOBALS._v50206 = 18; ??
_sceneMessage.setup(THE_NEXT_DAY);
_sceneMode = 6;
setAction(&_sceneMessage, this);
diff --git a/engines/tsage/blue_force/blueforce_scenes2.cpp b/engines/tsage/blue_force/blueforce_scenes2.cpp
index c992afe620..e444c8b91d 100644
--- a/engines/tsage/blue_force/blueforce_scenes2.cpp
+++ b/engines/tsage/blue_force/blueforce_scenes2.cpp
@@ -1603,7 +1603,6 @@ void Scene271::signal() {
}
break;
case 12:
- BF_GLOBALS._v51C44 = 0;
BF_GLOBALS._sound1.changeSound(67);
BF_GLOBALS._sceneManager.changeScene(280);
break;
@@ -1617,7 +1616,6 @@ void Scene271::signal() {
_field2E16 = 1;
break;
case 2704:
- BF_GLOBALS._v51C44 = 1;
BF_GLOBALS._sound1.fadeOut2(NULL);
BF_GLOBALS._sceneManager.changeScene(690);
break;
@@ -1649,7 +1647,6 @@ void Scene271::signal() {
addFader((const byte *)&black, 2, this);
break;
case 2712:
- BF_GLOBALS._v51C44 = 1;
BF_GLOBALS._sound1.fadeOut2(NULL);
BF_GLOBALS._sceneManager.changeScene(180);
break;
@@ -1657,7 +1654,6 @@ void Scene271::signal() {
BF_GLOBALS._player.enableControl();
break;
case 2714:
- BF_GLOBALS._v51C44 = 1;
BF_GLOBALS._sceneManager.changeScene(560);
break;
case 2715:
@@ -1752,7 +1748,7 @@ void Scene280::Action1::signal() {
case 1:
scene->_jake.setStrip(2);
scene->_jake.setFrame(1);
- scene->_jake.animate(ANIM_MODE_8, NULL);
+ scene->_jake.animate(ANIM_MODE_8, 0, NULL);
scene->_jake._numFrames = 5;
scene->_stripManager.start(2800, this);
diff --git a/engines/tsage/blue_force/blueforce_scenes3.cpp b/engines/tsage/blue_force/blueforce_scenes3.cpp
index 81e4af6e97..feaf789392 100644
--- a/engines/tsage/blue_force/blueforce_scenes3.cpp
+++ b/engines/tsage/blue_force/blueforce_scenes3.cpp
@@ -564,7 +564,6 @@ void Scene300::dispatch() {
if ((BF_GLOBALS._player._position.y < 59) && (BF_GLOBALS._player._position.x > 137) &&
(_sceneMode != 6308) && (_sceneMode != 7308)) {
- // The original was setting a useless global variable (removed)
_sceneMode = 6308;
BF_GLOBALS._player.disableControl();
ADD_MOVER(BF_GLOBALS._player, BF_GLOBALS._player._position.x + 20,
@@ -967,7 +966,6 @@ void Scene315::Action1::signal() {
/*--------------------------------------------------------------------------*/
Scene315::Scene315() {
- BF_GLOBALS._v51C44 = 1;
_field1B6C = _field139C = 0;
if (BF_GLOBALS._dayNumber == 0)
BF_GLOBALS._dayNumber = 1;
@@ -977,12 +975,19 @@ Scene315::Scene315() {
_doorOpened = false;
_invGreenCount = _bookGreenCount = 0;
_invGangCount = _bookGangCount = 0;
+
+ _stripNumber = 0;
+ _field1398 = 0;
+ _currentCursor = INV_NONE;
}
void Scene315::synchronize(Serializer &s) {
SceneExt::synchronize(s);
- s.syncAsSint16LE(_field1390);
+ if (s.getVersion() < 11) {
+ int useless = 0;
+ s.syncAsSint16LE(useless);
+ }
s.syncAsSint16LE(_stripNumber);
s.syncAsSint16LE(_field1398);
s.syncAsSint16LE(_invGreenCount);
@@ -1399,7 +1404,7 @@ bool Scene325::Item1::startAction(CursorType action, Event &event) {
void Scene325::postInit(SceneObjectList *OwnerList) {
SceneExt::postInit();
loadScene(325);
- BF_GLOBALS._interfaceY = 200;
+ BF_GLOBALS._interfaceY = SCREEN_HEIGHT;
BF_GLOBALS.clearFlag(fCanDrawGun);
if (BF_GLOBALS._dayNumber == 0)
@@ -1973,12 +1978,7 @@ void Scene340::Action8::signal() {
setDelay(6);
break;
- case 4:
- remove();
- break;
default:
- // This is present in the original game
- warning("Bugs");
remove();
break;
}
@@ -2868,9 +2868,9 @@ void Scene350::checkGun() {
void Scene355::Doorway::synchronize(Serializer &s) {
NamedObject::synchronize(s);
- s.syncAsSint16LE(_v1);
- s.syncAsSint16LE(_v2);
- s.syncAsSint16LE(_v3);
+ s.syncAsSint16LE(_mode1356Count);
+ s.syncAsSint16LE(_talkCount);
+ s.syncAsSint16LE(_onDuty);
}
bool Scene355::Doorway::startAction(CursorType action, Event &event) {
@@ -2890,9 +2890,9 @@ bool Scene355::Doorway::startAction(CursorType action, Event &event) {
return true;
case CURSOR_TALK:
if (BF_GLOBALS._dayNumber >= 5) {
- switch (_v2) {
+ switch (_talkCount) {
case 0:
- ++_v2;
+ ++_talkCount;
BF_GLOBALS._sound1.play(109);
BF_GLOBALS._player.disableControl();
scene->_sceneMode = 0;
@@ -2920,7 +2920,7 @@ bool Scene355::Doorway::startAction(CursorType action, Event &event) {
BF_GLOBALS._player.disableControl();
scene->_sceneMode = 3562;
scene->setAction(&scene->_sequenceManager, scene, 3562, &BF_GLOBALS._player, NULL);
- _v3 = !_v3 ? 1 : 0;
+ _onDuty = !_onDuty;
return true;
default:
break;
@@ -3355,14 +3355,14 @@ bool Scene355::Item11::startAction(CursorType action, Event &event) {
return true;
case CURSOR_TALK:
if (BF_GLOBALS._dayNumber == 5) {
- switch (scene->_doorway._v2) {
+ switch (scene->_doorway._talkCount) {
case 0:
BF_GLOBALS._player.disableControl();
scene->_sceneMode = 0;
BF_GLOBALS.setFlag(fTookTrailerAmmo);
scene->_stripManager.start(3575, scene);
scene->_lyle._flag = 1;
- scene->_doorway._v2 = 1;
+ scene->_doorway._talkCount = 1;
break;
case 1:
BF_GLOBALS._player.disableControl();
@@ -3534,28 +3534,28 @@ void Scene355::postInit(SceneObjectList *OwnerList) {
_doorway.setVisage(355);
_doorway.setPosition(Common::Point(193, 105));
_doorway.fixPriority(18);
- _doorway._v1 = 0;
- _doorway._v3 = 0;
+ _doorway._mode1356Count = 0;
+ _doorway._onDuty = false;
BF_GLOBALS._sceneItems.push_back(&_doorway);
switch (BF_GLOBALS._dayNumber) {
case 1:
if (!BF_GLOBALS.getFlag(onDuty))
- _doorway._v3 = 1;
+ _doorway._onDuty = true;
else if (BF_INVENTORY.getObjectScene(INV_GREENS_GUN) == 320)
- _doorway._v3 = 1;
+ _doorway._onDuty = true;
break;
case 2:
case 3:
case 4:
- _doorway._v3 = 1;
+ _doorway._onDuty = true;
break;
default:
break;
}
if (BF_GLOBALS._dayNumber == 5)
- _doorway._v2 = BF_GLOBALS.getFlag(fTookTrailerAmmo) ? 1 : 0;
+ _doorway._talkCount = BF_GLOBALS.getFlag(fTookTrailerAmmo) ? 1 : 0;
_object8.postInit();
_object8.setVisage(355);
@@ -3614,8 +3614,8 @@ void Scene355::postInit(SceneObjectList *OwnerList) {
_object11.animate(ANIM_MODE_2);
_doorway.setPosition(Common::Point(146, 107));
- _doorway._v3 = 0;
- _doorway._v2 = 2;
+ _doorway._onDuty = false;
+ _doorway._talkCount = 2;
_lyle._flag = 2;
_green.postInit();
@@ -3713,16 +3713,16 @@ void Scene355::signal() {
_stripManager.start(BF_GLOBALS.getFlag(fBackupIn350) ? 3559 : 3554, this);
break;
case 1356:
- switch (_doorway._v1) {
+ switch (_doorway._mode1356Count) {
case 0:
- ++_doorway._v1;
+ ++_doorway._mode1356Count;
_sceneMode = 9999;
_stripManager.start(3550, this);
break;
case 1:
_sceneMode = 9999;
_stripManager.start(3551, this);
- ++_doorway._v1;
+ ++_doorway._mode1356Count;
break;
default:
break;
@@ -3787,7 +3787,7 @@ void Scene355::signal() {
T2_GLOBALS._uiElements.addScore(10);
}
- SceneItem::display2(355, !_doorway._v3 ? 24 : 25);
+ SceneItem::display2(355, !_doorway._onDuty ? 24 : 25);
BF_GLOBALS._player.enableControl();
break;
case 4550:
@@ -3796,8 +3796,8 @@ void Scene355::signal() {
BF_GLOBALS._sound1.play(90);
BF_GLOBALS._player._regionBitList |= 0x10;
- _doorway._v3 = 0;
- _doorway._v2 = 2;
+ _doorway._onDuty = false;
+ _doorway._talkCount = 2;
_lyle._flag = 2;
BF_GLOBALS._player.enableControl();
break;
@@ -3867,13 +3867,13 @@ void Scene355::signal() {
case 9984:
if (BF_GLOBALS._dayNumber == 5) {
_sceneMode = 0;
- switch (_doorway._v2) {
+ switch (_doorway._talkCount) {
case 0:
BF_GLOBALS._sound1.play(109);
BF_GLOBALS.setFlag(fTookTrailerAmmo);
_stripManager.start(3575, this);
_lyle._flag = 1;
- ++_doorway._v2;
+ ++_doorway._talkCount;
break;
case 1:
_stripManager.start(3573, this);
@@ -3884,7 +3884,7 @@ void Scene355::signal() {
break;
}
} else if (BF_GLOBALS.getFlag(greenTaken) || (BF_GLOBALS._dayNumber > 1)) {
- if (_doorway._v3) {
+ if (_doorway._onDuty) {
SceneItem::display2(355, 23);
_sceneMode = 0;
signal();
@@ -4009,14 +4009,14 @@ void Scene355::signal() {
}
case 9997:
_sceneMode = 9999;
- _doorway._v1 = 2;
+ _doorway._mode1356Count = 2;
_stripManager.start(3562, this);
break;
case 9998:
error("Talkdoor state");
break;
case 9999:
- if (_doorway._v1 != 2) {
+ if (_doorway._mode1356Count != 2) {
BF_GLOBALS._player.enableControl();
BF_GLOBALS._player._canWalk = false;
} else if (BF_GLOBALS.getFlag(gunDrawn)) {
@@ -4439,7 +4439,6 @@ void Scene360::postInit(SceneObjectList *OwnerList) {
BF_GLOBALS._player.enableControl();
if ((BF_GLOBALS._sceneManager._previousScene == 355) || (BF_GLOBALS._sceneManager._previousScene != 370)) {
- // The original was using there a useless variable (now removed)
BF_GLOBALS._player.setPosition(Common::Point(253, 135));
BF_GLOBALS._player.setStrip(2);
@@ -4527,7 +4526,7 @@ void Scene360::signal() {
BF_GLOBALS._player.enableControl();
break;
case 3608:
- BF_GLOBALS._sceneManager.changeScene(355);
+ BF_GLOBALS._sceneManager.changeScene(355);
break;
case 3610:
BF_GLOBALS._sceneManager.changeScene(666);
@@ -4652,10 +4651,10 @@ bool Scene370::Green::startAction(CursorType action, Event &event) {
switch (action) {
case CURSOR_LOOK:
- SceneItem::display2(370, (_v2 < 3) ? 10 : 0);
+ SceneItem::display2(370, (_talkCount < 3) ? 10 : 0);
return true;
case CURSOR_USE:
- if (_v2 != 3)
+ if (_talkCount != 3)
SceneItem::display2(370, 1);
else if (BF_INVENTORY.getObjectScene(INV_HANDCUFFS) == 1)
SceneItem::display2(370, 26);
@@ -4671,14 +4670,14 @@ bool Scene370::Green::startAction(CursorType action, Event &event) {
return true;
case CURSOR_TALK:
BF_GLOBALS._player.disableControl();
- switch (_v2) {
+ switch (_talkCount) {
case 0:
- ++_v2;
+ ++_talkCount;
scene->_sceneMode = 3706;
scene->setAction(&scene->_sequenceManager, scene, 3706, NULL);
break;
case 1:
- ++_v2;
+ ++_talkCount;
scene->_sceneMode = 3707;
scene->_object5.postInit();
@@ -4690,7 +4689,7 @@ bool Scene370::Green::startAction(CursorType action, Event &event) {
scene->setAction(&scene->_sequenceManager, scene, 3707, &scene->_harrison, &scene->_object5, NULL);
break;
case 2:
- ++_v2;
+ ++_talkCount;
scene->_sceneMode = 3708;
scene->setAction(&scene->_sequenceManager, scene, 3708, this, &scene->_laura, &scene->_harrison,
&scene->_object5, &scene->_greensGun, NULL);
@@ -4716,7 +4715,7 @@ bool Scene370::Green::startAction(CursorType action, Event &event) {
}
return true;
case INV_HANDCUFFS:
- if (_v2 != 3)
+ if (_talkCount != 3)
SceneItem::display2(370, 2);
else {
T2_GLOBALS._uiElements.addScore(50);
@@ -4753,7 +4752,7 @@ bool Scene370::Harrison::startAction(CursorType action, Event &event) {
SceneItem::display2(370, 8);
return true;
case CURSOR_TALK:
- if (scene->_green._v2 != 3) {
+ if (scene->_green._talkCount != 3) {
scene->_sceneMode = 3;
scene->_stripManager.start(3714, scene);
} else if ((BF_INVENTORY.getObjectScene(INV_GREENS_KNIFE) == 1) ||
diff --git a/engines/tsage/blue_force/blueforce_scenes3.h b/engines/tsage/blue_force/blueforce_scenes3.h
index ea9d5f7311..894c3e5ffd 100644
--- a/engines/tsage/blue_force/blueforce_scenes3.h
+++ b/engines/tsage/blue_force/blueforce_scenes3.h
@@ -210,7 +210,6 @@ public:
WestExit _westExit;
SouthWestExit _swExit;
Action1 _action1;
- int _field1390;
int _stripNumber;
int _field1398;
int _invGreenCount, _bookGreenCount, _invGangCount;
@@ -494,9 +493,10 @@ class Scene355: public PalettedScene {
/* Objects */
class Doorway: public NamedObject {
public:
- int _v1, _v2, _v3;
+ int _mode1356Count, _talkCount;
+ bool _onDuty;
- Doorway() { _v1 = _v2 = _v3 = 0; }
+ Doorway() { _mode1356Count = _talkCount = 0; _onDuty = false; }
virtual Common::String getClassName() { return "Scene355_Doorway"; }
virtual void synchronize(Serializer &s);
virtual bool startAction(CursorType action, Event &event);
diff --git a/engines/tsage/blue_force/blueforce_scenes4.cpp b/engines/tsage/blue_force/blueforce_scenes4.cpp
index a10f311791..2b4c0ff348 100644
--- a/engines/tsage/blue_force/blueforce_scenes4.cpp
+++ b/engines/tsage/blue_force/blueforce_scenes4.cpp
@@ -39,7 +39,7 @@ namespace BlueForce {
void Scene410::Action1::signal() {
Scene410 *scene = (Scene410 *)BF_GLOBALS._sceneManager._scene;
- switch (scene->_field1FB6++) {
+ switch (scene->_action1Count++) {
case 0:
if (BF_GLOBALS.getFlag(fTalkedDriverNoBkup)) {
setDelay(3);
@@ -136,11 +136,11 @@ void Scene410::Action5::signal() {
switch (_actionIndex++) {
case 0:
- if (scene->_field1FC4 == 0) {
+ if (!scene->_harrisonMovedFl) {
ADD_PLAYER_MOVER(114, 133);
} else {
ADD_PLAYER_MOVER(195, 139);
- }
+ }
break;
case 1:
BF_GLOBALS._player.updateAngle(scene->_passenger._position);
@@ -167,7 +167,7 @@ void Scene410::Action6::signal() {
switch (_actionIndex++) {
case 0:
- if (scene->_field1FC4 == 0) {
+ if (!scene->_harrisonMovedFl) {
ADD_PLAYER_MOVER(114, 133);
} else {
ADD_PLAYER_MOVER(126, 99);
@@ -243,7 +243,7 @@ bool Scene410::Motorcycle::startAction(CursorType action, Event &event) {
} else if (BF_GLOBALS.getFlag(fSearchedTruck) && !BF_GLOBALS._sceneObjects->contains(&scene->_harrison)) {
scene->_sceneMode = 4103;
scene->signal();
- } else if (scene->_field1FBC != 0) {
+ } else if (scene->_cuffedDriverFl) {
SceneItem::display2(410, 12);
} else {
scene->_sceneMode = 4103;
@@ -260,7 +260,7 @@ bool Scene410::TruckFront::startAction(CursorType action, Event &event) {
switch (action) {
case CURSOR_USE:
- if ((BF_GLOBALS._bookmark < bStoppedFrankie) && (!scene->_field1FBC || !scene->_field1FBA))
+ if ((BF_GLOBALS._bookmark < bStoppedFrankie) && (!scene->_cuffedDriverFl || !scene->_harrissonTalkFl))
break;
else if (BF_GLOBALS.getFlag(fSearchedTruck))
SceneItem::display2(410, 13);
@@ -293,11 +293,11 @@ bool Scene410::Driver::startAction(CursorType action, Event &event) {
} else {
SceneItem::display2(410, 7);
}
- } else if (!scene->_field1FBC) {
+ } else if (!scene->_cuffedDriverFl) {
SceneItem::display2(410, 7);
- } else if (!scene->_field1FC0) {
+ } else if (!scene->_getDriverFl) {
scene->_sceneMode = 4124;
- scene->_field1FC0 = 1;
+ scene->_getDriverFl = true;
T2_GLOBALS._uiElements.addScore(30);
scene->signal();
} else {
@@ -309,13 +309,13 @@ bool Scene410::Driver::startAction(CursorType action, Event &event) {
return true;
case INV_HANDCUFFS:
if (BF_GLOBALS.getFlag(fCalledBackup)) {
- if ((scene->_talkCount < 5) || (scene->_field1FB6 < 1) || (scene->_field1FBC != 0))
+ if ((scene->_talkCount < 5) || (scene->_action1Count < 1) || scene->_cuffedDriverFl)
break;
BF_GLOBALS._player.disableControl();
scene->_sceneMode = 4123;
scene->_stripManager.start(4125, scene);
- scene->_field1FBC = 1;
+ scene->_cuffedDriverFl = true;
T2_GLOBALS._uiElements.addScore(30);
} else {
if (BF_GLOBALS.getFlag(fTalkedDriverNoBkup)) {
@@ -328,14 +328,14 @@ bool Scene410::Driver::startAction(CursorType action, Event &event) {
case INV_TICKET_BOOK:
if (!BF_GLOBALS.getFlag(fDriverOutOfTruck)) {
return startAction(CURSOR_TALK, event);
- } else if (!scene->_field1FC4) {
+ } else if (!scene->_harrisonMovedFl) {
BF_GLOBALS._player.disableControl();
scene->_sceneMode = 2;
scene->setAction(&scene->_sequenceManager1, scene, 4120, &scene->_passenger, &BF_GLOBALS._player, NULL);
- } else if ((scene->_field1FBC != 0) || (scene->_field1FC2 != 0)) {
+ } else if (scene->_cuffedDriverFl || scene->_driverOutOfTruckFl) {
break;
} else {
- scene->_field1FC2 = 1;
+ scene->_driverOutOfTruckFl = true;
T2_GLOBALS._uiElements.addScore(30);
BF_GLOBALS._player.disableControl();
scene->_sceneMode = 4127;
@@ -343,7 +343,7 @@ bool Scene410::Driver::startAction(CursorType action, Event &event) {
}
return true;
case INV_MIRANDA_CARD:
- if (scene->_field1FBC == 0)
+ if (!scene->_cuffedDriverFl)
return false;
if (BF_GLOBALS.getFlag(readFrankRights)) {
@@ -379,15 +379,15 @@ bool Scene410::Passenger::startAction(CursorType action, Event &event) {
SET_Y, GLOBALS._sceneManager._scene->_sceneBounds.top + UI_INTERFACE_Y + 2,
SET_FONT, 4, SET_BG_COLOR, 1, SET_FG_COLOR, 96, SET_EXT_BGCOLOR, 99,
SET_EXT_FGCOLOR, 13, LIST_END);
- } else if (!scene->_field1FBA) {
+ } else if (!scene->_harrissonTalkFl) {
SceneItem::display(410, 5, SET_WIDTH, 300,
SET_X, 10 + GLOBALS._sceneManager._scene->_sceneBounds.left,
SET_Y, GLOBALS._sceneManager._scene->_sceneBounds.top + UI_INTERFACE_Y + 2,
SET_FONT, 4, SET_BG_COLOR, 1, SET_FG_COLOR, 96, SET_EXT_BGCOLOR, 99,
SET_EXT_FGCOLOR, 13, LIST_END);
- } else if (!scene->_field1FBE) {
+ } else if (!scene->_cuffedPassengerFl) {
scene->_sceneMode = 4121;
- scene->_field1FBE = 1;
+ scene->_cuffedPassengerFl = true;
T2_GLOBALS._uiElements.addScore(50);
scene->signal();
} else
@@ -398,7 +398,7 @@ bool Scene410::Passenger::startAction(CursorType action, Event &event) {
return true;
case INV_HANDCUFFS:
if (BF_GLOBALS.getFlag(fCalledBackup)) {
- if ((scene->_talkCount < 5) || (scene->_field1FBA != 0))
+ if ((scene->_talkCount < 5) || (scene->_harrissonTalkFl))
break;
BF_GLOBALS._player.disableControl();
@@ -413,7 +413,7 @@ bool Scene410::Passenger::startAction(CursorType action, Event &event) {
}
return true;
case INV_MIRANDA_CARD:
- if (!scene->_field1FBA)
+ if (!scene->_harrissonTalkFl)
break;
if (BF_GLOBALS.getFlag(readFrankRights)) {
@@ -455,7 +455,7 @@ bool Scene410::Harrison::startAction(CursorType action, Event &event) {
SET_FONT, 4, SET_BG_COLOR, 1, SET_FG_COLOR, 32, SET_EXT_BGCOLOR, 49,
SET_EXT_FGCOLOR, 13, LIST_END);
}
- } else if ((scene->_field1FBA != 0) && (scene->_field1FBC != 0)) {
+ } else if (scene->_harrissonTalkFl && scene->_cuffedDriverFl) {
BF_GLOBALS._player.disableControl();
scene->_sceneMode = 4112;
scene->_stripManager.start(4113, scene);
@@ -463,27 +463,27 @@ bool Scene410::Harrison::startAction(CursorType action, Event &event) {
BF_GLOBALS.set2Flags(f1098Frankie);
BF_GLOBALS.clearFlag(f1098Marina);
} else if ((BF_INVENTORY.getObjectScene(INV_HANDCUFFS) == 1) ||
- (!scene->_field1FBA && (scene->_talkCount < 5))) {
+ (!scene->_harrissonTalkFl && (scene->_talkCount < 5))) {
SceneItem::display(350, 13, SET_WIDTH, 300,
SET_X, 10 + GLOBALS._sceneManager._scene->_sceneBounds.left,
SET_Y, GLOBALS._sceneManager._scene->_sceneBounds.top + UI_INTERFACE_Y + 2,
SET_FONT, 4, SET_BG_COLOR, 1, SET_FG_COLOR, 32, SET_EXT_BGCOLOR, 49,
SET_EXT_FGCOLOR, 13, LIST_END);
- } else if (!scene->_field1FBA) {
+ } else if (!scene->_harrissonTalkFl) {
BF_GLOBALS._player.disableControl();
- scene->_field1FBA = 1;
- scene->_field1FBE = 1;
+ scene->_harrissonTalkFl = true;
+ scene->_cuffedPassengerFl = true;
BF_GLOBALS._walkRegions.enableRegion(22);
scene->_sceneMode = 4122;
scene->_stripManager.start(4112, scene);
- } else if (scene->_field1FB6 < 1) {
+ } else if (scene->_action1Count < 1) {
break;
- } else if (scene->_field1FBC != 0) {
+ } else if (scene->_cuffedDriverFl) {
error("Error - want to cuff driver, but he's cuffed already");
} else {
BF_GLOBALS._player.disableControl();
- scene->_field1FBC = 1;
- scene->_field1FC0 = 1;
+ scene->_cuffedDriverFl = true;
+ scene->_getDriverFl = true;
BF_GLOBALS._walkRegions.enableRegion(22);
scene->_sceneMode = 4109;
scene->_stripManager.start(4112, scene);
@@ -500,20 +500,24 @@ bool Scene410::Harrison::startAction(CursorType action, Event &event) {
/*--------------------------------------------------------------------------*/
Scene410::Scene410(): SceneExt() {
- _field1FB6 = _talkCount = _field1FBA = _field1FBC = 0;
- _field1FBE = _field1FC0 = _field1FC2 = _field1FC4 = 0;
+ _cuffedDriverFl = _harrissonTalkFl = _driverOutOfTruckFl = false;
+ _harrisonMovedFl = false;
+
+ _action1Count = _talkCount = 0;
+ _cuffedPassengerFl = false;
+ _getDriverFl = false;
}
void Scene410::synchronize(Serializer &s) {
SceneExt::synchronize(s);
- s.syncAsSint16LE(_field1FB6);
+ s.syncAsSint16LE(_action1Count);
s.syncAsSint16LE(_talkCount);
- s.syncAsSint16LE(_field1FBA);
- s.syncAsSint16LE(_field1FBC);
- s.syncAsSint16LE(_field1FBE);
- s.syncAsSint16LE(_field1FC0);
- s.syncAsSint16LE(_field1FC2);
- s.syncAsSint16LE(_field1FC4);
+ s.syncAsSint16LE(_harrissonTalkFl);
+ s.syncAsSint16LE(_cuffedDriverFl);
+ s.syncAsSint16LE(_cuffedPassengerFl);
+ s.syncAsSint16LE(_getDriverFl);
+ s.syncAsSint16LE(_driverOutOfTruckFl);
+ s.syncAsSint16LE(_harrisonMovedFl);
}
void Scene410::postInit(SceneObjectList *OwnerList) {
@@ -593,7 +597,7 @@ void Scene410::postInit(SceneObjectList *OwnerList) {
_patrolCar.fixPriority(148);
_patrolCar.setPosition(Common::Point(39, 168));
- _field1FC4 = 1;
+ _harrisonMovedFl = true;
_sceneMode = 0;
signal();
break;
@@ -603,10 +607,10 @@ void Scene410::postInit(SceneObjectList *OwnerList) {
_driver.remove();
_sceneMode = 0;
} else {
- _field1FC4 = BF_GLOBALS._v50CC8;
- _field1FBA = BF_GLOBALS._v50CC2;
- _talkCount = BF_GLOBALS._v50CC6;
- _field1FB6 = BF_GLOBALS._v50CC4;
+ _harrisonMovedFl = BF_GLOBALS._scene410HarrisonMovedFl;
+ _harrissonTalkFl = BF_GLOBALS._scene410HarrisonTalkFl;
+ _talkCount = BF_GLOBALS._scene410TalkCount;
+ _action1Count = BF_GLOBALS._scene410Action1Count;
_passenger.setVisage(418);
_passenger.setStrip(6);
@@ -617,7 +621,7 @@ void Scene410::postInit(SceneObjectList *OwnerList) {
_passenger.setStrip(2);
_passenger.setFrame(5);
}
- if (_field1FBA) {
+ if (_harrissonTalkFl) {
_passenger.setVisage(415);
_passenger.setStrip(6);
_passenger.setFrame(8);
@@ -651,7 +655,7 @@ void Scene410::postInit(SceneObjectList *OwnerList) {
_patrolCar.setDetails(410, 8, 9, 10, 1, (SceneItem *)NULL);
_patrolCar.fixPriority(148);
- if (_field1FC4) {
+ if (_harrisonMovedFl) {
_harrison.setPosition(Common::Point(108, 112));
_patrolCar.fixPriority(148);
_patrolCar.setPosition(Common::Point(39, 168));
@@ -664,7 +668,7 @@ void Scene410::postInit(SceneObjectList *OwnerList) {
_sceneMode = 0;
}
- _field1FC4 = 1;
+ _harrisonMovedFl = true;
}
break;
case 50:
@@ -686,10 +690,10 @@ void Scene410::signal() {
BF_GLOBALS.set2Flags(f1097Frankie);
BF_GLOBALS.clearFlag(f1097Marina);
- BF_GLOBALS._v50CC8 = _field1FC4;
- BF_GLOBALS._v50CC2 = _field1FBA;
- BF_GLOBALS._v50CC6 = _talkCount;
- BF_GLOBALS._v50CC4 = _field1FB6;
+ BF_GLOBALS._scene410HarrisonMovedFl = _harrisonMovedFl;
+ BF_GLOBALS._scene410HarrisonTalkFl = _harrissonTalkFl;
+ BF_GLOBALS._scene410TalkCount = _talkCount;
+ BF_GLOBALS._scene410Action1Count = _action1Count;
BF_GLOBALS._sceneManager.changeScene(60);
break;
case 2:
@@ -730,7 +734,7 @@ void Scene410::signal() {
case 9:
_sceneMode = 4106;
_stripManager.start(4111, this);
- _field1FBA = 1;
+ _harrissonTalkFl = true;
BF_GLOBALS.setFlag(fCuffedFrankie);
T2_GLOBALS._uiElements.addScore(30);
break;
@@ -760,7 +764,7 @@ void Scene410::signal() {
break;
case 4104:
// After call for backup, patrol car is coming
- _field1FC4 = 1;
+ _harrisonMovedFl = true;
BF_GLOBALS._player.disableControl();
_sceneMode = 0;
setAction(&_sequenceManager1, this, 4104, &_patrolCar, &_harrison, NULL);
@@ -1432,21 +1436,21 @@ bool Scene450::Manager::startAction(CursorType action, Event &event) {
} else {
animate(ANIM_MODE_8, 1, NULL);
- if (scene->_field19AC) {
+ if (scene->_managerCallsWeaselFl) {
scene->_sceneMode = 2;
- if (scene->_field19AE) {
+ if (scene->_talkManagerFl) {
scene->_stripManager.start(4521, scene);
} else {
- scene->_field19AE = 1;
+ scene->_talkManagerFl = true;
scene->_stripManager.start(4512, scene);
}
} else {
scene->_sceneMode = 4506;
- if (scene->_field19AE) {
+ if (scene->_talkManagerFl) {
scene->setAction(&scene->_sequenceManager, scene, 4518, &BF_GLOBALS._player, this, NULL);
} else {
scene->_sceneMode = 4506;
- scene->_field19AE = 1;
+ scene->_talkManagerFl = true;
scene->setAction(&scene->_sequenceManager, scene, 4506, &BF_GLOBALS._player, this, NULL);
}
}
@@ -1524,13 +1528,13 @@ bool Scene450::Exit::startAction(CursorType action, Event &event) {
/*--------------------------------------------------------------------------*/
Scene450::Scene450(): SceneExt() {
- _field19AC = _field19AE = 0;
+ _managerCallsWeaselFl = _talkManagerFl = false;
}
void Scene450::synchronize(Serializer &s) {
SceneExt::synchronize(s);
- s.syncAsSint16LE(_field19AC);
- s.syncAsSint16LE(_field19AE);
+ s.syncAsSint16LE(_managerCallsWeaselFl);
+ s.syncAsSint16LE(_talkManagerFl);
}
void Scene450::postInit(SceneObjectList *OwnerList) {
@@ -1654,7 +1658,7 @@ void Scene450::signal() {
case 4510:
case 4511:
BF_GLOBALS.setFlag(fMgrCallsWeasel);
- _field19AC = 1;
+ _managerCallsWeaselFl = true;
_sceneMode = 4503;
setAction(&_sequenceManager, this, 4503, &_weasel, &_door, &_manager, NULL);
break;
diff --git a/engines/tsage/blue_force/blueforce_scenes4.h b/engines/tsage/blue_force/blueforce_scenes4.h
index 937c015a4c..e5877df4f0 100644
--- a/engines/tsage/blue_force/blueforce_scenes4.h
+++ b/engines/tsage/blue_force/blueforce_scenes4.h
@@ -116,9 +116,12 @@ public:
SpeakerDriver _driverSpeaker;
SpeakerShooter _shooterSpeaker;
ASoundExt _sound1;
- int _field1FB6, _talkCount, _field1FBA;
- int _field1FBC, _field1FBE;
- int _field1FC0, _field1FC2, _field1FC4;
+ int _action1Count, _talkCount;
+ bool _harrissonTalkFl;
+ bool _cuffedDriverFl;
+ bool _cuffedPassengerFl;
+ bool _getDriverFl;
+ bool _driverOutOfTruckFl, _harrisonMovedFl;
Scene410();
virtual void postInit(SceneObjectList *OwnerList = NULL);
@@ -254,7 +257,8 @@ public:
NamedObject _door, _counterDoor;
Exit _exit;
NamedHotspot _interior, _shelf, _counter;
- int _field19AC, _field19AE;
+ bool _managerCallsWeaselFl;
+ bool _talkManagerFl;
Scene450();
virtual void synchronize(Serializer &s);
diff --git a/engines/tsage/blue_force/blueforce_scenes5.cpp b/engines/tsage/blue_force/blueforce_scenes5.cpp
index 0cf487daa9..101a39c4b7 100644
--- a/engines/tsage/blue_force/blueforce_scenes5.cpp
+++ b/engines/tsage/blue_force/blueforce_scenes5.cpp
@@ -1772,12 +1772,12 @@ void Scene570::IconManager::refreshList() {
}
void Scene570::IconManager::addItem(Icon *item) {
- item->_mode = _mode;
_list.push_back(item);
}
Scene570::Icon::Icon(): NamedObject() {
_iconId = _folderId = 0;
+ _parentFolderId = 0;
}
void Scene570::Icon::synchronize(Serializer &s) {
@@ -1785,7 +1785,10 @@ void Scene570::Icon::synchronize(Serializer &s) {
s.syncAsSint16LE(_iconId);
s.syncAsSint16LE(_folderId);
s.syncAsSint16LE(_parentFolderId);
- s.syncAsSint16LE(_mode);
+ if (s.getVersion() < 11) {
+ int useless = 0;
+ s.syncAsSint16LE(useless);
+ }
}
void Scene570::Icon::remove() {
@@ -1906,7 +1909,7 @@ bool Scene570::Icon::startAction(CursorType action, Event &event) {
}
}
-void Scene570::Icon::setDetails(int iconId, int folderId, int parentFolderId, int unused, const Common::String &msg) {
+void Scene570::Icon::setDetails(int iconId, int folderId, int parentFolderId, const Common::String &msg) {
Scene570 *scene = (Scene570 *)BF_GLOBALS._sceneManager._scene;
NamedObject::postInit();
@@ -2073,23 +2076,23 @@ void Scene570::signal() {
_printerIcon.setDetails(570, 14, 15, -1, 2, (SceneItem *)NULL);
_iconManager.setup(2);
- _folder1.setDetails(1, 1, 0, 2, SCENE570_C_DRIVE);
- _folder2.setDetails(1, 2, 1, 2, SCENE570_RING);
- _folder3.setDetails(1, 3, 1, 2, SCENE570_PROTO);
- _folder4.setDetails(1, 4, 1, 2, SCENE570_WACKY);
+ _folder1.setDetails(1, 1, 0, SCENE570_C_DRIVE);
+ _folder2.setDetails(1, 2, 1, SCENE570_RING);
+ _folder3.setDetails(1, 3, 1, SCENE570_PROTO);
+ _folder4.setDetails(1, 4, 1, SCENE570_WACKY);
if (!BF_GLOBALS.getFlag(fDecryptedBluePrints))
- _icon1.setDetails(3, 5, 0, 2, SCENE570_COBB);
- _icon2.setDetails(2, 7, 0, 2, SCENE570_LETTER);
+ _icon1.setDetails(3, 5, 0, SCENE570_COBB);
+ _icon2.setDetails(2, 7, 0, SCENE570_LETTER);
if (BF_GLOBALS.getFlag(fDecryptedBluePrints))
- _icon3.setDetails(7, 6, 0, 2, SCENE570_COBB);
+ _icon3.setDetails(7, 6, 0, SCENE570_COBB);
- _icon4.setDetails(6, 8, 1, 2, SCENE570_RINGEXE);
- _icon5.setDetails(5, 9, 1, 2, SCENE570_RINGDATA);
- _icon6.setDetails(6, 10, 2, 2, SCENE570_PROTOEXE);
- _icon7.setDetails(5, 11, 2, 2, SCENE570_PROTODATA);
- _icon8.setDetails(6, 12, 3, 2, SCENE570_WACKYEXE);
- _icon9.setDetails(5, 13, 3, 2, SCENE570_WACKYDATA);
+ _icon4.setDetails(6, 8, 1, SCENE570_RINGEXE);
+ _icon5.setDetails(5, 9, 1, SCENE570_RINGDATA);
+ _icon6.setDetails(6, 10, 2, SCENE570_PROTOEXE);
+ _icon7.setDetails(5, 11, 2, SCENE570_PROTODATA);
+ _icon8.setDetails(6, 12, 3, SCENE570_WACKYEXE);
+ _icon9.setDetails(5, 13, 3, SCENE570_WACKYDATA);
_iconManager.refreshList();
BF_GLOBALS._player.enableControl();
@@ -2104,7 +2107,7 @@ void Scene570::signal() {
_object3.setFrame(1);
_object3.fixPriority(1);
- _icon3.setDetails(7, 6, 0, 2, SCENE570_COBB);
+ _icon3.setDetails(7, 6, 0, SCENE570_COBB);
_iconManager.refreshList();
T2_GLOBALS._uiElements._active = true;
T2_GLOBALS._uiElements.show();
diff --git a/engines/tsage/blue_force/blueforce_scenes5.h b/engines/tsage/blue_force/blueforce_scenes5.h
index 56bf20c93b..71c7f3d8f1 100644
--- a/engines/tsage/blue_force/blueforce_scenes5.h
+++ b/engines/tsage/blue_force/blueforce_scenes5.h
@@ -257,7 +257,7 @@ class Scene570: public SceneExt {
class Icon: public NamedObject {
public:
SceneText _sceneText;
- int _iconId, _folderId, _parentFolderId, _mode;
+ int _iconId, _folderId, _parentFolderId;
Common::String _text;
Icon();
@@ -266,7 +266,7 @@ class Scene570: public SceneExt {
virtual void remove();
virtual bool startAction(CursorType action, Event &event);
- void setDetails(int iconId, int folderId, int parentFolderId, int unused, const Common::String &msg);
+ void setDetails(int iconId, int folderId, int parentFolderId, const Common::String &msg);
};
class IconManager: public EventHandler {
public:
diff --git a/engines/tsage/blue_force/blueforce_scenes6.cpp b/engines/tsage/blue_force/blueforce_scenes6.cpp
index 9467df7917..b20092492f 100644
--- a/engines/tsage/blue_force/blueforce_scenes6.cpp
+++ b/engines/tsage/blue_force/blueforce_scenes6.cpp
@@ -79,7 +79,6 @@ void Scene600::Action1::signal() {
}
BF_GLOBALS._screenSurface.fillRect(BF_GLOBALS._screenSurface.getBounds(), 0);
- BF_GLOBALS._v51C44 = 1;
scene->loadScene(999);
setDelay(5);
break;
@@ -88,7 +87,6 @@ void Scene600::Action1::signal() {
setDelay(5);
break;
case 7:
- BF_GLOBALS._v51C44 = 0;
remove();
break;
default:
@@ -275,7 +273,7 @@ bool Scene666::Item1::startAction(CursorType action, Event &event) {
void Scene666::postInit(SceneObjectList *OwnerList) {
BF_GLOBALS._sound1.play(27);
SceneExt::postInit();
- BF_GLOBALS._interfaceY = 200;
+ BF_GLOBALS._interfaceY = SCREEN_HEIGHT;
loadScene(999);
BF_GLOBALS._screenSurface.fillRect(BF_GLOBALS._screenSurface.getBounds(), 0);
diff --git a/engines/tsage/blue_force/blueforce_scenes7.cpp b/engines/tsage/blue_force/blueforce_scenes7.cpp
index 4cdd2f3f15..2f52c4df95 100644
--- a/engines/tsage/blue_force/blueforce_scenes7.cpp
+++ b/engines/tsage/blue_force/blueforce_scenes7.cpp
@@ -148,7 +148,7 @@ void Scene710::postInit(SceneObjectList *OwnerList) {
BF_GLOBALS._sound1.fadeSound(14);
_soundExt1.fadeSound(48);
- _v51C34.set(40, 0, 280, 240);
+
BF_GLOBALS._player.postInit();
BF_GLOBALS._player.hide();
BF_GLOBALS._player._moveDiff = Common::Point(4, 2);
diff --git a/engines/tsage/blue_force/blueforce_scenes8.cpp b/engines/tsage/blue_force/blueforce_scenes8.cpp
index 9a20788b6a..f78a332be9 100644
--- a/engines/tsage/blue_force/blueforce_scenes8.cpp
+++ b/engines/tsage/blue_force/blueforce_scenes8.cpp
@@ -577,17 +577,15 @@ bool Scene810::Lyle::startAction(CursorType action, Event &event) {
if ((BF_GLOBALS.getFlag(shownLyleRapsheet)) || (BF_GLOBALS.getFlag(shownLyleCrate1))){
scene->_sceneMode = 8141;
} else {
- // Doublecheck on shownLyleCrate1 removed: useless
scene->_sceneMode = 8144;
}
} else {
if ((BF_GLOBALS.getFlag(shownLyleRapsheet)) || (BF_GLOBALS.getFlag(shownLyleCrate1))) {
scene->_sceneMode = 8129;
- } else { // if (BF_GLOBALS.getFlag(shownLyleCrate1)) {
+ } else {
scene->_sceneMode = 8132;
- // doublecheck Present in the original, may hide a bug in the original
- //} else
- // scene->_sceneMode = 8121;
+ // Double check on ShownLyleCrate1 present in the original, may hide a bug in the original
+ // The original was then setting _sceneMode 8121
}
}
}
@@ -1071,7 +1069,6 @@ void Scene810::postInit(SceneObjectList *OwnerList) {
setAction(&_sequenceManager1, this, 8107, &BF_GLOBALS._player, &_lyle, NULL);
break;
case 935:
- BF_GLOBALS._v51C44 = 1;
BF_GLOBALS._scenePalette.loadPalette(2);
_lyle.remove();
@@ -1804,13 +1801,11 @@ void Scene830::signal() {
_sceneMode = 832;
BF_GLOBALS._scenePalette.clearListeners();
addFader((const byte *)&black, 5, this);
- BF_GLOBALS._v51C44 = 0;
break;
case 12:
_sceneMode = 831;
BF_GLOBALS._scenePalette.clearListeners();
addFader((const byte *)&black, 5, this);
- BF_GLOBALS._v51C44 = 0;
break;
case 13:
BF_GLOBALS._sceneManager.changeScene(850);
@@ -1963,7 +1958,7 @@ void Scene840::BoatKeysInset::postInit(SceneObjectList *OwnerList) {
_waveKeys.setDetails(840, 53, 8, -1, 2, (SceneItem *)NULL);
}
- _v1B4 = _v1B6 = 0;
+ _usedRentalKeys = _usedWaveKeys = false;
}
void Scene840::BoatKeysInset::remove() {
@@ -2072,7 +2067,7 @@ bool Scene840::BoatKeysInset::RentalKeys::startAction(CursorType action, Event &
BF_INVENTORY.setObjectScene(INV_RENTAL_KEYS, 1);
T2_GLOBALS._uiElements.addScore(30);
- scene->_boatKeysInset._v1B4 = 1;
+ scene->_boatKeysInset._usedRentalKeys = true;
remove();
}
return true;
@@ -2090,7 +2085,7 @@ bool Scene840::BoatKeysInset::WaveKeys::startAction(CursorType action, Event &ev
SceneItem::display2(840, 56);
BF_INVENTORY.setObjectScene(INV_WAVE_KEYS, 1);
T2_GLOBALS._uiElements.addScore(50);
- scene->_boatKeysInset._v1B6 = 1;
+ scene->_boatKeysInset._usedWaveKeys = true;
remove();
} else {
SceneItem::display2(840, 9);
@@ -2101,6 +2096,15 @@ bool Scene840::BoatKeysInset::WaveKeys::startAction(CursorType action, Event &ev
}
}
+void Scene840::BoatKeysInset::synchronize(Serializer &s) {
+ FocusObject::synchronize(s);
+
+ if (s.getVersion() >= 12) {
+ s.syncAsSint16LE(_usedWaveKeys);
+ s.syncAsSint16LE(_usedRentalKeys);
+ }
+}
+
bool Scene840::BoatKeys::startAction(CursorType action, Event &event) {
Scene840 *scene = (Scene840 *)BF_GLOBALS._sceneManager._scene;
@@ -2472,10 +2476,10 @@ void Scene840::signal() {
_boatKeysInset.setDetails(840, 50, 8, 51);
break;
case 8412:
- if (_boatKeysInset._v1B6) {
+ if (_boatKeysInset._usedWaveKeys) {
_sceneMode = 8409;
setAction(&_sequenceManager1, this, 8409, &BF_GLOBALS._player, &_carter, &_doors, NULL);
- } else if (!_boatKeysInset._v1B4) {
+ } else if (!_boatKeysInset._usedRentalKeys) {
BF_GLOBALS._player.enableControl();
} else {
_sceneMode = 3;
diff --git a/engines/tsage/blue_force/blueforce_scenes8.h b/engines/tsage/blue_force/blueforce_scenes8.h
index ef5ef81563..b9e6ebd640 100644
--- a/engines/tsage/blue_force/blueforce_scenes8.h
+++ b/engines/tsage/blue_force/blueforce_scenes8.h
@@ -348,8 +348,9 @@ class Scene840: public PalettedScene {
public:
RentalKeys _rentalKeys;
WaveKeys _waveKeys;
- int _v1B4, _v1B6;
+ bool _usedRentalKeys,_usedWaveKeys;
+ virtual void synchronize(Serializer &s);
virtual void postInit(SceneObjectList *OwnerList = NULL);
virtual void remove();
virtual void process(Event &event);
diff --git a/engines/tsage/blue_force/blueforce_scenes9.cpp b/engines/tsage/blue_force/blueforce_scenes9.cpp
index 52115b95fe..405a436f55 100644
--- a/engines/tsage/blue_force/blueforce_scenes9.cpp
+++ b/engines/tsage/blue_force/blueforce_scenes9.cpp
@@ -840,14 +840,14 @@ bool Scene910::Nico::startAction(CursorType action, Event &event) {
if (BF_GLOBALS._nico910State >= 4)
return NamedObject::startAction(action, event);
- if (BF_GLOBALS._v4CEE6 < 4)
- BF_GLOBALS._v4CEE6++;
+ if (BF_GLOBALS._nico910Talk < 4)
+ BF_GLOBALS._nico910Talk++;
- if (BF_GLOBALS._v4CEE6 == 2) {
+ if (BF_GLOBALS._nico910Talk == 2) {
scene->_sceneMode = 13;
scene->_stripManager.start(9105, scene);
} else
- scene->_stripManager.start(9103 + BF_GLOBALS._v4CEE6, &BF_GLOBALS._stripProxy);
+ scene->_stripManager.start(9103 + BF_GLOBALS._nico910Talk, &BF_GLOBALS._stripProxy);
return true;
break;
case INV_COLT45:
@@ -887,14 +887,14 @@ bool Scene910::Nico::startAction(CursorType action, Event &event) {
if (BF_GLOBALS._nico910State >= 4)
return NamedObject::startAction(action, event);
- if (BF_GLOBALS._v4CEE6 < 4)
- BF_GLOBALS._v4CEE6++;
+ if (BF_GLOBALS._nico910Talk < 4)
+ BF_GLOBALS._nico910Talk++;
- if (BF_GLOBALS._v4CEE6 == 2) {
+ if (BF_GLOBALS._nico910Talk == 2) {
scene->_sceneMode = 13;
scene->_stripManager.start(9105, scene);
} else
- scene->_stripManager.start(9103 + BF_GLOBALS._v4CEE6, &BF_GLOBALS._stripProxy);
+ scene->_stripManager.start(9103 + BF_GLOBALS._nico910Talk, &BF_GLOBALS._stripProxy);
return true;
break;
@@ -966,16 +966,16 @@ bool Scene910::Stuart::startAction(CursorType action, Event &event) {
return true;
break;
case CURSOR_TALK:
- if (BF_GLOBALS._v4CEE8 < 3)
- BF_GLOBALS._v4CEE8++;
+ if (BF_GLOBALS._stuart910Talk < 3)
+ BF_GLOBALS._stuart910Talk++;
- scene->_stripManager.start(9107 + BF_GLOBALS._v4CEE8, &BF_GLOBALS._stripProxy);
+ scene->_stripManager.start(9107 + BF_GLOBALS._stuart910Talk, &BF_GLOBALS._stripProxy);
return true;
break;
case INV_COLT45:
if ((BF_GLOBALS.getFlag(gunDrawn)) && (BF_GLOBALS.getFlag(fGunLoaded)) && (BF_GLOBALS.getHasBullets())){
BF_GLOBALS._player.disableControl();
- if (BF_GLOBALS._v4CEE4 == 2) {
+ if (BF_GLOBALS._stuart910State == 2) {
scene->_sceneMode = 9132;
scene->setAction(&scene->_sequenceManager1, scene, 9132, &scene->_stuart, NULL);
return NamedObject::startAction(action, event);
@@ -1422,6 +1422,10 @@ void Scene910::Object13::setupBreaker(int x, int y, int mode, int8 frameNumber)
BF_GLOBALS._sceneItems.push_front(this);
}
+Scene910::Object25::Object25() {
+ _field90 = _field92 = 0;
+}
+
void Scene910::Object25::synchronize(Serializer &s) {
NamedObject::synchronize(s);
s.syncAsSint16LE(_field90);
@@ -1874,7 +1878,7 @@ bool Scene910::Item2::startAction(CursorType action, Event &event) {
bool Scene910::Item3::startAction(CursorType action, Event &event) {
Scene910 *scene = (Scene910 *)BF_GLOBALS._sceneManager._scene;
- if ((action == CURSOR_TALK) && (BF_GLOBALS._nico910State == 4) && (BF_GLOBALS._v4CEE4 == 0)) {
+ if ((action == CURSOR_TALK) && (BF_GLOBALS._nico910State == 4) && (BF_GLOBALS._stuart910State == 0)) {
BF_GLOBALS._player.disableControl();
scene->_sceneMode = 15;
scene->_stripManager.start(9102, scene);
@@ -1962,7 +1966,6 @@ void Scene910::postInit(SceneObjectList *OwnerList) {
loadScene(910);
BF_GLOBALS._sound1.changeSound(99);
- BF_GLOBALS._v51C44 = 0;
_stripManager.addSpeaker(&_gameTextSpeaker);
_stripManager.addSpeaker(&_jakeJacketSpeaker);
@@ -2054,7 +2057,7 @@ void Scene910::postInit(SceneObjectList *OwnerList) {
|| (BF_GLOBALS._sceneManager._previousScene == 300)) {
BF_GLOBALS._sceneManager._previousScene = 900;
BF_GLOBALS._nico910State = 0;
- BF_GLOBALS._v4CEE4 = 0;
+ BF_GLOBALS._stuart910State = 0;
}
_field2DE0 = 0;
@@ -2146,7 +2149,7 @@ void Scene910::postInit(SceneObjectList *OwnerList) {
_nico.setVisage(913);
_nico.setPosition(Common::Point(262, 124));
_nico.setStrip(6);
- BF_GLOBALS._v4CEE6 = 0;
+ BF_GLOBALS._nico910Talk = 0;
BF_GLOBALS._nico910State = 1;
_nico.setDetails(910, 63, 64, 67, 5, &_item4);
BF_GLOBALS._v4CECA = 2;
@@ -2273,7 +2276,6 @@ void Scene910::signal() {
break;
case 10:
BF_GLOBALS._player.disableControl();
- BF_GLOBALS._v51C44 = 0;
BF_GLOBALS._sceneManager.changeScene(935);
break;
case 11:
@@ -2307,12 +2309,11 @@ void Scene910::signal() {
case 15:
_stuart.postInit();
_stuart.setDetails(910, 66, 67, 68, 5, &_nico);
- BF_GLOBALS._v4CEE8 = 0;
+ BF_GLOBALS._stuart910Talk = 0;
_sceneMode = 9121;
setAction(&_sequenceManager1, this, 9121, &_stuart, NULL);
break;
case 14:
- BF_GLOBALS._v51C44 = 1;
BF_GLOBALS._sceneManager.changeScene(940);
break;
case 16:
@@ -2348,7 +2349,7 @@ void Scene910::signal() {
case 18:
BF_GLOBALS._player._strip = 7;
BF_GLOBALS._player._frame = 1;
- if (BF_GLOBALS._v4CEE4 == 3) {
+ if (BF_GLOBALS._stuart910State == 3) {
if (_field2DE4 == 0) {
_field2DE4 = 1;
_sceneMode = 9142;
@@ -2372,7 +2373,6 @@ void Scene910::signal() {
break;
case 19:
BF_GLOBALS._deathReason = 14;
- BF_GLOBALS._v51C44 = 1;
BF_GLOBALS._sceneManager.changeScene(666);
break;
case 20:
@@ -2388,7 +2388,6 @@ void Scene910::signal() {
BF_GLOBALS.clearFlag(fGotPointsForSearchingDA);
else
BF_GLOBALS.setFlag(fGotPointsForSearchingDA);
- BF_GLOBALS._v51C44 = 1;
BF_GLOBALS._sceneManager.changeScene(900);
break;
case 9102:
@@ -2461,7 +2460,7 @@ void Scene910::signal() {
BF_GLOBALS._player.disableControl();
_nico.postInit();
_nico.setDetails(910, 63, 64, 65, 5, &_item4);
- BF_GLOBALS._v4CEE6 = 0;
+ BF_GLOBALS._nico910Talk = 0;
_shadow.postInit();
_action2.remove();
_sceneMode = 9116;
@@ -2482,7 +2481,6 @@ void Scene910::signal() {
// No break on purpose
case 9137:
BF_GLOBALS._deathReason = 16;
- BF_GLOBALS._v51C44 = 1;
BF_GLOBALS._sceneManager.changeScene(666);
break;
case 9119:
@@ -2500,7 +2498,7 @@ void Scene910::signal() {
break;
case 9121:
_item3.setDetails(7, 910, 96, 60, 61, 3);
- BF_GLOBALS._v4CEE4 = 2;
+ BF_GLOBALS._stuart910State = 2;
if (BF_GLOBALS._nico910State == 4) {
_sceneMode = 20;
_stripManager.start(9115, this);
@@ -2584,7 +2582,7 @@ void Scene910::signal() {
_yellowCord.hide();
_sceneMode = 9136;
setAction(&_sequenceManager1, this, 9136, &BF_GLOBALS._player, &_stuart, &_yellowCord, NULL);
- BF_GLOBALS._v4CEE4 = 3;
+ BF_GLOBALS._stuart910State = 3;
break;
case 11:
_sceneMode = 9137;
@@ -2607,13 +2605,13 @@ void Scene910::signal() {
_stuart.postInit();
_nico.setDetails(910, 72, 73, 74, 3, (SceneItem *)NULL);
_stuart.setDetails(910, 66, 67, 68, 5, &_nico);
- BF_GLOBALS._v4CEE8 = 0;
+ BF_GLOBALS._stuart910Talk = 0;
_sceneMode = 9121;
setAction(&_sequenceManager1, this, 9121, &_stuart, NULL);
break;
case 9126:
_sceneMode = 19;
- if (BF_GLOBALS._v4CEE4 == 0)
+ if (BF_GLOBALS._stuart910State == 0)
signal();
else
_stripManager.start(9115, this);
@@ -2622,7 +2620,6 @@ void Scene910::signal() {
// No break on purpose
case 9134:
BF_GLOBALS._deathReason = 17;
- BF_GLOBALS._v51C44 = 1;
BF_GLOBALS._sceneManager.changeScene(666);
break;
case 9130:
@@ -2633,14 +2630,12 @@ void Scene910::signal() {
break;
case 9132:
BF_GLOBALS._player.enableControl();
- BF_GLOBALS._v4CEE4 = 4;
+ BF_GLOBALS._stuart910State = 4;
BF_GLOBALS._deathReason = 13;
- BF_GLOBALS._v51C44 = 1;
BF_GLOBALS._sceneManager.changeScene(666);
break;
case 9135:
BF_GLOBALS._deathReason = 15;
- BF_GLOBALS._v51C44 = 1;
BF_GLOBALS._sceneManager.changeScene(666);
break;
case 9136:
@@ -2685,7 +2680,6 @@ void Scene910::signal() {
break;
case 9143:
if (BF_GLOBALS._nico910State == 0) {
- BF_GLOBALS._v51C44 = 1;
BF_GLOBALS._sceneManager.changeScene(920);
} else {
SceneItem::display(910, 89, SET_WIDTH, 312,
@@ -2704,7 +2698,6 @@ void Scene910::signal() {
break;
case 9148:
BF_GLOBALS._deathReason = 23;
- BF_GLOBALS._v51C44 = 1;
BF_GLOBALS._sceneManager.changeScene(666);
break;
case 9149:
@@ -2984,7 +2977,6 @@ bool Scene920::Item8::startAction(CursorType action, Event &event) {
// On the other hand, it's not really important as just after the hero leaves the scene
// so the variable is no longer used.
// scene->_oldCoord = &scene;
- _field10 = 1;
} else {
scene->_sceneMode = 9201;
scene->setAction(&scene->_sequenceManager1, scene, 9201, &BF_GLOBALS._player, NULL);
@@ -3577,7 +3569,7 @@ void Scene935::postInit(SceneObjectList *OwnerList) {
PalettedScene::postInit();
loadScene(935);
- BF_GLOBALS._interfaceY = 200;
+ BF_GLOBALS._interfaceY = SCREEN_HEIGHT;
BF_GLOBALS._player.disableControl();
_visualSpeaker._textMode = ALIGN_CENTER;
_visualSpeaker._hideObjects = false;
@@ -3812,7 +3804,7 @@ void Scene940::postInit(SceneObjectList *OwnerList) {
BF_GLOBALS._sound1.play(115);
BF_GLOBALS._dayNumber = 6;
- BF_GLOBALS._interfaceY = 200;
+ BF_GLOBALS._interfaceY = SCREEN_HEIGHT;
T2_GLOBALS._uiElements._active = false;
_gameTextSpeaker2._speakerName = "SENTTEXT";
diff --git a/engines/tsage/blue_force/blueforce_scenes9.h b/engines/tsage/blue_force/blueforce_scenes9.h
index 74708b94de..8bf7f343a1 100644
--- a/engines/tsage/blue_force/blueforce_scenes9.h
+++ b/engines/tsage/blue_force/blueforce_scenes9.h
@@ -188,6 +188,7 @@ class Scene910: public PalettedScene {
class Object25: public NamedObject {
int _field90, _field92;
public:
+ Object25();
void setupHiddenSwitch(int x, int y, int arg8, int argA);
virtual void synchronize(Serializer &s);
virtual bool startAction(CursorType action, Event &event);
diff --git a/engines/tsage/blue_force/blueforce_speakers.cpp b/engines/tsage/blue_force/blueforce_speakers.cpp
index 2a57616640..b15d2f4716 100644
--- a/engines/tsage/blue_force/blueforce_speakers.cpp
+++ b/engines/tsage/blue_force/blueforce_speakers.cpp
@@ -63,8 +63,8 @@ void VisualSpeaker::synchronize(Serializer &s) {
s.syncAsSint16LE(_offsetPos.y);
}
-void VisualSpeaker::proc12(Action *action) {
- Speaker::proc12(action);
+void VisualSpeaker::startSpeaking(Action *action) {
+ Speaker::startSpeaking(action);
_textPos = Common::Point(_offsetPos.x + BF_GLOBALS._sceneManager._scene->_sceneBounds.left,
_offsetPos.y + BF_GLOBALS._sceneManager._scene->_sceneBounds.top);
_numFrames = 0;
diff --git a/engines/tsage/blue_force/blueforce_speakers.h b/engines/tsage/blue_force/blueforce_speakers.h
index e406a50fbe..e9150df056 100644
--- a/engines/tsage/blue_force/blueforce_speakers.h
+++ b/engines/tsage/blue_force/blueforce_speakers.h
@@ -51,7 +51,7 @@ public:
virtual Common::String getClassName() { return "VisualSpeaker"; }
virtual void synchronize(Serializer &s);
virtual void remove();
- virtual void proc12(Action *action);
+ virtual void startSpeaking(Action *action);
virtual void setText(const Common::String &msg);
};
diff --git a/engines/tsage/configure.engine b/engines/tsage/configure.engine
new file mode 100644
index 0000000000..2b8edf8266
--- /dev/null
+++ b/engines/tsage/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 tsage "TsAGE" yes
diff --git a/engines/tsage/converse.cpp b/engines/tsage/converse.cpp
index 9828ca71d4..ba8cfb82a9 100644
--- a/engines/tsage/converse.cpp
+++ b/engines/tsage/converse.cpp
@@ -451,6 +451,13 @@ int ConversationChoiceDialog::execute(const Common::StringArray &choiceList) {
draw();
g_globals->_events.showCursor();
+ // WORKAROUND: On-screen dialogs are really meant to use a GfxManager instance
+ // for their lifetime, which prevents saving or loading. Since I don't want to spend a lot
+ // of time refactoring this already working dialog, fake it by putting a dummy gfxmanager at
+ // the end of the gfx manager list so as to prevent saving or loading
+ GfxManager gfxManager;
+ GLOBALS._gfxManagers.push_back(&gfxManager);
+
// Event handling loop
Event event;
while (!g_vm->shouldQuit()) {
@@ -502,6 +509,7 @@ int ConversationChoiceDialog::execute(const Common::StringArray &choiceList) {
// Remove the dialog
remove();
+ GLOBALS._gfxManagers.remove(&gfxManager);
return _selectedIndex;
}
@@ -640,11 +648,11 @@ void StripManager::reset() {
_delayFrames = 0;
_owner = NULL;
_endHandler = NULL;
- _field2E6 = false;
+ _uselessFl = false;
_stripNum = -1;
- _obj44Index = 0;
- _field2E8 = 0;
- _field20 = 0;
+ _obj44ListIndex = 0;
+ _currObj44Id = 0;
+ _useless = 0;
_activeSpeaker = NULL;
_textShown = false;
_callbackObject = NULL;
@@ -688,14 +696,14 @@ void StripManager::synchronize(Serializer &s) {
Action::synchronize(s);
s.syncAsSint32LE(_stripNum);
- s.syncAsSint32LE(_obj44Index);
- s.syncAsSint32LE(_field20);
+ s.syncAsSint32LE(_obj44ListIndex);
+ s.syncAsSint32LE(_useless);
s.syncAsSint32LE(_sceneNumber);
_sceneBounds.synchronize(s);
SYNC_POINTER(_activeSpeaker);
s.syncAsByte(_textShown);
- s.syncAsByte(_field2E6);
- s.syncAsSint32LE(_field2E8);
+ s.syncAsByte(_uselessFl);
+ s.syncAsSint32LE(_currObj44Id);
if (g_vm->getGameID() == GType_Ringworld2)
s.syncAsSint16LE(_exitMode);
@@ -727,10 +735,10 @@ void StripManager::synchronize(Serializer &s) {
}
void StripManager::remove() {
- if (g_vm->getGameID() == GType_Ringworld2) {
+ if (g_vm->getGameID() == GType_Ringworld2) {
for (uint i = 0; i < _speakerList.size(); ++i) {
if (_activeSpeaker != _speakerList[i])
- _speakerList[i]->proc16();
+ _speakerList[i]->stopSpeaking();
}
}
@@ -741,7 +749,7 @@ void StripManager::remove() {
}
if (_activeSpeaker) {
- if (g_vm->getGameID() == GType_Ringworld2)
+ if (g_vm->getGameID() == GType_Ringworld2)
static_cast<Ringworld2::VisualSpeaker *>(_activeSpeaker)->_speakerMode = 0xff;
_activeSpeaker->remove();
}
@@ -760,6 +768,15 @@ void StripManager::remove() {
Action::remove();
}
+void StripManager::dispatch() {
+ if (g_vm->getGameID() == GType_Ringworld2) {
+ if (_activeSpeaker)
+ _activeSpeaker->dispatch();
+ }
+
+ Action::dispatch();
+}
+
void StripManager::signal() {
int strIndex = 0;
@@ -768,14 +785,14 @@ void StripManager::signal() {
_textShown = false;
}
- if (_obj44Index < 0) {
+ if (_obj44ListIndex < 0) {
EventHandler *owner = _endHandler;
- int stripNum = ABS(_obj44Index);
+ int stripNum = ABS(_obj44ListIndex);
remove();
start(stripNum, owner);
return;
- } else if (_obj44Index == 10000) {
+ } else if (_obj44ListIndex == 10000) {
// Reached end of strip
EventHandler *endHandler = _endHandler;
remove();
@@ -792,7 +809,7 @@ void StripManager::signal() {
// Load the data for the strip
load();
- Obj44 &obj44 = _obj44List[_obj44Index];
+ Obj44 &obj44 = _obj44List[_obj44ListIndex];
if (g_vm->getGameID() == GType_Ringworld2) {
// Return to Ringworld specific handling
@@ -813,8 +830,8 @@ void StripManager::signal() {
break;
}
}
-
- _field2E8 = obj44._id;
+
+ _currObj44Id = obj44._id;
Common::StringArray choiceList;
// Build up a list of script entries
@@ -827,7 +844,7 @@ void StripManager::signal() {
int f16Index = _lookupList[obj44._field16[0] - 1];
int entryId = obj44._field16[f16Index];
- Obj0A &entry = obj44._list[idx];
+ Obj0A &entry = obj44._list[idx];
if (entry._id == entryId) {
// Get the next one
choiceList.push_back((const char *)&_script[0] + entry._scriptOffset);
@@ -836,6 +853,17 @@ void StripManager::signal() {
break;
}
}
+
+ // If no entry found, get the default response
+ if (!delayFlag) {
+ idx = 0;
+ while (obj44._list[idx + 1]._id)
+ ++idx;
+
+ choiceList.push_back((const char *)&_script[0] + obj44._list[idx]._scriptOffset);
+ strIndex = idx;
+ delayFlag = true;
+ }
} else {
// Standard choices loading
for (idx = 0; idx < OBJ0A_LIST_SIZE; ++idx) {
@@ -844,7 +872,7 @@ void StripManager::signal() {
// Get the next one
const char *choiceStr = (const char *)&_script[0] + obj44._list[idx]._scriptOffset;
-
+
if (!*choiceStr) {
// Choice is empty
assert(g_vm->getGameID() == GType_Ringworld2);
@@ -852,7 +880,7 @@ void StripManager::signal() {
if (obj44._list[1]._id) {
// it's a reference to another list slot
int listId = obj44._list[idx]._id;
-
+
int obj44Idx = 0;
while (_obj44List[obj44Idx]._id != listId)
++obj44Idx;
@@ -862,7 +890,7 @@ void StripManager::signal() {
// seems to be set to the R2_GLOBALS._stripManager_lookupList, so manually set it
if (!_lookupList)
_lookupList = R2_GLOBALS._stripManager_lookupList;
-
+
int f16Index = _lookupList[_obj44List[obj44Idx]._field16[0] - 1];
listId = _obj44List[obj44Idx]._field16[f16Index];
@@ -897,7 +925,7 @@ void StripManager::signal() {
// Get the user to select a conversation option
strIndex = _choiceDialog.execute(choiceList);
- if ((delayFlag || choiceList.size() != 1) && !_field2E6)
+ if ((delayFlag || choiceList.size() != 1) && !_uselessFl)
_delayFrames = 1;
else {
Speaker *speakerP = getSpeaker((const char *)&_script[0] + obj44._speakerOffset);
@@ -914,7 +942,7 @@ void StripManager::signal() {
g_globals->_sceneManager._scene->loadScene(_sceneNumber);
}
- _activeSpeaker->proc12(this);
+ _activeSpeaker->startSpeaking(this);
}
if (_callbackObject) {
@@ -928,11 +956,11 @@ void StripManager::signal() {
if (g_vm->getGameID() == GType_Ringworld2) {
Ringworld2::VisualSpeaker *speaker = static_cast<Ringworld2::VisualSpeaker *>(_activeSpeaker);
-
+
if (speaker) {
speaker->_speakerMode = obj44._speakerMode;
if (!choiceList[strIndex].empty())
- speaker->proc15();
+ speaker->animateSpeaker();
}
if (!choiceList[strIndex].empty()) {
@@ -942,7 +970,7 @@ void StripManager::signal() {
_delayFrames = 1;
} else {
_delayFrames = 0;
- speaker->proc15();
+ speaker->animateSpeaker();
}
} else {
_textShown = true;
@@ -950,10 +978,10 @@ void StripManager::signal() {
}
}
- _obj44Index = getNewIndex(obj44._list[strIndex]._id);
- if (_obj44Index == 10001) {
+ _obj44ListIndex = getNewIndex(obj44._list[strIndex]._id);
+ if (_obj44ListIndex == 10001) {
MessageDialog::show("Strip Failure: Node not found", OK_BTN_STRING);
- _obj44Index = 0;
+ _obj44ListIndex = 0;
}
}
@@ -963,16 +991,16 @@ void StripManager::process(Event &event) {
return;
if ((event.eventType == EVENT_KEYPRESS) && (event.kbd.keycode == Common::KEYCODE_ESCAPE)) {
- if (_obj44Index != 10000) {
- int currIndex = _obj44Index;
- while (!_obj44List[_obj44Index]._list[1]._id) {
- _obj44Index = getNewIndex(_obj44List[_obj44Index]._list[0]._id);
- if ((_obj44Index < 0) || (_obj44Index == 10000))
+ if (_obj44ListIndex != 10000) {
+ int currIndex = _obj44ListIndex;
+ while (!_obj44List[_obj44ListIndex]._list[1]._id) {
+ _obj44ListIndex = getNewIndex(_obj44List[_obj44ListIndex]._list[0]._id);
+ if ((_obj44ListIndex < 0) || (_obj44ListIndex == 10000))
break;
- currIndex = _obj44Index;
+ currIndex = _obj44ListIndex;
}
- _field2E8 = _obj44List[currIndex]._id;
+ _currObj44Id = _obj44List[currIndex]._id;
}
// Signal the end of the strip
@@ -1068,7 +1096,7 @@ void Speaker::remove() {
SceneObjectList::deactivate();
}
-void Speaker::proc12(Action *action) {
+void Speaker::startSpeaking(Action *action) {
_action = action;
if (_newSceneNumber != -1) {
_oldSceneNumber = g_globals->_sceneManager._sceneNumber;
diff --git a/engines/tsage/converse.h b/engines/tsage/converse.h
index 5aef0d8a7f..8aa91ec3ef 100644
--- a/engines/tsage/converse.h
+++ b/engines/tsage/converse.h
@@ -91,10 +91,10 @@ public:
virtual Common::String getClassName() { return "Speaker"; }
virtual void synchronize(Serializer &s);
virtual void remove();
- virtual void proc12(Action *action);
+ virtual void startSpeaking(Action *action);
virtual void setText(const Common::String &msg);
virtual void removeText();
- virtual void proc16() {}
+ virtual void stopSpeaking() {}
void setTextPos(const Common::Point &pt) { _textPos = pt; }
};
@@ -212,8 +212,8 @@ private:
int getNewIndex(int newId);
public:
int _stripNum;
- int _obj44Index;
- int _field20;
+ int _obj44ListIndex;
+ int _useless;
int _sceneNumber;
Rect _sceneBounds;
ConversationChoiceDialog _choiceDialog;
@@ -221,8 +221,8 @@ public:
StripCallback *_callbackObject;
Speaker *_activeSpeaker;
bool _textShown;
- bool _field2E6;
- int _field2E8;
+ bool _uselessFl;
+ int _currObj44Id;
int _exitMode;
Common::Array<Obj44> _obj44List;
Common::Array<byte> _script;
@@ -237,6 +237,7 @@ public:
virtual void synchronize(Serializer &s);
virtual void remove();
+ virtual void dispatch();
virtual void signal();
virtual void process(Event &event);
diff --git a/engines/tsage/core.cpp b/engines/tsage/core.cpp
index b0220b53e0..16fe45044b 100644
--- a/engines/tsage/core.cpp
+++ b/engines/tsage/core.cpp
@@ -860,6 +860,8 @@ void PlayerMover::doStepsOfNpcMovement(const Common::Point &srcPos, const Common
int PlayerMover::calculateRestOfRoute(int *routeList, int srcRegion, int destRegion, bool &foundRoute) {
// Make a copy of the provided route. The first entry is the size.
int tempList[REGION_LIST_SIZE + 1];
+ memset(tempList, 0, sizeof(tempList));
+
foundRoute = false;
for (int idx = 0; idx <= *routeList; ++idx)
tempList[idx] = routeList[idx];
@@ -1151,6 +1153,13 @@ void PaletteRotation::signal() {
if (flag)
_currIndex = _start;
}
+
+ // Added in Return to Ringworld
+ if (_currIndex < _start) {
+ flag = decDuration();
+ if (flag)
+ _currIndex = _end;
+ }
break;
case 2:
_currIndex += _idxChange;
@@ -1292,7 +1301,6 @@ ScenePalette::ScenePalette() {
*palData++ = idx;
}
- _field412 = 0;
_redColor = _greenColor = _blueColor = 0;
_aquaColor = 0;
_purpleColor = 0;
@@ -1304,7 +1312,6 @@ ScenePalette::~ScenePalette() {
}
ScenePalette::ScenePalette(int paletteNum) {
- _field412 = 0;
_redColor = _greenColor = _blueColor = 0;
_aquaColor = 0;
_purpleColor = 0;
@@ -1536,7 +1543,11 @@ void ScenePalette::synchronize(Serializer &s) {
s.syncAsSint32LE(_colors.foreground);
s.syncAsSint32LE(_colors.background);
- s.syncAsSint32LE(_field412);
+ if (s.getVersion() < 12) {
+ int useless = 0;
+ s.syncAsSint32LE(useless);
+ }
+
s.syncAsByte(_redColor);
s.syncAsByte(_greenColor);
s.syncAsByte(_blueColor);
@@ -1552,8 +1563,13 @@ void SceneItem::synchronize(Serializer &s) {
_bounds.synchronize(s);
s.syncString(_msg);
- s.syncAsSint32LE(_fieldE);
- s.syncAsSint32LE(_field10);
+
+ if (s.getVersion() < 15) {
+ int useless = 0;
+ s.syncAsSint32LE(useless);
+ s.syncAsSint32LE(useless);
+ }
+
s.syncAsSint16LE(_position.x); s.syncAsSint32LE(_position.y);
s.syncAsSint16LE(_yDiff);
s.syncAsSint32LE(_sceneRegionId);
@@ -1619,7 +1635,8 @@ void SceneItem::display(int resNum, int lineNum, ...) {
Common::String msg = (!resNum || (resNum == -1)) ? Common::String() :
g_resourceManager->getMessage(resNum, lineNum);
- if ((g_vm->getGameID() != GType_Ringworld) && T2_GLOBALS._uiElements._active)
+ if ((g_vm->getGameID() != GType_Ringworld) && (g_vm->getGameID() != GType_Ringworld2)
+ && T2_GLOBALS._uiElements._active)
T2_GLOBALS._uiElements.hide();
if (g_globals->_sceneObjects->contains(&g_globals->_sceneText)) {
@@ -1729,9 +1746,13 @@ void SceneItem::display(int resNum, int lineNum, ...) {
font.setFontNumber(g_globals->_sceneText._fontNumber);
font.getStringBounds(msg.c_str(), textRect, maxWidth);
+ Rect screenBounds = g_globals->gfxManager()._bounds;
+ if (g_vm->getGameID() == GType_Ringworld2)
+ screenBounds.collapse(20, 15);
+
// Center the text at the specified position, and then constrain it to be-
textRect.center(pos.x, pos.y);
- textRect.contain(g_globals->gfxManager()._bounds);
+ textRect.contain(screenBounds);
if (centerText) {
g_globals->_sceneText._color1 = g_globals->_sceneText._color2;
@@ -1749,9 +1770,22 @@ void SceneItem::display(int resNum, int lineNum, ...) {
}
g_globals->_sceneText.fixPriority(255);
+
+ // In Return to Ringworld, if in voice mode only, don't show the text
+ if ((g_vm->getGameID() == GType_Ringworld2) && (R2_GLOBALS._speechSubtitles & SPEECH_VOICE)
+ && !(R2_GLOBALS._speechSubtitles & SPEECH_TEXT))
+ g_globals->_sceneText.hide();
+
g_globals->_sceneObjects->draw();
}
+ // For Return to Ringworld, play the voice overs in sequence
+ if ((g_vm->getGameID() == GType_Ringworld2) && (R2_GLOBALS._speechSubtitles & SPEECH_VOICE)
+ && !playList.empty()) {
+ R2_GLOBALS._playStream.play(*playList.begin(), NULL);
+ playList.pop_front();
+ }
+
// Unless the flag is set to keep the message on-screen, show it until a mouse or keypress, then remove it
if (!keepOnscreen && !msg.empty()) {
Event event;
@@ -1761,18 +1795,31 @@ void SceneItem::display(int resNum, int lineNum, ...) {
EVENT_BUTTON_DOWN | EVENT_KEYPRESS)) {
GLOBALS._screenSurface.updateScreen();
g_system->delayMillis(10);
- }
- // For Return to Ringworld, play the voice overs in sequence
- if ((g_vm->getGameID() == GType_Ringworld2) && !playList.empty() && !R2_GLOBALS._playStream.isPlaying()) {
- R2_GLOBALS._playStream.play(*playList.begin(), NULL);
- playList.pop_front();
+ if ((g_vm->getGameID() == GType_Ringworld2) && (R2_GLOBALS._speechSubtitles & SPEECH_VOICE)) {
+ // Allow the play stream to do processing
+ R2_GLOBALS._playStream.dispatch();
+ if (!R2_GLOBALS._playStream.isPlaying()) {
+ // Check if there are further voice samples to play
+ if (!playList.empty()) {
+ R2_GLOBALS._playStream.play(*playList.begin(), NULL);
+ playList.pop_front();
+ } else if (!(R2_GLOBALS._speechSubtitles & SPEECH_TEXT)) {
+ // If not showing text, don't both waiting for a click to end
+ break;
+ }
+ }
+ }
}
+ if (g_vm->getGameID() == GType_Ringworld2)
+ R2_GLOBALS._playStream.stop();
+
g_globals->_sceneText.remove();
}
- if ((g_vm->getGameID() != GType_Ringworld) && T2_GLOBALS._uiElements._active) {
+ if ((g_vm->getGameID() != GType_Ringworld) && (g_vm->getGameID() != GType_Ringworld2)
+ && T2_GLOBALS._uiElements._active) {
// Show user interface
T2_GLOBALS._uiElements.show();
@@ -2066,18 +2113,18 @@ SceneObject::SceneObject() : SceneHotspot() {
_visage = 0;
_strip = 0;
_frame = 0;
- _effect = 0;
- _shade = _shade2 = 0;
+ _effect = EFFECT_NONE;
+ _shade = _oldShade = 0;
_linkedActor = NULL;
- _field8A = Common::Point(0, 0);
+ _actorDestPos = Common::Point(0, 0);
_angle = 0;
_xs = 0;
_xe = 0;
_endFrame = 0;
- _field68 = 0;
+ _loopCount = 0;
_regionIndex = 0;
- _field9C = NULL;
+ _shadowMap = NULL;
}
SceneObject::SceneObject(const SceneObject &so) : SceneHotspot() {
@@ -2324,7 +2371,7 @@ void SceneObject::animate(AnimateMode animMode, ...) {
case ANIM_MODE_1:
_frameChange = 1;
- _field2E = _position;
+ _oldPosition = _position;
_endAction = 0;
break;
@@ -2372,9 +2419,9 @@ void SceneObject::animate(AnimateMode animMode, ...) {
case ANIM_MODE_9:
if (_animateMode == ANIM_MODE_9 && g_vm->getGameID() == GType_Ringworld2) {
_frameChange = -1;
- _field2E = _position;
+ _oldPosition = _position;
} else {
- _field68 = va_arg(va, int);
+ _loopCount = va_arg(va, int);
_endAction = va_arg(va, Action *);
_frameChange = 1;
_endFrame = getFrameCount();
@@ -2441,7 +2488,7 @@ void SceneObject::synchronize(Serializer &s) {
s.syncAsUint32LE(_updateStartFrame);
s.syncAsUint32LE(_walkStartFrame);
- s.syncAsSint16LE(_field2E.x); s.syncAsSint16LE(_field2E.y);
+ s.syncAsSint16LE(_oldPosition.x); s.syncAsSint16LE(_oldPosition.y);
s.syncAsSint16LE(_percent);
s.syncAsSint16LE(_priority);
s.syncAsSint16LE(_angle);
@@ -2456,7 +2503,7 @@ void SceneObject::synchronize(Serializer &s) {
SYNC_ENUM(_animateMode, AnimateMode);
s.syncAsSint32LE(_frame);
s.syncAsSint32LE(_endFrame);
- s.syncAsSint32LE(_field68);
+ s.syncAsSint32LE(_loopCount);
s.syncAsSint32LE(_frameChange);
s.syncAsSint32LE(_numFrames);
s.syncAsSint32LE(_regionIndex);
@@ -2464,8 +2511,8 @@ void SceneObject::synchronize(Serializer &s) {
s.syncAsSint16LE(_moveDiff.x); s.syncAsSint16LE(_moveDiff.y);
s.syncAsSint32LE(_moveRate);
if (g_vm->getGameID() == GType_Ringworld2) {
- s.syncAsSint16LE(_field8A.x);
- s.syncAsSint16LE(_field8A.y);
+ s.syncAsSint16LE(_actorDestPos.x);
+ s.syncAsSint16LE(_actorDestPos.y);
}
SYNC_POINTER(_endAction);
s.syncAsUint32LE(_regionBitList);
@@ -2473,7 +2520,7 @@ void SceneObject::synchronize(Serializer &s) {
if (g_vm->getGameID() == GType_Ringworld2) {
s.syncAsSint16LE(_effect);
s.syncAsSint16LE(_shade);
- s.syncAsSint16LE(_shade2);
+ s.syncAsSint16LE(_oldShade);
SYNC_POINTER(_linkedActor);
}
}
@@ -2482,7 +2529,8 @@ void SceneObject::postInit(SceneObjectList *OwnerList) {
if (!OwnerList)
OwnerList = g_globals->_sceneObjects;
- if (!OwnerList->contains(this) || ((_flags & OBJFLAG_REMOVE) != 0)) {
+ bool isExisting = OwnerList->contains(this);
+ if (!isExisting || ((_flags & OBJFLAG_REMOVE) != 0)) {
_percent = 100;
_priority = 255;
_flags = OBJFLAG_ZOOMED;
@@ -2501,7 +2549,8 @@ void SceneObject::postInit(SceneObjectList *OwnerList) {
_numFrames = 10;
_regionBitList = 0;
- OwnerList->push_back(this);
+ if (!isExisting)
+ OwnerList->push_back(this);
_flags |= OBJFLAG_PANES;
}
}
@@ -2519,9 +2568,9 @@ void SceneObject::remove() {
void SceneObject::dispatch() {
if (g_vm->getGameID() == GType_Ringworld2) {
- if (_shade != _shade2)
+ if (_shade != _oldShade)
_flags |= OBJFLAG_PANES;
- _shade2 = _shade;
+ _oldShade = _shade;
}
uint32 currTime = g_globals->_events.getFrameNumber();
@@ -2541,9 +2590,9 @@ void SceneObject::dispatch() {
case ANIM_MODE_1:
if (isNoMover())
setFrame(1);
- else if ((_field2E.x != _position.x) || (_field2E.y != _position.y)) {
+ else if ((_oldPosition.x != _position.x) || (_oldPosition.y != _position.y)) {
setFrame(changeFrame());
- _field2E = _position;
+ _oldPosition = _position;
}
break;
@@ -2586,7 +2635,7 @@ void SceneObject::dispatch() {
_endFrame = 1;
setFrame(changeFrame());
- } else if (!_field68 || (--_field68 > 0)) {
+ } else if (!_loopCount || (--_loopCount > 0)) {
_frameChange = 1;
_endFrame = getFrameCount();
@@ -2605,7 +2654,7 @@ void SceneObject::dispatch() {
_frameChange = -1;
_strip = ((_strip - 1) ^ 1) + 1;
_endFrame = 1;
- } else if ((_field68 == 0) || (--_field68 != 0)) {
+ } else if (!_loopCount || (--_loopCount > 0)) {
_frameChange = 1;
_endFrame = getFrameCount();
@@ -2639,8 +2688,9 @@ void SceneObject::dispatch() {
_linkedActor->setFrame(_frame);
}
- if ((_effect == 1) && (getRegionIndex() < 11))
- _shade = 0;
+ int regionIndex = getRegionIndex();
+ if ((_effect == EFFECT_SHADED) && (regionIndex < 11))
+ _shade = regionIndex;
}
}
@@ -2669,11 +2719,46 @@ void SceneObject::removeObject() {
GfxSurface SceneObject::getFrame() {
_visageImages.setVisage(_visage, _strip);
- return _visageImages.getFrame(_frame);
+ GfxSurface frame = _visageImages.getFrame(_frame);
+
+ // Reset any centroid adjustment flags, in
+ frame._flags &= ~(FRAME_FLIP_CENTROID_X | FRAME_FLIP_CENTROID_Y);
+
+ // For later games, check whether the appropriate object flags are set for flipping
+ if (g_vm->getGameID() != GType_Ringworld) {
+ if ((_flags & OBJFLAG_FLIP_CENTROID_X) || _visageImages._flipHoriz)
+ frame._flags |= FRAME_FLIP_CENTROID_X;
+ if ((_flags & OBJFLAG_FLIP_CENTROID_Y) || _visageImages._flipVert)
+ frame._flags |= FRAME_FLIP_CENTROID_Y;
+ }
+
+ // If shading is needed, post apply the shadiing onto the frame
+ if ((g_vm->getGameID() == GType_Ringworld2) && (_shade >= 1)) {
+ Graphics::Surface s = frame.lockSurface();
+ byte *p = (byte *)s.getPixels();
+ byte *endP = p + s.w * s.h;
+
+ while (p < endP) {
+ if (*p != frame._transColor)
+ *p = R2_GLOBALS._fadePaletteMap[_shade - 1][*p];
+ ++p;
+ }
+
+ frame.unlockSurface();
+ }
+
+ return frame;
}
void SceneObject::reposition() {
+ if (g_vm->getGameID() == GType_Ringworld2) {
+ if (!(_flags & OBJFLAG_ZOOMED)) {
+ setZoom(g_globals->_sceneManager._scene->_zoomPercents[MIN(_position.y, (int16)255)]);
+ }
+ }
+
GfxSurface frame = getFrame();
+
_bounds.resize(frame, _position.x, _position.y - _yDiff, _percent);
_xs = _bounds.left;
_xe = _bounds.right;
@@ -2684,11 +2769,27 @@ void SceneObject::reposition() {
*/
void SceneObject::draw() {
Rect destRect = _bounds;
- destRect.translate(-g_globals->_sceneManager._scene->_sceneBounds.left,
- -g_globals->_sceneManager._scene->_sceneBounds.top);
- Region *priorityRegion = g_globals->_sceneManager._scene->_priorities.find(_priority);
+ Scene *scene = g_globals->_sceneManager._scene;
+ destRect.translate(-scene->_sceneBounds.left, -scene->_sceneBounds.top);
GfxSurface frame = getFrame();
- g_globals->gfxManager().copyFrom(frame, destRect, priorityRegion);
+ Region *priorityRegion = scene->_priorities.find(_priority);
+
+ if (g_vm->getGameID() == GType_Ringworld2) {
+ switch (_effect) {
+ case EFFECT_SHADOW_MAP: {
+ if (!_shadowMap)
+ _shadowMap = static_cast<Ringworld2::SceneExt *>(scene)->_shadowPaletteMap;
+
+ GLOBALS.gfxManager().getSurface().copyFrom(frame, frame.getBounds(),
+ destRect, priorityRegion, _shadowMap);
+ return;
+ }
+ default:
+ break;
+ }
+ }
+
+ GLOBALS.gfxManager().copyFrom(frame, destRect, priorityRegion);
}
/**
@@ -2790,10 +2891,17 @@ void BackgroundSceneObject::setup2(int visage, int stripFrameNum, int frameNum,
setFrame(frameNum);
setPosition(Common::Point(posX, posY));
fixPriority(priority);
+
+ _effect = effect;
}
void BackgroundSceneObject::copySceneToBackground() {
GLOBALS._sceneManager._scene->_backSurface.copyFrom(g_globals->gfxManager().getSurface(), 0, 0);
+
+ // WORKAROUND: Since savegames don't store the active screen data, once we copy the
+ // foreground objects to the background, we have to prevent the scene being saved.
+ if (g_vm->getGameID() == GType_Ringworld2)
+ ((Ringworld2::SceneExt *)GLOBALS._sceneManager._scene)->_preventSaving = true;
}
/*--------------------------------------------------------------------------*/
@@ -2856,8 +2964,9 @@ void SceneObjectList::draw() {
g_globals->_sceneManager._sceneBgOffset.y);
}
- // Set up the flag mask
- uint32 flagMask = (paneNum == 0) ? OBJFLAG_PANE_0 : OBJFLAG_PANE_1;
+ // Set up the flag mask. Currently, paneNum is always set to 0, so the check is meaningless
+ // uint32 flagMask = (paneNum == 0) ? OBJFLAG_PANE_0 : OBJFLAG_PANE_1;
+ uint32 flagMask = OBJFLAG_PANE_0;
// Initial loop to set up object list and update object position, priority, and flags
for (SynchronizedList<SceneObject *>::iterator i = g_globals->_sceneObjects->begin();
@@ -3260,7 +3369,6 @@ Player::Player(): SceneObject() {
_canWalk = false;
_enabled = false;
_uiEnabled = false;
- _field8C = 0;
// Return to Ringworld specific fields
_characterIndex = R2_NONE;
@@ -3279,18 +3387,14 @@ void Player::postInit(SceneObjectList *OwnerList) {
_canWalk = true;
_uiEnabled = true;
_percent = 100;
- _field8C = 10;
- if (g_vm->getGameID() != GType_Ringworld2)
- {
+ if (g_vm->getGameID() != GType_Ringworld2) {
_moveDiff.x = 4;
_moveDiff.y = 2;
- }
- else
- {
+ } else {
_moveDiff.x = 3;
_moveDiff.y = 2;
- _effect = 1;
+ _effect = EFFECT_SHADED;
_shade = 0;
_linkedActor = NULL;
@@ -3304,20 +3408,24 @@ void Player::postInit(SceneObjectList *OwnerList) {
void Player::disableControl() {
_canWalk = false;
- _uiEnabled = false;
g_globals->_events.setCursor(CURSOR_NONE);
_enabled = false;
- if ((g_vm->getGameID() != GType_Ringworld) && T2_GLOBALS._uiElements._active)
- T2_GLOBALS._uiElements.hide();
+ if (g_vm->getGameID() != GType_Ringworld2) {
+ _uiEnabled = false;
+
+ if ((g_vm->getGameID() != GType_Ringworld) && T2_GLOBALS._uiElements._active)
+ T2_GLOBALS._uiElements.hide();
+ }
}
void Player::enableControl() {
CursorType cursor;
_canWalk = true;
- _uiEnabled = true;
_enabled = true;
+ if (g_vm->getGameID() != GType_Ringworld2)
+ _uiEnabled = true;
switch (g_vm->getGameID()) {
case GType_BlueForce:
@@ -3325,7 +3433,7 @@ void Player::enableControl() {
cursor = g_globals->_events.getCursor();
g_globals->_events.setCursor(cursor);
- if (T2_GLOBALS._uiElements._active)
+ if (g_vm->getGameID() == GType_BlueForce && T2_GLOBALS._uiElements._active)
T2_GLOBALS._uiElements.show();
break;
@@ -3391,7 +3499,10 @@ void Player::synchronize(Serializer &s) {
s.syncAsByte(_canWalk);
s.syncAsByte(_uiEnabled);
- s.syncAsSint16LE(_field8C);
+ if (s.getVersion() < 15) {
+ int useless = 0;
+ s.syncAsSint16LE(useless);
+ }
if (g_vm->getGameID() != GType_Ringworld)
s.syncAsByte(_enabled);
@@ -4139,7 +4250,6 @@ double FloatSet::sqrt(FloatSet &floatSet) {
GameHandler::GameHandler() : EventHandler() {
_nextWaitCtr = 1;
_waitCtr.setCtr(1);
- _field14 = 10;
}
GameHandler::~GameHandler() {
@@ -4161,7 +4271,11 @@ void GameHandler::synchronize(Serializer &s) {
_lockCtr.synchronize(s);
_waitCtr.synchronize(s);
s.syncAsSint16LE(_nextWaitCtr);
- s.syncAsSint16LE(_field14);
+
+ if (s.getVersion() < 14) {
+ int useless = 0;
+ s.syncAsSint16LE(useless);
+ }
}
/*--------------------------------------------------------------------------*/
@@ -4235,11 +4349,11 @@ void SceneHandler::process(Event &event) {
g_vm->_debugger->onFrame();
}
- if ((event.eventType == EVENT_KEYPRESS) && g_globals->_player._enabled && g_globals->_player._canWalk) {
+ if ((event.eventType == EVENT_KEYPRESS) && g_globals->_player._enabled) {
// Keyboard shortcuts for different actions
switch (event.kbd.keycode) {
case Common::KEYCODE_w:
- g_globals->_events.setCursor(CURSOR_WALK);
+ g_globals->_events.setCursor(GLOBALS._player._canWalk ? CURSOR_WALK : CURSOR_USE);
event.handled = true;
break;
case Common::KEYCODE_l:
@@ -4273,7 +4387,7 @@ void SceneHandler::process(Event &event) {
// Scan the item list to find one the mouse is within
SynchronizedList<SceneItem *>::iterator i;
for (i = g_globals->_sceneItems.begin(); i != g_globals->_sceneItems.end(); ++i) {
- SceneItem *item = *i;
+ SceneItem *item = *i;
if (item->contains(event.mousePos)) {
// Pass the action to the item
bool handled = item->startAction(g_globals->_events.getCursor(), event);
diff --git a/engines/tsage/core.h b/engines/tsage/core.h
index 6156d13b34..c285fba669 100644
--- a/engines/tsage/core.h
+++ b/engines/tsage/core.h
@@ -358,7 +358,6 @@ public:
byte _palette[256 * 3];
GfxColors _colors;
SynchronizedList<PaletteModifier *> _listeners;
- int _field412;
uint8 _redColor;
uint8 _greenColor;
@@ -410,12 +409,11 @@ class SceneItem : public EventHandler {
public:
Rect _bounds;
Common::String _msg;
- int _fieldE, _field10;
Common::Point _position;
int _yDiff;
int _sceneRegionId;
public:
- SceneItem() : EventHandler() { _msg = "Feature"; _action = NULL; _sceneRegionId = 0; _yDiff = 0; _fieldE = _field10 = 0;}
+ SceneItem() : EventHandler() { _msg = "Feature"; _action = NULL; _sceneRegionId = 0; _yDiff = 0;}
virtual void synchronize(Serializer &s);
virtual Common::String getClassName() { return "SceneItem"; }
@@ -466,6 +464,10 @@ enum AnimateMode {ANIM_MODE_NONE = 0, ANIM_MODE_1 = 1, ANIM_MODE_2 = 2, ANIM_MOD
ANIM_MODE_9 = 9
};
+// Actor effect enumeration used in Return to Ringworld 2
+enum Effect { EFFECT_NONE = 0, EFFECT_SHADED = 1, EFFECT_3 = 3,
+ EFFECT_SHADOW_MAP = 5, EFFECT_SHADED2 = 6 };
+
class SceneObject;
class Visage {
@@ -511,7 +513,8 @@ public:
enum ObjectFlags {OBJFLAG_FIXED_PRIORITY = 1, OBJFLAG_NO_UPDATES = 2, OBJFLAG_ZOOMED = 4,
OBJFLAG_SUPPRESS_DISPATCH = 8, OBJFLAG_HIDE = 0x100, OBJFLAG_HIDING = 0x200, OBJFLAG_REMOVE = 0x400,
OBJFLAG_CLONED = 0x800, OBJFLAG_CHECK_REGION = 0x1000, OBJFLAG_PANE_0 = 0x4000, OBJFLAG_PANE_1 = 0x8000,
- OBJFLAG_PANES = OBJFLAG_PANE_0 | OBJFLAG_PANE_1
+ OBJFLAG_PANES = OBJFLAG_PANE_0 | OBJFLAG_PANE_1,
+ OBJFLAG_FLIP_CENTROID_X = 0x10000, OBJFLAG_FLIP_CENTROID_Y = 0x20000
};
class SceneObject : public SceneHotspot {
@@ -524,7 +527,7 @@ public:
int changeFrame();
uint32 _updateStartFrame;
uint32 _walkStartFrame;
- Common::Point _field2E;
+ Common::Point _oldPosition;
int _percent;
int _priority;
int _angle;
@@ -537,20 +540,20 @@ public:
AnimateMode _animateMode;
int _frame;
int _endFrame;
- int _field68;
+ int _loopCount;
int _frameChange;
int _numFrames;
int _regionIndex;
EventHandler *_mover;
Common::Point _moveDiff;
int _moveRate;
- Common::Point _field8A;
+ Common::Point _actorDestPos;
Action *_endAction;
uint32 _regionBitList;
// Ringworld 2 specific fields
- byte *_field9C;
- int _shade, _shade2;
+ byte *_shadowMap;
+ int _shade, _oldShade;
int _effect;
SceneObject *_linkedActor;
public:
@@ -646,7 +649,6 @@ class Player : public SceneObject {
public:
bool _canWalk;
bool _uiEnabled;
- int _field8C;
bool _enabled;
// Return to Ringworld specific fields
@@ -773,8 +775,6 @@ public:
class ScenePriorities : public Common::List<Region> {
public:
int _resNum;
- int _field14;
- int _field16;
Region _defaultPriorityRegion;
public:
void load(int resNum);
@@ -880,7 +880,6 @@ public:
RefCounter _lockCtr;
RefCounter _waitCtr;
int _nextWaitCtr;
- int _field14;
public:
GameHandler();
virtual ~GameHandler();
diff --git a/engines/tsage/debugger.cpp b/engines/tsage/debugger.cpp
index 82645f2d62..e81e5cddb3 100644
--- a/engines/tsage/debugger.cpp
+++ b/engines/tsage/debugger.cpp
@@ -30,18 +30,19 @@
namespace TsAGE {
Debugger::Debugger() : GUI::Debugger() {
- DCmd_Register("continue", WRAP_METHOD(Debugger, Cmd_Exit));
- DCmd_Register("scene", WRAP_METHOD(Debugger, Cmd_Scene));
- DCmd_Register("walk_regions", WRAP_METHOD(Debugger, Cmd_WalkRegions));
- DCmd_Register("priority_regions", WRAP_METHOD(Debugger, Cmd_PriorityRegions));
- DCmd_Register("scene_regions", WRAP_METHOD(Debugger, Cmd_SceneRegions));
- DCmd_Register("setflag", WRAP_METHOD(Debugger, Cmd_SetFlag));
- DCmd_Register("getflag", WRAP_METHOD(Debugger, Cmd_GetFlag));
- DCmd_Register("clearflag", WRAP_METHOD(Debugger, Cmd_ClearFlag));
- DCmd_Register("listobjects", WRAP_METHOD(Debugger, Cmd_ListObjects));
- DCmd_Register("moveobject", WRAP_METHOD(Debugger, Cmd_MoveObject));
- DCmd_Register("hotspots", WRAP_METHOD(Debugger, Cmd_Hotspots));
- DCmd_Register("sound", WRAP_METHOD(Debugger, Cmd_Sound));
+ DCmd_Register("continue", WRAP_METHOD(Debugger, Cmd_Exit));
+ DCmd_Register("scene", WRAP_METHOD(Debugger, Cmd_Scene));
+ DCmd_Register("walk_regions", WRAP_METHOD(Debugger, Cmd_WalkRegions));
+ DCmd_Register("priority_regions", WRAP_METHOD(Debugger, Cmd_PriorityRegions));
+ DCmd_Register("scene_regions", WRAP_METHOD(Debugger, Cmd_SceneRegions));
+ DCmd_Register("setflag", WRAP_METHOD(Debugger, Cmd_SetFlag));
+ DCmd_Register("getflag", WRAP_METHOD(Debugger, Cmd_GetFlag));
+ DCmd_Register("clearflag", WRAP_METHOD(Debugger, Cmd_ClearFlag));
+ DCmd_Register("listobjects", WRAP_METHOD(Debugger, Cmd_ListObjects));
+ DCmd_Register("moveobject", WRAP_METHOD(Debugger, Cmd_MoveObject));
+ DCmd_Register("hotspots", WRAP_METHOD(Debugger, Cmd_Hotspots));
+ DCmd_Register("sound", WRAP_METHOD(Debugger, Cmd_Sound));
+ DCmd_Register("setdebug", WRAP_METHOD(Debugger, Cmd_SetDebug));
}
static int strToInt(const char *s) {
@@ -340,6 +341,14 @@ bool Debugger::Cmd_Sound(int argc, const char **argv) {
return false;
}
+/**
+ * Activate internal debugger, when available
+ */
+bool Debugger::Cmd_SetDebug(int argc, const char **argv) {
+ DebugPrintf("Not available in this game\n");
+ return true;
+}
+
/*
* This command lists the objects available, and their ID
*/
@@ -632,57 +641,57 @@ bool Ringworld2Debugger::Cmd_ListObjects(int argc, const char **argv) {
DebugPrintf("Available objects for this game are:\n");
DebugPrintf("1 - R2_OPTO_DISK\n");
- DebugPrintf("2 - R2_2\n");
+ DebugPrintf("2 - R2_READER\n");
DebugPrintf("3 - R2_NEGATOR_GUN\n");
DebugPrintf("4 - R2_STEPPING_DISKS\n");
- DebugPrintf("5 - R2_5\n");
- DebugPrintf("6 - R2_6\n");
- DebugPrintf("7 - R2_7\n");
- DebugPrintf("8 - R2_8\n");
- DebugPrintf("9 - R2_9\n");
- DebugPrintf("10 - R2_10\n");
- DebugPrintf("11 - R2_11\n");
- DebugPrintf("12 - R2_12\n");
- DebugPrintf("13 - R2_13\n");
- DebugPrintf("14 - R2_14\n");
- DebugPrintf("15 - R2_15\n");
- DebugPrintf("16 - R2_16\n");
- DebugPrintf("17 - R2_17\n");
- DebugPrintf("18 - R2_18\n");
- DebugPrintf("19 - R2_19\n");
- DebugPrintf("20 - R2_20\n");
- DebugPrintf("21 - R2_21\n");
- DebugPrintf("22 - R2_22\n");
- DebugPrintf("23 - R2_23\n");
- DebugPrintf("24 - R2_24\n");
- DebugPrintf("25 - R2_25\n");
- DebugPrintf("26 - R2_26\n");
- DebugPrintf("27 - R2_27\n");
- DebugPrintf("28 - R2_28\n");
- DebugPrintf("29 - R2_29\n");
- DebugPrintf("30 - R2_30\n");
- DebugPrintf("31 - R2_31\n");
- DebugPrintf("32 - R2_32\n");
- DebugPrintf("33 - R2_33\n");
- DebugPrintf("34 - R2_34\n");
- DebugPrintf("35 - R2_35\n");
- DebugPrintf("36 - R2_36\n");
- DebugPrintf("37 - R2_37\n");
- DebugPrintf("38 - R2_38\n");
- DebugPrintf("39 - R2_39\n");
- DebugPrintf("40 - R2_40\n");
- DebugPrintf("41 - R2_41\n");
- DebugPrintf("42 - R2_42\n");
- DebugPrintf("43 - R2_43\n");
- DebugPrintf("44 - R2_44\n");
- DebugPrintf("45 - R2_45\n");
- DebugPrintf("46 - R2_46\n");
- DebugPrintf("47 - R2_47\n");
- DebugPrintf("48 - R2_48\n");
- DebugPrintf("49 - R2_49\n");
- DebugPrintf("50 - R2_50\n");
- DebugPrintf("51 - R2_51\n");
- DebugPrintf("52 - R2_52\n");
+ DebugPrintf("5 - R2_ATTRACTOR_UNIT\n");
+ DebugPrintf("6 - R2_SENSOR_PROBE\n");
+ DebugPrintf("7 - R2_SONIC_STUNNER\n");
+ DebugPrintf("8 - R2_CABLE_HARNESS\n");
+ DebugPrintf("9 - R2_COM_SCANNER\n");
+ DebugPrintf("10 - R2_SPENT_POWER_CAPSULE\n");
+ DebugPrintf("11 - R2_CHARGED_POWER_CAPSULE\n");
+ DebugPrintf("12 - R2_AEROSOL\n");
+ DebugPrintf("13 - R2_REMOTE_CONTROL\n");
+ DebugPrintf("14 - R2_OPTICAL_FIBRE\n");
+ DebugPrintf("15 - R2_CLAMP\n");
+ DebugPrintf("16 - R2_ATTRACTOR_CABLE_HARNESS\n");
+ DebugPrintf("17 - R2_FUEL_CELL\n");
+ DebugPrintf("18 - R2_GYROSCOPE\n");
+ DebugPrintf("19 - R2_AIRBAG\n");
+ DebugPrintf("20 - R2_REBREATHER_TANK\n");
+ DebugPrintf("21 - R2_RESERVE_REBREATHER_TANK\n");
+ DebugPrintf("22 - R2_GUIDANCE_MODULE\n");
+ DebugPrintf("23 - R2_THRUSTER_VALVE\n");
+ DebugPrintf("24 - R2_BALLOON_BACKPACK\n");
+ DebugPrintf("25 - R2_RADAR_MECHANISM\n");
+ DebugPrintf("26 - R2_JOYSTICK\n");
+ DebugPrintf("27 - R2_IGNITOR\n");
+ DebugPrintf("28 - R2_DIAGNOSTICS_DISPLAY\n");
+ DebugPrintf("29 - R2_GLASS_DOME\n");
+ DebugPrintf("30 - R2_WICK_LAMP\n");
+ DebugPrintf("31 - R2_SCRITH_KEY\n");
+ DebugPrintf("32 - R2_TANNER_MASK\n");
+ DebugPrintf("33 - R2_PURE_GRAIN_ALCOHOL\n");
+ DebugPrintf("34 - R2_SAPPHIRE_BLUE\n");
+ DebugPrintf("35 - R2_ANCIENT_SCROLLS\n");
+ DebugPrintf("36 - R2_FLUTE\n");
+ DebugPrintf("37 - R2_GUNPOWDER\n");
+ DebugPrintf("38 - R2_NONAME\n");
+ DebugPrintf("39 - R2_COM_SCANNER_2\n");
+ DebugPrintf("40 - R2_SUPERCONDUCTOR_WIRE\n");
+ DebugPrintf("41 - R2_PILLOW\n");
+ DebugPrintf("42 - R2_FOOD_TRAY\n");
+ DebugPrintf("43 - R2_LASER_HACKSAW\n");
+ DebugPrintf("44 - R2_PHOTON_STUNNER\n");
+ DebugPrintf("45 - R2_BATTERY\n");
+ DebugPrintf("46 - R2_SOAKED_FACEMASK\n");
+ DebugPrintf("47 - R2_LIGHT_BULB\n");
+ DebugPrintf("48 - R2_ALCOHOL_LAMP\n");
+ DebugPrintf("49 - R2_ALCOHOL_LAMP_2\n");
+ DebugPrintf("50 - R2_ALCOHOL_LAMP_3\n");
+ DebugPrintf("51 - R2_BROKEN_DISPLAY\n");
+ DebugPrintf("52 - R2_TOOLBOX\n");
return true;
}
@@ -707,4 +716,19 @@ bool Ringworld2Debugger::Cmd_MoveObject(int argc, const char **argv) {
return true;
}
+
+/**
+ * Activate internal debugger, when available
+ */
+bool Ringworld2Debugger::Cmd_SetDebug(int argc, const char **argv) {
+ if (argc != 1) {
+ DebugPrintf("Usage: %s\n", argv[0]);
+ return true;
+ }
+
+ // Set the internal debugger flag(s?) to true
+ // _debugCardGame is reset by scene1337::subPostInit()
+ R2_GLOBALS._debugCardGame = true;
+ return true;
+}
} // End of namespace TsAGE
diff --git a/engines/tsage/debugger.h b/engines/tsage/debugger.h
index bf826a3f77..c9b7e75039 100644
--- a/engines/tsage/debugger.h
+++ b/engines/tsage/debugger.h
@@ -45,6 +45,7 @@ protected:
bool Cmd_Sound(int argc, const char **argv);
virtual bool Cmd_ListObjects(int argc, const char **argv) = 0;
virtual bool Cmd_MoveObject(int argc, const char **argv) = 0;
+ virtual bool Cmd_SetDebug(int argc, const char **argv);
};
class DemoDebugger : public Debugger {
@@ -69,6 +70,7 @@ class Ringworld2Debugger : public Debugger {
protected:
virtual bool Cmd_ListObjects(int argc, const char **argv);
virtual bool Cmd_MoveObject(int argc, const char **argv);
+ virtual bool Cmd_SetDebug(int argc, const char **argv);
};
} // End of namespace TsAGE
diff --git a/engines/tsage/detection.cpp b/engines/tsage/detection.cpp
index a35d663b93..5eae7557d2 100644
--- a/engines/tsage/detection.cpp
+++ b/engines/tsage/detection.cpp
@@ -75,7 +75,6 @@ class TSageMetaEngine : public AdvancedMetaEngine {
public:
TSageMetaEngine() : AdvancedMetaEngine(TsAGE::gameDescriptions, sizeof(TsAGE::tSageGameDescription), tSageGameTitles) {
_singleid = "tsage";
- _guioptions = GUIO1(GUIO_NOSPEECH);
}
virtual const char *getName() const {
diff --git a/engines/tsage/detection_tables.h b/engines/tsage/detection_tables.h
index b374dbc98b..123f04f8e2 100644
--- a/engines/tsage/detection_tables.h
+++ b/engines/tsage/detection_tables.h
@@ -165,13 +165,26 @@ static const tSageGameDescription gameDescriptions[] = {
AD_ENTRY1s("r2rw.rlb", "df6c25622387007788ca36d99362c1f0", 47586928),
Common::EN_ANY,
Common::kPlatformDOS,
- ADGF_CD | ADGF_UNSTABLE,
+ ADGF_CD | ADGF_TESTING,
GUIO0()
},
GType_Ringworld2,
GF_CD | GF_ALT_REGIONS
},
-
+ // Return to Ringworld - Demo
+ {
+ {
+ "ringworld2",
+ "CD Demo",
+ AD_ENTRY1s("r2rw.rlb", "c8e1a82c67c3caf57368eadde13dc15f", 32384464),
+ Common::EN_ANY,
+ Common::kPlatformDOS,
+ ADGF_CD | ADGF_TESTING,
+ GUIO0()
+ },
+ GType_Ringworld2,
+ GF_CD | GF_ALT_REGIONS | GF_DEMO
+ },
{ AD_TABLE_END_MARKER, 0, 0 }
};
diff --git a/engines/tsage/events.cpp b/engines/tsage/events.cpp
index d2d8464763..0ba60384bf 100644
--- a/engines/tsage/events.cpp
+++ b/engines/tsage/events.cpp
@@ -71,7 +71,7 @@ bool EventsClass::pollEvent() {
break;
default:
- break;
+ break;
}
return true;
@@ -156,7 +156,7 @@ void EventsClass::setCursor(CursorType cursorType) {
// No cursor
g_globals->setFlag(122);
- if ((g_vm->getFeatures() & GF_DEMO) || (g_vm->getGameID() != GType_Ringworld)) {
+ if ((g_vm->getGameID() != GType_Ringworld) || ((g_vm->getGameID() == GType_Ringworld) && (g_vm->getFeatures() & GF_DEMO))) {
CursorMan.showMouse(false);
return;
}
diff --git a/engines/tsage/globals.cpp b/engines/tsage/globals.cpp
index 9bd7249902..f270e23ea5 100644
--- a/engines/tsage/globals.cpp
+++ b/engines/tsage/globals.cpp
@@ -3,7 +3,7 @@
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
- *
+ *
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
@@ -26,6 +26,7 @@
#include "tsage/ringworld/ringworld_demo.h"
#include "tsage/ringworld/ringworld_logic.h"
#include "tsage/ringworld2/ringworld2_logic.h"
+#include "tsage/ringworld2/ringworld2_scenes0.h"
#include "tsage/staticres.h"
namespace TsAGE {
@@ -47,6 +48,11 @@ static SavedObject *classFactoryProc(const Common::String &className) {
if (className == "SceneObjectWrapper") return new SceneObjectWrapper();
if (className == "PaletteRotation") return new PaletteRotation();
if (className == "PaletteFader") return new PaletteFader();
+ if (className == "SceneText") return new SceneText();
+
+ // Return to Ringworld specific classes
+ if (className == "Scene205_Star") return new Ringworld2::Star();
+
return NULL;
}
@@ -57,18 +63,41 @@ Globals::Globals() : _dialogCenter(160, 140), _gfxManagerInstance(_screenSurface
reset();
_stripNum = 0;
_gfxEdgeAdjust = 3;
-
- if (g_vm->getFeatures() & GF_DEMO) {
- _gfxFontNumber = 0;
- _gfxColors.background = 6;
- _gfxColors.foreground = 0;
- _fontColors.background = 255;
- _fontColors.foreground = 6;
- _dialogCenter.y = 80;
- // Workaround in order to use later version of the engine
- _color1 = _gfxColors.foreground;
- _color2 = _gfxColors.foreground;
- _color3 = _gfxColors.foreground;
+ _gfxFontNumber = 0;
+
+ if (g_vm->getGameID() == GType_Ringworld) {
+ if (g_vm->getFeatures() & GF_DEMO) {
+ _gfxFontNumber = 0;
+ _gfxColors.background = 6;
+ _gfxColors.foreground = 0;
+ _fontColors.background = 255;
+ _fontColors.foreground = 6;
+ _dialogCenter.y = 80;
+ // Workaround in order to use later version of the engine
+ _color1 = _gfxColors.foreground;
+ _color2 = _gfxColors.foreground;
+ _color3 = _gfxColors.foreground;
+ } else if (g_vm->getFeatures() & GF_CD) {
+ _gfxFontNumber = 50;
+ _gfxColors.background = 53;
+ _gfxColors.foreground = 0;
+ _fontColors.background = 51;
+ _fontColors.foreground = 54;
+ _color1 = 18;
+ _color2 = 18;
+ _color3 = 18;
+ } else {
+ // Floppy version
+ _gfxFontNumber = 50;
+ _gfxColors.background = 53;
+ _gfxColors.foreground = 18;
+ _fontColors.background = 51;
+ _fontColors.foreground = 54;
+ // Workaround in order to use later version of the engine
+ _color1 = _gfxColors.foreground;
+ _color2 = _gfxColors.foreground;
+ _color3 = _gfxColors.foreground;
+ }
} else if (g_vm->getGameID() == GType_BlueForce) {
// Blue Force
_gfxFontNumber = 0;
@@ -88,26 +117,6 @@ Globals::Globals() : _dialogCenter(160, 140), _gfxManagerInstance(_screenSurface
_color2 = 15;
_color3 = 4;
_dialogCenter.y = 100;
- } else if ((g_vm->getGameID() == GType_Ringworld) && (g_vm->getFeatures() & GF_CD)) {
- _gfxFontNumber = 50;
- _gfxColors.background = 53;
- _gfxColors.foreground = 0;
- _fontColors.background = 51;
- _fontColors.foreground = 54;
- _color1 = 18;
- _color2 = 18;
- _color3 = 18;
- } else {
- // Ringworld
- _gfxFontNumber = 50;
- _gfxColors.background = 53;
- _gfxColors.foreground = 18;
- _fontColors.background = 51;
- _fontColors.foreground = 54;
- // Workaround in order to use later version of the engine
- _color1 = _gfxColors.foreground;
- _color2 = _gfxColors.foreground;
- _color3 = _gfxColors.foreground;
}
_screenSurface.setScreenSurface();
_gfxManagers.push_back(&_gfxManagerInstance);
@@ -119,8 +128,11 @@ Globals::Globals() : _dialogCenter(160, 140), _gfxManagerInstance(_screenSurface
_sounds.push_back(&_soundHandler);
_sounds.push_back(&_sequenceManager._soundHandler);
- _scrollFollower = NULL;
- _inventory = NULL;
+ _scrollFollower = nullptr;
+
+ _inventory = nullptr;
+ _game = nullptr;
+ _sceneHandler = nullptr;
switch (g_vm->getGameID()) {
case GType_Ringworld:
@@ -145,6 +157,7 @@ Globals::Globals() : _dialogCenter(160, 140), _gfxManagerInstance(_screenSurface
_sceneHandler = new Ringworld2::SceneHandlerExt();
break;
}
+
}
Globals::~Globals() {
@@ -204,6 +217,11 @@ void Globals::dispatchSounds() {
/*--------------------------------------------------------------------------*/
+TsAGE2Globals::TsAGE2Globals() {
+ _onSelectItem = NULL;
+ _interfaceY = 0;
+}
+
void TsAGE2Globals::reset() {
Globals::reset();
@@ -224,15 +242,46 @@ void TsAGE2Globals::synchronize(Serializer &s) {
namespace BlueForce {
BlueForceGlobals::BlueForceGlobals(): TsAGE2Globals() {
+ _hiddenDoorStatus = 0;
+ _nico910State = 0;
+ _stuart910State = 0;
+ _nico910Talk = 0;
+ _stuart910Talk = 0;
+ _deziTopic = 0;
+ _deathReason = 0;
+ _driveFromScene = 300;
+ _driveToScene = 0;
+ _subFlagBitArr1 = 0;
+ _subFlagBitArr2 = 0;
+ _scene410HarrisonTalkFl = false;
+ _scene410Action1Count = 0;
+ _scene410TalkCount = 0;
+ _scene410HarrisonMovedFl = false;
+ _bookmark = bNone;
+ _mapLocationId = 1;
+ _clip1Bullets = 8;
+ _clip2Bullets = 8;
+
+ _dayNumber = 0;
+ _tonyDialogCtr = 0;
+ _marinaWomanCtr = 0;
+ _kateDialogCtr = 0;
+ _v4CEB6 = 0;
+ _safeCombination = 0;
+ _gateStatus = 0;
+ _greenDay5TalkCtr = 0;
+ _v4CEC8 = 1;
+ _v4CECA = 0;
+ _v4CECC = 0;
}
void BlueForceGlobals::synchronize(Serializer &s) {
TsAGE2Globals::synchronize(s);
+ int16 useless = 0;
s.syncAsSint16LE(_dayNumber);
if (s.getVersion() < 9) {
- int tmpVar = 0;
- s.syncAsSint16LE(tmpVar);
+ s.syncAsSint16LE(useless);
}
s.syncAsSint16LE(_tonyDialogCtr);
s.syncAsSint16LE(_marinaWomanCtr);
@@ -241,7 +290,8 @@ void BlueForceGlobals::synchronize(Serializer &s) {
s.syncAsSint16LE(_safeCombination);
s.syncAsSint16LE(_gateStatus);
s.syncAsSint16LE(_greenDay5TalkCtr);
- s.syncAsSint16LE(_v4CEC4);
+ if (s.getVersion() < 11)
+ s.syncAsSint16LE(useless);
s.syncAsSint16LE(_v4CEC8);
s.syncAsSint16LE(_v4CECA);
s.syncAsSint16LE(_v4CECC);
@@ -249,26 +299,30 @@ void BlueForceGlobals::synchronize(Serializer &s) {
s.syncAsByte(_breakerBoxStatusArr[i]);
s.syncAsSint16LE(_hiddenDoorStatus);
s.syncAsSint16LE(_nico910State);
- s.syncAsSint16LE(_v4CEE4);
- s.syncAsSint16LE(_v4CEE6);
- s.syncAsSint16LE(_v4CEE8);
+ s.syncAsSint16LE(_stuart910State);
+ s.syncAsSint16LE(_nico910Talk);
+ s.syncAsSint16LE(_stuart910Talk);
s.syncAsSint16LE(_deziTopic);
s.syncAsSint16LE(_deathReason);
s.syncAsSint16LE(_driveFromScene);
s.syncAsSint16LE(_driveToScene);
- s.syncAsSint16LE(_v501F8);
- s.syncAsSint16LE(_v501FA);
- s.syncAsSint16LE(_v501FC);
- s.syncAsSint16LE(_v5020C);
- s.syncAsSint16LE(_v50696);
+ if (s.getVersion() < 11) {
+ s.syncAsSint16LE(useless);
+ s.syncAsSint16LE(useless);
+ s.syncAsSint16LE(useless);
+ s.syncAsSint16LE(useless);
+ s.syncAsSint16LE(useless);
+ }
s.syncAsSint16LE(_subFlagBitArr1);
s.syncAsSint16LE(_subFlagBitArr2);
- s.syncAsSint16LE(_v50CC2);
- s.syncAsSint16LE(_v50CC4);
- s.syncAsSint16LE(_v50CC6);
- s.syncAsSint16LE(_v50CC8);
- s.syncAsSint16LE(_v51C42);
- s.syncAsSint16LE(_v51C44);
+ s.syncAsSint16LE(_scene410HarrisonTalkFl);
+ s.syncAsSint16LE(_scene410Action1Count);
+ s.syncAsSint16LE(_scene410TalkCount);
+ s.syncAsSint16LE(_scene410HarrisonMovedFl);
+ if (s.getVersion() < 11) {
+ s.syncAsSint16LE(useless);
+ s.syncAsSint16LE(useless);
+ }
s.syncAsSint16LE(_bookmark);
s.syncAsSint16LE(_mapLocationId);
s.syncAsSint16LE(_clip1Bullets);
@@ -298,7 +352,6 @@ void BlueForceGlobals::reset() {
_safeCombination = 0;
_gateStatus = 0;
_greenDay5TalkCtr = 0;
- _v4CEC4 = 0;
_v4CEC8 = 1;
_v4CECA = 0;
_v4CECC = 0;
@@ -322,24 +375,17 @@ void BlueForceGlobals::reset() {
_breakerBoxStatusArr[17] = 0;
_hiddenDoorStatus = 0;
_nico910State = 0;
- _v4CEE4 = 0;
- _v4CEE6 = 0;
- _v4CEE8 = 0;
+ _stuart910State = 0;
+ _nico910Talk = 0;
+ _stuart910Talk = 0;
_deziTopic = 0;
_deathReason = 0;
- _v501F8 = 0;
- _v501FA = 0;
- _v501FC = 0;
- _v5020C = 0;
- _v50696 = 0;
_subFlagBitArr1 = 0;
_subFlagBitArr2 = 0;
- _v50CC2 = 0;
- _v50CC4 = 0;
- _v50CC6 = 0;
- _v50CC8 = 0;
- _v51C42 = 0;
- _v51C44 = 1;
+ _scene410HarrisonTalkFl = false;
+ _scene410Action1Count = 0;
+ _scene410TalkCount = 0;
+ _scene410HarrisonMovedFl = false;
_clip1Bullets = 8;
_clip2Bullets = 8;
}
@@ -369,6 +415,53 @@ namespace Ringworld2 {
Ringworld2Globals::Ringworld2Globals() {
_scannerDialog = new ScannerDialog();
+ _speechSubtitles = SPEECH_TEXT;
+
+ // Register the inner sound objects for each of the global ASoundExt fields.
+ // Normally the ASound constructor would do this, but because they're fields
+ // of the globals, the g_globals reference isn't ready for them to use
+ _sounds.push_back(&_sound1);
+ _sounds.push_back(&_sound2);
+ _sounds.push_back(&_sound3);
+ _sounds.push_back(&_sound4);
+
+ // Initialize fields
+ _stripModifier = 0;
+ _flubMazeArea = 1;
+ _flubMazeEntryDirection = 0;
+ _maze3800SceneNumb = 3800;
+ _landerSuitNumber = 2;
+ _desertStepsRemaining = 5;
+ _desertCorrectDirection = 0;
+ _desertPreviousDirection = 0;
+ _desertWrongDirCtr = -1;
+ _balloonAltitude = 5;
+ _scene1925CurrLevel = 0;
+ _walkwaySceneNumber = 0;
+ _mirandaJailState = 0;
+ _scientistConvIndex = 0;
+ _ductMazePanel1State = 1;
+ _ductMazePanel2State = 1;
+ _ductMazePanel3State = 1;
+ _scene180Mode = -1;
+ _v57709 = 0;
+ _v5780C = 0;
+ _mouseCursorId = 0;
+ _v57810 = 0;
+
+ _fadePaletteFlag = false;
+ _insetUp = 0;
+ _frameEdgeColor = 2;
+ _animationCtr = 0;
+ _electromagnetChangeAmount = 0;
+ _electromagnetZoom = 0;
+ _tractorField = false;
+ _cableAttached = 0;
+ _foodCount = 0;
+ _rimLocation = 0;
+ _rimTransportLocation = 0;
+
+ _debugCardGame = false;
}
Ringworld2Globals::~Ringworld2Globals() {
@@ -397,21 +490,15 @@ void Ringworld2Globals::reset() {
Common::fill(&_paletteMap[0], &_paletteMap[4096], 0);
_fadePaletteFlag = false;
- _v5589E.set(0, 0, 0, 0);
- _v558B6.set(0, 0, 0, 0);
- _v558C2 = 0;
_animationCtr = 0;
- _v5657C = 0;
_electromagnetChangeAmount = 0;
_electromagnetZoom = 0;
- _v565E5 = 0;
- _v565E7 = 0;
- _v565E9 = -5;
- _v565EB = 26;
+ _tractorField = false;
+ _cableAttached = 0;
_foodCount = 0;
_rimLocation = 0;
_rimTransportLocation = 0;
- _v565AE = 0;
+ _stripModifier = 0;
_spillLocation[0] = 0;
_spillLocation[1] = 3;
_spillLocation[R2_SEEKER] = 5;
@@ -427,7 +514,7 @@ void Ringworld2Globals::reset() {
_spillLocation[12] = 27;
_spillLocation[13] = 31;
- // Initialise the vampire data within the Flub maze
+ // Initialize the vampire data within the Flub maze
for (int i = 0; i < 18; i++) {
_vampireData[i]._isAlive = true;
_vampireData[i]._position = Common::Point();
@@ -451,7 +538,7 @@ void Ringworld2Globals::reset() {
_vampireData[16]._shotsRequired = 1;
_vampireData[17]._shotsRequired = 1;
- _v566A6 = 3800;
+ _maze3800SceneNumb = 3800;
_landerSuitNumber = 2;
_flubMazeArea = 1;
_flubMazeEntryDirection = 0;
@@ -464,23 +551,20 @@ void Ringworld2Globals::reset() {
_balloonAltitude = 5;
_scene1925CurrLevel = 0; //_v56A9C
_walkwaySceneNumber = 0;
- _v56AA0 = 0;
+ _mirandaJailState = 0;
_scientistConvIndex = 0;
_ventCellPos = Common::Point(60, 660);
- _v56AA6 = 1;
- _v56AA7 = 1;
- _v56AA8 = 1;
- _v56AAB = 0;
+ _ductMazePanel1State = 1;
+ _ductMazePanel2State = 1;
+ _ductMazePanel3State = 1;
_scene180Mode = -1;
_v57709 = 0;
_v5780C = 0;
- _v5780E = 0;
+ _mouseCursorId = 0;
_v57810 = 0;
- _v57C2C = 0;
_s1550PlayerArea[R2_QUINN] = Common::Point(27, 4);
_s1550PlayerArea[R2_SEEKER] = Common::Point(27, 4);
Common::fill(&_scannerFrequencies[0], &_scannerFrequencies[MAX_CHARACTERS], 1);
- _speechSubtitles = SPEECH_VOICE | SPEECH_TEXT;
_insetUp = 0;
_frameEdgeColor = 2;
Common::fill(&_stripManager_lookupList[0], &_stripManager_lookupList[12], 0);
@@ -504,45 +588,35 @@ void Ringworld2Globals::reset() {
_player._characterScene[R2_QUINN] = 100;
_player._characterScene[R2_SEEKER] = 300;
_player._characterScene[R2_MIRANDA] = 300;
+
+ _debugCardGame = false;
}
void Ringworld2Globals::synchronize(Serializer &s) {
TsAGE2Globals::synchronize(s);
int i;
- _v5589E.synchronize(s);
- _v558B6.synchronize(s);
-
- s.syncAsSint16LE(_v558C2);
s.syncAsSint16LE(_animationCtr);
- s.syncAsSint16LE(_v5657C);
s.syncAsSint16LE(_electromagnetChangeAmount);
s.syncAsSint16LE(_electromagnetZoom);
- s.syncAsSint16LE(_v565E5);
- s.syncAsSint16LE(_v565E7);
- s.syncAsSint16LE(_v565E9);
- s.syncAsSint16LE(_v565EB);
+ s.syncAsSint16LE(_tractorField);
+ s.syncAsSint16LE(_cableAttached);
s.syncAsSint16LE(_foodCount);
s.syncAsSint32LE(_rimLocation);
s.syncAsSint16LE(_rimTransportLocation);
s.syncAsSint16LE(_landerSuitNumber);
- s.syncAsSint16LE(_v566A6);
+ s.syncAsSint16LE(_maze3800SceneNumb);
s.syncAsSint16LE(_desertWrongDirCtr);
s.syncAsSint16LE(_scene1925CurrLevel); // _v56A9C
s.syncAsSint16LE(_walkwaySceneNumber);
s.syncAsSint16LE(_ventCellPos.x);
s.syncAsSint16LE(_ventCellPos.y);
- s.syncAsSint16LE(_v56AAB);
s.syncAsSint16LE(_scene180Mode);
s.syncAsSint16LE(_v57709);
s.syncAsSint16LE(_v5780C);
- s.syncAsSint16LE(_v5780E);
+ s.syncAsSint16LE(_mouseCursorId);
s.syncAsSint16LE(_v57810);
- s.syncAsSint16LE(_v57C2C);
- s.syncAsSint16LE(_speechSubtitles);
- byte temp;
- s.syncAsByte(temp);
s.syncAsByte(_s1550PlayerArea[R2_QUINN].x);
s.syncAsByte(_s1550PlayerArea[R2_SEEKER].x);
s.syncAsByte(_s1550PlayerArea[R2_QUINN].y);
@@ -551,17 +625,17 @@ void Ringworld2Globals::synchronize(Serializer &s) {
for (i = 0; i < MAX_CHARACTERS; ++i)
s.syncAsByte(_scannerFrequencies[i]);
- s.syncAsByte(_v565AE);
+ s.syncAsByte(_stripModifier);
s.syncAsByte(_flubMazeArea);
s.syncAsByte(_flubMazeEntryDirection);
s.syncAsByte(_desertStepsRemaining);
s.syncAsByte(_desertCorrectDirection);
s.syncAsByte(_desertPreviousDirection);
- s.syncAsByte(_v56AA0);
+ s.syncAsByte(_mirandaJailState);
s.syncAsByte(_scientistConvIndex);
- s.syncAsByte(_v56AA6);
- s.syncAsByte(_v56AA7);
- s.syncAsByte(_v56AA8);
+ s.syncAsByte(_ductMazePanel1State);
+ s.syncAsByte(_ductMazePanel2State);
+ s.syncAsByte(_ductMazePanel3State);
for (i = 0; i < 14; ++i)
s.syncAsByte(_spillLocation[i]);
@@ -580,7 +654,7 @@ void Ringworld2Globals::synchronize(Serializer &s) {
s.syncAsSint16LE(_balloonPosition.x);
s.syncAsSint16LE(_balloonPosition.y);
- // Synchronise Flub maze vampire data
+ // Synchronize Flub maze vampire data
for (i = 0; i < 18; ++i) {
s.syncAsSint16LE(_vampireData[i]._isAlive);
s.syncAsSint16LE(_vampireData[i]._shotsRequired);
diff --git a/engines/tsage/globals.h b/engines/tsage/globals.h
index ad47f7f620..777697edbd 100644
--- a/engines/tsage/globals.h
+++ b/engines/tsage/globals.h
@@ -110,7 +110,7 @@ public:
int _interfaceY;
ASoundExt _inventorySound;
- TsAGE2Globals() { _onSelectItem = NULL; }
+ TsAGE2Globals();
virtual void reset();
virtual void synchronize(Serializer &s);
};
@@ -194,33 +194,25 @@ public:
int _safeCombination;
int _gateStatus;
int _greenDay5TalkCtr;
- int _v4CEC4;
int _v4CEC8;
int _v4CECA;
int _v4CECC;
int8 _breakerBoxStatusArr[18];
int _hiddenDoorStatus;
int _nico910State;
- int _v4CEE4;
- int _v4CEE6;
- int _v4CEE8;
+ int _stuart910State;
+ int _nico910Talk;
+ int _stuart910Talk;
int _deziTopic;
int _deathReason;
int _driveFromScene;
int _driveToScene;
- int _v501F8;
- int _v501FA;
- int _v501FC;
- int _v5020C;
- int _v50696;
uint8 _subFlagBitArr1;
uint8 _subFlagBitArr2;
- int _v50CC2;
- int _v50CC4;
- int _v50CC6;
- int _v50CC8;
- int _v51C42;
- int _v51C44;
+ bool _scene410HarrisonTalkFl;
+ int _scene410Action1Count;
+ int _scene410TalkCount;
+ bool _scene410HarrisonMovedFl;
Bookmark _bookmark;
int _mapLocationId;
int _clip1Bullets, _clip2Bullets;
@@ -259,27 +251,21 @@ public:
byte _fadePaletteMap[10][256];
byte _paletteMap[4096];
int _insetUp;
- int _frameEdgeColor; // _v421e
- Rect _v5589E;
- Rect _v558B6;
- int _v558C2;
+ int _frameEdgeColor;
int _animationCtr;
int _electromagnetChangeAmount;
int _electromagnetZoom;
- int _v565E5;
- int _v565E7;
- int _v565E9;
- int _v565EB;
+ bool _tractorField;
+ bool _cableAttached;
int _foodCount;
int _rimLocation;
int _rimTransportLocation;
- int _v5657C;
- byte _v565AE;
+ byte _stripModifier;
byte _spillLocation[14];
VampireData _vampireData[18];
byte _flubMazeArea;
byte _flubMazeEntryDirection;
- int _v566A6;
+ int _maze3800SceneNumb;
byte _landerSuitNumber;
byte _desertStepsRemaining;
byte _desertCorrectDirection;
@@ -289,26 +275,24 @@ public:
byte _balloonAltitude;
int _scene1925CurrLevel; //_v56A9C
int _walkwaySceneNumber;
- byte _v56AA0;
+ byte _mirandaJailState;
byte _scientistConvIndex;
Common::Point _ventCellPos;
- int _v56AA4;
- byte _v56AA6;
- byte _v56AA7;
- byte _v56AA8;
- int _v56AAB;
+ byte _ductMazePanel1State;
+ byte _ductMazePanel2State;
+ byte _ductMazePanel3State;
int _scene180Mode; // _v575f7
int _v57709;
int _v5780C;
- int _v5780E;
+ int _mouseCursorId;
int _v57810;
- int _v57C2C;
int _speechSubtitles;
Common::Point _s1550PlayerArea[3]; // only used for Quinn and Seeker
byte _scannerFrequencies[4];
byte _stripManager_lookupList[12];
byte _scene1550JunkLocations[508];
Common::Point _balloonPosition;
+ bool _debugCardGame; // moved from scene 1337 so it can be easily set in the debugger
ScannerDialog *_scannerDialog;
diff --git a/engines/tsage/graphics.cpp b/engines/tsage/graphics.cpp
index 2395cc67ed..97857aca34 100644
--- a/engines/tsage/graphics.cpp
+++ b/engines/tsage/graphics.cpp
@@ -68,11 +68,16 @@ GfxSurface surfaceFromRes(const byte *imgData) {
Rect r(0, 0, READ_LE_UINT16(imgData), READ_LE_UINT16(imgData + 2));
GfxSurface s;
s.create(r.width(), r.height());
- s._centroid.x = READ_LE_UINT16(imgData + 4);
- s._centroid.y = READ_LE_UINT16(imgData + 6);
s._transColor = *(imgData + 8);
- bool rleEncoded = (imgData[9] & 2) != 0;
+ byte flags = imgData[9];
+ s._flags = (g_vm->getGameID() != GType_Ringworld) ? flags : 0;
+
+ bool rleEncoded = (flags & 2) != 0;
+
+ // Figure out the centroid
+ s._centroid.x = READ_LE_UINT16(imgData + 4);
+ s._centroid.y = READ_LE_UINT16(imgData + 6);
const byte *srcP = imgData + 10;
Graphics::Surface destSurface = s.lockSurface();
@@ -184,8 +189,9 @@ void Rect::contain(const Rect &r) {
* @percent Scaling percentage
*/
void Rect::resize(const GfxSurface &surface, int xp, int yp, int percent) {
- int xe = surface.getBounds().width() * percent / 100;
- int ye = surface.getBounds().height() * percent / 100;
+ const Rect &bounds = surface.getBounds();
+ int xe = bounds.width() * percent / 100;
+ int ye = bounds.height() * percent / 100;
this->set(0, 0, xe, ye);
if (!right) ++right;
@@ -193,8 +199,13 @@ void Rect::resize(const GfxSurface &surface, int xp, int yp, int percent) {
this->moveTo(xp, yp);
- int xd = surface._centroid.x * percent / 100;
- int yd = surface._centroid.y * percent / 100;
+ int xa = (surface._flags & FRAME_FLIP_CENTROID_X) == 0 ? surface._centroid.x :
+ bounds.width() - (surface._centroid.x + 1);
+ int ya = (surface._flags & FRAME_FLIP_CENTROID_Y) == 0 ? surface._centroid.y :
+ bounds.height() - (surface._centroid.y + 1);
+
+ int xd = xa * percent / 100;
+ int yd = ya * percent / 100;
this->translate(-xd, -yd);
}
@@ -224,6 +235,7 @@ GfxSurface::GfxSurface() : _bounds(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT) {
_customSurface = NULL;
_transColor = -1;
_trackDirtyRects = false;
+ _flags = 0;
}
GfxSurface::GfxSurface(const GfxSurface &s) {
@@ -407,6 +419,7 @@ GfxSurface &GfxSurface::operator=(const GfxSurface &s) {
_bounds = s._bounds;
_centroid = s._centroid;
_transColor = s._transColor;
+ _flags = s._flags;
if (_customSurface) {
// Surface owns the internal data, so replicate it so new surface owns it's own
@@ -559,9 +572,11 @@ static GfxSurface ResizeSurface(GfxSurface &src, int xSize, int ySize, int trans
}
/**
- * Copys an area from one GfxSurface to another
+ * Copys an area from one GfxSurface to another.
+ *
*/
-void GfxSurface::copyFrom(GfxSurface &src, Rect srcBounds, Rect destBounds, Region *priorityRegion) {
+void GfxSurface::copyFrom(GfxSurface &src, Rect srcBounds, Rect destBounds,
+ Region *priorityRegion, const byte *shadowMap) {
GfxSurface srcImage;
if (srcBounds.isEmpty())
return;
@@ -591,20 +606,24 @@ void GfxSurface::copyFrom(GfxSurface &src, Rect srcBounds, Rect destBounds, Regi
Graphics::Surface srcSurface = srcImage.lockSurface();
Graphics::Surface destSurface = lockSurface();
+ // Get clipping area
+ Rect clipRect = !_clipRect.isEmpty() ? _clipRect :
+ Rect(0, 0, destSurface.w, destSurface.h);
+
// Adjust bounds to ensure destination will be on-screen
int srcX = 0, srcY = 0;
- if (destBounds.left < 0) {
- srcX = -destBounds.left;
- destBounds.left = 0;
+ if (destBounds.left < clipRect.left) {
+ srcX = clipRect.left - destBounds.left;
+ destBounds.left = clipRect.left;
}
- if (destBounds.top < 0) {
- srcY = -destBounds.top;
- destBounds.top = 0;
+ if (destBounds.top < clipRect.top) {
+ srcY = clipRect.top - destBounds.top;
+ destBounds.top = clipRect.top;
}
- if (destBounds.right > destSurface.w)
- destBounds.right = destSurface.w;
- if (destBounds.bottom > destSurface.h)
- destBounds.bottom = destSurface.h;
+ if (destBounds.right > clipRect.right)
+ destBounds.right = clipRect.right;
+ if (destBounds.bottom > clipRect.bottom)
+ destBounds.bottom = clipRect.bottom;
if (destBounds.isValidRect() && !((destBounds.right < 0) || (destBounds.bottom < 0)
|| (destBounds.left >= destSurface.w) || (destBounds.top >= destSurface.h))) {
@@ -627,8 +646,15 @@ void GfxSurface::copyFrom(GfxSurface &src, Rect srcBounds, Rect destBounds, Regi
if (!priorityRegion || !priorityRegion->contains(Common::Point(
xp + g_globals->_sceneManager._scene->_sceneBounds.left,
destBounds.top + y + g_globals->_sceneManager._scene->_sceneBounds.top))) {
- if (*tempSrc != src._transColor)
- *tempDest = *tempSrc;
+ if (*tempSrc != src._transColor) {
+ if (shadowMap) {
+ // Using a shadow map, so translate the dest pixel using the mapping array
+ *tempDest = shadowMap[*tempDest];
+ } else {
+ // Otherwise, it's a standard pixel copy
+ *tempDest = *tempSrc;
+ }
+ }
}
++tempSrc;
++tempDest;
@@ -706,6 +732,11 @@ GfxElement::GfxElement() {
_owner = NULL;
_keycode = 0;
_flags = 0;
+
+ _fontNumber = 0;
+ _color1 = 0;
+ _color2 = 0;
+ _color3 = 0;
}
void GfxElement::setDefaults() {
@@ -796,8 +827,8 @@ void GfxElement::drawFrame() {
// Draw the edge frame
// Outer frame border
- surface.hLine(tempRect.left + 2, tempRect.top, tempRect.right - 2, 0);
- surface.hLine(tempRect.left + 2, tempRect.bottom, tempRect.right - 2, 0);
+ surface.hLine(tempRect.left + 2, tempRect.top, tempRect.right - 2, 0);
+ surface.hLine(tempRect.left + 2, tempRect.bottom, tempRect.right - 2, 0);
surface.vLine(tempRect.left, tempRect.top + 2, tempRect.bottom - 2, 0);
surface.vLine(tempRect.right, tempRect.top + 2, tempRect.bottom - 2, 0);
*((byte *)surface.getBasePtr(tempRect.left + 1, tempRect.top + 1)) = 0;
@@ -806,8 +837,8 @@ void GfxElement::drawFrame() {
*((byte *)surface.getBasePtr(tempRect.right - 1, tempRect.bottom - 1)) = 0;
// Inner frame border
- surface.hLine(tempRect.left + 2, tempRect.top + 1, tempRect.right - 2, R2_GLOBALS._frameEdgeColor);
- surface.hLine(tempRect.left + 2, tempRect.bottom - 1, tempRect.right - 2, R2_GLOBALS._frameEdgeColor);
+ surface.hLine(tempRect.left + 2, tempRect.top + 1, tempRect.right - 2, R2_GLOBALS._frameEdgeColor);
+ surface.hLine(tempRect.left + 2, tempRect.bottom - 1, tempRect.right - 2, R2_GLOBALS._frameEdgeColor);
surface.vLine(tempRect.left + 1, tempRect.top + 2, tempRect.bottom - 2, R2_GLOBALS._frameEdgeColor);
surface.vLine(tempRect.right - 1, tempRect.top + 2, tempRect.bottom - 2, R2_GLOBALS._frameEdgeColor);
*((byte *)surface.getBasePtr(tempRect.left + 2, tempRect.top + 2)) = R2_GLOBALS._frameEdgeColor;
@@ -1214,8 +1245,9 @@ GfxButton *GfxDialog::execute(GfxButton *defaultButton) {
}
void GfxDialog::setPalette() {
- if (g_vm->getGameID() == GType_BlueForce) {
- g_globals->_scenePalette.loadPalette(2);
+ if (g_vm->getGameID() != GType_Ringworld) {
+ if (g_vm->getGameID() == GType_BlueForce)
+ g_globals->_scenePalette.loadPalette(2);
g_globals->_scenePalette.setPalette(0, 1);
g_globals->_scenePalette.setPalette(g_globals->_gfxColors.background, 1);
g_globals->_scenePalette.setPalette(g_globals->_gfxColors.foreground, 1);
@@ -1358,11 +1390,16 @@ void GfxManager::copyFrom(GfxSurface &src, const Rect &srcBounds, const Rect &de
GfxFont::GfxFont() {
- _fontNumber = (g_vm->getFeatures() & GF_DEMO) ? 0 : 50;
+ if ((g_vm->getGameID() == GType_Ringworld) && (g_vm->getFeatures() & GF_DEMO))
+ _fontNumber = 0;
+ else
+ _fontNumber = 50;
_numChars = 0;
_bpp = 0;
_fontData = NULL;
_fillFlag = false;
+
+ _gfxManager = nullptr;
}
GfxFont::~GfxFont() {
diff --git a/engines/tsage/graphics.h b/engines/tsage/graphics.h
index 7239a99a68..47961dd02a 100644
--- a/engines/tsage/graphics.h
+++ b/engines/tsage/graphics.h
@@ -71,6 +71,8 @@ public:
LineSlice(int xStart, int xEnd) { xs = xStart; xe = xEnd; }
};
+enum FrameFlag { FRAME_FLIP_CENTROID_X = 4, FRAME_FLIP_CENTROID_Y = 8 };
+
class GfxSurface {
private:
Graphics::Surface *_customSurface;
@@ -88,6 +90,8 @@ private:
public:
Common::Point _centroid;
int _transColor;
+ Rect _clipRect;
+ byte _flags;
public:
GfxSurface();
GfxSurface(const GfxSurface &s);
@@ -104,7 +108,8 @@ public:
void setBounds(const Rect &bounds) { _bounds = bounds; }
const Rect &getBounds() const { return _bounds; }
- void copyFrom(GfxSurface &src, Rect srcBounds, Rect destBounds, Region *priorityRegion = NULL);
+ void copyFrom(GfxSurface &src, Rect srcBounds, Rect destBounds,
+ Region *priorityRegion = NULL, const byte *shadowMap = NULL);
void copyFrom(GfxSurface &src, Rect destBounds, Region *priorityRegion = NULL) {
copyFrom(src, src.getBounds(), destBounds, priorityRegion);
}
diff --git a/engines/tsage/ringworld/ringworld_logic.cpp b/engines/tsage/ringworld/ringworld_logic.cpp
index 0584570ac2..1e9d14cdcf 100644
--- a/engines/tsage/ringworld/ringworld_logic.cpp
+++ b/engines/tsage/ringworld/ringworld_logic.cpp
@@ -270,6 +270,11 @@ bool DisplayObject::performAction(int action) {
SceneArea::SceneArea() {
_savedArea = NULL;
_pt.x = _pt.y = 0;
+
+ _resNum = 0;
+ _rlbNum = 0;
+ _subNum = 0;
+ _actionId = 0;
}
SceneArea::~SceneArea() {
diff --git a/engines/tsage/ringworld/ringworld_scenes1.cpp b/engines/tsage/ringworld/ringworld_scenes1.cpp
index 89c07273fc..df456f9ced 100644
--- a/engines/tsage/ringworld/ringworld_scenes1.cpp
+++ b/engines/tsage/ringworld/ringworld_scenes1.cpp
@@ -52,52 +52,52 @@ void Scene10::Action1::signal() {
scene->_stripManager.start(11, this, scene);
break;
case 3:
- scene->_object2.hide();
- scene->_object3.hide();
- scene->_object3.setAction(NULL);
- scene->_object4.animate(ANIM_MODE_5, this);
+ scene->_veeshkaHead.hide();
+ scene->_veeshkaRightArm.hide();
+ scene->_veeshkaRightArm.setAction(NULL);
+ scene->_centurion.animate(ANIM_MODE_5, this);
break;
case 4:
case 9:
- scene->_object1.animate(ANIM_MODE_5, this);
+ scene->_veeshkaBody.animate(ANIM_MODE_5, this);
break;
case 5:
- scene->_object2.setStrip(3);
- scene->_object2.setFrame(1);
- scene->_object2.setPosition(Common::Point(240, 51));
- scene->_object2.show();
+ scene->_veeshkaHead.setStrip(3);
+ scene->_veeshkaHead.setFrame(1);
+ scene->_veeshkaHead.setPosition(Common::Point(240, 51));
+ scene->_veeshkaHead.show();
- scene->_object3.setStrip(6);
- scene->_object3.setFrame(1);
- scene->_object3.setPosition(Common::Point(200, 76));
- scene->_object3._numFrames = 20;
- scene->_object3.show();
+ scene->_veeshkaRightArm.setStrip(6);
+ scene->_veeshkaRightArm.setFrame(1);
+ scene->_veeshkaRightArm.setPosition(Common::Point(200, 76));
+ scene->_veeshkaRightArm._numFrames = 20;
+ scene->_veeshkaRightArm.show();
scene->_stripManager.start(12, this, scene);
break;
case 6:
- scene->_object2.hide();
- scene->_object3.hide();
- scene->_object1.animate(ANIM_MODE_6, this);
+ scene->_veeshkaHead.hide();
+ scene->_veeshkaRightArm.hide();
+ scene->_veeshkaBody.animate(ANIM_MODE_6, this);
break;
case 7:
- scene->_object3.show();
- scene->_object3.setStrip2(5);
- scene->_object3._numFrames = 10;
- scene->_object3.setPosition(Common::Point(180, 87));
- scene->_object3.setAction(&scene->_action2);
+ scene->_veeshkaRightArm.show();
+ scene->_veeshkaRightArm.setStrip2(5);
+ scene->_veeshkaRightArm._numFrames = 10;
+ scene->_veeshkaRightArm.setPosition(Common::Point(180, 87));
+ scene->_veeshkaRightArm.setAction(&scene->_action2);
- scene->_object2.setStrip(4);
- scene->_object2.setFrame(1);
- scene->_object2.setPosition(Common::Point(204, 59));
- scene->_object2.show();
+ scene->_veeshkaHead.setStrip(4);
+ scene->_veeshkaHead.setFrame(1);
+ scene->_veeshkaHead.setPosition(Common::Point(204, 59));
+ scene->_veeshkaHead.show();
scene->_stripManager.start(13, this, scene);
break;
case 8:
- scene->_object2.hide();
- scene->_object3.hide();
- scene->_object4.animate(ANIM_MODE_6, this);
+ scene->_veeshkaHead.hide();
+ scene->_veeshkaRightArm.hide();
+ scene->_centurion.animate(ANIM_MODE_6, this);
break;
case 10:
g_globals->_soundHandler.fadeOut(this);
@@ -109,6 +109,7 @@ void Scene10::Action1::signal() {
}
}
+// Move Veeshka's fingers
void Scene10::Action2::signal() {
Scene10 *scene = (Scene10 *)g_globals->_sceneManager._scene;
@@ -117,8 +118,8 @@ void Scene10::Action2::signal() {
setDelay(g_globals->_randomSource.getRandomNumber(179));
break;
case 1:
- scene->_object3.setFrame(1);
- scene->_object3.animate(ANIM_MODE_5, this);
+ scene->_veeshkaRightArm.setFrame(1);
+ scene->_veeshkaRightArm.animate(ANIM_MODE_5, this);
_actionIndex = 0;
break;
}
@@ -145,43 +146,43 @@ void Scene10::postInit(SceneObjectList *OwnerList) {
_stripManager.setCallback(this);
- _object1.postInit();
- _object1.setVisage(10);
- _object1.setPosition(Common::Point(232, 90));
- _object1.fixPriority(1);
-
- _object2.postInit();
- _object2.setVisage(10);
- _object2.setStrip(4);
- _object2.setFrame(1);
- _object2.setPosition(Common::Point(204, 59));
- _object2.fixPriority(198);
-
- _object3.postInit();
- _object3.setVisage(10);
- _object3.setStrip2(5);
- _object3.setPosition(Common::Point(180, 87));
- _object3.fixPriority(196);
- _object3.setAction(&_action2);
-
- _object4.postInit();
- _object4.setVisage(10);
- _object4.setStrip(2);
- _object4.setPosition(Common::Point(0, 209));
- _object4.animate(ANIM_MODE_1, NULL);
-
- _object5.postInit();
- _object5.setVisage(11);
- _object5.setPosition(Common::Point(107, 146));
- _object5.animate(ANIM_MODE_2, NULL);
- _object5._numFrames = 5;
-
- _object6.postInit();
- _object6.setVisage(11);
- _object6.setStrip(2);
- _object6.setPosition(Common::Point(287, 149));
- _object6.animate(ANIM_MODE_2, NULL);
- _object6._numFrames = 5;
+ _veeshkaBody.postInit();
+ _veeshkaBody.setVisage(10);
+ _veeshkaBody.setPosition(Common::Point(232, 90));
+ _veeshkaBody.fixPriority(1);
+
+ _veeshkaHead.postInit();
+ _veeshkaHead.setVisage(10);
+ _veeshkaHead.setStrip(4);
+ _veeshkaHead.setFrame(1);
+ _veeshkaHead.setPosition(Common::Point(204, 59));
+ _veeshkaHead.fixPriority(198);
+
+ _veeshkaRightArm.postInit();
+ _veeshkaRightArm.setVisage(10);
+ _veeshkaRightArm.setStrip2(5);
+ _veeshkaRightArm.setPosition(Common::Point(180, 87));
+ _veeshkaRightArm.fixPriority(196);
+ _veeshkaRightArm.setAction(&_action2);
+
+ _centurion.postInit();
+ _centurion.setVisage(10);
+ _centurion.setStrip(2);
+ _centurion.setPosition(Common::Point(0, 209));
+ _centurion.animate(ANIM_MODE_1, NULL);
+
+ _leftSmoke.postInit();
+ _leftSmoke.setVisage(11);
+ _leftSmoke.setPosition(Common::Point(107, 146));
+ _leftSmoke.animate(ANIM_MODE_2, NULL);
+ _leftSmoke._numFrames = 5;
+
+ _rightSmoke.postInit();
+ _rightSmoke.setVisage(11);
+ _rightSmoke.setStrip(2);
+ _rightSmoke.setPosition(Common::Point(287, 149));
+ _rightSmoke.animate(ANIM_MODE_2, NULL);
+ _rightSmoke._numFrames = 5;
g_globals->_sceneManager._scene->_sceneBounds.contain(g_globals->_sceneManager._scene->_backgroundBounds);
g_globals->_sceneOffset.x = (g_globals->_sceneManager._scene->_sceneBounds.left / 160) * 160;
@@ -193,14 +194,14 @@ void Scene10::postInit(SceneObjectList *OwnerList) {
void Scene10::stripCallback(int v) {
switch (v) {
case 1:
- _object2.animate(ANIM_MODE_7, -1, NULL);
+ _veeshkaHead.animate(ANIM_MODE_7, -1, NULL);
break;
case 2:
- _object2.animate(ANIM_MODE_NONE);
+ _veeshkaHead.animate(ANIM_MODE_NONE);
break;
case 3:
- _object2.animate(ANIM_MODE_7, -1, NULL);
- _object3.animate(ANIM_MODE_5, NULL);
+ _veeshkaHead.animate(ANIM_MODE_7, -1, NULL);
+ _veeshkaRightArm.animate(ANIM_MODE_5, NULL);
break;
default:
break;
@@ -227,13 +228,13 @@ void Scene15::Action1::signal() {
case 2: {
SceneItem::display(15, 1, SET_Y, 20, SET_FONT, 2, SET_BG_COLOR, -1, SET_EXT_BGCOLOR, 7,
SET_WIDTH, 320, SET_KEEP_ONSCREEN, 1, LIST_END);
- scene->_object1.postInit();
- scene->_object1.setVisage(15);
- scene->_object1.setPosition(Common::Point(160, -10));
- scene->_object1.animate(ANIM_MODE_2, NULL);
+ scene->_ship.postInit();
+ scene->_ship.setVisage(15);
+ scene->_ship.setPosition(Common::Point(160, -10));
+ scene->_ship.animate(ANIM_MODE_2, NULL);
Common::Point pt(160, 100);
NpcMover *mover = new NpcMover();
- scene->_object1.addMover(mover, &pt, this);
+ scene->_ship.addMover(mover, &pt, this);
scene->_soundHandler.play(7);
break;
}
@@ -247,8 +248,8 @@ void Scene15::Action1::signal() {
void Scene15::Action1::dispatch() {
Scene15 *scene = (Scene15 *)g_globals->_sceneManager._scene;
- if (scene->_object1._position.y < 100)
- scene->_object1.changeZoom(100 - scene->_object1._position.y);
+ if (scene->_ship._position.y < 100)
+ scene->_ship.changeZoom(100 - scene->_ship._position.y);
Action::dispatch();
}
@@ -307,9 +308,9 @@ void Scene20::Action2::signal() {
Common::Point pt(455, 77);
g_globals->_player.addMover(mover, &pt, this);
ObjectMover2 *mover2 = new ObjectMover2();
- scene->_SceneObjectExt.addMover(mover2, 5, 10, &g_globals->_player);
+ scene->_assassinShip1.addMover(mover2, 5, 10, &g_globals->_player);
ObjectMover2 *mover3 = new ObjectMover2();
- scene->_sceneObject3.addMover(mover3, 10, 15, &g_globals->_player);
+ scene->_assassinShip2.addMover(mover3, 10, 15, &g_globals->_player);
break;
}
case 3: {
@@ -369,9 +370,9 @@ void Scene20::Action3::signal() {
Common::Point pt(615, 81);
g_globals->_player.addMover(npcMover, &pt, this);
ObjectMover2 *mover1 = new ObjectMover2();
- scene->_SceneObjectExt.addMover(mover1, 5, 10, &g_globals->_player);
+ scene->_assassinShip1.addMover(mover1, 5, 10, &g_globals->_player);
ObjectMover2 *mover2 = new ObjectMover2();
- scene->_sceneObject3.addMover(mover2, 20, 25, &g_globals->_player);
+ scene->_assassinShip2.addMover(mover2, 20, 25, &g_globals->_player);
break;
}
case 2: {
@@ -382,8 +383,8 @@ void Scene20::Action3::signal() {
}
case 3: {
g_globals->_player._moveDiff = Common::Point(10, 10);
- scene->_SceneObjectExt._moveDiff = Common::Point(10, 10);
- scene->_sceneObject3._moveDiff = Common::Point(10, 10);
+ scene->_assassinShip1._moveDiff = Common::Point(10, 10);
+ scene->_assassinShip2._moveDiff = Common::Point(10, 10);
npcMover = new NpcMover();
Common::Point pt(445, 132);
g_globals->_player.addMover(npcMover, &pt, this);
@@ -427,73 +428,73 @@ void Scene20::Action4::signal() {
Common::Point pt(486, 134);
g_globals->_player.addMover(npcMover, &pt, this);
ObjectMover2 *mover1 = new ObjectMover2();
- scene->_SceneObjectExt.addMover(mover1, 20, 35, &g_globals->_player);
+ scene->_assassinShip1.addMover(mover1, 20, 35, &g_globals->_player);
break;
}
case 2: {
g_globals->_player._moveDiff = Common::Point(12, 12);
- scene->_SceneObjectExt._moveDiff = Common::Point(12, 12);
+ scene->_assassinShip1._moveDiff = Common::Point(12, 12);
NpcMover *mover1 = new NpcMover();
Common::Point pt(486, 134);
- scene->_sceneObject3.addMover(mover1, &pt, this);
+ scene->_assassinShip2.addMover(mover1, &pt, this);
NpcMover *mover2 = new NpcMover();
pt = Common::Point(-15, 134);
g_globals->_player.addMover(mover2, &pt, NULL);
NpcMover *mover3 = new NpcMover();
pt = Common::Point(-15, 134);
- scene->_SceneObjectExt.addMover(mover3, &pt, NULL);
+ scene->_assassinShip1.addMover(mover3, &pt, NULL);
break;
}
case 3: {
- scene->_sceneObject3._moveDiff = Common::Point(20, 20);
+ scene->_assassinShip2._moveDiff = Common::Point(20, 20);
npcMover = new NpcMover();
Common::Point pt(320, 134);
- scene->_sceneObject3.addMover(npcMover, &pt, this);
+ scene->_assassinShip2.addMover(npcMover, &pt, this);
break;
}
case 4: {
scene->_sound.play(28);
- scene->_sceneObject4.postInit();
- scene->_sceneObject4.setVisage(21);
- scene->_sceneObject4.setStrip(3);
- scene->_sceneObject4.setPosition(Common::Point(scene->_sceneObject3._position.x - 36,
- scene->_sceneObject3._position.y - 1));
- scene->_sceneObject4._moveDiff.x = 48;
+ scene->_laserShot1.postInit();
+ scene->_laserShot1.setVisage(21);
+ scene->_laserShot1.setStrip(3);
+ Common::Point pt = Common::Point(scene->_assassinShip2._position.x - 36, scene->_assassinShip2._position.y - 1);
+ scene->_laserShot1.setPosition(pt);
+ scene->_laserShot1._moveDiff.x = 48;
ObjectMover3 *mover = new ObjectMover3();
- scene->_sceneObject4.addMover(mover, &scene->_SceneObjectExt, 4, this);
+ scene->_laserShot1.addMover(mover, &scene->_assassinShip1, 4, this);
break;
}
case 5: {
scene->_sound.play(42);
- scene->_sceneObject4.remove();
- scene->_SceneObjectExt.setVisage(21);
- scene->_SceneObjectExt.setStrip(1);
- scene->_SceneObjectExt.setFrame(1);
- scene->_SceneObjectExt.animate(ANIM_MODE_5, NULL);
+ scene->_laserShot1.remove();
+ scene->_assassinShip1.setVisage(21);
+ scene->_assassinShip1.setStrip(1);
+ scene->_assassinShip1.setFrame(1);
+ scene->_assassinShip1.animate(ANIM_MODE_5, NULL);
- scene->_SceneObjectExt._moveDiff.x = 4;
+ scene->_assassinShip1._moveDiff.x = 4;
NpcMover *mover1 = new NpcMover();
- Common::Point pt(scene->_SceneObjectExt._position.x - 12, scene->_SceneObjectExt._position.y + 5);
- scene->_SceneObjectExt.addMover(mover1, &pt, NULL);
+ Common::Point pt(scene->_assassinShip1._position.x - 12, scene->_assassinShip1._position.y + 5);
+ scene->_assassinShip1.addMover(mover1, &pt, NULL);
- scene->_sceneObject5.postInit();
- scene->_sceneObject5.setVisage(21);
- scene->_sceneObject5.setStrip(3);
- scene->_sceneObject5.setPosition(Common::Point(scene->_sceneObject3._position.x - 36,
- scene->_sceneObject3._position.y - 1));
- scene->_sceneObject5._moveDiff.x = 48;
+ scene->_laserShot2.postInit();
+ scene->_laserShot2.setVisage(21);
+ scene->_laserShot2.setStrip(3);
+ pt = Common::Point(scene->_assassinShip2._position.x - 36, scene->_assassinShip2._position.y - 1);
+ scene->_laserShot2.setPosition(pt);
+ scene->_laserShot2._moveDiff.x = 48;
ObjectMover3 *mover = new ObjectMover3();
- scene->_sceneObject5.addMover(mover, &g_globals->_player, 4, this);
+ scene->_laserShot2.addMover(mover, &g_globals->_player, 4, this);
break;
}
case 6: {
scene->_sound.play(42);
- scene->_SceneObjectExt.setStrip(2);
- scene->_SceneObjectExt.animate(ANIM_MODE_2, NULL);
+ scene->_assassinShip1.setStrip(2);
+ scene->_assassinShip1.animate(ANIM_MODE_2, NULL);
- scene->_sceneObject5.remove();
+ scene->_laserShot2.remove();
g_globals->_player.setVisage(21);
g_globals->_player.setStrip(1);
g_globals->_player.setFrame(1);
@@ -539,18 +540,18 @@ void Scene20::postInit(SceneObjectList *OwnerList) {
g_globals->_player._moveDiff = Common::Point(10, 10);
g_globals->_player.animate(ANIM_MODE_1, NULL);
- _SceneObjectExt.postInit();
- _SceneObjectExt.setVisage(20);
- _SceneObjectExt.setPosition(Common::Point(400, 69));
- _SceneObjectExt.animate(ANIM_MODE_1, NULL);
+ _assassinShip1.postInit();
+ _assassinShip1.setVisage(20);
+ _assassinShip1.setPosition(Common::Point(400, 69));
+ _assassinShip1.animate(ANIM_MODE_1, NULL);
- _sceneObject3.postInit();
- _sceneObject3.setVisage(20);
- _sceneObject3.setPosition(Common::Point(395, 69));
- _sceneObject3.animate(ANIM_MODE_1, NULL);
+ _assassinShip2.postInit();
+ _assassinShip2.setVisage(20);
+ _assassinShip2.setPosition(Common::Point(395, 69));
+ _assassinShip2.animate(ANIM_MODE_1, NULL);
- _SceneObjectExt._moveDiff = Common::Point(10, 10);
- _sceneObject3._moveDiff = Common::Point(10, 10);
+ _assassinShip1._moveDiff = Common::Point(10, 10);
+ _assassinShip2._moveDiff = Common::Point(10, 10);
g_globals->_soundHandler.play(20);
_sound.play(21);
_sound.holdAt(true);
@@ -567,16 +568,16 @@ void Scene20::postInit(SceneObjectList *OwnerList) {
g_globals->_player.fixPriority(50);
g_globals->_player.animate(ANIM_MODE_1, NULL);
- _SceneObjectExt.postInit();
- _SceneObjectExt.setVisage(20);
- _SceneObjectExt.setPosition(Common::Point(583, 79));
- _SceneObjectExt.animate(ANIM_MODE_1, NULL);
+ _assassinShip1.postInit();
+ _assassinShip1.setVisage(20);
+ _assassinShip1.setPosition(Common::Point(583, 79));
+ _assassinShip1.animate(ANIM_MODE_1, NULL);
- _sceneObject3.postInit();
- _sceneObject3.setVisage(20);
- _sceneObject3.setStrip2(2);
- _sceneObject3.setPosition(Common::Point(595, 79));
- _sceneObject3.animate(ANIM_MODE_1, NULL);
+ _assassinShip2.postInit();
+ _assassinShip2.setVisage(20);
+ _assassinShip2.setStrip2(2);
+ _assassinShip2.setPosition(Common::Point(595, 79));
+ _assassinShip2.animate(ANIM_MODE_1, NULL);
if ((g_globals->getFlag(120) && g_globals->getFlag(116)) ||
(g_globals->getFlag(117) && g_globals->getFlag(119))) {
@@ -584,10 +585,10 @@ void Scene20::postInit(SceneObjectList *OwnerList) {
setAction(&_action3);
} else if (g_globals->getFlag(104)) {
_sceneMode = 21;
- setAction(&_sequenceManager, this, 21, &g_globals->_player, &_SceneObjectExt, NULL);
+ setAction(&_sequenceManager, this, 21, &g_globals->_player, &_assassinShip1, NULL);
} else {
// Failed evasion
- _sceneObject3._moveDiff = Common::Point(8, 8);
+ _assassinShip2._moveDiff = Common::Point(8, 8);
setAction(&_action4);
}
_sceneBounds.center(g_globals->_player._position.x, g_globals->_player._position.y);
@@ -626,26 +627,37 @@ void Scene20::signal() {
*--------------------------------------------------------------------------*/
void Scene30::BeamObject::doAction(int action) {
- if (action == OBJECT_SCANNER)
+ switch (action) {
+ case OBJECT_SCANNER:
display2(30, 14);
- else if (action == CURSOR_LOOK)
+ break;
+ case CURSOR_LOOK:
display2(30, 2);
- else if (action == CURSOR_USE) {
+ break;
+ case CURSOR_USE: {
Scene30 *parent = (Scene30 *)g_globals->_sceneManager._scene;
parent->setAction(&parent->_beamAction);
- } else
+ }
+ break;
+ default:
SceneObject::doAction(action);
+ }
}
void Scene30::DoorObject::doAction(int action) {
- if (action == OBJECT_SCANNER)
+ switch (action) {
+ case OBJECT_SCANNER:
display2(30, 13);
- else if (action == CURSOR_LOOK)
+ break;
+ case CURSOR_LOOK:
display2(30, 1);
- else if (action == CURSOR_USE)
+ break;
+ case CURSOR_USE:
display2(30, 7);
- else
+ break;
+ default:
SceneObject::doAction(action);
+ }
}
void Scene30::BeamAction::signal() {
@@ -963,16 +975,16 @@ void Scene40::Action1::signal() {
scene->_doorway.hide();
scene->_dyingKzin.setPosition(Common::Point(296, 62));
g_globals->_player.animate(ANIM_MODE_5, NULL);
- scene->_object1.setVisage(43);
- scene->_object1.setStrip(3);
- scene->_object1.animate(ANIM_MODE_5, NULL);
- scene->_object2.hide();
- scene->_object3.hide();
+ scene->_seeker.setVisage(43);
+ scene->_seeker.setStrip(3);
+ scene->_seeker.animate(ANIM_MODE_5, NULL);
+ scene->_seekerTail.hide();
+ scene->_seekerHand.hide();
scene->_stripManager.start(45, this);
break;
case 4:
- scene->_object2.remove();
- scene->_object3.remove();
+ scene->_seekerTail.remove();
+ scene->_seekerHand.remove();
scene->_assassin.setVisage(42);
scene->_assassin.setStrip(2);
scene->_assassin.setFrame(1);
@@ -1049,10 +1061,10 @@ void Scene40::Action1::signal() {
break;
case 15:
g_globals->_player.disableControl();
- scene->_object1.setVisage(40);
- scene->_object1.setStrip(4);
- scene->_object1.setFrame(1);
- scene->_object1.animate(ANIM_MODE_5, NULL);
+ scene->_seeker.setVisage(40);
+ scene->_seeker.setStrip(4);
+ scene->_seeker.setFrame(1);
+ scene->_seeker.animate(ANIM_MODE_5, NULL);
g_globals->_player.setVisage(40);
g_globals->_player.setStrip(2);
g_globals->_player.setFrame(1);
@@ -1122,13 +1134,13 @@ void Scene40::Action2::signal() {
}
case 6: {
g_globals->_player.setStrip(7);
- scene->_object1.setVisage(2806);
- scene->_object1.animate(ANIM_MODE_1, NULL);
+ scene->_seeker.setVisage(2806);
+ scene->_seeker.animate(ANIM_MODE_1, NULL);
SceneObjectWrapper *wrapper = new SceneObjectWrapper();
- scene->_object1.setObjectWrapper(wrapper);
+ scene->_seeker.setObjectWrapper(wrapper);
Common::Point pt(200, 190);
NpcMover *mover = new NpcMover();
- scene->_object1.addMover(mover, &pt, this);
+ scene->_seeker.addMover(mover, &pt, this);
break;
}
case 7:
@@ -1137,12 +1149,12 @@ void Scene40::Action2::signal() {
case 8: {
Common::Point pt(170, 260);
NpcMover *mover = new NpcMover();
- scene->_object1.addMover(mover, &pt, this);
+ scene->_seeker.addMover(mover, &pt, this);
break;
}
case 9:
scene->_dyingKzin.setAction(&scene->_action7);
- scene->_object1.remove();
+ scene->_seeker.remove();
g_globals->_stripNum = 88;
g_globals->_events.setCursor(CURSOR_WALK);
g_globals->_player.enableControl();
@@ -1202,6 +1214,7 @@ void Scene40::Action4::signal() {
}
}
+// Animate the tail of Seeker, with random pauses
void Scene40::Action5::signal() {
Scene40 *scene = (Scene40 *)g_globals->_sceneManager._scene;
@@ -1210,7 +1223,7 @@ void Scene40::Action5::signal() {
setDelay(g_globals->_randomSource.getRandomNumber(119) + 120);
break;
case 1:
- scene->_object2.animate(ANIM_MODE_8, 1, this);
+ scene->_seekerTail.animate(ANIM_MODE_8, 1, this);
_actionIndex = 0;
}
}
@@ -1220,17 +1233,17 @@ void Scene40::Action6::signal() {
switch (_actionIndex++) {
case 0: {
- scene->_object1.postInit();
- scene->_object1.setVisage(16);
- scene->_object1.setStrip2(6);
- scene->_object1._moveDiff = Common::Point(40, 40);
- scene->_object1.setPosition(Common::Point(313, 53));
- scene->_object1._moveRate = 60;
+ scene->_seeker.postInit();
+ scene->_seeker.setVisage(16);
+ scene->_seeker.setStrip2(6);
+ scene->_seeker._moveDiff = Common::Point(40, 40);
+ scene->_seeker.setPosition(Common::Point(313, 53));
+ scene->_seeker._moveRate = 60;
Common::Point pt(141, 194);
NpcMover *mover = new NpcMover();
- scene->_object1.addMover(mover, &pt, NULL);
- scene->_object1.animate(ANIM_MODE_5, NULL);
+ scene->_seeker.addMover(mover, &pt, NULL);
+ scene->_seeker.animate(ANIM_MODE_5, NULL);
scene->_doorway.postInit();
scene->_doorway.setVisage(46);
@@ -1260,21 +1273,21 @@ void Scene40::Action7::signal() {
setDelay(g_globals->_randomSource.getRandomNumber(499) + 500);
break;
case 1:
- scene->_object7.postInit();
- scene->_object7.setVisage(46);
+ scene->_leftEntrance.postInit();
+ scene->_leftEntrance.setVisage(46);
if (g_globals->_randomSource.getRandomNumber(32767) >= 16384) {
- scene->_object7.setStrip(3);
- scene->_object7.setPosition(Common::Point(15, 185));
+ scene->_leftEntrance.setStrip(3);
+ scene->_leftEntrance.setPosition(Common::Point(15, 185));
} else {
- scene->_object7.setPosition(Common::Point(305, 61));
- scene->_object7.setFrame(15);
+ scene->_leftEntrance.setPosition(Common::Point(305, 61));
+ scene->_leftEntrance.setFrame(15);
}
- scene->_object7.animate(ANIM_MODE_5, this);
+ scene->_leftEntrance.animate(ANIM_MODE_5, this);
scene->_soundHandler.play(25);
break;
case 2:
- scene->_object7.remove();
+ scene->_leftEntrance.remove();
_actionIndex = 0;
setDelay(60);
break;
@@ -1465,12 +1478,12 @@ void Scene40::Item6::doAction(int action) {
/*--------------------------------------------------------------------------*/
Scene40::Scene40() :
- _item1(2, OBJECT_SCANNER, 40, 24, OBJECT_STUNNER, 40, 25, CURSOR_LOOK, 40, 7, CURSOR_USE, 40, 16, LIST_END),
- _item3(5, OBJECT_SCANNER, 40, 28, OBJECT_STUNNER, 40, 27, CURSOR_LOOK, 40, 2, CURSOR_USE, 40, 30, LIST_END),
- _item4(6, OBJECT_SCANNER, 40, 31, OBJECT_STUNNER, 40, 32, CURSOR_LOOK, 40, 5, CURSOR_USE, 40, 33, LIST_END),
- _item5(0, CURSOR_LOOK, 40, 11, LIST_END),
- _item7(4, OBJECT_SCANNER, 40, 26, OBJECT_STUNNER, 40, 27, CURSOR_LOOK, 40, 9, CURSOR_USE, 40, 17, LIST_END),
- _item8(8, OBJECT_SCANNER, 40, 39, OBJECT_STUNNER, 40, 40, CURSOR_LOOK, 40, 3, CURSOR_USE, 40, 41, LIST_END) {
+ _ball(2, OBJECT_SCANNER, 40, 24, OBJECT_STUNNER, 40, 25, CURSOR_LOOK, 40, 7, CURSOR_USE, 40, 16, LIST_END),
+ _window(5, OBJECT_SCANNER, 40, 28, OBJECT_STUNNER, 40, 27, CURSOR_LOOK, 40, 2, CURSOR_USE, 40, 30, LIST_END),
+ _entrance(6, OBJECT_SCANNER, 40, 31, OBJECT_STUNNER, 40, 32, CURSOR_LOOK, 40, 5, CURSOR_USE, 40, 33, LIST_END),
+ _background(0, CURSOR_LOOK, 40, 11, LIST_END),
+ _emerald(4, OBJECT_SCANNER, 40, 26, OBJECT_STUNNER, 40, 27, CURSOR_LOOK, 40, 9, CURSOR_USE, 40, 17, LIST_END),
+ _tree(8, OBJECT_SCANNER, 40, 39, OBJECT_STUNNER, 40, 40, CURSOR_LOOK, 40, 3, CURSOR_USE, 40, 41, LIST_END) {
}
void Scene40::postInit(SceneObjectList *OwnerList) {
@@ -1489,7 +1502,7 @@ void Scene40::postInit(SceneObjectList *OwnerList) {
_speakerGameText._color1 = 9;
_speakerGameText.setTextPos(Common::Point(160, 30));
_speakerQText._npc = &g_globals->_player;
- _speakerSText._npc = &_object1;
+ _speakerSText._npc = &_seeker;
g_globals->_player.postInit();
g_globals->_player.setVisage(0);
@@ -1502,23 +1515,24 @@ void Scene40::postInit(SceneObjectList *OwnerList) {
g_globals->_soundHandler.play(24);
g_globals->_player.setVisage(43);
- _object1.postInit();
- _object1.setVisage(41);
- _object1.setPosition(Common::Point(105, 220));
- _object2.postInit();
- _object2.setVisage(41);
- _object2.setStrip(6);
- _object2.fixPriority(200);
- _object2.setPosition(Common::Point(94, 189));
- _object2.setAction(&_action5);
-
- _object3.postInit();
- _object3.setVisage(41);
- _object3.setStrip(5);
- _object3.fixPriority(205);
- _object3.setPosition(Common::Point(110, 186));
- _object3._numFrames = 2;
- _object3.animate(ANIM_MODE_8, NULL, NULL);
+ _seeker.postInit();
+ _seeker.setVisage(41);
+ _seeker.setPosition(Common::Point(105, 220));
+
+ _seekerTail.postInit();
+ _seekerTail.setVisage(41);
+ _seekerTail.setStrip(6);
+ _seekerTail.fixPriority(200);
+ _seekerTail.setPosition(Common::Point(94, 189));
+ _seekerTail.setAction(&_action5);
+
+ _seekerHand.postInit();
+ _seekerHand.setVisage(41);
+ _seekerHand.setStrip(5);
+ _seekerHand.fixPriority(205);
+ _seekerHand.setPosition(Common::Point(110, 186));
+ _seekerHand._numFrames = 2;
+ _seekerHand.animate(ANIM_MODE_8, NULL, NULL);
_assassin.postInit();
_assassin.setPosition(Common::Point(-40, 191));
@@ -1563,12 +1577,12 @@ void Scene40::postInit(SceneObjectList *OwnerList) {
setAction(&_action4);
}
- _item5.setBounds(Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT));
- _item6._sceneRegionId = 3;
- _item2._sceneRegionId = 7;
+ _background.setBounds(Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT));
+ _pedestal._sceneRegionId = 3;
+ _statue._sceneRegionId = 7;
- g_globals->_sceneItems.addItems(&_dyingKzin, &_item8, &_item1, &_item2, &_item3, &_item4,
- &_item6, &_item7, &_item5, NULL);
+ g_globals->_sceneItems.addItems(&_dyingKzin, &_tree, &_ball, &_statue, &_window, &_entrance,
+ &_pedestal, &_emerald, &_background, NULL);
}
void Scene40::signal() {
@@ -1609,7 +1623,7 @@ void Scene50::Action1::signal() {
scene->_stripManager.start(63, this);
break;
case 2:
- if (scene->_stripManager._field2E8 != 107) {
+ if (scene->_stripManager._currObj44Id != 107) {
g_globals->_player.enableControl();
remove();
} else {
@@ -1691,7 +1705,7 @@ void Scene50::Object1::doAction(int action) {
}
}
-void Scene50::Object2::doAction(int action) {
+void Scene50::LeftFlyCycle::doAction(int action) {
Scene50 *scene = (Scene50 *)g_globals->_sceneManager._scene;
switch (action) {
@@ -1715,7 +1729,7 @@ void Scene50::Object2::doAction(int action) {
}
}
-void Scene50::Object3::doAction(int action) {
+void Scene50::CenterFlyCycle::doAction(int action) {
Scene50 *scene = (Scene50 *)g_globals->_sceneManager._scene;
switch (action) {
@@ -1743,7 +1757,7 @@ void Scene50::Object3::doAction(int action) {
}
}
-void Scene50::Object4::doAction(int action) {
+void Scene50::RightFlyCycle::doAction(int action) {
Scene50 *scene = (Scene50 *)g_globals->_sceneManager._scene;
switch (action) {
@@ -1772,12 +1786,13 @@ void Scene50::Object4::doAction(int action) {
/*--------------------------------------------------------------------------*/
Scene50::Scene50() :
- _item0(0, CURSOR_LOOK, 50, 3, LIST_END),
+ _background(0, CURSOR_LOOK, 50, 3, LIST_END),
_item1(0, OBJECT_SCANNER, 50, 15, CURSOR_USE, 50, 16, CURSOR_LOOK, 50, 3, LIST_END),
- _item2(0, CURSOR_LOOK, 50, 7, LIST_END),
- _item3(8, OBJECT_STUNNER, 50, 14, OBJECT_SCANNER, 50, 13, CURSOR_LOOK, 50, 3, LIST_END),
- _item4(9, OBJECT_SCANNER, 40, 39, OBJECT_STUNNER, 40, 40, CURSOR_USE, 40, 41, CURSOR_LOOK, 50, 5, LIST_END),
- _item5(10, OBJECT_SCANNER, 50, 17, OBJECT_STUNNER, 50, 18, CURSOR_LOOK, 50, 6, CURSOR_USE, 30, 8, LIST_END) {
+ _entrance(0, CURSOR_LOOK, 50, 7, LIST_END),
+ // The original was using dialog 50/3 for CURSOR_LOOK, which is too generic.
+ _bulwark(8, OBJECT_STUNNER, 50, 14, OBJECT_SCANNER, 50, 13, CURSOR_LOOK, 30, 0, LIST_END),
+ _tree(9, OBJECT_SCANNER, 40, 39, OBJECT_STUNNER, 40, 40, CURSOR_USE, 40, 41, CURSOR_LOOK, 50, 5, LIST_END),
+ _flagstones(10, OBJECT_SCANNER, 50, 17, OBJECT_STUNNER, 50, 18, CURSOR_LOOK, 50, 6, CURSOR_USE, 30, 8, LIST_END) {
_doorwayRect = Rect(80, 108, 160, 112);
}
@@ -1806,25 +1821,25 @@ void Scene50::postInit(SceneObjectList *OwnerList) {
g_globals->_player.setPosition(Common::Point(270, 143));
}
- _object2.postInit();
- _object2.setVisage(2331);
- _object2.setStrip(6);
- _object2.setPosition(Common::Point(136, 192));
- _object2.fixPriority(200);
+ _leftFlyCycle.postInit();
+ _leftFlyCycle.setVisage(2331);
+ _leftFlyCycle.setStrip(6);
+ _leftFlyCycle.setPosition(Common::Point(136, 192));
+ _leftFlyCycle.fixPriority(200);
- _object3.postInit();
- _object3.setVisage(2337);
- _object3.setStrip(6);
- _object3.setPosition(Common::Point(260, 180));
- _object3.fixPriority(200);
+ _centerFlyCycle.postInit();
+ _centerFlyCycle.setVisage(2337);
+ _centerFlyCycle.setStrip(6);
+ _centerFlyCycle.setPosition(Common::Point(260, 180));
+ _centerFlyCycle.fixPriority(200);
- _object4.postInit();
- _object4.setVisage(2331);
- _object4.setStrip(6);
- _object4.setPosition(Common::Point(295, 144));
- _object4.fixPriority(178);
+ _rightFlyCycle.postInit();
+ _rightFlyCycle.setVisage(2331);
+ _rightFlyCycle.setStrip(6);
+ _rightFlyCycle.setPosition(Common::Point(295, 144));
+ _rightFlyCycle.fixPriority(178);
- g_globals->_sceneItems.addItems(&_object2, &_object3, &_object4, NULL);
+ g_globals->_sceneItems.addItems(&_leftFlyCycle, &_centerFlyCycle, &_rightFlyCycle, NULL);
if (!g_globals->getFlag(101)) {
g_globals->_player.disableControl();
@@ -1840,8 +1855,8 @@ void Scene50::postInit(SceneObjectList *OwnerList) {
}
}
- _item0.setBounds(Rect(200, 0, 320, 200));
- g_globals->_sceneItems.addItems(&_item3, &_item4, &_item5, &_item0, NULL);
+ _background.setBounds(Rect(0, 0, 320, 200));
+ g_globals->_sceneItems.addItems(&_bulwark, &_tree, &_flagstones, &_background, NULL);
}
void Scene50::signal() {
@@ -1928,8 +1943,8 @@ void Scene60::Action1::signal() {
scene->_controlButton.remove();
scene->_slaveButton.remove();
scene->_masterButton.remove();
- scene->_item1.remove();
- scene->_item2.remove();
+ scene->_diskDrive.remove();
+ scene->_dashboard.remove();
scene->_nextButton.postInit();
scene->_nextButton.setVisage(65);
@@ -2030,11 +2045,11 @@ void Scene60::Action2::signal() {
/*--------------------------------------------------------------------------*/
void Scene60::PrevObject::doAction(int action) {
- Scene60 *scene = (Scene60 *)g_globals->_sceneManager._scene;
-
if (action == CURSOR_LOOK) {
SceneItem::display2(60, 16);
} else if (action == CURSOR_USE) {
+ Scene60 *scene = (Scene60 *)g_globals->_sceneManager._scene;
+
animate(ANIM_MODE_8, 1, NULL);
if (scene->_action1.getActionIndex() > 5) {
@@ -2048,11 +2063,11 @@ void Scene60::PrevObject::doAction(int action) {
}
void Scene60::NextObject::doAction(int action) {
- Scene60 *scene = (Scene60 *)g_globals->_sceneManager._scene;
-
if (action == CURSOR_LOOK) {
SceneItem::display2(60, 17);
} else if (action == CURSOR_USE) {
+ Scene60 *scene = (Scene60 *)g_globals->_sceneManager._scene;
+
animate(ANIM_MODE_8, 1, NULL);
if (scene->_action1.getActionIndex() < 8) {
@@ -2065,11 +2080,11 @@ void Scene60::NextObject::doAction(int action) {
}
void Scene60::ExitObject::doAction(int action) {
- Scene60 *scene = (Scene60 *)g_globals->_sceneManager._scene;
-
if (action == CURSOR_LOOK) {
SceneItem::display2(60, 18);
} else if (action == CURSOR_USE) {
+ Scene60 *scene = (Scene60 *)g_globals->_sceneManager._scene;
+
scene->_soundHandler3.play(36);
animate(ANIM_MODE_8, 1, NULL);
scene->_nextButton.remove();
@@ -2111,11 +2126,11 @@ void Scene60::ExitObject::doAction(int action) {
if (scene->_masterButton._state)
scene->_masterButton.setFrame(2);
- g_globals->_sceneItems.push_front(&scene->_item1);
+ g_globals->_sceneItems.push_front(&scene->_diskDrive);
g_globals->_sceneItems.push_front(&scene->_controlButton);
g_globals->_sceneItems.push_front(&scene->_slaveButton);
g_globals->_sceneItems.push_front(&scene->_masterButton);
- g_globals->_sceneItems.push_back(&scene->_item2);
+ g_globals->_sceneItems.push_back(&scene->_dashboard);
g_globals->gfxManager()._font.setFontNumber(2);
g_globals->_sceneText._fontNumber = 2;
@@ -2130,11 +2145,11 @@ void Scene60::ExitObject::doAction(int action) {
}
void Scene60::MessageObject::doAction(int action) {
- Scene60 *scene = (Scene60 *)g_globals->_sceneManager._scene;
-
if (action == CURSOR_LOOK) {
SceneItem::display2(60, 9);
} else if (action == CURSOR_USE) {
+ Scene60 *scene = (Scene60 *)g_globals->_sceneManager._scene;
+
scene->_action1.setDelay(1);
g_globals->setFlag(83);
} else {
@@ -2143,11 +2158,11 @@ void Scene60::MessageObject::doAction(int action) {
}
void Scene60::ControlObject::doAction(int action) {
- Scene60 *scene = (Scene60 *)g_globals->_sceneManager._scene;
-
if (action == CURSOR_LOOK) {
SceneItem::display2(60, 11);
} else if (action == CURSOR_USE) {
+ Scene60 *scene = (Scene60 *)g_globals->_sceneManager._scene;
+
if (_animateMode == ANIM_MODE_NONE)
SceneItem::display2(60, 14);
else if (!scene->_slaveButton._state) {
@@ -2164,11 +2179,11 @@ void Scene60::ControlObject::doAction(int action) {
}
void Scene60::SlaveObject::doAction(int action) {
- Scene60 *scene = (Scene60 *)g_globals->_sceneManager._scene;
-
if (action == CURSOR_LOOK) {
SceneItem::display2(60, 8);
} else if (action == CURSOR_USE) {
+ Scene60 *scene = (Scene60 *)g_globals->_sceneManager._scene;
+
if (scene->_masterButton._state)
scene->_sceneMode = 19;
else if (_state) {
@@ -2194,11 +2209,11 @@ void Scene60::SlaveObject::doAction(int action) {
}
void Scene60::MasterObject::doAction(int action) {
- Scene60 *scene = (Scene60 *)g_globals->_sceneManager._scene;
-
if (action == CURSOR_LOOK) {
SceneItem::display2(60, 7);
} else if (action == CURSOR_USE) {
+ Scene60 *scene = (Scene60 *)g_globals->_sceneManager._scene;
+
if (!scene->_controlButton._animateMode)
scene->_sceneMode = 14;
else if (scene->_slaveButton._state)
@@ -2226,11 +2241,11 @@ void Scene60::MasterObject::doAction(int action) {
}
void Scene60::FloppyDrive::doAction(int action) {
- Scene60 *scene = (Scene60 *)g_globals->_sceneManager._scene;
-
if (action == CURSOR_LOOK) {
SceneItem::display2(60, 13);
} else if (action == CURSOR_USE) {
+ Scene60 *scene = (Scene60 *)g_globals->_sceneManager._scene;
+
g_globals->setFlag(!g_globals->_stripNum ? 118 : 121);
scene->setAction(&scene->_action1);
} else {
@@ -2300,11 +2315,11 @@ void Scene60::Item::doAction(int action) {
/*--------------------------------------------------------------------------*/
Scene60::Scene60() :
- _item2(0, 12, 12),
- _item3(8, 22, 23),
- _item4(9, 24, 25),
- _item5(10, 26, 27),
- _item6(11, 28, 29) {
+ _dashboard(0, 12, 12),
+ _intercomm(8, 22, 23),
+ _viewScreen(9, 24, 25),
+ _speedControl(10, 26, 27),
+ _speaker(11, 28, 29) {
}
void Scene60::postInit(SceneObjectList *OwnerList) {
@@ -2345,8 +2360,8 @@ void Scene60::postInit(SceneObjectList *OwnerList) {
setAction(&_sequenceManager, this, 61, NULL);
}
- _item1.setBounds(Rect(130, 55, 174, 70));
- _item2.setBounds(Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT));
+ _diskDrive.setBounds(Rect(130, 55, 174, 70));
+ _dashboard.setBounds(Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT));
if (g_globals->_stripNum == 0) {
if (g_globals->getFlag(117)) {
@@ -2419,8 +2434,7 @@ void Scene60::postInit(SceneObjectList *OwnerList) {
}
}
- g_globals->_sceneItems.addItems(&_item3, &_item4, &_item5, &_item6,
- &_item1, &_item2, NULL);
+ g_globals->_sceneItems.addItems(&_intercomm, &_viewScreen, &_speedControl, &_speaker, &_diskDrive, &_dashboard, NULL);
}
void Scene60::signal() {
@@ -2474,17 +2488,17 @@ void Scene90::Action1::signal() {
case 3: {
Common::Point pt(278, 191);
NpcMover *mover = new NpcMover();
- scene->_object2.addMover(mover, &pt, this);
+ scene->_guard.addMover(mover, &pt, this);
break;
}
case 4:
- scene->_object2.setStrip(3);
+ scene->_guard.setStrip(3);
setDelay(2);
break;
case 5:
scene->_soundHandler2.play(58);
- if (scene->_stripManager._field2E8 == 220)
+ if (scene->_stripManager._currObj44Id == 220)
scene->_stripManager.start(91, this, scene);
else {
scene->_stripManager.start(g_globals->getFlag(104) ? 93 : 92, this, scene);
@@ -2492,36 +2506,36 @@ void Scene90::Action1::signal() {
}
break;
case 6:
- scene->_object2.animate(ANIM_MODE_NONE);
+ scene->_guard.animate(ANIM_MODE_NONE);
g_globals->_player._uiEnabled = true;
break;
case 7:
- scene->_object2.animate(ANIM_MODE_NONE);
+ scene->_guard.animate(ANIM_MODE_NONE);
g_globals->_soundHandler.play(56);
- scene->_object3.animate(ANIM_MODE_5, this);
+ scene->_headGate.animate(ANIM_MODE_5, this);
break;
case 8: {
Common::Point pt(215, 127);
PlayerMover *mover = new PlayerMover();
- scene->_object5.addMover(mover, &pt, this);
+ scene->_quinnShip.addMover(mover, &pt, this);
break;
}
case 9: {
Common::Point pt1(215, 127);
PlayerMover *mover1 = new PlayerMover();
- scene->_object1.addMover(mover1, &pt1, this);
+ scene->_seekerShip.addMover(mover1, &pt1, this);
Common::Point pt2(86, 62);
PlayerMover *mover2 = new PlayerMover();
- scene->_object5.addMover(mover2, &pt2, this);
+ scene->_quinnShip.addMover(mover2, &pt2, this);
break;
}
case 10: {
PlayerMover2 *mover = new PlayerMover2();
- scene->_object1.addMover(mover, 10, 15, &scene->_object5);
+ scene->_seekerShip.addMover(mover, 10, 15, &scene->_quinnShip);
if (!g_globals->getFlag(104)) {
mover = new PlayerMover2();
- scene->_object4.addMover(mover, 10, 15, &scene->_object1);
+ scene->_emptyShip.addMover(mover, 10, 15, &scene->_seekerShip);
}
setDelay(60);
break;
@@ -2529,7 +2543,7 @@ void Scene90::Action1::signal() {
case 11:
g_globals->_soundHandler.play(57);
g_globals->_soundHandler.play(68);
- scene->_object3.animate(ANIM_MODE_6, NULL);
+ scene->_headGate.animate(ANIM_MODE_6, NULL);
SceneItem::display(90, g_globals->getFlag(104) ? 15 : 14,
SET_EXT_BGCOLOR, 13, SET_KEEP_ONSCREEN, -1, SET_X, 120, SET_Y, 20, LIST_END);
@@ -2544,7 +2558,7 @@ void Scene90::Action1::signal() {
/*--------------------------------------------------------------------------*/
-void Scene90::Object1::doAction(int action) {
+void Scene90::SeekerShip::doAction(int action) {
Scene90 *scene = (Scene90 *)g_globals->_sceneManager._scene;
switch (action) {
@@ -2562,23 +2576,23 @@ void Scene90::Object1::doAction(int action) {
}
}
-void Scene90::Object2::doAction(int action) {
+void Scene90::Guard::doAction(int action) {
Scene90 *scene = (Scene90 *)g_globals->_sceneManager._scene;
switch (action) {
case OBJECT_STUNNER:
case CURSOR_USE:
g_globals->_player.disableControl();
- scene->_object6.postInit();
- scene->_object6.setVisage(90);
- scene->_object6.setStrip(6);
- scene->_object6.setPosition(Common::Point(184, 210));
- scene->_object6.hide();
+ scene->_bubble.postInit();
+ scene->_bubble.setVisage(90);
+ scene->_bubble.setStrip(6);
+ scene->_bubble.setPosition(Common::Point(184, 210));
+ scene->_bubble.hide();
scene->_sceneMode = 91;
scene->_soundHandler1.play(59);
scene->_soundHandler1.holdAt(true);
- scene->setAction(&scene->_sequenceManager, scene, 91, this, &scene->_object6, NULL);
+ scene->setAction(&scene->_sequenceManager, scene, 91, this, &scene->_bubble, NULL);
break;
case CURSOR_LOOK:
SceneItem::display2(90, 8);
@@ -2596,21 +2610,21 @@ void Scene90::Object2::doAction(int action) {
/*--------------------------------------------------------------------------*/
Scene90::Scene90() :
- _item1(0, CURSOR_LOOK, 90, 9, LIST_END),
- _item2(0, CURSOR_LOOK, 90, 10, LIST_END),
- _item3(0, CURSOR_LOOK, 90, 11, LIST_END),
- _object3(OBJECT_STUNNER, 90, 13, CURSOR_LOOK, 90, 12, CURSOR_USE, 90, 16, LIST_END),
- _object4(CURSOR_LOOK, 90, 17, LIST_END),
- _object5(CURSOR_LOOK, 90, 18, CURSOR_USE, 90, 19, LIST_END) {
+ _guardShack(0, CURSOR_LOOK, 90, 9, LIST_END),
+ _shed(0, CURSOR_LOOK, 90, 10, LIST_END),
+ _background(0, CURSOR_LOOK, 90, 11, LIST_END),
+ _headGate(OBJECT_STUNNER, 90, 13, CURSOR_LOOK, 90, 12, CURSOR_USE, 90, 16, LIST_END),
+ _emptyShip(CURSOR_LOOK, 90, 17, LIST_END),
+ _quinnShip(CURSOR_LOOK, 90, 18, CURSOR_USE, 90, 19, LIST_END) {
}
void Scene90::stripCallback(int v) {
Scene90 *scene = (Scene90 *)g_globals->_sceneManager._scene;
if (v == 1)
- scene->_object2.animate(ANIM_MODE_7, 0, NULL);
+ scene->_guard.animate(ANIM_MODE_7, 0, NULL);
else if (v == 2)
- scene->_object2.animate(ANIM_MODE_NONE);
+ scene->_guard.animate(ANIM_MODE_NONE);
}
void Scene90::postInit(SceneObjectList *OwnerList) {
@@ -2624,53 +2638,53 @@ void Scene90::postInit(SceneObjectList *OwnerList) {
_stripManager.addSpeaker(&_speakerQL);
_stripManager.addSpeaker(&_speakerSR);
- _speakerMText._npc = &_object2;
+ _speakerMText._npc = &_guard;
_speakerQText._textWidth = 160;
- _speakerQText._npc = &_object5;
- _speakerSText._npc = &_object1;
-
- _object5.postInit();
- _object5.setVisage(2333);
- _object5.setObjectWrapper(new SceneObjectWrapper());
- _object5._strip = 7;
- _object5._moveDiff = Common::Point(22, 22);
- _object5.setPosition(Common::Point(151, 177));
- _object5.changeZoom(-1);
- g_globals->_sceneItems.push_back(&_object5);
-
- _object1.postInit();
- _object1.setVisage(2337);
- _object1.setObjectWrapper(new SceneObjectWrapper());
- _object1._strip = 4;
- _object1._moveDiff = Common::Point(20, 20);
- _object1.setPosition(Common::Point(212, 183));
- _object1.changeZoom(-1);
- g_globals->_sceneItems.push_back(&_object1);
+ _speakerQText._npc = &_quinnShip;
+ _speakerSText._npc = &_seekerShip;
+
+ _quinnShip.postInit();
+ _quinnShip.setVisage(2333);
+ _quinnShip.setObjectWrapper(new SceneObjectWrapper());
+ _quinnShip._strip = 7;
+ _quinnShip._moveDiff = Common::Point(22, 22);
+ _quinnShip.setPosition(Common::Point(151, 177));
+ _quinnShip.changeZoom(-1);
+ g_globals->_sceneItems.push_back(&_quinnShip);
+
+ _seekerShip.postInit();
+ _seekerShip.setVisage(2337);
+ _seekerShip.setObjectWrapper(new SceneObjectWrapper());
+ _seekerShip._strip = 4;
+ _seekerShip._moveDiff = Common::Point(20, 20);
+ _seekerShip.setPosition(Common::Point(212, 183));
+ _seekerShip.changeZoom(-1);
+ g_globals->_sceneItems.push_back(&_seekerShip);
if (!g_globals->getFlag(104)) {
- _object4.postInit();
- _object4.setVisage(2331);
- _object4.setObjectWrapper(new SceneObjectWrapper());
- _object4._strip = 4;
- _object4._moveDiff = Common::Point(20, 20);
- _object4.setPosition(Common::Point(251, 207));
- _object4.changeZoom(-1);
- g_globals->_sceneItems.push_back(&_object4);
- }
-
- _object2.postInit();
- _object2.setVisage(90);
- _object2.animate(ANIM_MODE_1, NULL);
- _object2.setPosition(Common::Point(315, 185));
- _object2._strip = 2;
- g_globals->_sceneItems.push_back(&_object2);
-
- _object3.postInit();
- _object3.setVisage(90);
- _object3.animate(ANIM_MODE_1, NULL);
- _object3.setPosition(Common::Point(196, 181));
- _object3.fixPriority(175);
- g_globals->_sceneItems.push_back(&_object3);
+ _emptyShip.postInit();
+ _emptyShip.setVisage(2331);
+ _emptyShip.setObjectWrapper(new SceneObjectWrapper());
+ _emptyShip._strip = 4;
+ _emptyShip._moveDiff = Common::Point(20, 20);
+ _emptyShip.setPosition(Common::Point(251, 207));
+ _emptyShip.changeZoom(-1);
+ g_globals->_sceneItems.push_back(&_emptyShip);
+ }
+
+ _guard.postInit();
+ _guard.setVisage(90);
+ _guard.animate(ANIM_MODE_1, NULL);
+ _guard.setPosition(Common::Point(315, 185));
+ _guard._strip = 2;
+ g_globals->_sceneItems.push_back(&_guard);
+
+ _headGate.postInit();
+ _headGate.setVisage(90);
+ _headGate.animate(ANIM_MODE_1, NULL);
+ _headGate.setPosition(Common::Point(196, 181));
+ _headGate.fixPriority(175);
+ g_globals->_sceneItems.push_back(&_headGate);
g_globals->_player.disableControl();
g_globals->_soundHandler.play(55);
@@ -2679,11 +2693,11 @@ void Scene90::postInit(SceneObjectList *OwnerList) {
setAction(&_action1);
- _item3.setBounds(Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT));
- _item1.setBounds(Rect(271, 65, 271, 186));
- _item2.setBounds(Rect(0, 17, 124, 77));
+ _background.setBounds(Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT));
+ _guardShack.setBounds(Rect(271, 65, 271, 186));
+ _shed.setBounds(Rect(0, 17, 124, 77));
- g_globals->_sceneItems.addItems(&_item1, &_item2, &_item3, NULL);
+ g_globals->_sceneItems.addItems(&_guardShack, &_shed, &_background, NULL);
}
void Scene90::signal() {
@@ -2700,7 +2714,7 @@ void Scene90::signal() {
g_globals->_player.enableControl();
break;
case 97:
- _stripManager._field2E8 = 0;
+ _stripManager._currObj44Id = 0;
_action1.setActionIndex(5);
_action1.setDelay(1);
break;
@@ -2925,7 +2939,7 @@ void Scene6100::Action3::signal() {
case 4:
g_globals->setFlag(76);
g_globals->_sceneManager.changeScene(
- (scene->_stripManager._field2E8 == 135) ? 6100 : 2320);
+ (scene->_stripManager._currObj44Id == 135) ? 6100 : 2320);
remove();
break;
}
diff --git a/engines/tsage/ringworld/ringworld_scenes1.h b/engines/tsage/ringworld/ringworld_scenes1.h
index bb98c89a8c..d52d4fb6ec 100644
--- a/engines/tsage/ringworld/ringworld_scenes1.h
+++ b/engines/tsage/ringworld/ringworld_scenes1.h
@@ -54,8 +54,12 @@ public:
Speaker _speakerQText;
Action1 _action1;
Action2 _action2;
- SceneObject _object1, _object2, _object3;
- SceneObject _object4, _object5, _object6;
+ SceneObject _veeshkaBody;
+ SceneObject _veeshkaHead;
+ SceneObject _veeshkaRightArm;
+ SceneObject _centurion;
+ SceneObject _leftSmoke;
+ SceneObject _rightSmoke;
virtual void stripCallback(int v);
virtual void postInit(SceneObjectList *OwnerList = NULL);
@@ -70,7 +74,7 @@ class Scene15 : public Scene {
};
public:
Action1 _action1;
- SceneObject _object1;
+ SceneObject _ship;
ASound _soundHandler;
virtual void postInit(SceneObjectList *OwnerList = NULL);
@@ -102,7 +106,10 @@ public:
Action2 _action2;
Action3 _action3;
Action4 _action4;
- SceneObject _sceneObject1, _SceneObjectExt, _sceneObject3, _sceneObject4, _sceneObject5;
+ SceneObject _assassinShip1;
+ SceneObject _assassinShip2;
+ SceneObject _laserShot1;
+ SceneObject _laserShot2;
ASound _sound;
public:
Scene20();
@@ -248,15 +255,21 @@ public:
Action6 _action6;
Action7 _action7;
Action8 _action8;
- SceneObject _object1, _object2, _object3;
+ SceneObject _seeker;
+ SceneObject _seekerTail;
+ SceneObject _seekerHand;
DyingKzin _dyingKzin;
Assassin _assassin;
- SceneObject _doorway, _object7, _object8;
- DisplayHotspot _item1;
- Item2 _item2;
- DisplayHotspot _item3, _item4, _item5;
- Item6 _item6;
- DisplayHotspot _item7, _item8;
+ SceneObject _doorway;
+ SceneObject _leftEntrance;
+ DisplayHotspot _ball;
+ Item2 _statue;
+ DisplayHotspot _window;
+ DisplayHotspot _entrance;
+ DisplayHotspot _background;
+ Item6 _pedestal;
+ DisplayHotspot _emerald;
+ DisplayHotspot _tree;
Scene40();
virtual void postInit(SceneObjectList *OwnerList = NULL);
@@ -284,15 +297,15 @@ class Scene50 : public Scene {
public:
virtual void doAction(int action);
};
- class Object2 : public SceneObject {
+ class LeftFlyCycle : public SceneObject {
public:
virtual void doAction(int action);
};
- class Object3 : public SceneObject {
+ class CenterFlyCycle : public SceneObject {
public:
virtual void doAction(int action);
};
- class Object4 : public SceneObject {
+ class RightFlyCycle : public SceneObject {
public:
virtual void doAction(int action);
};
@@ -302,15 +315,18 @@ public:
Action1 _action1;
Action2 _action2;
Action3 _action3;
- Object1 _object1;
- Object2 _object2;
- Object3 _object3;
- Object4 _object4;
+ LeftFlyCycle _leftFlyCycle;
+ CenterFlyCycle _centerFlyCycle;
+ RightFlyCycle _rightFlyCycle;
Rect _doorwayRect;
SpeakerSText _speakerSText;
SpeakerQText _speakerQText;
- DisplayHotspot _item0, _item1, _item2;
- DisplayHotspot _item3, _item4, _item5;
+ DisplayHotspot _background;
+ DisplayHotspot _item1;
+ DisplayHotspot _entrance;
+ DisplayHotspot _bulwark;
+ DisplayHotspot _tree;
+ DisplayHotspot _flagstones;
Scene50();
virtual void postInit(SceneObjectList *OwnerList = NULL);
@@ -392,8 +408,12 @@ public:
MasterObject _masterButton;
FloppyDrive _floppyDrive;
SceneObject _redLights;
- Item1 _item1;
- Item _item2, _item3, _item4, _item5, _item6;
+ Item1 _diskDrive;
+ Item _dashboard;
+ Item _intercomm;
+ Item _viewScreen;
+ Item _speedControl;
+ Item _speaker;
ASound _soundHandler1;
ASound _soundHandler2;
ASound _soundHandler3;
@@ -409,11 +429,11 @@ class Scene90 : public Scene {
public:
virtual void signal();
};
- class Object1 : public SceneObject {
+ class SeekerShip : public SceneObject {
public:
virtual void doAction(int action);
};
- class Object2 : public SceneObject {
+ class Guard : public SceneObject {
public:
virtual void doAction(int action);
};
@@ -425,11 +445,15 @@ public:
SpeakerSR _speakerSR;
SpeakerMText _speakerMText;
Action1 _action1;
- Object1 _object1;
- Object2 _object2;
- DisplayObject _object3, _object4, _object5;
- SceneObject _object6;
- DisplayHotspot _item1, _item2, _item3;
+ SeekerShip _seekerShip;
+ Guard _guard;
+ DisplayObject _headGate;
+ DisplayObject _emptyShip;
+ DisplayObject _quinnShip;
+ SceneObject _bubble;
+ DisplayHotspot _guardShack;
+ DisplayHotspot _shed;
+ DisplayHotspot _background;
ASound _soundHandler1, _soundHandler2;
Scene90();
diff --git a/engines/tsage/ringworld/ringworld_scenes10.cpp b/engines/tsage/ringworld/ringworld_scenes10.cpp
index f9a8e7996a..eac181e350 100644
--- a/engines/tsage/ringworld/ringworld_scenes10.cpp
+++ b/engines/tsage/ringworld/ringworld_scenes10.cpp
@@ -1870,7 +1870,7 @@ void Scene9900::signal() {
setAction(&_sequenceManager, this, 9908, &_object1, &_object2, &_object3, &_object4, &_object5, &_object6);
break;
case 162:
- warning("TBC: shutdown();");
+ // shutdown();
g_globals->_game->quitGame();
break;
case 9901:
diff --git a/engines/tsage/ringworld/ringworld_scenes3.cpp b/engines/tsage/ringworld/ringworld_scenes3.cpp
index b2ed986331..e834e659b5 100644
--- a/engines/tsage/ringworld/ringworld_scenes3.cpp
+++ b/engines/tsage/ringworld/ringworld_scenes3.cpp
@@ -799,7 +799,7 @@ void Scene2100::Action9::signal() {
scene->_stripManager.start(6010, this);
break;
case 6:
- if (scene->_stripManager._field2E8 != 165)
+ if (scene->_stripManager._currObj44Id != 165)
setAction(&scene->_action10);
else
setAction(&scene->_action11);
@@ -1010,7 +1010,7 @@ void Scene2100::Action12::signal() {
scene->_stripManager.start(6052, this);
break;
case 8:
- if (scene->_stripManager._field2E8 == 320)
+ if (scene->_stripManager._currObj44Id == 320)
g_globals->setFlag(74);
setDelay(30);
break;
@@ -2352,11 +2352,11 @@ void Scene2150::Action2::signal() {
scene->_hotspot14.setStrip(6);
scene->_hotspot14.setPosition(Common::Point(59, 54));
- if (scene->_stripManager._field2E8 == 15) {
+ if (scene->_stripManager._currObj44Id == 15) {
scene->_hotspot14.setFrame(5);
RING_INVENTORY._ale._sceneNumber = 1;
} else {
- scene->_hotspot14.setFrame(scene->_stripManager._field2E8 - 5);
+ scene->_hotspot14.setFrame(scene->_stripManager._currObj44Id - 5);
}
g_globals->_player.setFrame(1);
@@ -3160,7 +3160,7 @@ void Scene2230::Action1::signal() {
switch (_actionIndex++) {
case 0:
- switch (scene->_field30A) {
+ switch (scene->_sceneMode) {
case 1:
scene->setAction(&scene->_action3);
break;
@@ -3201,7 +3201,7 @@ void Scene2230::Action2::signal() {
switch (_actionIndex++) {
case 0:
- switch (scene->_field30A) {
+ switch (scene->_sceneMode) {
case 2:
scene->setAction(&scene->_action6, this);
break;
@@ -3212,7 +3212,7 @@ void Scene2230::Action2::signal() {
break;
case 1: {
g_globals->_player.disableControl();
- scene->_field30A = 1;
+ scene->_sceneMode = 1;
g_globals->_player._regionBitList |= ~0x80;
Common::Point pt(160, 96);
NpcMover *mover = new NpcMover();
@@ -3262,7 +3262,7 @@ void Scene2230::Action3::signal() {
break;
case 2:
g_globals->_player._regionBitList |= 0x80;
- scene->_field30A = 0;
+ scene->_sceneMode = 0;
g_globals->_player.setVisage(0);
g_globals->_player.setStrip2(-1);
@@ -3292,7 +3292,7 @@ void Scene2230::Action5::signal() {
switch (_actionIndex++) {
case 0:
- switch (scene->_field30A) {
+ switch (scene->_sceneMode) {
case 2:
scene->setAction(&scene->_action3, this);
break;
@@ -3318,7 +3318,7 @@ void Scene2230::Action5::signal() {
case 3:
g_globals->_events.setCursor(CURSOR_USE);
g_globals->_player._uiEnabled = true;
- scene->_field30A = 2;
+ scene->_sceneMode = 2;
remove();
break;
}
@@ -3335,7 +3335,7 @@ void Scene2230::Action6::signal() {
g_globals->_player.animate(ANIM_MODE_5, this);
break;
case 1:
- scene->_field30A = 0;
+ scene->_sceneMode = 0;
g_globals->_player.setVisage(0);
g_globals->_player._strip = 1;
g_globals->_player._canWalk = true;
@@ -3352,7 +3352,7 @@ void Scene2230::Action7::signal() {
case 0:
g_globals->_player.disableControl();
- switch (scene->_field30A) {
+ switch (scene->_sceneMode) {
case 1:
scene->setAction(&scene->_action3, this);
break;
@@ -3408,7 +3408,7 @@ void Scene2230::Action8::signal() {
case 0:
g_globals->_player.disableControl();
- switch (scene->_field30A) {
+ switch (scene->_sceneMode) {
case 1:
scene->setAction(&scene->_action3, this);
break;
@@ -3431,7 +3431,7 @@ void Scene2230::Action8::signal() {
g_globals->_sceneItems.remove(&scene->_hotspot11);
g_globals->_sceneItems.remove(&scene->_hotspot12);
- switch (scene->_field30A) {
+ switch (scene->_sceneMode) {
case 1:
scene->setAction(&scene->_action3, this);
break;
@@ -3560,7 +3560,7 @@ void Scene2230::Hotspot6::doAction(int action) {
}
break;
case CURSOR_USE:
- if (scene->_field30A == 1)
+ if (scene->_sceneMode == 1)
scene->setAction(&scene->_action3);
else if (g_globals->getFlag(13))
SceneItem::display2(2230, 28);
@@ -3586,7 +3586,7 @@ void Scene2230::Hotspot7::doAction(int action) {
}
break;
case CURSOR_USE:
- if (scene->_field30A == 2)
+ if (scene->_sceneMode == 2)
scene->setAction(&scene->_action6);
else if (g_globals->getFlag(13))
SceneItem::display2(2230, 29);
@@ -3692,7 +3692,7 @@ void Scene2230::Hotspot12::doAction(int action) {
/*--------------------------------------------------------------------------*/
Scene2230::Scene2230() : _hotspot9(0, CURSOR_LOOK, 2230, 16, CURSOR_USE, 2230, 18, LIST_END) {
- _field30A = 0;
+ _sceneMode = 0;
}
void Scene2230::postInit(SceneObjectList *OwnerList) {
@@ -3726,7 +3726,7 @@ void Scene2230::postInit(SceneObjectList *OwnerList) {
g_globals->_player._regionBitList |= 0x80;
g_globals->_player.changeZoom(-1);
- _field30A = 0;
+ _sceneMode = 0;
g_globals->_player.enableControl();
_hotspot5.setBounds(Rect(108, 34, 142, 76));
@@ -3748,7 +3748,7 @@ void Scene2230::postInit(SceneObjectList *OwnerList) {
void Scene2230::synchronize(Serializer &s) {
Scene::synchronize(s);
_rect1.synchronize(s);
- s.syncAsSint16LE(_field30A);
+ s.syncAsSint16LE(_sceneMode);
}
void Scene2230::dispatch() {
diff --git a/engines/tsage/ringworld/ringworld_scenes3.h b/engines/tsage/ringworld/ringworld_scenes3.h
index 682ef44fc6..fafb72fcea 100644
--- a/engines/tsage/ringworld/ringworld_scenes3.h
+++ b/engines/tsage/ringworld/ringworld_scenes3.h
@@ -579,7 +579,7 @@ public:
Hotspot11 _hotspot11;
Hotspot12 _hotspot12;
Rect _rect1;
- int _field30A;
+ int _sceneMode;
Scene2230();
virtual void postInit(SceneObjectList *OwnerList = NULL);
diff --git a/engines/tsage/ringworld/ringworld_scenes5.cpp b/engines/tsage/ringworld/ringworld_scenes5.cpp
index 004ccbbb6d..1242f9f448 100644
--- a/engines/tsage/ringworld/ringworld_scenes5.cpp
+++ b/engines/tsage/ringworld/ringworld_scenes5.cpp
@@ -34,6 +34,9 @@ namespace Ringworld {
* Scene 4000 - Village
*
*--------------------------------------------------------------------------*/
+Scene4000::Hotspot8::Hotspot8() : SceneObject() {
+ _ctr = 0;
+}
void Scene4000::Action1::signal() {
// Quinn has the peg. Everybody enter the screen.
@@ -459,7 +462,7 @@ void Scene4000::Action12::signal() {
break;
case 2:
g_globals->setFlag(32);
- if (scene->_stripManager._field2E8 == 275) {
+ if (scene->_stripManager._currObj44Id == 275) {
g_globals->setFlag(82);
ADD_MOVER_NULL(scene->_guardRock, 292, 138);
ADD_PLAYER_MOVER(283, 147);
@@ -468,7 +471,7 @@ void Scene4000::Action12::signal() {
}
break;
case 3:
- if (scene->_stripManager._field2E8 == 275) {
+ if (scene->_stripManager._currObj44Id == 275) {
g_globals->_sceneManager.changeScene(4100);
} else {
ADD_PLAYER_MOVER_THIS(scene->_guardRock, 300, 132);
@@ -4219,7 +4222,12 @@ void Scene4300::process(Event &event) {
void Scene4301::Action1::synchronize(Serializer &s) {
Action::synchronize(s);
- s.syncAsSint16LE(_field34E);
+
+ if (s.getVersion() < 14) {
+ int useless = 0;
+ s.syncAsSint16LE(useless);
+ }
+
for (int idx = 0; idx < 6; ++idx)
s.syncAsSint16LE(_indexList[idx]);
}
@@ -4265,7 +4273,6 @@ void Scene4301::Action1::signal() {
scene->_hotspot3.fixPriority(255);
scene->_hotspot3.hide();
- _field34E = 0;
_state = 0;
_actionIndex = 2;
break;
diff --git a/engines/tsage/ringworld/ringworld_scenes5.h b/engines/tsage/ringworld/ringworld_scenes5.h
index c93df2a1d8..b49d2a6f02 100644
--- a/engines/tsage/ringworld/ringworld_scenes5.h
+++ b/engines/tsage/ringworld/ringworld_scenes5.h
@@ -99,6 +99,7 @@ class Scene4000 : public Scene {
private:
int _ctr;
public:
+ Hotspot8();
virtual void synchronize(Serializer &s) {
SceneObject::synchronize(s);
s.syncAsUint16LE(_ctr);
@@ -655,7 +656,6 @@ class Scene4301 : public Scene {
class Action1 : public ActionExt {
public:
SceneObject _buttonList[6];
- int _field34E;
int _indexList[6];
virtual void synchronize(Serializer &s);
diff --git a/engines/tsage/ringworld/ringworld_scenes6.cpp b/engines/tsage/ringworld/ringworld_scenes6.cpp
index 30a91b57aa..777eed2aab 100644
--- a/engines/tsage/ringworld/ringworld_scenes6.cpp
+++ b/engines/tsage/ringworld/ringworld_scenes6.cpp
@@ -1608,8 +1608,6 @@ Scene5200::Scene5200() :
void Scene5200::postInit(SceneObjectList *OwnerList) {
Scene::postInit();
setZoomPercents(0, 150, 199, 150);
- _fieldA = 5600;
- _fieldE = 5100;
_hotspot9._state = 0;
_hotspot10._state = 0;
@@ -2032,7 +2030,15 @@ void Scene5300::Hotspot8::doAction(int action) {
/*--------------------------------------------------------------------------*/
Scene5300::Scene5300() :
- _hotspot3(0, CURSOR_LOOK, 5300, 3, CURSOR_USE, 5300, 16, LIST_END) {
+ _hotspot3(0, CURSOR_LOOK, 5300, 3, CURSOR_USE, 5300, 16, LIST_END) {
+}
+
+void Scene5300::synchronize(Serializer &s) {
+ Scene::synchronize(s);
+ if (s.getVersion() < 11) {
+ int useless = 0;
+ s.syncAsSint16LE(useless);
+ }
}
void Scene5300::postInit(SceneObjectList *OwnerList) {
@@ -2119,7 +2125,6 @@ void Scene5300::postInit(SceneObjectList *OwnerList) {
setAction(&_sequenceManager, this, 5306, &g_globals->_player, &_hotspot3, NULL);
}
- _field1B0A = 1;
if (RING_INVENTORY._bone._sceneNumber == 5300) {
_hotspot5.postInit();
_hotspot5.setVisage(5301);
diff --git a/engines/tsage/ringworld/ringworld_scenes6.h b/engines/tsage/ringworld/ringworld_scenes6.h
index bf353de415..4c10e4a711 100644
--- a/engines/tsage/ringworld/ringworld_scenes6.h
+++ b/engines/tsage/ringworld/ringworld_scenes6.h
@@ -318,15 +318,11 @@ public:
Hotspot6 _hotspot6;
Hotspot7 _hotspot7;
Hotspot8 _hotspot8;
- int _field1B0A;
Scene5300();
virtual void postInit(SceneObjectList *OwnerList = NULL);
virtual void signal();
- virtual void synchronize(Serializer &s) {
- Scene::synchronize(s);
- s.syncAsSint16LE(_field1B0A);
- }
+ virtual void synchronize(Serializer &s);
};
} // End of namespace Ringworld
diff --git a/engines/tsage/ringworld/ringworld_scenes8.cpp b/engines/tsage/ringworld/ringworld_scenes8.cpp
index 9cb85a6930..f9156479e5 100644
--- a/engines/tsage/ringworld/ringworld_scenes8.cpp
+++ b/engines/tsage/ringworld/ringworld_scenes8.cpp
@@ -30,6 +30,10 @@ namespace TsAGE {
namespace Ringworld {
+NamedHotspotMult::NamedHotspotMult() : SceneHotspot() {
+ _useLineNum = _lookLineNum = 0;
+}
+
void NamedHotspotMult::synchronize(Serializer &s) {
SceneHotspot::synchronize(s);
s.syncAsSint16LE(_useLineNum);
@@ -2533,6 +2537,10 @@ Scene7700::Scene7700() {
_object5._state = 0;
_object6._state = 0;
_prof._state = 0;
+
+ _seatCountLeft1 = 0;
+ _seatCountLeft2 = 0;
+ _seatCountRight = 0;
}
void Scene7700::synchronize(Serializer &s) {
diff --git a/engines/tsage/ringworld/ringworld_scenes8.h b/engines/tsage/ringworld/ringworld_scenes8.h
index b24f220f8c..fa441f87da 100644
--- a/engines/tsage/ringworld/ringworld_scenes8.h
+++ b/engines/tsage/ringworld/ringworld_scenes8.h
@@ -40,7 +40,7 @@ using namespace TsAGE;
class NamedHotspotMult : public SceneHotspot {
public:
int _useLineNum, _lookLineNum;
- NamedHotspotMult() : SceneHotspot() {}
+ NamedHotspotMult();
virtual Common::String getClassName() { return "NamedHotspotMult"; }
virtual void synchronize(Serializer &s);
diff --git a/engines/tsage/ringworld2/ringworld2_dialogs.cpp b/engines/tsage/ringworld2/ringworld2_dialogs.cpp
index 057d91a46e..3e35831138 100644
--- a/engines/tsage/ringworld2/ringworld2_dialogs.cpp
+++ b/engines/tsage/ringworld2/ringworld2_dialogs.cpp
@@ -50,6 +50,7 @@ RightClickDialog::RightClickDialog() : GfxDialog() {
_btnList[5] = Common::Point(83, 47);
// Set the palette and change the cursor
+ _previousCursor = R2_GLOBALS._events.getCursor();
R2_GLOBALS._events.setCursor(CURSOR_ARROW);
setPalette();
@@ -136,7 +137,7 @@ bool RightClickDialog::process(Event &event) {
return false;
}
-void RightClickDialog::execute() {
+int RightClickDialog::execute() {
// Draw the dialog
draw();
@@ -157,7 +158,8 @@ void RightClickDialog::execute() {
}
// Execute the specified action
- CursorType cursorNum = CURSOR_NONE;
+ CursorType cursorNum = _previousCursor;
+ int result = -1;
switch (_selectedAction) {
case 0:
// Look action
@@ -165,7 +167,7 @@ void RightClickDialog::execute() {
break;
case 1:
// Walk action
- cursorNum = CURSOR_WALK;
+ cursorNum = R2_GLOBALS._player._canWalk ? CURSOR_WALK : CURSOR_USE;
break;
case 2:
// Use action
@@ -177,17 +179,18 @@ void RightClickDialog::execute() {
break;
case 4:
// Change player
- CharacterDialog::show();
+ result = 0;
break;
case 5:
// Options dialog
+ result = 1;
break;
}
- if (cursorNum != CURSOR_NONE)
- R2_GLOBALS._events.setCursor(cursorNum);
-
+ R2_GLOBALS._events.setCursor(cursorNum);
_gfxManager.deactivate();
+
+ return result;
}
/*--------------------------------------------------------------------------*/
@@ -200,13 +203,13 @@ void CharacterDialog::show() {
GfxButton *btn = NULL;
int oldCharacter = R2_GLOBALS._player._characterIndex;
switch (oldCharacter) {
- case 1:
+ case R2_QUINN:
btn = &dlg->_btnQuinn;
break;
- case 2:
+ case R2_SEEKER:
btn = &dlg->_btnSeeker;
break;
- case 3:
+ case R2_MIRANDA:
btn = &dlg->_btnMiranda;
break;
default:
@@ -234,7 +237,7 @@ void CharacterDialog::show() {
SceneExt *scene = (SceneExt *)R2_GLOBALS._sceneManager._scene;
scene->saveCharacter(oldCharacter);
- // Play the correctfrequency, if any, of the character being switched to's scanner device
+ // Play the correctfrequency, if any, of the character being switched to's scanner device
if (R2_GLOBALS._player._characterScene[R2_NONE] != 300) {
switch (R2_GLOBALS._scannerFrequencies[R2_GLOBALS._player._characterIndex] - 1) {
case 0:
@@ -312,6 +315,9 @@ void CharacterDialog::show() {
}
}
+ // Reset the current cursor
+ R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
+
// Change to whichever scene the newly selected character is in
R2_GLOBALS._sceneManager.changeScene(R2_GLOBALS._player._characterScene[R2_GLOBALS._player._characterIndex]);
}
@@ -344,7 +350,7 @@ CharacterDialog::CharacterDialog() {
/*--------------------------------------------------------------------------*/
void HelpDialog::show() {
- // Set the palette and change the cursor
+ // change the cursor
R2_GLOBALS._events.setCursor(CURSOR_ARROW);
// Create the dialog and draw it
@@ -381,6 +387,8 @@ void HelpDialog::show() {
// If a action button was selected, dispatch to handle it
if (evt.kbd.keycode != Common::KEYCODE_INVALID)
R2_GLOBALS._game->processEvent(evt);
+ else
+ R2_GLOBALS._events.setCursorFromFlag();
}
HelpDialog::HelpDialog() {
diff --git a/engines/tsage/ringworld2/ringworld2_dialogs.h b/engines/tsage/ringworld2/ringworld2_dialogs.h
index 02a1aed81c..0c19ae4371 100644
--- a/engines/tsage/ringworld2/ringworld2_dialogs.h
+++ b/engines/tsage/ringworld2/ringworld2_dialogs.h
@@ -50,13 +50,14 @@ private:
int _highlightedAction;
int _selectedAction;
+ CursorType _previousCursor;
public:
RightClickDialog();
~RightClickDialog();
virtual void draw();
virtual bool process(Event &event);
- void execute();
+ int execute();
};
class CharacterDialog: public GfxDialog {
diff --git a/engines/tsage/ringworld2/ringworld2_logic.cpp b/engines/tsage/ringworld2/ringworld2_logic.cpp
index 4050c62a78..39e398023d 100644
--- a/engines/tsage/ringworld2/ringworld2_logic.cpp
+++ b/engines/tsage/ringworld2/ringworld2_logic.cpp
@@ -38,8 +38,6 @@ namespace TsAGE {
namespace Ringworld2 {
Scene *Ringworld2Game::createScene(int sceneNumber) {
- warning("Switching to scene %d", sceneNumber);
-
switch (sceneNumber) {
/* Scene group #0 */
case 50:
@@ -67,8 +65,12 @@ Scene *Ringworld2Game::createScene(int sceneNumber) {
// Deck #2 - By Lift
return new Scene200();
case 205:
- // Star-field Credits
- return new Scene205();
+ if (g_vm->getFeatures() & GF_DEMO)
+ // End of Demo
+ return new Scene205Demo();
+ else
+ // Star-field Credits
+ return new Scene205();
case 250:
// Lift
return new Scene250();
@@ -114,8 +116,10 @@ Scene *Ringworld2Game::createScene(int sceneNumber) {
// Cutscene - trip in space
return new Scene1010();
case 1020:
+ // Cutscene - trip in space 2
return new Scene1020();
case 1100:
+ // Canyon
return new Scene1100();
case 1200:
// ARM Base - Air Ducts Maze
@@ -131,12 +135,13 @@ Scene *Ringworld2Game::createScene(int sceneNumber) {
// Cutscene - Ship
return new Scene1525();
case 1530:
- // Cutscene - Elevator
+ // Cutscene - Crashing on Rimwall
return new Scene1530();
case 1550:
// Spaceport
return new Scene1550();
case 1575:
+ // Spaceport - unused ship scene
return new Scene1575();
case 1580:
// Inside wreck
@@ -172,7 +177,6 @@ Scene *Ringworld2Game::createScene(int sceneNumber) {
// Flup Tube Corridor Maze
return new Scene1950();
/* Scene group #2 */
- //
case 2000:
// Spill Mountains
return new Scene2000();
@@ -180,7 +184,7 @@ Scene *Ringworld2Game::createScene(int sceneNumber) {
// Spill Mountains: Balloon Launch Platform
return new Scene2350();
case 2400:
- // Spill Mountains: Large empty room
+ // Spill Mountains: Unused large empty room
return new Scene2400();
case 2425:
// Spill Mountains: The Hall of Records
@@ -204,7 +208,7 @@ Scene *Ringworld2Game::createScene(int sceneNumber) {
// Spill Mountains: Inside crevasse
return new Scene2455();
case 2500:
- // Spill Mountains: Large Cave
+ // Spill Mountains: Large Ledge
return new Scene2500();
case 2525:
// Spill Mountains: Furnace room
@@ -290,7 +294,7 @@ Scene *Ringworld2Game::createScene(int sceneNumber) {
// Confrontation
return new Scene3400();
case 3500:
- // Maze action sequencec
+ // Flub tube maze
return new Scene3500();
case 3600:
// Cutscene - walking at gunpoint
@@ -322,8 +326,11 @@ bool Ringworld2Game::canLoadGameStateCurrently() {
* Returns true if it is currently okay to save the game
*/
bool Ringworld2Game::canSaveGameStateCurrently() {
- // Don't allow a game to be saved if a dialog is active
- return g_globals->_gfxManagers.size() == 1;
+ // Don't allow a game to be saved if a dialog is active, or if an animation
+ // is playing, or if an active scene prevents it
+ return g_globals->_gfxManagers.size() == 1 && R2_GLOBALS._animationCtr == 0 &&
+ (!R2_GLOBALS._sceneManager._scene ||
+ !((SceneExt *)R2_GLOBALS._sceneManager._scene)->_preventSaving);
}
/*--------------------------------------------------------------------------*/
@@ -333,11 +340,15 @@ SceneExt::SceneExt(): Scene() {
_stripManager._onEnd = SceneExt::endStrip;
for (int i = 0; i < 256; i++)
- _field312[i] = 0;
+ _shadowPaletteMap[i] = 0;
_savedPlayerEnabled = false;
_savedUiEnabled = false;
_savedCanWalk = false;
+ _preventSaving = false;
+
+ // Reset screen clipping area
+ R2_GLOBALS._screenSurface._clipRect = Rect();
// WORKAROUND: In the original, playing animations don't reset the global _animationCtr
// counter as scene changes unless the playing animation explicitly finishes. For now,
@@ -349,7 +360,7 @@ SceneExt::SceneExt(): Scene() {
void SceneExt::synchronize(Serializer &s) {
Scene::synchronize(s);
- s.syncBytes(&_field312[0], 256);
+ s.syncBytes(&_shadowPaletteMap[0], 256);
_sceneAreas.synchronize(s);
}
@@ -361,15 +372,24 @@ void SceneExt::postInit(SceneObjectList *OwnerList) {
// Initialize fields
_action = NULL;
- _field12 = 0;
_sceneMode = 0;
+ static_cast<SceneHandlerExt *>(R2_GLOBALS._sceneHandler)->setupPaletteMaps();
+
int prevScene = R2_GLOBALS._sceneManager._previousScene;
int sceneNumber = R2_GLOBALS._sceneManager._sceneNumber;
- if (((prevScene == -1) && (sceneNumber != 180) && (sceneNumber != 205) && (sceneNumber != 50))
+ if (g_vm->getFeatures() & GF_DEMO) {
+ if (((prevScene == -1) && (sceneNumber != 180) && (sceneNumber != 205) && (sceneNumber != 50))
+ || (prevScene == 0) || (sceneNumber == 600)
+ || ((prevScene == 205 || prevScene == 180) && (sceneNumber == 100))) {
+ R2_GLOBALS._uiElements._active = true;
+ R2_GLOBALS._uiElements.show();
+ } else {
+ R2_GLOBALS._uiElements.updateInventory();
+ }
+ } else if (((prevScene == -1) && (sceneNumber != 180) && (sceneNumber != 205) && (sceneNumber != 50))
|| (sceneNumber == 50)
|| ((sceneNumber == 100) && (prevScene == 0 || prevScene == 180 || prevScene == 205))) {
- static_cast<SceneHandlerExt *>(R2_GLOBALS._sceneHandler)->setupPaletteMaps();
R2_GLOBALS._uiElements._active = true;
R2_GLOBALS._uiElements.show();
} else {
@@ -382,7 +402,7 @@ void SceneExt::remove() {
Scene::remove();
R2_GLOBALS._uiElements._active = true;
- if (R2_GLOBALS._events.getCursor() >= EXITCURSOR_N &&
+ if (R2_GLOBALS._events.getCursor() >= EXITCURSOR_N &&
R2_GLOBALS._events.getCursor() <= SHADECURSOR_DOWN)
R2_GLOBALS._events.setCursor(CURSOR_WALK);
}
@@ -393,19 +413,6 @@ void SceneExt::process(Event &event) {
}
void SceneExt::dispatch() {
-/*
- _timerList.dispatch();
-
- if (_field37A) {
- if ((--_field37A == 0) && R2_GLOBALS._dayNumber) {
- if (R2_GLOBALS._uiElements._active && R2_GLOBALS._player._enabled) {
- R2_GLOBALS._uiElements.show();
- }
-
- _field37A = 0;
- }
- }
-*/
Scene::dispatch();
}
@@ -430,9 +437,9 @@ bool SceneExt::display(CursorType action, Event &event) {
SceneItem::display2(5, 0);
break;
case R2_SONIC_STUNNER:
- if ((R2_GLOBALS._scannerFrequencies[R2_QUINN] == 2)
+ if ((R2_GLOBALS._scannerFrequencies[R2_QUINN] == 2)
|| ((R2_GLOBALS._scannerFrequencies[R2_QUINN] == 1) &&
- (R2_GLOBALS._scannerFrequencies[R2_SEEKER] == 2) &&
+ (R2_GLOBALS._scannerFrequencies[R2_SEEKER] == 2) &&
(R2_GLOBALS._sceneManager._previousScene == 300))) {
R2_GLOBALS._sound4.stop();
R2_GLOBALS._sound3.play(46);
@@ -578,7 +585,7 @@ void SceneExt::scalePalette(int RFactor, int GFactor, int BFactor) {
varC = tmp;
varD = j;
}
- this->_field312[i] = varD;
+ this->_shadowPaletteMap[i] = varD;
}
}
@@ -593,6 +600,9 @@ void SceneExt::loadBlankScene() {
void SceneHandlerExt::postInit(SceneObjectList *OwnerList) {
SceneHandler::postInit(OwnerList);
+
+ if (!R2_GLOBALS._playStream.setFile("SND4K.RES"))
+ warning("Could not find SND4K.RES voice file");
}
void SceneHandlerExt::process(Event &event) {
@@ -616,9 +626,8 @@ void SceneHandlerExt::process(Event &event) {
}
void SceneHandlerExt::postLoad(int priorSceneBeforeLoad, int currentSceneBeforeLoad) {
- if (priorSceneBeforeLoad == -1 || priorSceneBeforeLoad == 50
- || priorSceneBeforeLoad == 180 || priorSceneBeforeLoad == 205)
- setupPaletteMaps();
+ // Set up the shading maps used for showing the player in shadows
+ setupPaletteMaps();
if (currentSceneBeforeLoad == 2900) {
R2_GLOBALS._gfxFontNumber = 50;
@@ -1090,7 +1099,7 @@ void Ringworld2InvObjectList::selectDefault(int objectNumber) {
Common::String line = Common::String::format("%.5s%.5s%.5s%.5s%s %s %s %s.",
msg1.c_str(), msg2.c_str(), msg3.c_str(), msg4.c_str(),
msg1.c_str() + 5, msg2.c_str() + 5, msg3.c_str() + 5, msg4.c_str() + 5);
-
+
SceneItem::display(-1, -1, line.c_str(),
SET_WIDTH, 280,
SET_X, 160,
@@ -1118,19 +1127,30 @@ void Ringworld2Game::start() {
if (slot >= 0)
R2_GLOBALS._sceneHandler->_loadGameSlot = slot;
else {
- // Switch to the first game scene
- R2_GLOBALS._events.setCursor(CURSOR_WALK);
+ // Switch to the first title screen
R2_GLOBALS._uiElements._active = true;
- R2_GLOBALS._sceneManager.setNewScene(100);
+ R2_GLOBALS._sceneManager.setNewScene(180);
}
g_globals->_events.showCursor();
}
+void Ringworld2Game::restartGame() {
+ if (MessageDialog::show(Ringworld2::R2_RESTART_MSG, CANCEL_BTN_STRING, YES_MSG) == 1)
+ restart();
+}
+
void Ringworld2Game::restart() {
g_globals->_scenePalette.clearListeners();
g_globals->_soundHandler.stop();
+ // Reset the globals
+ g_globals->reset();
+
+ // Clear save/load slots
+ g_globals->_sceneHandler->_saveGameSlot = -1;
+ g_globals->_sceneHandler->_loadGameSlot = -1;
+
// Change to the first game scene
g_globals->_sceneManager.changeScene(100);
}
@@ -1187,25 +1207,25 @@ void Ringworld2Game::processEvent(Event &event) {
case Common::KEYCODE_F4:
// F4 - Restart
restartGame();
- g_globals->_events.setCursorFromFlag();
+ R2_GLOBALS._events.setCursorFromFlag();
break;
case Common::KEYCODE_F7:
// F7 - Restore
restoreGame();
- g_globals->_events.setCursorFromFlag();
+ R2_GLOBALS._events.setCursorFromFlag();
break;
case Common::KEYCODE_F8:
// F8 - Credits
- warning("TODO: Show Credits");
+ R2_GLOBALS._sceneManager.changeScene(205);
break;
case Common::KEYCODE_F10:
// F10 - Pause
GfxDialog::setPalette();
MessageDialog::show(GAME_PAUSED_MSG, OK_BTN_STRING);
- g_globals->_events.setCursorFromFlag();
+ R2_GLOBALS._events.setCursorFromFlag();
break;
default:
@@ -1216,8 +1236,13 @@ void Ringworld2Game::processEvent(Event &event) {
void Ringworld2Game::rightClick() {
RightClickDialog *dlg = new RightClickDialog();
- dlg->execute();
+ int option = dlg->execute();
delete dlg;
+
+ if (option == 0)
+ CharacterDialog::show();
+ else if (option == 1)
+ HelpDialog::show();
}
/*--------------------------------------------------------------------------*/
@@ -1264,7 +1289,7 @@ void SceneActor::postInit(SceneObjectList *OwnerList) {
void SceneActor::remove() {
R2_GLOBALS._sceneItems.remove(this);
- _field9C = NULL;
+ _shadowMap = NULL;
_linkedActor = NULL;
SceneObject::remove();
@@ -1305,26 +1330,6 @@ bool SceneActor::startAction(CursorType action, Event &event) {
GfxSurface SceneActor::getFrame() {
GfxSurface frame = SceneObject::getFrame();
- // TODO: Proper effects handling
- switch (_effect) {
- case 0:
- case 5:
- // TODO: Figure out purpose of setting image flags to 64, and getting
- // scene priorities -1 or _shade
- break;
- case 1:
- // TODO: Transposing using R2_GLOBALS._pixelArrayMap
- break;
- case 2:
- // No effect
- break;
- case 4:
- break;
- default:
- // TODO: Default effect
- break;
- }
-
return frame;
}
@@ -1335,6 +1340,7 @@ SceneArea::SceneArea(): SceneItem() {
_insideArea = false;
_savedCursorNum = CURSOR_NONE;
_cursorState = 0;
+ _cursorNum = CURSOR_NONE;
}
void SceneArea::synchronize(Serializer &s) {
@@ -1387,6 +1393,8 @@ void SceneArea::setDetails(const Rect &bounds, CursorType cursor) {
SceneExit::SceneExit(): SceneArea() {
_moving = false;
_destPos = Common::Point(-1, -1);
+
+ _sceneNumber = 0;
}
void SceneExit::synchronize(Serializer &s) {
@@ -1461,7 +1469,7 @@ void SceneAreaObject::process(Event &event) {
_savedCursorNum = R2_GLOBALS._events.getCursor();
R2_GLOBALS._events.setCursor(CURSOR_INVALID);
}
-
+
if (event.eventType == EVENT_BUTTON_DOWN) {
event.handled = true;
R2_GLOBALS._events.setCursor(_savedCursorNum);
@@ -1498,7 +1506,7 @@ MazeUI::MazeUI() {
_cellSize.x = _cellSize.y = 0;
_mapOffset.x = _mapOffset.y = 0;
_resNum = _cellsResNum = 0;
- _frameCount = _resCount = _mapImagePitch = _unused = 0;
+ _frameCount = _resCount = _mapImagePitch = 0;
}
MazeUI::~MazeUI() {
@@ -1514,7 +1522,9 @@ void MazeUI::synchronize(Serializer &s) {
s.syncAsSint16LE(_mapOffset.x);
s.syncAsSint16LE(_mapOffset.y);
- s.syncAsSint16LE(_unused);
+
+ int dummy = 0;
+ s.syncAsSint16LE(dummy);
}
void MazeUI::load(int resNum) {
@@ -1599,12 +1609,13 @@ void MazeUI::draw() {
(_cellSize.y - 1)) / _cellSize.y;
// Loop to handle the cell rows of the visible display area one at a time
- for (int yCtr = 0; yCtr < _cellsVisible.y; ++yCtr, yPos += ySize) {
+ for (int yCtr = 0; yCtr <= _cellsVisible.y; ++yCtr, yPos += ySize) {
int cellY = _mapOffset.y / _cellSize.y + yCtr;
// Loop to iterate through the horizontal visible cells to build up
- // an entire cell high horizontal slice of the map
- for (int xCtr = 0; xCtr < _cellsVisible.x; ++xCtr) {
+ // an entire cell high horizontal slice of the map, plus one extra cell
+ // to allow for partial cell scrolling on-screen on the left/right sides
+ for (int xCtr = 0; xCtr <= _cellsVisible.x; ++xCtr) {
int cellX = _mapOffset.x / _cellSize.x + xCtr;
// Get the type of content to display in the cell
@@ -1704,6 +1715,12 @@ void AnimationSlice::load(Common::File &f) {
AnimationSlices::AnimationSlices() {
_pixelData = NULL;
+
+ _dataSize = 0;
+ _dataSize2 = 0;
+ _slices->_sliceOffset = 0;
+ _slices->_drawMode = 0;
+ _slices->_secondaryIndex = 0;
}
AnimationSlices::~AnimationSlices() {
@@ -1765,10 +1782,21 @@ AnimationPlayer::AnimationPlayer(): EventHandler() {
_screenBounds = R2_GLOBALS._gfxManagerInstance._bounds;
_rect1 = R2_GLOBALS._gfxManagerInstance._bounds;
_paletteMode = ANIMPALMODE_REPLACE_PALETTE;
- _field3A = 1;
+ _canSkip = true;
_sliceHeight = 1;
- _field58 = 1;
_endAction = NULL;
+
+ _sliceCurrent = nullptr;
+ _sliceNext = nullptr;
+ _animLoaded = false;
+ _objectMode = ANIMOBJMODE_1;
+ _dataNeeded = 0;
+ _playbackTick = 0;
+ _playbackTickPrior = 0;
+ _position = 0;
+ _nextSlicesPosition = 0;
+ _frameDelay = 0;
+ _gameFrame = 0;
}
AnimationPlayer::~AnimationPlayer() {
@@ -1778,7 +1806,9 @@ AnimationPlayer::~AnimationPlayer() {
void AnimationPlayer::synchronize(Serializer &s) {
EventHandler::synchronize(s);
- warning("TODO AnimationPlayer::synchronize");
+
+ // TODO: Implement saving for animation player state. Currently, I disable saving
+ // when an animation is active, so saving it's state would a "nice to have".
}
void AnimationPlayer::remove() {
@@ -1789,8 +1819,7 @@ void AnimationPlayer::remove() {
}
void AnimationPlayer::process(Event &event) {
- if ((event.eventType == EVENT_KEYPRESS) && (event.kbd.keycode == Common::KEYCODE_ESCAPE) &&
- (_field3A)) {
+ if ((event.eventType == EVENT_KEYPRESS) && (event.kbd.keycode == Common::KEYCODE_ESCAPE) && _canSkip) {
// Move the current position to the end
_position = _subData._duration;
}
@@ -1836,11 +1865,13 @@ bool AnimationPlayer::load(int animId, Action *endAction) {
_playbackTickPrior = -1;
_playbackTick = 0;
- // The final multiplication is used to deliberately slow down playback, since the original
- // was slowed down by the amount of time spent to decode and display the frames
- _frameDelay = (60 / _subData._frameRate) * 8;
+ _frameDelay = (60 / _subData._frameRate);
_gameFrame = R2_GLOBALS._events.getFrameNumber();
+ // WORKAROUND: Slow down the title sequences to better match the original
+ if (animId <= 4 || animId == 15)
+ _frameDelay *= 8;
+
if (_subData._totalSize) {
_dataNeeded = _subData._totalSize;
} else {
@@ -1909,7 +1940,7 @@ bool AnimationPlayer::load(int animId, Action *endAction) {
}
++R2_GLOBALS._animationCtr;
- _field38 = 1;
+ _animLoaded = true;
return true;
}
@@ -2006,7 +2037,7 @@ void AnimationPlayer::drawFrame(int sliceIndex) {
// Unlock the screen surface
R2_GLOBALS._screenSurface.unlockSurface();
- if (_objectMode == 42) {
+ if (_objectMode == ANIMOBJMODE_42) {
_screenBounds.expandPanes();
// Copy the drawn frame to the back surface
@@ -2056,7 +2087,7 @@ bool AnimationPlayer::isCompleted() {
}
void AnimationPlayer::close() {
- if (_field38) {
+ if (_animLoaded) {
switch (_paletteMode) {
case 0:
R2_GLOBALS._scenePalette.replace(&_palette);
@@ -2075,7 +2106,7 @@ void AnimationPlayer::close() {
// Close the resource file
_resourceFile.close();
- if (_objectMode != 42) {
+ if (_objectMode != ANIMOBJMODE_42) {
// flip screen in original
}
@@ -2085,9 +2116,9 @@ void AnimationPlayer::close() {
_animData1 = NULL;
_animData2 = NULL;
- _field38 = 0;
+ _animLoaded = false;
if (g_globals != NULL)
- R2_GLOBALS._animationCtr = MAX(R2_GLOBALS._animationCtr, 0);
+ R2_GLOBALS._animationCtr = MAX(R2_GLOBALS._animationCtr - 1, 0);
}
void AnimationPlayer::rleDecode(const byte *pSrc, byte *pDest, int size) {
@@ -2133,13 +2164,13 @@ void AnimationPlayer::getSlices() {
/*--------------------------------------------------------------------------*/
AnimationPlayerExt::AnimationPlayerExt(): AnimationPlayer() {
- _v = 0;
- _field3A = 0;
+ _isActive = false;
+ _canSkip = false;
}
void AnimationPlayerExt::synchronize(Serializer &s) {
AnimationPlayer::synchronize(s);
- s.syncAsSint16LE(_v);
+ s.syncAsSint16LE(_isActive);
}
/*--------------------------------------------------------------------------*/
@@ -2186,7 +2217,7 @@ void ModalWindow::process(Event &event) {
}
}
-void ModalWindow::proc12(int visage, int stripFrameNum, int frameNum, int posX, int posY) {
+void ModalWindow::setup2(int visage, int stripFrameNum, int frameNum, int posX, int posY) {
Scene1200 *scene = (Scene1200 *)R2_GLOBALS._sceneManager._scene;
_object1.postInit();
@@ -2199,7 +2230,7 @@ void ModalWindow::proc12(int visage, int stripFrameNum, int frameNum, int posX,
_insetCount = R2_GLOBALS._insetUp;
}
-void ModalWindow::proc13(int resNum, int lookLineNum, int talkLineNum, int useLineNum) {
+void ModalWindow::setup3(int resNum, int lookLineNum, int talkLineNum, int useLineNum) {
_object1.setDetails(resNum, lookLineNum, talkLineNum, useLineNum, 2, (SceneItem *) NULL);
}
@@ -2243,7 +2274,7 @@ void ScannerDialog::Button::process(Event &event) {
setFrame(2);
_buttonDown = false;
event.handled = true;
-
+
reset();
}
}
@@ -2458,15 +2489,15 @@ void ScannerDialog::remove() {
ModalWindow::remove();
}
-void ScannerDialog::proc12(int visage, int stripFrameNum, int frameNum, int posX, int posY) {
+void ScannerDialog::setup2(int visage, int stripFrameNum, int frameNum, int posX, int posY) {
// Stop player moving if currently doing so
if (R2_GLOBALS._player._mover)
R2_GLOBALS._player.addMover(NULL);
R2_GLOBALS._events.setCursor(CURSOR_USE);
- ModalWindow::proc12(visage, stripFrameNum, frameNum, posX, posY);
+ ModalWindow::setup2(visage, stripFrameNum, frameNum, posX, posY);
- proc13(100, -1, -1, -1);
+ setup3(100, -1, -1, -1);
_talkButton.setup(1);
_scanButton.setup(2);
_slider.setup(R2_GLOBALS._scannerFrequencies[R2_GLOBALS._player._characterIndex], 142, 124, 35, 5);
diff --git a/engines/tsage/ringworld2/ringworld2_logic.h b/engines/tsage/ringworld2/ringworld2_logic.h
index 57a30dcc13..c9695c921d 100644
--- a/engines/tsage/ringworld2/ringworld2_logic.h
+++ b/engines/tsage/ringworld2/ringworld2_logic.h
@@ -81,10 +81,11 @@ private:
static void startStrip();
static void endStrip();
public:
- byte _field312[256];
+ byte _shadowPaletteMap[256];
bool _savedPlayerEnabled;
bool _savedUiEnabled;
bool _savedCanWalk;
+ bool _preventSaving;
Visage _cursorVisage;
SynchronizedList<EventHandler *> _sceneAreas;
@@ -228,6 +229,7 @@ public:
class Ringworld2Game: public Game {
public:
virtual void start();
+ virtual void restartGame();
virtual void restart();
virtual void endGame(int resNum, int lineNum);
@@ -305,7 +307,6 @@ public:
int _frameCount;
int _resCount;
int _mapImagePitch;
- int _unused;
public:
MazeUI();
virtual ~MazeUI();
@@ -405,11 +406,11 @@ public:
AnimationData *_sliceNext;
Common::File _resourceFile;
Rect _rect1, _screenBounds;
- int _field38;
- int _field3A;
+ bool _animLoaded;
+ bool _canSkip;
AnimationPaletteMode _paletteMode;
AnimationObjectMode _objectMode;
- int _field58, _sliceHeight;
+ int _sliceHeight;
byte _palIndexes[256];
ScenePalette _palette;
AnimationPlayerSubData _subData;
@@ -441,7 +442,7 @@ public:
class AnimationPlayerExt: public AnimationPlayer {
public:
- int _v;
+ bool _isActive;
public:
AnimationPlayerExt();
@@ -459,8 +460,8 @@ public:
virtual void synchronize(Serializer &s);
virtual Common::String getClassName() { return "ModalWindow"; }
virtual void process(Event &event);
- virtual void proc12(int visage, int stripFrameNum, int frameNum, int posX, int posY);
- virtual void proc13(int resNum, int lookLineNum, int talkLineNum, int useLineNum);
+ 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 ScannerDialog: public ModalWindow {
@@ -513,7 +514,7 @@ public:
virtual Common::String getClassName() { return "ScannerDialog"; }
virtual void remove();
- void proc12(int visage, int stripFrameNum, int frameNum, int posX, int posY);
+ virtual void setup2(int visage, int stripFrameNum, int frameNum, int posX, int posY);
};
} // End of namespace Ringworld2
diff --git a/engines/tsage/ringworld2/ringworld2_scenes0.cpp b/engines/tsage/ringworld2/ringworld2_scenes0.cpp
index 4eefa11de9..2fbce0646c 100644
--- a/engines/tsage/ringworld2/ringworld2_scenes0.cpp
+++ b/engines/tsage/ringworld2/ringworld2_scenes0.cpp
@@ -31,6 +31,11 @@ namespace TsAGE {
namespace Ringworld2 {
+/*--------------------------------------------------------------------------
+ * Scene 50 - Waking up cutscene
+ *
+ *--------------------------------------------------------------------------*/
+
void Scene50::Action1::signal() {
switch (_actionIndex++) {
case 0:
@@ -48,8 +53,8 @@ void Scene50::Action1::signal() {
}
void Scene50::postInit(SceneObjectList *OwnerList) {
- SceneExt::postInit(OwnerList);
loadScene(110);
+ SceneExt::postInit(OwnerList);
R2_GLOBALS._uiElements._active = false;
R2_GLOBALS._scenePalette.loadPalette(0);
@@ -111,7 +116,7 @@ bool Scene100::Table::startAction(CursorType action, Event &event) {
R2_GLOBALS._player.disableControl();
if (_strip == 2) {
scene->_sceneMode = 108;
- scene->_object3.postInit();
+ scene->_tableLocker.postInit();
scene->_stasisNegator.postInit();
if (R2_INVENTORY.getObjectScene(R2_NEGATOR_GUN) == 1) {
@@ -121,11 +126,13 @@ bool Scene100::Table::startAction(CursorType action, Event &event) {
scene->_stasisNegator.setDetails(100, 21, 22, 23, 2, (SceneItem *)NULL);
}
- scene->setAction(&scene->_sequenceManager2, scene, 108, this, &scene->_object3,
+ // Open table locker
+ scene->setAction(&scene->_sequenceManager2, scene, 108, this, &scene->_tableLocker,
&scene->_stasisNegator, &R2_GLOBALS._player, NULL);
} else {
scene->_sceneMode = 109;
- scene->setAction(&scene->_sequenceManager2, scene, 109, this, &scene->_object3,
+ // Close table locker
+ scene->setAction(&scene->_sequenceManager2, scene, 109, this, &scene->_tableLocker,
&scene->_stasisNegator, &R2_GLOBALS._player, NULL);
}
return true;
@@ -135,7 +142,7 @@ bool Scene100::Table::startAction(CursorType action, Event &event) {
if (_strip == 2) {
SceneItem::display2(100, 18);
scene->_sceneMode = 102;
- scene->_object3.postInit();
+ scene->_tableLocker.postInit();
scene->_stasisNegator.postInit();
if (R2_INVENTORY.getObjectScene(R2_NEGATOR_GUN) == 1) {
@@ -145,12 +152,12 @@ bool Scene100::Table::startAction(CursorType action, Event &event) {
scene->_stasisNegator.setDetails(100, 21, 22, 23, 2, (SceneItem *)NULL);
}
- scene->setAction(&scene->_sequenceManager2, scene, 102, this, &scene->_object3,
+ scene->setAction(&scene->_sequenceManager2, scene, 102, this, &scene->_tableLocker,
&scene->_stasisNegator, NULL);
} else {
SceneItem::display2(100, 19);
scene->_sceneMode = 103;
- scene->setAction(&scene->_sequenceManager2, scene, 103, this, &scene->_object3,
+ scene->setAction(&scene->_sequenceManager2, scene, 103, this, &scene->_tableLocker,
&scene->_stasisNegator, NULL);
}
return true;
@@ -160,22 +167,21 @@ bool Scene100::Table::startAction(CursorType action, Event &event) {
}
bool Scene100::StasisNegator::startAction(CursorType action, Event &event) {
- Scene100 *scene = (Scene100 *)R2_GLOBALS._sceneManager._scene;
-
switch (action) {
- case CURSOR_USE:
+ case CURSOR_USE: {
+ Scene100 *scene = (Scene100 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 107;
scene->setAction(&scene->_sequenceManager1, scene, 107, &R2_GLOBALS._player, &scene->_stasisNegator, NULL);
return true;
+ }
default:
return SceneActor::startAction(action, event);
}
}
bool Scene100::DoorDisplay::startAction(CursorType action, Event &event) {
- Scene100 *scene = (Scene100 *)R2_GLOBALS._sceneManager._scene;
-
switch (action) {
case CURSOR_LOOK:
SceneItem::display2(100, _state ? 24 : 25);
@@ -183,25 +189,29 @@ bool Scene100::DoorDisplay::startAction(CursorType action, Event &event) {
case CURSOR_TALK:
SceneItem::display2(100, _state ? 26 : 27);
return true;
- case CURSOR_USE:
+ case CURSOR_USE: {
+ Scene100 *scene = (Scene100 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 110;
scene->setAction(&scene->_sequenceManager1, scene, 110, &R2_GLOBALS._player, NULL);
return true;
+ }
default:
return SceneActor::startAction(action, event);
}
}
bool Scene100::SteppingDisks::startAction(CursorType action, Event &event) {
- Scene100 *scene = (Scene100 *)R2_GLOBALS._sceneManager._scene;
-
switch (action) {
- case CURSOR_USE:
+ case CURSOR_USE: {
+ Scene100 *scene = (Scene100 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 111;
scene->setAction(&scene->_sequenceManager1, scene, 111, &R2_GLOBALS._player, this, NULL);
return true;
+ }
default:
return SceneActor::startAction(action, event);
}
@@ -210,14 +220,15 @@ bool Scene100::SteppingDisks::startAction(CursorType action, Event &event) {
/*--------------------------------------------------------------------------*/
bool Scene100::Terminal::startAction(CursorType action, Event &event) {
- Scene100 *scene = (Scene100 *)R2_GLOBALS._sceneManager._scene;
-
switch (action) {
- case CURSOR_USE:
+ case CURSOR_USE: {
+ Scene100 *scene = (Scene100 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 105;
scene->setAction(&scene->_sequenceManager1, scene, 105, &R2_GLOBALS._player, this, NULL);
return true;
+ }
default:
return NamedHotspot::startAction(action, event);
}
@@ -227,7 +238,6 @@ bool Scene100::Terminal::startAction(CursorType action, Event &event) {
void Scene100::postInit(SceneObjectList *OwnerList) {
loadScene(100);
- R2_GLOBALS._scenePalette.loadPalette(0);
SceneExt::postInit();
if (R2_GLOBALS._sceneManager._previousScene != 125)
@@ -291,10 +301,10 @@ void Scene100::postInit(SceneObjectList *OwnerList) {
switch (R2_GLOBALS._sceneManager._previousScene) {
case 50:
case 180:
- _object5.postInit();
- _object4.postInit();
+ _wardrobeColorAnim.postInit();
+ _wardrobeTopAnim.postInit();
_sceneMode = 104;
- setAction(&_sequenceManager1, this, 104, &R2_GLOBALS._player, &_wardrobe, &_object4, &_object5, NULL);
+ setAction(&_sequenceManager1, this, 104, &R2_GLOBALS._player, &_wardrobe, &_wardrobeTopAnim, &_wardrobeColorAnim, NULL);
break;
case 125:
_sceneMode = 100;
@@ -327,14 +337,14 @@ void Scene100::signal() {
_table.setStrip(2);
_table.setFrame(3);
- _object3.remove();
+ _tableLocker.remove();
_stasisNegator.remove();
R2_GLOBALS._player.enableControl();
break;
case 104:
_sceneMode = 0;
- _object5.remove();
- _object4.remove();
+ _wardrobeColorAnim.remove();
+ _wardrobeTopAnim.remove();
R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
R2_GLOBALS._player._numFrames = 10;
@@ -383,7 +393,7 @@ void Scene100::dispatch() {
SceneExt::dispatch();
if ((_sceneMode == 101) && (_door._frame == 2) && (_table._strip == 5)) {
- _table.setAction(&_sequenceManager2, NULL, 103, &_table, &_object3, &_stasisNegator, NULL);
+ _table.setAction(&_sequenceManager2, NULL, 103, &_table, &_tableLocker, &_stasisNegator, NULL);
}
}
@@ -403,16 +413,16 @@ bool Scene125::Food::startAction(CursorType action, Event &event) {
Scene125::Icon::Icon(): SceneActor() {
_lookLineNum = 0;
- _field98 = 0;
+ _iconId = 0;
_pressed = false;
}
void Scene125::Icon::postInit(SceneObjectList *OwnerList) {
SceneObject::postInit();
- _object1.postInit();
- _object1.fixPriority(255);
- _object1.hide();
+ _glyph.postInit();
+ _glyph.fixPriority(255);
+ _glyph.hide();
_sceneText1._color1 = 92;
_sceneText1._color2 = 0;
@@ -426,7 +436,7 @@ void Scene125::Icon::postInit(SceneObjectList *OwnerList) {
void Scene125::Icon::synchronize(Serializer &s) {
SceneActor::synchronize(s);
s.syncAsSint16LE(_lookLineNum);
- s.syncAsSint16LE(_field98);
+ s.syncAsSint16LE(_iconId);
s.syncAsSint16LE(_pressed);
}
@@ -455,15 +465,15 @@ void Scene125::Icon::process(Event &event) {
scene->_sound1.play(14);
setFrame(2);
- switch (_object1._strip) {
+ switch (_glyph._strip) {
case 1:
- _object1.setStrip(2);
+ _glyph.setStrip(2);
break;
case 3:
- _object1.setStrip(4);
+ _glyph.setStrip(4);
break;
case 5:
- _object1.setStrip(6);
+ _glyph.setStrip(6);
break;
default:
break;
@@ -482,15 +492,15 @@ void Scene125::Icon::process(Event &event) {
if ((event.eventType == EVENT_BUTTON_UP) && _pressed) {
setFrame(1);
- switch (_object1._strip) {
+ switch (_glyph._strip) {
case 2:
- _object1.setStrip(1);
+ _glyph.setStrip(1);
break;
case 4:
- _object1.setStrip(3);
+ _glyph.setStrip(3);
break;
case 6:
- _object1.setStrip(5);
+ _glyph.setStrip(5);
break;
default:
break;
@@ -504,18 +514,18 @@ void Scene125::Icon::process(Event &event) {
}
void Scene125::Icon::setIcon(int id) {
- Scene125 *scene = (Scene125 *)R2_GLOBALS._sceneManager._scene;
-
- _lookLineNum = _field98 = id;
+ _lookLineNum = _iconId = id;
SceneActor::_lookLineNum = id;
_sceneText1.remove();
_sceneText2.remove();
if (_lookLineNum) {
+ Scene125 *scene = (Scene125 *)R2_GLOBALS._sceneManager._scene;
+
showIcon();
- _object1.setup(161, ((id - 1) / 10) * 2 + 1, ((id - 1) % 10) + 1);
- _object1.setPosition(_position);
+ _glyph.setup(161, ((id - 1) / 10) * 2 + 1, ((id - 1) % 10) + 1);
+ _glyph.setPosition(_position);
_sceneText1._fontNumber = scene->_iconFontNumber;
_sceneText1.setup(CONSOLE125_MESSAGES[id]);
@@ -558,16 +568,16 @@ void Scene125::Icon::setIcon(int id) {
void Scene125::Icon::showIcon() {
_sceneText1.show();
_sceneText2.show();
- _object1.show();
- _object2.show();
+ _glyph.show();
+ _horizLine.show();
show();
}
void Scene125::Icon::hideIcon() {
_sceneText1.hide();
_sceneText2.hide();
- _object1.hide();
- _object2.hide();
+ _glyph.hide();
+ _horizLine.hide();
hide();
}
@@ -613,8 +623,8 @@ Scene125::Scene125(): SceneExt() {
}
void Scene125::postInit(SceneObjectList *OwnerList) {
- SceneExt::postInit();
loadScene(160);
+ SceneExt::postInit();
_palette.loadPalette(0);
if (R2_GLOBALS._sceneManager._previousScene != 125)
@@ -662,28 +672,28 @@ void Scene125::signal() {
case 2:
_icon1.setup(160, 1, 1);
_icon1.setPosition(Common::Point(65, 17));
- _icon1._object2.postInit();
- _icon1._object2.setup(160, 7, 1);
- _icon1._object2.setPosition(Common::Point(106, 41));
+ _icon1._horizLine.postInit();
+ _icon1._horizLine.setup(160, 7, 1);
+ _icon1._horizLine.setPosition(Common::Point(106, 41));
_icon2.setup(160, 1, 1);
_icon2.setPosition(Common::Point(80, 32));
- _icon2._object2.postInit();
- _icon2._object2.setup(160, 7, 2);
- _icon2._object2.setPosition(Common::Point(106, 56));
+ _icon2._horizLine.postInit();
+ _icon2._horizLine.setup(160, 7, 2);
+ _icon2._horizLine.setPosition(Common::Point(106, 56));
_icon3.setup(160, 1, 1);
_icon3.setPosition(Common::Point(65, 47));
- _icon3._object2.postInit();
- _icon3._object2.setup(160, 7, 1);
- _icon3._object2.setPosition(Common::Point(106, 71));
+ _icon3._horizLine.postInit();
+ _icon3._horizLine.setup(160, 7, 1);
+ _icon3._horizLine.setPosition(Common::Point(106, 71));
_icon4.setup(160, 1, 1);
_icon4.setPosition(Common::Point(80, 62));
_icon4._sceneRegionId = 5;
- _icon4._object2.postInit();
- _icon4._object2.setup(160, 7, 2);
- _icon4._object2.setPosition(Common::Point(106, 86));
+ _icon4._horizLine.postInit();
+ _icon4._horizLine.setup(160, 7, 2);
+ _icon4._horizLine.setPosition(Common::Point(106, 86));
_icon5.postInit();
_icon5.setup(160, 1, 1);
@@ -702,20 +712,23 @@ void Scene125::signal() {
R2_GLOBALS._player._canWalk = false;
break;
case 10:
- switch (_consoleMode) {
+ switch (_consoleMode) {
case 12:
_sceneMode = 129;
- _object1.postInit();
- _object2.postInit();
- _object3.postInit();
+ _starchart1.postInit();
+ _starchart2.postInit();
+ _starchart3.postInit();
if (R2_GLOBALS.getFlag(13)) {
- _object4.postInit();
- setAction(&_sequenceManager, this, 130, &R2_GLOBALS._player, &_object1, &_object2,
- &_object3, &_object4, NULL);
+ // Show starchart with Ringworld present
+ _starchart4.postInit();
+ setAction(&_sequenceManager, this, 130, &R2_GLOBALS._player, &_starchart1, &_starchart2,
+ &_starchart3, &_starchart4, NULL);
} else {
- setAction(&_sequenceManager, this, 129, &R2_GLOBALS._player, &_object1, &_object2, &_object3, NULL);
+ // Show starchart without Ringworld
+ setAction(&_sequenceManager, this, 129, &R2_GLOBALS._player, &_starchart1, &_starchart2,
+ &_starchart3, NULL);
}
break;
case 13:
@@ -772,7 +785,7 @@ void Scene125::signal() {
case 12:
if (_soundCount > 0)
--_soundCount;
- if (!_soundCount || (R2_GLOBALS._speechSubtitles & SPEECH_VOICE)) {
+ if (!_soundCount || !(R2_GLOBALS._speechSubtitles & SPEECH_VOICE)) {
_soundIndex = 0;
R2_GLOBALS._playStream.stop();
} else {
@@ -832,7 +845,7 @@ void Scene125::process(Event &event) {
void Scene125::dispatch() {
if (_soundCount)
- R2_GLOBALS._playStream.proc1();
+ R2_GLOBALS._playStream.dispatch();
Scene::dispatch();
}
@@ -916,7 +929,7 @@ void Scene125::consoleAction(int id) {
_icon4.setPosition(Common::Point(52, 107));
_icon4._sceneRegionId = 9;
_icon4.setIcon(25);
- _icon4._object2.hide();
+ _icon4._horizLine.hide();
_icon6.setIcon(26);
_sceneMode = 10;
@@ -959,7 +972,7 @@ void Scene125::consoleAction(int id) {
_icon4.setPosition(Common::Point(52, 107));
_icon4._sceneRegionId = 9;
_icon4.setIcon(25);
- _icon4._object2.hide();
+ _icon4._horizLine.hide();
_icon6.setIcon(26);
_sceneMode = 10;
@@ -1043,7 +1056,7 @@ void Scene125::consoleAction(int id) {
break;
case 24:
_icon4.setIcon(25);
- _icon4._object2.hide();
+ _icon4._horizLine.hide();
if (_consoleMode == 10) {
setDetails(127, --_logIndex);
@@ -1055,7 +1068,7 @@ void Scene125::consoleAction(int id) {
break;
case 25:
_icon4.setIcon(25);
- _icon4._object2.hide();
+ _icon4._horizLine.hide();
if (_consoleMode == 10) {
setDetails(127, ++_logIndex);
@@ -1073,10 +1086,10 @@ void Scene125::consoleAction(int id) {
_icon4.hideIcon();
R2_GLOBALS._player.hide();
- _object1.hide();
- _object2.hide();
- _object3.hide();
- _object4.hide();
+ _starchart1.hide();
+ _starchart2.hide();
+ _starchart3.hide();
+ _starchart4.hide();
_sceneMode = 11;
_palette.loadPalette(160);
@@ -1099,7 +1112,7 @@ void Scene125::consoleAction(int id) {
_icon4.setPosition(Common::Point(52, 107));
_icon4._sceneRegionId = 9;
_icon4.setIcon(25);
- _icon4._object2.hide();
+ _icon4._horizLine.hide();
_icon6.setIcon(26);
_sceneMode = 10;
@@ -1159,7 +1172,7 @@ void Scene125::setDetails(int resNum, int lineNum) {
if ((_soundCount > 0) && (R2_GLOBALS._speechSubtitles & SPEECH_VOICE)) {
_sceneMode = 12;
- R2_GLOBALS._playStream.play(_soundIndexes[_soundIndex], this);
+ R2_GLOBALS._playStream.play(_soundIndexes[_soundIndex++], this);
}
} else {
// Passed the start or end of the message set, so return to the menu
@@ -1213,8 +1226,8 @@ Common::String Scene125::parseMessage(const Common::String &msg) {
*--------------------------------------------------------------------------*/
void Scene150::postInit(SceneObjectList *OwnerList) {
- SceneExt::postInit();
loadScene(100);
+ SceneExt::postInit();
_door.postInit();
_door._state = 0;
@@ -1420,8 +1433,9 @@ Scene160::Scene160(): SceneExt() {
}
void Scene160::postInit(SceneObjectList *OwnerList) {
- SceneExt::postInit();
loadScene(4001);
+ R2_GLOBALS._uiElements._active = false;
+ SceneExt::postInit();
R2_GLOBALS._player._uiEnabled = false;
R2_GLOBALS._player.enableControl();
@@ -1442,6 +1456,8 @@ void Scene160::synchronize(Serializer &s) {
s.syncAsSint16LE(_frameNumber);
s.syncAsSint16LE(_yChange);
s.syncAsSint16LE(_lineNum);
+
+ _creditsList.synchronize(s);
}
void Scene160::remove() {
@@ -1480,14 +1496,14 @@ void Scene180::Action1::signal() {
case 0:
case 1:
case 2:
- scene->_object5.setStrip((_actionIndex == 1) ? 1 : 2);
- scene->_object5.setFrame(1);
- scene->_object5.animate(ANIM_MODE_5, this);
+ scene->_shipDisplay.setStrip((_actionIndex == 1) ? 1 : 2);
+ scene->_shipDisplay.setFrame(1);
+ scene->_shipDisplay.animate(ANIM_MODE_5, this);
break;
case 4:
- scene->_object5.setStrip(3);
- scene->_object5.setFrame(1);
- scene->_object5.animate(ANIM_MODE_5, this);
+ scene->_shipDisplay.setStrip(3);
+ scene->_shipDisplay.setFrame(1);
+ scene->_shipDisplay.animate(ANIM_MODE_5, this);
_actionIndex = 0;
break;
}
@@ -1495,12 +1511,10 @@ void Scene180::Action1::signal() {
/*--------------------------------------------------------------------------*/
-Scene180::Scene180(): SceneExt(), _webbsterSpeaker(27) {
- _field412 = 0;
+Scene180::Scene180(): SceneExt() {
+ _helpEnabled = false;
_frameInc = 0;
_frameNumber = R2_GLOBALS._events.getFrameNumber();
- _field480 = 1;
- _field482 = -1;
_fontNumber = R2_GLOBALS.gfxManager()._font._fontNumber;
GfxFont font;
@@ -1527,10 +1541,13 @@ void Scene180::postInit(SceneObjectList *OwnerList) {
}
void Scene180::remove() {
- _stripManager._field2E8 = -1;
+ _stripManager._currObj44Id = -1;
// _stripManager._field2EA = -1;
SceneExt::remove();
+ R2_GLOBALS._scenePalette.loadPalette(0);
+ R2_GLOBALS._scenePalette.setEntry(255, 255, 255, 255);
+
R2_GLOBALS._events.setCursor(CURSOR_WALK);
// word_575F7 = 0;
R2_GLOBALS._playStream.stop();
@@ -1542,9 +1559,7 @@ void Scene180::synchronize(Serializer &s) {
SceneExt::synchronize(s);
s.syncAsSint16LE(_frameNumber);
- s.syncAsSint16LE(_field412);
- s.syncAsSint16LE(_field480);
- s.syncAsSint16LE(_field482);
+ s.syncAsSint16LE(_helpEnabled);
s.syncAsSint16LE(_frameInc);
s.syncAsSint16LE(_fontNumber);
s.syncAsSint16LE(_fontHeight);
@@ -1559,10 +1574,10 @@ void Scene180::signal() {
break;
case 1:
- _field412 = 1;
+ _helpEnabled = true;
R2_GLOBALS._sceneManager._hasPalette = true;
_animationPlayer._paletteMode = ANIMPALMODE_NONE;
- _animationPlayer._v = 1;
+ _animationPlayer._isActive = true;
_animationPlayer._objectMode = ANIMOBJMODE_1;
R2_GLOBALS._scene180Mode = 1;
@@ -1597,7 +1612,8 @@ void Scene180::signal() {
case 30:
case 43:
case 47:
- _field412 = 0;
+ _helpEnabled = false;
+ R2_GLOBALS._screenSurface.fillRect(Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT), 0);
_palette.loadPalette(0);
_palette.loadPalette(9998);
R2_GLOBALS._scenePalette.addFader(_palette._palette, 256, 8, this);
@@ -1605,12 +1621,12 @@ void Scene180::signal() {
case 5:
_animationPlayer._paletteMode = ANIMPALMODE_NONE;
- _animationPlayer._v = 1;
+ _animationPlayer._isActive = true;
_animationPlayer._objectMode = ANIMOBJMODE_1;
R2_GLOBALS._scene180Mode = 2;
_animationPlayer.load(2);
- _field412 = 1;
+ _helpEnabled = true;
R2_GLOBALS._scenePalette.addFader(_animationPlayer._subData._palData, 256, 6, NULL);
R2_GLOBALS._sound1.play(2);
break;
@@ -1647,10 +1663,10 @@ void Scene180::signal() {
break;
case 11:
- _field412 = 1;
- _object4.postInit();
- _object5.postInit();
- setAction(&_sequenceManager, this, 4000, &_object4, &_object5, NULL);
+ _helpEnabled = true;
+ _door.postInit();
+ _shipDisplay.postInit();
+ setAction(&_sequenceManager, this, 4000, &_door, &_shipDisplay, NULL);
break;
case 12:
@@ -1666,51 +1682,51 @@ void Scene180::signal() {
break;
case 13:
- setAction(&_sequenceManager, this, 4001, &_object4, &_object5, NULL);
+ setAction(&_sequenceManager, this, 4001, &_door, &_shipDisplay, NULL);
break;
case 15:
- setAction(&_sequenceManager, this, 4002, &_object4, &_object5, NULL);
+ setAction(&_sequenceManager, this, 4002, &_door, &_shipDisplay, NULL);
break;
case 17:
- setAction(&_sequenceManager, this, 4003, &_object4, &_object5, NULL);
+ setAction(&_sequenceManager, this, 4003, &_door, &_shipDisplay, NULL);
break;
case 19:
- setAction(&_sequenceManager, this, 4004, &_object4, &_object5, NULL);
+ setAction(&_sequenceManager, this, 4004, &_door, &_shipDisplay, NULL);
break;
case 21:
- setAction(&_sequenceManager, this, 4005, &_object4, &_object5, NULL);
+ setAction(&_sequenceManager, this, 4005, &_door, &_shipDisplay, NULL);
break;
case 23:
- setAction(&_sequenceManager, this, 4006, &_object4, &_object5, NULL);
+ setAction(&_sequenceManager, this, 4006, &_door, &_shipDisplay, NULL);
break;
case 25:
- setAction(&_sequenceManager, this, 4007, &_object4, &_object5, NULL);
+ setAction(&_sequenceManager, this, 4007, &_door, &_shipDisplay, NULL);
break;
case 27:
- _field412 = 0;
- _object4.remove();
- _object5.remove();
+ _helpEnabled = false;
+ _door.remove();
+ _shipDisplay.remove();
setSceneDelay(2);
break;
case 28:
- _field412 = 0;
+ _helpEnabled = false;
_palette.loadPalette(0);
_palette.loadPalette(9998);
R2_GLOBALS._scenePalette.addFader(_palette._palette, 256, 100, this);
break;
case 29:
- _field412 = 1;
+ _helpEnabled = true;
_animationPlayer._paletteMode = ANIMPALMODE_REPLACE_PALETTE;
- _animationPlayer._v = 1;
+ _animationPlayer._isActive = true;
_animationPlayer._objectMode = ANIMOBJMODE_42;
R2_GLOBALS._scene180Mode = 3;
_animationPlayer.load(3);
@@ -1719,12 +1735,12 @@ void Scene180::signal() {
case 31:
R2_GLOBALS._sound2.play(7);
- _object4.postInit();
- _object4.setVisage(76);
- _object4.setStrip(1);
- _object4.setFrame(1);
- _object4.setPosition(Common::Point(288, 143));
- _object4.fixPriority(210);
+ _door.postInit();
+ _door.setVisage(76);
+ _door.setStrip(1);
+ _door.setFrame(1);
+ _door.setPosition(Common::Point(288, 143));
+ _door.fixPriority(210);
loadScene(75);
@@ -1737,70 +1753,71 @@ void Scene180::signal() {
break;
case 32:
- _field412 = 1;
+ _helpEnabled = true;
- _object2.postInit();
- _object2.setPosition(Common::Point(161, 97));
- _object2.hide();
+ _teal.postInit();
+ _teal.setPosition(Common::Point(161, 97));
+ _teal.hide();
- _object3.postInit();
- _object3.setPosition(Common::Point(60, 96));
- _object3.hide();
- R2_GLOBALS._scenePalette.addFader(_palette._palette, 256, 11, this);
+ _webbster.postInit();
+ _webbster.setPosition(Common::Point(60, 96));
+ _webbster.hide();
+ _stripManager.start(11, this);
break;
case 33:
- _object2.hide();
+ _teal.hide();
- _object3.setup(76, 4, 1);
- _object3.setFrame(_object3.getFrameCount());
+ _webbster.setup(76, 4, 1);
+ _webbster.setFrame(_webbster.getFrameCount());
- _object5.postInit();
- _object5.setup(75, 1, 1);
- _object5.setPosition(Common::Point(221, 125));
- _object5.fixPriority(210);
- _object5.setAction(&_action1);
- R2_GLOBALS._scenePalette.addFader(_palette._palette, 256, 12, this);
+ _shipDisplay.postInit();
+ _shipDisplay.setup(75, 1, 1);
+ _shipDisplay.setPosition(Common::Point(221, 125));
+ _shipDisplay.fixPriority(210);
+ _shipDisplay.setAction(&_action1);
+ _stripManager.start(12, this);
break;
case 34:
- _object2.hide();
- _object3.hide();
+ _teal.hide();
+ _webbster.remove();
- _object1.postInit();
- _object1.setup(76, 2, 1);
- _object1.setPosition(Common::Point(287, 135));
- _object1.fixPriority(200);
+ _dutyOfficer.postInit();
+ _dutyOfficer.setup(76, 2, 1);
+ _dutyOfficer.setPosition(Common::Point(287, 135));
+ _dutyOfficer.fixPriority(200);
_sound1.play(19);
- R2_GLOBALS._scenePalette.addFader(_palette._palette, 256, 5, this);
+ _door.animate(ANIM_MODE_5, this);
break;
case 35:
- R2_GLOBALS._scenePalette.addFader(_palette._palette, 256, 13, this);
+ _stripManager.start(13, this);
break;
case 36:
- _object2.remove();
+ _teal.remove();
_sound1.play(19);
-
- R2_GLOBALS._scenePalette.addFader(_palette._palette, 256, 6, this);
+ _door.animate(ANIM_MODE_6, this);
break;
case 37:
- _field412 = 0;
- _object1.remove();
+ _helpEnabled = false;
+ _dutyOfficer.remove();
_palette.loadPalette(9998);
R2_GLOBALS._scenePalette.addFader(_palette._palette, 256, 8, this);
break;
case 38:
- _object4.remove();
- _object5.setAction(NULL);
- _object5.remove();
+ _door.remove();
+ _shipDisplay.setAction(NULL);
+ _shipDisplay.remove();
+ _backSurface.fillRect(Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT), 0);
+ R2_GLOBALS._screenSurface.fillRect(Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT), 0);
R2_GLOBALS._sound2.fadeOut2(NULL);
- R2_GLOBALS._sound1.fadeOut2(NULL);
+ R2_GLOBALS._sound1.fadeOut2(this);
break;
case 39:
@@ -1822,8 +1839,8 @@ void Scene180::signal() {
break;
case 41:
- _field412 = 1;
- _animationPlayer._v = 1;
+ _helpEnabled = true;
+ _animationPlayer._isActive = true;
break;
case 42:
@@ -1842,13 +1859,14 @@ void Scene180::signal() {
break;
case 45:
- R2_GLOBALS._scenePalette.addFader(_animationPlayer._subData._palData, 256, 28, this);
+ _helpEnabled = true;
+ _stripManager.start(28, this);
break;
case 48:
- _field412 = 1;
+ _helpEnabled = true;
_animationPlayer._paletteMode = ANIMPALMODE_NONE;
- _animationPlayer._v = 1;
+ _animationPlayer._isActive = true;
_animationPlayer._objectMode = ANIMOBJMODE_1;
R2_GLOBALS._scene180Mode = 15;
_animationPlayer.load(15, NULL);
@@ -1860,13 +1878,21 @@ void Scene180::signal() {
case 49:
R2_GLOBALS._scene180Mode = 15;
R2_GLOBALS._paneRefreshFlag[0] = 3;
+
+ _backSurface.fillRect(Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT), 0);
+ R2_GLOBALS._screenSurface.fillRect(Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT), 0);
+
setSceneDelay(1);
break;
case 50:
R2_GLOBALS._scene180Mode = 0;
- _field412 = 0;
- R2_GLOBALS._sceneManager.changeScene(100);
+ _helpEnabled = false;
+
+ // WORKAROUND: The original changed to scene 100 here, Quinn's Bedroom,
+ // but instead we're changing to the previously unused scene 50, which shows
+ // a closeup of Quinn in the floatation bed first
+ R2_GLOBALS._sceneManager.changeScene(50);
break;
}
}
@@ -1878,11 +1904,10 @@ void Scene180::setSceneDelay(int v) {
void Scene180::process(Event &event) {
if ((event.eventType == EVENT_KEYPRESS) && (event.kbd.keycode == Common::KEYCODE_ESCAPE)) {
- event.handled = 1;
- if (!_field412) {
- if (R2_GLOBALS._scenePalette._listeners.size() == 0) {
+ event.handled = true;
+ if (_helpEnabled) {
+ if (R2_GLOBALS._scenePalette._listeners.size() == 0)
HelpDialog::show();
- }
}
}
@@ -1905,9 +1930,9 @@ void Scene180::dispatch() {
}
}
- if (_animationPlayer._v) {
+ if (_animationPlayer._isActive) {
if (_animationPlayer.isCompleted()) {
- _animationPlayer._v = 0;
+ _animationPlayer._isActive = false;
_animationPlayer.close();
_animationPlayer.remove();
@@ -1991,9 +2016,9 @@ void Scene180::restore() {
*--------------------------------------------------------------------------*/
bool Scene200::NorthDoor::startAction(CursorType action, Event &event) {
- Scene200 *scene = (Scene200 *)R2_GLOBALS._sceneManager._scene;
-
if (action == CURSOR_USE) {
+ Scene200 *scene = (Scene200 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 202;
scene->setAction(&scene->_sequenceManager, scene, 202, &R2_GLOBALS._player, this, NULL);
@@ -2004,9 +2029,9 @@ bool Scene200::NorthDoor::startAction(CursorType action, Event &event) {
}
bool Scene200::EastDoor::startAction(CursorType action, Event &event) {
- Scene200 *scene = (Scene200 *)R2_GLOBALS._sceneManager._scene;
-
if (action == CURSOR_USE) {
+ Scene200 *scene = (Scene200 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 200;
scene->setAction(&scene->_sequenceManager, scene, 200, &R2_GLOBALS._player, this, NULL);
@@ -2017,9 +2042,9 @@ bool Scene200::EastDoor::startAction(CursorType action, Event &event) {
}
bool Scene200::WestDoor::startAction(CursorType action, Event &event) {
- Scene200 *scene = (Scene200 *)R2_GLOBALS._sceneManager._scene;
-
if (action == CURSOR_USE) {
+ Scene200 *scene = (Scene200 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 204;
scene->setAction(&scene->_sequenceManager, scene, 204, &R2_GLOBALS._player, this, NULL);
@@ -2329,11 +2354,21 @@ Scene205::Scene205(): SceneExt() {
GfxFont font;
font.setFontNumber(4);
_fontHeight = font.getHeight();
+
+ for (int i = 0; i < 3; i++) {
+ _starList1[i] = nullptr;
+ _starList2[i] = nullptr;
+ }
+
+ for (int i = 0; i < 4; i++)
+ _starList3[i] = nullptr;
}
void Scene205::postInit(SceneObjectList *OwnerList) {
- SceneExt::postInit();
loadScene(4000);
+ R2_GLOBALS._uiElements._active = false;
+ SceneExt::postInit();
+ R2_GLOBALS._interfaceY = SCREEN_HEIGHT;
R2_GLOBALS._player._uiEnabled = false;
R2_GLOBALS._sound1.play(337);
@@ -2348,11 +2383,11 @@ void Scene205::synchronize(Serializer &s) {
SceneExt::synchronize(s);
for (int idx = 0; idx < 3; ++idx)
- SYNC_POINTER(_objList1[idx]);
+ SYNC_POINTER(_starList1[idx]);
for (int idx = 0; idx < 3; ++idx)
- SYNC_POINTER(_objList2[idx]);
+ SYNC_POINTER(_starList2[idx]);
for (int idx = 0; idx < 4; ++idx)
- SYNC_POINTER(_objList3[idx]);
+ SYNC_POINTER(_starList3[idx]);
s.syncAsSint16LE(_textIndex);
s.syncAsSint16LE(_lineNum);
@@ -2374,9 +2409,9 @@ void Scene205::process(Event &event) {
}
void Scene205::dispatch() {
- processList(_objList3, 4, Common::Rect(0, 0, 319, 200), 1, 1, 160, 100);
- processList(_objList2, 3, Common::Rect(0, 0, 319, 200), 2, 2, 160, 100);
- processList(_objList1, 3, Common::Rect(0, 0, 319, 200), 4, 3, 160, 100);
+ processList(_starList3, 4, Common::Rect(0, 0, 319, 200), 1, 1, 160, 100);
+ processList(_starList2, 3, Common::Rect(0, 0, 319, 200), 2, 2, 160, 100);
+ processList(_starList1, 3, Common::Rect(0, 0, 319, 200), 4, 3, 160, 100);
Scene::dispatch();
}
@@ -2388,10 +2423,10 @@ void Scene205::setup() {
Common::Point(140, 149), Common::Point(91, 166), Common::Point(299, 46), Common::Point(314, 10)
};
- // Set up the first object list
+ // Set up the first star list
for (int idx = 0; idx < 3; ++idx) {
- Object *obj = new Object();
- _objList1[idx] = obj;
+ Star *obj = new Star();
+ _starList1[idx] = obj;
obj->postInit();
obj->_flags |= OBJFLAG_CLONED;
@@ -2404,10 +2439,10 @@ void Scene205::setup() {
obj->fixPriority(12);
}
- // Setup the second object list
+ // Setup the second star list
for (int idx = 0; idx < 3; ++idx) {
- Object *obj = new Object();
- _objList2[idx] = obj;
+ Star *obj = new Star();
+ _starList2[idx] = obj;
obj->postInit();
obj->_flags |= OBJFLAG_CLONED;
@@ -2420,10 +2455,10 @@ void Scene205::setup() {
obj->fixPriority(11);
}
- // Setup the third object list
+ // Setup the third star list
for (int idx = 0; idx < 4; ++idx) {
- Object *obj = new Object();
- _objList3[idx] = obj;
+ Star *obj = new Star();
+ _starList3[idx] = obj;
obj->postInit();
obj->_flags |= OBJFLAG_CLONED;
@@ -2440,10 +2475,10 @@ void Scene205::setup() {
/**
* Handles moving a group of stars in the scene background
*/
-void Scene205::processList(Object **ObjList, int count, const Common::Rect &bounds,
+void Scene205::processList(Star **ObjList, int count, const Common::Rect &bounds,
int xMultiply, int yMultiply, int xCenter, int yCenter) {
for (int idx = 0; idx < count; ++idx) {
- Object *obj = ObjList[idx];
+ Star *obj = ObjList[idx];
Common::Point pt(obj->_position.x - xCenter, obj->_position.y - yCenter);
if ((obj->_position.x <= 319) && (obj->_position.x >= 0) &&
@@ -2484,6 +2519,72 @@ void Scene205::handleText() {
}
/*--------------------------------------------------------------------------
+ * Scene 205 Demo - End of Demo
+ *
+ *--------------------------------------------------------------------------*/
+
+void Scene205Demo::Action1::signal() {
+ Scene205Demo *scene = (Scene205Demo *)R2_GLOBALS._sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ setDelay(2);
+ break;
+ case 1:
+ MessageDialog::show2(BUY_FULL_GAME_MSG, OK_BTN_STRING);
+ setDelay(1);
+ break;
+ case 2:
+ scene->leaveScene();
+ break;
+ default:
+ break;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+void Scene205Demo::leaveScene() {
+ if (g_globals->getFlag(85))
+ R2_GLOBALS._sceneManager.changeScene(160);
+ else
+ R2_GLOBALS._sceneManager.changeScene(R2_GLOBALS._sceneManager._previousScene);
+
+ BF_GLOBALS._scenePalette.loadPalette(0);
+ BF_GLOBALS._scenePalette.refresh();
+}
+
+void Scene205Demo::postInit(SceneObjectList *OwnerList) {
+ R2_GLOBALS._sceneManager._hasPalette = true;
+ R2_GLOBALS._scenePalette.loadPalette(0);
+
+ loadScene(1000);
+ R2_GLOBALS._uiElements._active = false;
+ R2_GLOBALS._player.enableControl();
+
+ SceneExt::postInit();
+
+ _sound1.play(337);
+ _stripManager.addSpeaker(&_animationPlayer);
+
+ setAction(&_action1);
+}
+
+void Scene205Demo::remove() {
+ R2_GLOBALS._sound1.fadeOut2(NULL);
+ SceneExt::remove();
+}
+
+void Scene205Demo::process(Event &event) {
+ if ((event.eventType == EVENT_KEYPRESS) && (event.kbd.keycode == Common::KEYCODE_ESCAPE)) {
+ event.handled = true;
+ leaveScene();
+ } else {
+ Scene::process(event);
+ }
+}
+
+/*--------------------------------------------------------------------------
* Scene 250 - Lift
*
*--------------------------------------------------------------------------*/
@@ -2499,10 +2600,10 @@ void Scene250::Button::synchronize(Serializer &s) {
}
bool Scene250::Button::startAction(CursorType action, Event &event) {
- Scene250 *scene = (Scene250 *)R2_GLOBALS._sceneManager._scene;
-
switch (action) {
- case CURSOR_USE:
+ case CURSOR_USE: {
+ Scene250 *scene = (Scene250 *)R2_GLOBALS._sceneManager._scene;
+
if (scene->_destButtonY) {
SceneItem::display2(250, 15);
} else {
@@ -2525,6 +2626,7 @@ bool Scene250::Button::startAction(CursorType action, Event &event) {
}
}
return true;
+ }
case CURSOR_LOOK:
switch (_floorNumber) {
@@ -2594,7 +2696,9 @@ void Scene250::synchronize(Serializer &s) {
void Scene250::postInit(SceneObjectList *OwnerList) {
loadScene(250);
+ R2_GLOBALS._uiElements._active = false;
SceneExt::postInit();
+ R2_GLOBALS._interfaceY = SCREEN_HEIGHT;
R2_GLOBALS._player.postInit();
R2_GLOBALS._player.setVisage(10);
@@ -2606,12 +2710,12 @@ void Scene250::postInit(SceneObjectList *OwnerList) {
_currentFloor.setup(250, 1, 5);
_currentFloor.setDetails(250, 13, -1, -1, 1, (SceneItem *)NULL);
- _button1.setFloor(11);
- _button1.setup(250, 1, 3);
- _button1.setPosition(Common::Point(400, 100));
- _button1.setDetails(250, 14, -1, -1, 1, (SceneItem *)NULL);
- _button1.fixPriority(190);
- _button1.hide();
+ _destinationFloor.setFloor(11);
+ _destinationFloor.setup(250, 1, 3);
+ _destinationFloor.setPosition(Common::Point(400, 100));
+ _destinationFloor.setDetails(250, 14, -1, -1, 1, (SceneItem *)NULL);
+ _destinationFloor.fixPriority(190);
+ _destinationFloor.hide();
_floor1.setFloor(1);
_floor2.setFloor(2);
@@ -2623,8 +2727,8 @@ void Scene250::postInit(SceneObjectList *OwnerList) {
_floor8.setFloor(8);
_floor9.setFloor(9);
- _item2.setDetails(Rect(0, 0, 73, SCREEN_HEIGHT), 250, 9, -1, 9, 1, NULL);
- _item4.setDetails(Rect(239, 16, 283, 164), 250, 6, -1, -1, 1, NULL);
+ _door.setDetails(Rect(0, 0, 73, SCREEN_HEIGHT), 250, 9, -1, 9, 1, NULL);
+ _directionIndicator.setDetails(Rect(239, 16, 283, 164), 250, 6, -1, -1, 1, NULL);
_background.setDetails(Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT), 250, 0, 1, -1, 1, NULL);
R2_GLOBALS._events.setCursor(CURSOR_USE);
@@ -2669,7 +2773,7 @@ void Scene250::signal() {
case 2:
if (_destButtonY - 12 == _currButtonY)
_sceneMode = 4;
- else
+ else
_sceneMode = 3;
signal();
@@ -2759,8 +2863,8 @@ void Scene250::signal() {
void Scene250::changeFloor(int floorNumber) {
_destButtonY = (floorNumber - 1) * 12 + 43;
- _button1.setPosition(Common::Point(111, _destButtonY));
- _button1.show();
+ _destinationFloor.setPosition(Common::Point(111, _destButtonY));
+ _destinationFloor.show();
_skippableFl = true;
_sceneMode = (_currButtonY >= _destButtonY) ? 6 : 1;
@@ -2871,14 +2975,14 @@ void Scene300::Action3::signal() {
void Scene300::Action4::signal() {
- Scene300 *scene = (Scene300 *)R2_GLOBALS._sceneManager._scene;
-
if (!R2_GLOBALS._playStream.isPlaying()) {
- scene->_object7.setStrip2(R2_GLOBALS._randomSource.getRandomNumber(2));
- scene->_object7.setFrame(1);
+ Scene300 *scene = (Scene300 *)R2_GLOBALS._sceneManager._scene;
+
+ scene->_mirandaScreen.setStrip2(R2_GLOBALS._randomSource.getRandomNumber(2));
+ scene->_mirandaScreen.setFrame(1);
- scene->_object9.setStrip2(3);
- scene->_object9.setFrame(1);
+ scene->_quinnScreen.setStrip2(3);
+ scene->_quinnScreen.setFrame(1);
}
setDelay(60 + R2_GLOBALS._randomSource.getRandomNumber(479));
@@ -2887,16 +2991,16 @@ void Scene300::Action4::signal() {
/*--------------------------------------------------------------------------*/
bool Scene300::QuinnWorkstation::startAction(CursorType action, Event &event) {
- Scene300 *scene = (Scene300 *)R2_GLOBALS._sceneManager._scene;
-
switch (action) {
case CURSOR_USE:
- if (R2_GLOBALS._player._characterIndex != 1)
+ if (R2_GLOBALS._player._characterIndex != R2_QUINN)
SceneItem::display2(300, 46);
else if (R2_GLOBALS.getFlag(44)) {
R2_GLOBALS._player.setAction(NULL);
R2_GLOBALS._sceneManager.changeScene(325);
} else {
+ Scene300 *scene = (Scene300 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 306;
scene->setAction(&scene->_sequenceManager1, scene, 306, &R2_GLOBALS._player, NULL);
@@ -2920,7 +3024,7 @@ bool Scene300::QuinnWorkstation::startAction(CursorType action, Event &event) {
bool Scene300::MirandaWorkstation::startAction(CursorType action, Event &event) {
switch (action) {
case CURSOR_USE:
- if (R2_GLOBALS._player._characterIndex != 3)
+ if (R2_GLOBALS._player._characterIndex != R2_MIRANDA)
SceneItem::display2(300, 49);
else
R2_GLOBALS._sceneManager.changeScene(325);
@@ -2950,7 +3054,7 @@ bool Scene300::SeekerWorkstation::startAction(CursorType action, Event &event) {
break;
case CURSOR_USE:
- if (R2_GLOBALS._player._characterIndex != 2)
+ if (R2_GLOBALS._player._characterIndex != R2_SEEKER)
SceneItem::display2(300, 48);
else
R2_GLOBALS._sceneManager.changeScene(325);
@@ -2996,7 +3100,7 @@ bool Scene300::Miranda::startAction(CursorType action, Event &event) {
if (!R2_GLOBALS.getFlag(57)) {
R2_GLOBALS._events.setCursor(CURSOR_ARROW);
scene->_stripManager.start3(434, scene, R2_GLOBALS._stripManager_lookupList);
- } else if (R2_GLOBALS._player._characterScene[R2_MIRANDA] != 500) {
+ } else if (R2_GLOBALS._player._characterScene[R2_SEEKER] != 500) {
R2_GLOBALS._events.setCursor(CURSOR_ARROW);
scene->_stripManager.start3(407, scene, R2_GLOBALS._stripManager_lookupList);
} else {
@@ -3117,10 +3221,10 @@ bool Scene300::Seeker::startAction(CursorType action, Event &event) {
}
bool Scene300::Quinn::startAction(CursorType action, Event &event) {
- Scene300 *scene = (Scene300 *)R2_GLOBALS._sceneManager._scene;
-
switch (action) {
- case CURSOR_TALK:
+ case CURSOR_TALK: {
+ Scene300 *scene = (Scene300 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.disableControl();
R2_GLOBALS._events.setCursor(CURSOR_ARROW);
scene->_sceneMode = 10;
@@ -3129,33 +3233,31 @@ bool Scene300::Quinn::startAction(CursorType action, Event &event) {
if (R2_GLOBALS._player._characterScene[R2_MIRANDA] == 500)
scene->_stripId = 442;
else if (!R2_GLOBALS.getFlag(44))
- scene->_stripId = 177 + R2_GLOBALS._randomSource.getRandomNumber(2);
+ scene->_stripId = 125 + R2_GLOBALS._randomSource.getRandomNumber(2);
else if (!R2_GLOBALS.getFlag(55))
- scene->_stripId = 208;
+ scene->_stripId = 439;
else
- scene->_stripId = 441;
- } else if (R2_GLOBALS._player._characterScene[R2_MIRANDA] == 500) {
- scene->_stripId = 442;
+ scene->_stripId = 210;
} else if (R2_GLOBALS.getFlag(44)) {
- scene->_stripId = R2_GLOBALS.getFlag(55) ? 441 : 208;
+ scene->_stripId = R2_GLOBALS.getFlag(55) ? 439 : 210;
} else {
- scene->_stripId = 125 + R2_GLOBALS._randomSource.getRandomNumber(2);
+ scene->_stripId = 177 + R2_GLOBALS._randomSource.getRandomNumber(2);
}
scene->_stripManager.start3(scene->_stripId, scene, R2_GLOBALS._stripManager_lookupList);
return true;
-
+ }
default:
return SceneActor::startAction(action, event);
}
}
bool Scene300::Doorway::startAction(CursorType action, Event &event) {
- Scene300 *scene = (Scene300 *)R2_GLOBALS._sceneManager._scene;
-
if (action == CURSOR_USE) {
if ((R2_GLOBALS._player._characterIndex == R2_QUINN) &&
(!R2_GLOBALS.getFlag(44) || R2_GLOBALS._player._characterScene[R2_SEEKER] == 500)) {
+ Scene300 *scene = (Scene300 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 301;
scene->setAction(&scene->_sequenceManager1, scene, 301, &R2_GLOBALS._player, this, NULL);
@@ -3211,29 +3313,29 @@ void Scene300::postInit(SceneObjectList *OwnerList) {
_rotation->_countdown = 1;
if (R2_GLOBALS.getFlag(51) && !R2_GLOBALS.getFlag(25)) {
- _object1.postInit();
- _object1.setup(301, 7, 2);
- _object1.setPosition(Common::Point(65, 24));
+ _atmosphereLeftWindow.postInit();
+ _atmosphereLeftWindow.setup(301, 7, 2);
+ _atmosphereLeftWindow.setPosition(Common::Point(65, 24));
- _object2.postInit();
- _object2.setup(301, 8, 2);
- _object2.setPosition(Common::Point(254, 24));
+ _atmosphereRightWindow.postInit();
+ _atmosphereRightWindow.setup(301, 8, 2);
+ _atmosphereRightWindow.setPosition(Common::Point(254, 24));
}
_doorway.postInit();
_doorway.setVisage(300);
_doorway.setPosition(Common::Point(159, 79));
- _object3.postInit();
- _object3.setup(300, 4, 1);
- _object3.setPosition(Common::Point(84, 48));
- _object3.animate(ANIM_MODE_2, NULL);
- _object3._numFrames = 5;
+ _leftVerticalBarsAnim.postInit();
+ _leftVerticalBarsAnim.setup(300, 4, 1);
+ _leftVerticalBarsAnim.setPosition(Common::Point(84, 48));
+ _leftVerticalBarsAnim.animate(ANIM_MODE_2, NULL);
+ _leftVerticalBarsAnim._numFrames = 5;
- _object4.postInit();
- _object4.setup(300, 5, 1);
- _object4.setPosition(Common::Point(236, 48));
- _object4.animate(ANIM_MODE_2, NULL);
+ _rightVerticalBarsAnim.postInit();
+ _rightVerticalBarsAnim.setup(300, 5, 1);
+ _rightVerticalBarsAnim.setPosition(Common::Point(236, 48));
+ _rightVerticalBarsAnim.animate(ANIM_MODE_2, NULL);
_protocolDisplay.postInit();
_protocolDisplay.setup(300, 6, 1);
@@ -3241,38 +3343,38 @@ void Scene300::postInit(SceneObjectList *OwnerList) {
_protocolDisplay.animate(ANIM_MODE_7, 0, NULL);
_protocolDisplay._numFrames = 5;
- _object6.postInit();
- _object6.setup(300, 7, 1);
- _object6.setPosition(Common::Point(214, 37));
- _object6.animate(ANIM_MODE_2, NULL);
- _object6._numFrames = 3;
-
- _object7.postInit();
- _object7.setup(301, 1, 1);
- _object7.setPosition(Common::Point(39, 97));
- _object7.fixPriority(124);
- _object7.animate(ANIM_MODE_2, NULL);
- _object7._numFrames = 5;
- _object7.setAction(&_action4);
-
- _object8.postInit();
- _object8.setup(300, 8, 1);
- _object8.setPosition(Common::Point(105, 37));
- _object8.animate(ANIM_MODE_2, NULL);
- _object8._numFrames = 5;
-
- _object9.postInit();
- _object9.setup(301, 6, 1);
- _object9.setPosition(Common::Point(274, 116));
- _object9.fixPriority(143);
- _object9.animate(ANIM_MODE_2, NULL);
- _object9._numFrames = 5;
+ _rightTextDisplay.postInit();
+ _rightTextDisplay.setup(300, 7, 1);
+ _rightTextDisplay.setPosition(Common::Point(214, 37));
+ _rightTextDisplay.animate(ANIM_MODE_2, NULL);
+ _rightTextDisplay._numFrames = 3;
+
+ _mirandaScreen.postInit();
+ _mirandaScreen.setup(301, 1, 1);
+ _mirandaScreen.setPosition(Common::Point(39, 97));
+ _mirandaScreen.fixPriority(124);
+ _mirandaScreen.animate(ANIM_MODE_2, NULL);
+ _mirandaScreen._numFrames = 5;
+ _mirandaScreen.setAction(&_action4);
+
+ _leftTextDisplay.postInit();
+ _leftTextDisplay.setup(300, 8, 1);
+ _leftTextDisplay.setPosition(Common::Point(105, 37));
+ _leftTextDisplay.animate(ANIM_MODE_2, NULL);
+ _leftTextDisplay._numFrames = 5;
+
+ _quinnScreen.postInit();
+ _quinnScreen.setup(301, 6, 1);
+ _quinnScreen.setPosition(Common::Point(274, 116));
+ _quinnScreen.fixPriority(143);
+ _quinnScreen.animate(ANIM_MODE_2, NULL);
+ _quinnScreen._numFrames = 5;
_quinnWorkstation1.setDetails(Rect(243, 148, 315, 167), 300, 30, 31, 32, 1, NULL);
_mirandaWorkstation1.setDetails(Rect(4, 128, 69, 167), 300, 33, 31, 35, 1, NULL);
switch (R2_GLOBALS._player._characterIndex) {
- case 1:
+ case R2_QUINN:
_miranda.postInit();
_miranda.setup(302, 2, 1);
_miranda.setPosition(Common::Point(47, 128));
@@ -3294,7 +3396,7 @@ void Scene300::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player.disableControl();
break;
- case 2:
+ case R2_SEEKER:
_miranda.postInit();
_miranda.setup(302, 2, 1);
_miranda.setPosition(Common::Point(47, 128));
@@ -3314,9 +3416,10 @@ void Scene300::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player.setPosition(Common::Point(158, 108));
R2_GLOBALS._player.fixPriority(130);
R2_GLOBALS._player.enableControl(CURSOR_USE);
+ R2_GLOBALS._player._canWalk = false;
break;
- case 3:
+ case R2_MIRANDA:
if ((R2_GLOBALS._player._characterScene[R2_SEEKER] == 300) || (R2_GLOBALS._player._characterScene[R2_SEEKER] == 325)) {
_seeker.postInit();
_seeker.setVisage(302);
@@ -3338,6 +3441,7 @@ void Scene300::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player.setup(302, 2, 1);
R2_GLOBALS._player.setPosition(Common::Point(47, 128));
R2_GLOBALS._player.enableControl(CURSOR_USE);
+ R2_GLOBALS._player._canWalk = false;
break;
default:
@@ -3361,7 +3465,7 @@ void Scene300::postInit(SceneObjectList *OwnerList) {
_background.setDetails(Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT), 300, 0, -1, -1, 1, NULL);
switch (R2_GLOBALS._player._characterIndex) {
- case 1:
+ case R2_QUINN:
_sceneMode = 300;
switch (R2_GLOBALS._sceneManager._previousScene) {
@@ -3450,11 +3554,11 @@ void Scene300::postInit(SceneObjectList *OwnerList) {
}
break;
- case 3:
+ case R2_MIRANDA:
if (R2_GLOBALS._sceneManager._previousScene == 1500) {
R2_GLOBALS._player._oldCharacterScene[R2_MIRANDA] = 3150;
R2_GLOBALS._player._characterScene[R2_MIRANDA] = 3150;
- R2_GLOBALS._player._effect = 0;
+ R2_GLOBALS._player._effect = EFFECT_NONE;
R2_GLOBALS._player.setAction(NULL);
R2_GLOBALS._player.disableControl();
@@ -3508,17 +3612,21 @@ void Scene300::signal() {
R2_GLOBALS.setFlag(40);
break;
case 5:
- if (R2_GLOBALS._stripManager_lookupList[1] == 6)
+ if (R2_GLOBALS._stripManager_lookupList[0] == 6)
R2_GLOBALS.setFlag(40);
break;
case 6:
- R2_GLOBALS._sceneManager.changeScene(1000);
+ if (g_vm->getFeatures() & GF_DEMO) {
+ R2_GLOBALS.setFlag(85);
+ R2_GLOBALS._sceneManager.changeScene(205);
+ } else
+ R2_GLOBALS._sceneManager.changeScene(1000);
break;
default:
break;
}
- _stripManager._field2E8 = 0;
+ _stripManager._currObj44Id = 0;
switch (_stripId) {
case 400:
R2_GLOBALS._player.disableControl();
@@ -3531,7 +3639,7 @@ void Scene300::signal() {
default:
R2_GLOBALS._player.enableControl(CURSOR_TALK);
- if ((R2_GLOBALS._player._characterIndex != 1) || R2_GLOBALS.getFlag(44))
+ if ((R2_GLOBALS._player._characterIndex != R2_QUINN) || R2_GLOBALS.getFlag(44))
R2_GLOBALS._player._canWalk = false;
break;
}
@@ -3573,8 +3681,14 @@ void Scene300::signal() {
case 16:
if (_stripManager._exitMode == 1) {
- R2_GLOBALS._player.setAction(NULL);
- R2_GLOBALS._sceneManager.changeScene(1000);
+ if (g_vm->getFeatures() & GF_DEMO) {
+ R2_GLOBALS._player.setAction(NULL);
+ R2_GLOBALS.setFlag(85);
+ R2_GLOBALS._sceneManager.changeScene(205);
+ } else {
+ R2_GLOBALS._player.setAction(NULL);
+ R2_GLOBALS._sceneManager.changeScene(1000);
+ }
} else {
R2_GLOBALS._player.setAction(&_action1);
R2_GLOBALS._player.enableControl(CURSOR_TALK);
@@ -3639,7 +3753,7 @@ void Scene300::signal() {
case 313:
_sceneMode = 14;
- R2_GLOBALS._player._effect = 0;
+ R2_GLOBALS._player._effect = EFFECT_NONE;
_seeker.setAction(&_sequenceManager3, this, 314, &_seeker, &_doorway, NULL);
R2_GLOBALS._events.setCursor(CURSOR_ARROW);
_stripManager.start(301, this);
@@ -3648,7 +3762,7 @@ void Scene300::signal() {
case 314:
R2_GLOBALS._player.disableControl();
_sceneMode = 315;
- R2_GLOBALS._player._effect = 1;
+ R2_GLOBALS._player._effect = EFFECT_SHADED;
setAction(&_sequenceManager1, this, 315, &R2_GLOBALS._player, &_doorway, NULL);
break;
@@ -3659,7 +3773,7 @@ void Scene300::signal() {
case 316:
R2_GLOBALS._player._characterScene[R2_SEEKER] = 500;
_seeker.remove();
- R2_GLOBALS._player.enableControl(CURSOR_CROSSHAIRS);
+ R2_GLOBALS._player.enableControl(CURSOR_WALK);
break;
case 317:
@@ -3680,6 +3794,8 @@ void Scene300::signal() {
}
void Scene300::signal309() {
+ // Sets up what conversation items will be available when to talking to the
+ // others on the Bridge, and will be set dependent on game flags
if (R2_GLOBALS.getFlag(2))
R2_GLOBALS._stripManager_lookupList[0] = (R2_INVENTORY.getObjectScene(R2_READER) == 1) ? 3 : 2;
@@ -3729,16 +3845,16 @@ const double ADJUST_FACTOR = 0.06419999999999999;
Scene325::Icon::Icon(): SceneActor() {
_lookLineNum = 0;
- _field98 = 0;
+ _iconId = 0;
_pressed = false;
}
void Scene325::Icon::postInit(SceneObjectList *OwnerList) {
SceneObject::postInit();
- _object1.postInit();
- _object1.fixPriority(21);
- _object1.hide();
+ _glyph.postInit();
+ _glyph.fixPriority(21);
+ _glyph.hide();
_sceneText1._color1 = 92;
_sceneText1._color2 = 0;
@@ -3752,7 +3868,7 @@ void Scene325::Icon::postInit(SceneObjectList *OwnerList) {
void Scene325::Icon::synchronize(Serializer &s) {
SceneActor::synchronize(s);
s.syncAsSint16LE(_lookLineNum);
- s.syncAsSint16LE(_field98);
+ s.syncAsSint16LE(_iconId);
s.syncAsSint16LE(_pressed);
}
@@ -3777,18 +3893,18 @@ void Scene325::Icon::process(Event &event) {
scene->_sound1.play(14);
setFrame(2);
- switch (_object1._strip) {
+ switch (_glyph._strip) {
case 1:
- _object1.setStrip(2);
+ _glyph.setStrip(2);
break;
case 3:
- _object1.setStrip(4);
+ _glyph.setStrip(4);
break;
case 5:
- _object1.setStrip(6);
+ _glyph.setStrip(6);
break;
case 7:
- _object1.setStrip(8);
+ _glyph.setStrip(8);
break;
default:
break;
@@ -3807,15 +3923,15 @@ void Scene325::Icon::process(Event &event) {
if ((event.eventType == EVENT_BUTTON_UP) && _pressed) {
setFrame(1);
- switch (_object1._strip) {
+ switch (_glyph._strip) {
case 2:
- _object1.setStrip(1);
+ _glyph.setStrip(1);
break;
case 4:
- _object1.setStrip(3);
+ _glyph.setStrip(3);
break;
case 6:
- _object1.setStrip(5);
+ _glyph.setStrip(5);
break;
default:
break;
@@ -3829,18 +3945,18 @@ void Scene325::Icon::process(Event &event) {
}
void Scene325::Icon::setIcon(int id) {
- Scene325 *scene = (Scene325 *)R2_GLOBALS._sceneManager._scene;
-
- _lookLineNum = _field98 = id;
+ _lookLineNum = _iconId = id;
SceneActor::_lookLineNum = id;
_sceneText1.remove();
_sceneText2.remove();
if (_lookLineNum) {
+ Scene325 *scene = (Scene325 *)R2_GLOBALS._sceneManager._scene;
+
showIcon();
- _object1.setup(325, ((id - 1) / 10) * 2 + 1, ((id - 1) % 10) + 1);
- _object1.setPosition(_position);
+ _glyph.setup(325, ((id - 1) / 10) * 2 + 1, ((id - 1) % 10) + 1);
+ _glyph.setPosition(_position);
_sceneText1._fontNumber = scene->_iconFontNumber;
_sceneText1.setup(CONSOLE325_MESSAGES[id]);
@@ -3881,26 +3997,26 @@ void Scene325::Icon::setIcon(int id) {
void Scene325::Icon::showIcon() {
_sceneText1.show();
_sceneText2.show();
- _object1.show();
- _object2.show();
+ _glyph.show();
+ _horizLine.show();
show();
}
void Scene325::Icon::hideIcon() {
_sceneText1.hide();
_sceneText2.hide();
- _object1.hide();
- _object2.hide();
+ _glyph.hide();
+ _horizLine.hide();
hide();
}
/*--------------------------------------------------------------------------*/
Scene325::Scene325(): SceneExt() {
- _field412 = 7;
+ _consoleAction = 7;
_iconFontNumber = 50;
- _field416 = _field418 = 0;
- _field41A = _field41C = _field41E = _scannerLocation = 0;
+ _databasePage = _priorConsoleAction = 0;
+ _moveCounter = _yChange = _yDirection = _scannerLocation = 0;
_soundCount = _soundIndex = 0;
for (int idx = 0; idx < 10; ++idx)
@@ -3919,7 +4035,7 @@ void Scene325::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player.hide();
R2_GLOBALS._player.disableControl();
- _item2.setDetails(1, 325, 3, 4, 5);
+ _terminal.setDetails(1, 325, 3, 4, 5);
_background.setDetails(Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT), 325, 0, 1, 2, 1, (SceneItem *)NULL);
_sceneMode = 1;
signal();
@@ -3928,13 +4044,13 @@ void Scene325::postInit(SceneObjectList *OwnerList) {
void Scene325::synchronize(Serializer &s) {
SceneExt::synchronize(s);
- s.syncAsSint16LE(_field412);
+ s.syncAsSint16LE(_consoleAction);
s.syncAsSint16LE(_iconFontNumber);
- s.syncAsSint16LE(_field416);
- s.syncAsSint16LE(_field418);
- s.syncAsSint16LE(_field41A);
- s.syncAsSint16LE(_field41C);
- s.syncAsSint16LE(_field41E);
+ s.syncAsSint16LE(_databasePage);
+ s.syncAsSint16LE(_priorConsoleAction);
+ s.syncAsSint16LE(_moveCounter);
+ s.syncAsSint16LE(_yChange);
+ s.syncAsSint16LE(_yDirection);
s.syncAsSint16LE(_scannerLocation);
s.syncAsSint16LE(_soundCount);
s.syncAsSint16LE(_soundIndex);
@@ -3967,28 +4083,28 @@ void Scene325::signal() {
case 1:
_icon1.setup(160, 1, 1);
_icon1.setPosition(Common::Point(65, 17));
- _icon1._object2.postInit();
- _icon1._object2.setup(160, 7, 1);
- _icon1._object2.setPosition(Common::Point(106, 41));
+ _icon1._horizLine.postInit();
+ _icon1._horizLine.setup(160, 7, 1);
+ _icon1._horizLine.setPosition(Common::Point(106, 41));
_icon2.setup(160, 1, 1);
_icon2.setPosition(Common::Point(80, 32));
- _icon2._object2.postInit();
- _icon2._object2.setup(160, 7, 2);
- _icon2._object2.setPosition(Common::Point(106, 56));
+ _icon2._horizLine.postInit();
+ _icon2._horizLine.setup(160, 7, 2);
+ _icon2._horizLine.setPosition(Common::Point(106, 56));
_icon3.setup(160, 1, 1);
_icon3.setPosition(Common::Point(65, 47));
- _icon3._object2.postInit();
- _icon3._object2.setup(160, 7, 1);
- _icon3._object2.setPosition(Common::Point(106, 71));
+ _icon3._horizLine.postInit();
+ _icon3._horizLine.setup(160, 7, 1);
+ _icon3._horizLine.setPosition(Common::Point(106, 71));
_icon4.setup(160, 1, 1);
_icon4.setPosition(Common::Point(80, 62));
_icon4._sceneRegionId = 5;
- _icon4._object2.postInit();
- _icon4._object2.setup(160, 7, 2);
- _icon4._object2.setPosition(Common::Point(106, 86));
+ _icon4._horizLine.postInit();
+ _icon4._horizLine.setup(160, 7, 2);
+ _icon4._horizLine.setPosition(Common::Point(106, 86));
_icon5.postInit();
_icon5.setup(160, 1, 1);
@@ -4007,29 +4123,33 @@ void Scene325::signal() {
R2_GLOBALS._player._canWalk = false;
break;
case 9:
- switch (_field412) {
+ // Fade to black for console sub-section: database, or starchart
+ switch (_consoleAction) {
case 3:
+ // Starchart
_sceneMode = 129;
- _object1.postInit();
- _object2.postInit();
- _object3.postInit();
+ _starGrid1.postInit();
+ _starGrid2.postInit();
+ _starGrid3.postInit();
if (R2_GLOBALS.getFlag(13)) {
- _object4.postInit();
- setAction(&_sequenceManager1, this, 130, &R2_GLOBALS._player, &_object1,
- &_object2, &_object3, &_object4, NULL);
+ // Show starchart with Ringworld present
+ _starGrid4.postInit();
+ setAction(&_sequenceManager1, this, 130, &R2_GLOBALS._player, &_starGrid1,
+ &_starGrid2, &_starGrid3, &_starGrid4, NULL);
} else {
- setAction(&_sequenceManager1, this, 129, &R2_GLOBALS._player, &_object1,
- &_object2, &_object3, NULL);
+ // Show starchart without Ringworld
+ setAction(&_sequenceManager1, this, 129, &R2_GLOBALS._player, &_starGrid1,
+ &_starGrid2, &_starGrid3, NULL);
}
break;
case 17:
case 18:
case 19:
case 20: {
- int v = 10 - ((21 - _field412) * 2);
+ int v = 10 - ((21 - _consoleAction) * 2);
if (R2_GLOBALS.getFlag(50))
--v;
- if (_field418 == 5)
+ if (_priorConsoleAction == 5)
v += 8;
if (R2_GLOBALS.getFlag(51) && (v == 2))
R2_GLOBALS.setFlag(57);
@@ -4040,70 +4160,70 @@ void Scene325::signal() {
} else {
_scannerLocation = 864;
- _object12.postInit();
- _object12.setup(326, 4, 1);
- _object12.setPosition(Common::Point(149, 128));
- _object12.fixPriority(20);
-
- _scannerTab.postInit();
- _scannerTab.setup(326, 4, 2);
- _scannerTab.setPosition(Common::Point(149, 22 + (int)(_scannerLocation * ADJUST_FACTOR)));
- _scannerTab.fixPriority(21);
-
- _object10.postInit();
- _object10.setup(326, 1, 1);
- _object10.setPosition(Common::Point(210, 20));
- _object10.fixPriority(10);
-
- _object1.postInit();
- _object1.setup(326, 1, 1);
- _object1.setPosition(Common::Point(210, 32));
- _object1.fixPriority(10);
-
- _object2.postInit();
- _object2.setup(326, 1, 1);
- _object2.setPosition(Common::Point(210, 44));
- _object2.fixPriority(10);
-
- _object3.postInit();
- _object3.setup(326, 1, 1);
- _object3.setPosition(Common::Point(210, 56));
- _object3.fixPriority(10);
-
- _object4.postInit();
- _object4.setup(326, 1, 1);
- _object4.setPosition(Common::Point(210, 68));
- _object4.fixPriority(10);
-
- _object5.postInit();
- _object5.setup(326, 1, 1);
- _object5.setPosition(Common::Point(210, 80));
- _object5.fixPriority(10);
-
- _object6.postInit();
- _object6.setup(326, 1, 1);
- _object6.setPosition(Common::Point(210, 92));
- _object6.fixPriority(10);
-
- _object7.postInit();
- _object7.setup(326, 1, 1);
- _object7.setPosition(Common::Point(210, 104));
- _object7.fixPriority(10);
-
- _object8.postInit();
- _object8.setup(326, 1, 1);
- _object8.setPosition(Common::Point(210, 116));
- _object8.fixPriority(10);
-
- _object9.postInit();
- _object9.setup(326, 1, 1);
- _object9.setPosition(Common::Point(210, 128));
- _object9.fixPriority(10);
-
- _object11.postInit();
- _object11.setup(326, 1, 1);
- _object11.setPosition(Common::Point(210, 150));
- _object11.fixPriority(10);
+ _starGrid12.postInit();
+ _starGrid12.setup(326, 4, 1);
+ _starGrid12.setPosition(Common::Point(149, 128));
+ _starGrid12.fixPriority(20);
+
+ _starGrid13.postInit();
+ _starGrid13.setup(326, 4, 2);
+ _starGrid13.setPosition(Common::Point(149, 22 + (int)(_scannerLocation * ADJUST_FACTOR)));
+ _starGrid13.fixPriority(21);
+
+ _starGrid10.postInit();
+ _starGrid10.setup(326, 1, 1);
+ _starGrid10.setPosition(Common::Point(210, 20));
+ _starGrid10.fixPriority(10);
+
+ _starGrid1.postInit();
+ _starGrid1.setup(326, 1, 1);
+ _starGrid1.setPosition(Common::Point(210, 32));
+ _starGrid1.fixPriority(10);
+
+ _starGrid2.postInit();
+ _starGrid2.setup(326, 1, 1);
+ _starGrid2.setPosition(Common::Point(210, 44));
+ _starGrid2.fixPriority(10);
+
+ _starGrid3.postInit();
+ _starGrid3.setup(326, 1, 1);
+ _starGrid3.setPosition(Common::Point(210, 56));
+ _starGrid3.fixPriority(10);
+
+ _starGrid4.postInit();
+ _starGrid4.setup(326, 1, 1);
+ _starGrid4.setPosition(Common::Point(210, 68));
+ _starGrid4.fixPriority(10);
+
+ _starGrid5.postInit();
+ _starGrid5.setup(326, 1, 1);
+ _starGrid5.setPosition(Common::Point(210, 80));
+ _starGrid5.fixPriority(10);
+
+ _starGrid6.postInit();
+ _starGrid6.setup(326, 1, 1);
+ _starGrid6.setPosition(Common::Point(210, 92));
+ _starGrid6.fixPriority(10);
+
+ _starGrid7.postInit();
+ _starGrid7.setup(326, 1, 1);
+ _starGrid7.setPosition(Common::Point(210, 104));
+ _starGrid7.fixPriority(10);
+
+ _starGrid8.postInit();
+ _starGrid8.setup(326, 1, 1);
+ _starGrid8.setPosition(Common::Point(210, 116));
+ _starGrid8.fixPriority(10);
+
+ _starGrid9.postInit();
+ _starGrid9.setup(326, 1, 1);
+ _starGrid9.setPosition(Common::Point(210, 128));
+ _starGrid9.fixPriority(10);
+
+ _starGrid11.postInit();
+ _starGrid11.setup(326, 1, 1);
+ _starGrid11.setPosition(Common::Point(210, 150));
+ _starGrid11.fixPriority(10);
}
} else if (R2_GLOBALS.getFlag(51)) {
setMessage(329, (v == 12) ? 10 : v);
@@ -4115,41 +4235,42 @@ void Scene325::signal() {
case 21:
_sceneMode = 129;
- _object1.postInit();
- _object1.setup(327, 1, 1);
- _object1.setPosition(Common::Point(170, 80));
- _object1.fixPriority(10);
- _object1.animate(ANIM_MODE_5, NULL);
+ _starGrid1.postInit();
+ _starGrid1.setup(327, 1, 1);
+ _starGrid1.setPosition(Common::Point(170, 80));
+ _starGrid1.fixPriority(10);
+ _starGrid1.animate(ANIM_MODE_5, NULL);
break;
case 22:
_sceneMode = 129;
- _object1.postInit();
- _object1.setup(327, 2, 1);
- _object1.setPosition(Common::Point(160, 80));
- _object1.fixPriority(10);
- _object1.animate(ANIM_MODE_5, NULL);
+ _starGrid1.postInit();
+ _starGrid1.setup(327, 2, 1);
+ _starGrid1.setPosition(Common::Point(160, 80));
+ _starGrid1.fixPriority(10);
+ _starGrid1.animate(ANIM_MODE_5, NULL);
break;
case 24:
R2_GLOBALS._player.enableControl();
R2_GLOBALS._player._canWalk = false;
- _field416 = 37;
- setMessage(128, _field416);
+ _databasePage = 37;
+ setMessage(128, _databasePage);
break;
case 25:
R2_GLOBALS._player.enableControl();
R2_GLOBALS._player._canWalk = false;
- _field416 = 68;
- setMessage(128, _field416);
+ _databasePage = 68;
+ setMessage(128, _databasePage);
break;
case 26:
R2_GLOBALS._player.enableControl();
R2_GLOBALS._player._canWalk = false;
- _field416 = 105;
- setMessage(128, _field416);
+ _databasePage = 105;
+ setMessage(128, _databasePage);
break;
default:
- _field416 = 0;
+ _databasePage = 0;
+ setMessage(128, _databasePage);
break;
}
@@ -4160,7 +4281,7 @@ void Scene325::signal() {
R2_GLOBALS._player.enableControl();
R2_GLOBALS._player._canWalk = false;
- if ((_field412 >= 17) && (_field412 <= 20)) {
+ if ((_consoleAction >= 17) && (_consoleAction <= 20)) {
_icon5.setIcon(8);
consoleAction(4);
} else {
@@ -4211,7 +4332,7 @@ void Scene325::consoleAction(int id) {
if (id == 7)
_icon5.setIcon(9);
- else if ((_field412 != 3) && ((_field412 < 17) || (_field412 > 26)))
+ else if ((_consoleAction != 3) && ((_consoleAction < 17) || (_consoleAction > 26)))
_icon5.setIcon(8);
switch (id - 1) {
@@ -4220,10 +4341,12 @@ void Scene325::consoleAction(int id) {
_icon2.setIcon(11);
break;
case 1:
+ // Database screen
_icon1.setIcon(23);
_icon2.setIcon(24);
_icon3.setIcon(25);
_icon4.setIcon(26);
+ break;
case 2:
case 16:
case 17:
@@ -4237,13 +4360,13 @@ void Scene325::consoleAction(int id) {
_icon2.hideIcon();
_icon3.hideIcon();
- if (id == 2 || (id == 19 && _field418 == 5 && R2_GLOBALS.getFlag(50) &&
+ if (id == 2 || (id == 19 && _priorConsoleAction == 5 && R2_GLOBALS.getFlag(50) &&
R2_GLOBALS.getFlag(44) && !R2_GLOBALS.getFlag(51))) {
_icon5.setIcon(13);
_icon4.setPosition(Common::Point(52, 107));
_icon4._sceneRegionId = 9;
_icon4.setIcon(14);
- _icon4._object2.hide();
+ _icon4._horizLine.hide();
} else {
_icon4.hideIcon();
@@ -4253,16 +4376,17 @@ void Scene325::consoleAction(int id) {
_icon6.setIcon(12);
_sceneMode = 10;
_palette.loadPalette(161);
- BF_GLOBALS._scenePalette.addFader(&_palette._palette[0], 256, 5, this);
+ R2_GLOBALS._scenePalette.addFader(&_palette._palette[0], 256, 5, this);
break;
case 22:
case 23:
case 24:
case 25:
+ // Database sub-sections: A-G, N-O, P-S, T-Z
R2_GLOBALS._player.disableControl();
consoleAction(2);
- _field412 = id;
+ _consoleAction = id;
_icon1.hideIcon();
_icon2.hideIcon();
_icon3.hideIcon();
@@ -4272,12 +4396,12 @@ void Scene325::consoleAction(int id) {
_icon4.setPosition(Common::Point(52, 107));
_icon4._sceneRegionId = 9;
_icon4.setIcon(14);
- _icon4._object2.hide();
+ _icon4._horizLine.hide();
_icon6.setIcon(12);
_sceneMode = 10;
_palette.loadPalette(161);
- BF_GLOBALS._scenePalette.addFader(&_palette._palette[0], 256, 5, this);
+ R2_GLOBALS._scenePalette.addFader(&_palette._palette[0], 256, 5, this);
break;
case 11:
@@ -4295,24 +4419,25 @@ void Scene325::consoleAction(int id) {
_icon4._sceneRegionId = 5;
_icon4.hideIcon();
- _object12.remove();
- _scannerTab.remove();
- _object10.remove();
- _object1.remove();
- _object2.remove();
- _object3.remove();
- _object4.remove();
- _object5.remove();
- _object6.remove();
- _object7.remove();
- _object8.remove();
- _object9.remove();
- _object11.remove();
+ R2_GLOBALS._player.hide();
+ _starGrid1.remove();
+ _starGrid2.remove();
+ _starGrid3.remove();
+ _starGrid4.remove();
+ _starGrid5.remove();
+ _starGrid6.remove();
+ _starGrid7.remove();
+ _starGrid8.remove();
+ _starGrid9.remove();
+ _starGrid10.remove();
+ _starGrid11.remove();
+ _starGrid12.remove();
+ _starGrid13.remove();
_palette.loadPalette(160);
_sceneMode = 11;
- BF_GLOBALS._scenePalette.addFader(&_palette._palette[0], 256, 5, this);
+ R2_GLOBALS._scenePalette.addFader(&_palette._palette[0], 256, 5, this);
}
break;
@@ -4323,63 +4448,73 @@ void Scene325::consoleAction(int id) {
break;
case 4:
case 5:
- _field418 = id;
+ _priorConsoleAction = id;
_icon1.setIcon(17);
_icon2.setIcon(18);
_icon3.setIcon(19);
_icon4.setIcon(20);
break;
case 7:
- consoleAction(((_field412 == 5) || (_field412 == 6) || (_field412 == 15)) ? 4 : 7);
+ consoleAction(((_consoleAction == 5) || (_consoleAction == 6) || (_consoleAction == 15)) ? 4 : 7);
break;
case 8:
R2_GLOBALS._sceneManager.changeScene(300);
+ break;
case 9:
case 10:
+ // Set language: Interworld or Hero's Tongue
_iconFontNumber = (id - 1) == 9 ? 50 : 52;
_text1.remove();
_icon6.setIcon(7);
+ consoleAction(1);
break;
case 12:
+ // Page up button
_icon4.setIcon(14);
- _icon4._object2.hide();
+ _icon4._horizLine.hide();
- switch (_field412) {
+ switch (_consoleAction) {
case 17:
case 18:
case 19:
case 20:
if (_scannerLocation) {
R2_GLOBALS._player.disableControl();
- _field41A = 1296;
- _field41E = 1;
+ _moveCounter = 1296;
+ _yDirection = 1;
}
break;
default:
- setMessage(128, --_field416);
+ setMessage(128, --_databasePage);
break;
}
return;
case 13:
+ // Page down button
_icon4.setIcon(14);
- _icon4._object2.hide();
+ _icon4._horizLine.hide();
- switch (_field412) {
+ switch (_consoleAction) {
case 17:
case 18:
case 19:
case 20:
if (_scannerLocation < 1620) {
R2_GLOBALS._player.disableControl();
- _field41A = 1296;
- _field41E = -1;
+ _moveCounter = 1296;
+ _yDirection = -1;
}
break;
+ default:
+ setMessage(128, ++_databasePage);
+ break;
}
return;
case 14:
if (R2_GLOBALS.getFlag(55)) {
- SceneItem::display2(329, 17);
+ consoleAction(4);
+ // Empty message crashing the game. It should be a warning message forbidding to switch to active scan
+ // SceneItem::display2(329, 17);
} else {
R2_GLOBALS.setFlag(50);
consoleAction(4);
@@ -4393,6 +4528,7 @@ void Scene325::consoleAction(int id) {
break;
case 6:
default:
+ // Initial starting screen
_icon1.setIcon(1);
_icon2.setIcon(2);
_icon3.setIcon(3);
@@ -4402,7 +4538,7 @@ void Scene325::consoleAction(int id) {
}
if (id != 8)
- _field412 = id;
+ _consoleAction = id;
}
void Scene325::process(Event &event) {
@@ -4419,48 +4555,48 @@ void Scene325::process(Event &event) {
}
void Scene325::dispatch() {
- if (_field41A) {
- switch (_field41A) {
+ if (_moveCounter) {
+ switch (_moveCounter) {
case 13:
- _field41C = 1;
+ _yChange = 1;
break;
case 1296:
R2_GLOBALS._sound3.play(87);
- _field41C = 1;
+ _yChange = 1;
break;
case 33:
case 1283:
- _field41C = 2;
+ _yChange = 2;
break;
case 63:
case 1263:
- _field41C = 3;
+ _yChange = 3;
break;
case 103:
case 1233:
- _field41C = 4;
+ _yChange = 4;
break;
case 153:
case 1193:
- _field41C = 5;
+ _yChange = 5;
break;
case 213:
case 1143:
- _field41C = 6;
+ _yChange = 6;
break;
case 283:
case 1083:
- _field41C = 7;
+ _yChange = 7;
break;
case 1013:
- _field41C = 8;
+ _yChange = 8;
break;
default:
break;
}
- _field41A -= _field41C;
- int yp = _field41E * _field41C + _object10._position.y;
+ _moveCounter -= _yChange;
+ int yp = _yDirection * _yChange + _starGrid10._position.y;
bool flag = false;
if (yp >= 30) {
@@ -4473,51 +4609,51 @@ void Scene325::dispatch() {
++_scannerLocation;
flag = true;
}
- _scannerTab.setPosition(Common::Point(149, 22 + (int)(_scannerLocation * ADJUST_FACTOR)));
+ _starGrid13.setPosition(Common::Point(149, 22 + (int)(_scannerLocation * ADJUST_FACTOR)));
for (int idx = 0; idx < 4; ++idx)
_objList[idx].remove();
if (flag) {
int v = _scannerLocation - 758;
- _object10.setFrame((v++ <= 0) ? 1 : v);
- _object1.setFrame((v++ <= 0) ? 1 : v);
- _object2.setFrame((v++ <= 0) ? 1 : v);
- _object3.setFrame((v++ <= 0) ? 1 : v);
- _object4.setFrame((v++ <= 0) ? 1 : v);
- _object5.setFrame((v++ <= 0) ? 1 : v);
- _object6.setFrame((v++ <= 0) ? 1 : v);
- _object7.setFrame((v++ <= 0) ? 1 : v);
- _object8.setFrame((v++ <= 0) ? 1 : v);
- _object9.setFrame((v++ <= 0) ? 1 : v);
- _object11.setFrame((v++ <= 0) ? 1 : v);
- }
-
- _object10.setPosition(Common::Point(210, yp));
+ _starGrid10.setFrame((v++ <= 0) ? 1 : v);
+ _starGrid1.setFrame((v++ <= 0) ? 1 : v);
+ _starGrid2.setFrame((v++ <= 0) ? 1 : v);
+ _starGrid3.setFrame((v++ <= 0) ? 1 : v);
+ _starGrid4.setFrame((v++ <= 0) ? 1 : v);
+ _starGrid5.setFrame((v++ <= 0) ? 1 : v);
+ _starGrid6.setFrame((v++ <= 0) ? 1 : v);
+ _starGrid7.setFrame((v++ <= 0) ? 1 : v);
+ _starGrid8.setFrame((v++ <= 0) ? 1 : v);
+ _starGrid9.setFrame((v++ <= 0) ? 1 : v);
+ _starGrid11.setFrame((v++ <= 0) ? 1 : v);
+ }
+
+ _starGrid10.setPosition(Common::Point(210, yp));
yp += 12;
- _object1.setPosition(Common::Point(210, yp));
+ _starGrid1.setPosition(Common::Point(210, yp));
yp += 12;
- _object2.setPosition(Common::Point(210, yp));
+ _starGrid2.setPosition(Common::Point(210, yp));
yp += 12;
- _object3.setPosition(Common::Point(210, yp));
+ _starGrid3.setPosition(Common::Point(210, yp));
yp += 12;
- _object4.setPosition(Common::Point(210, yp));
+ _starGrid4.setPosition(Common::Point(210, yp));
yp += 12;
- _object5.setPosition(Common::Point(210, yp));
+ _starGrid5.setPosition(Common::Point(210, yp));
yp += 12;
- _object6.setPosition(Common::Point(210, yp));
+ _starGrid6.setPosition(Common::Point(210, yp));
yp += 12;
- _object7.setPosition(Common::Point(210, yp));
+ _starGrid7.setPosition(Common::Point(210, yp));
yp += 12;
- _object8.setPosition(Common::Point(210, yp));
+ _starGrid8.setPosition(Common::Point(210, yp));
yp += 12;
- _object9.setPosition(Common::Point(210, yp));
+ _starGrid9.setPosition(Common::Point(210, yp));
yp += 12;
- _object11.setPosition(Common::Point(210, yp));
+ _starGrid11.setPosition(Common::Point(210, yp));
- if (!_field41A) {
+ if (!_moveCounter) {
R2_GLOBALS._sound3.stop();
- _field41C = 0;
+ _yChange = 0;
if (_scannerLocation == 756) {
R2_GLOBALS._player.disableControl();
@@ -4535,9 +4671,11 @@ void Scene325::dispatch() {
}
void Scene325::setMessage(int resNum, int lineNum) {
- Common::String msg = g_resourceManager->getMessage(resNum, lineNum);
+ removeText();
+ Common::String msg = g_resourceManager->getMessage(resNum, lineNum, true);
if (!msg.empty()) {
+ // Found valid database entry to display
Common::String msgText = parseMessage(msg);
_text1._fontNumber = _iconFontNumber;
@@ -4555,7 +4693,9 @@ void Scene325::setMessage(int resNum, int lineNum) {
R2_GLOBALS._playStream.play(_soundQueue[_soundIndex++], this);
}
} else {
- _field412 = 13;
+ // No message for given database index, so we must have passed beyond
+ // the start or end of the database
+ _consoleAction = 13;
R2_GLOBALS._player.disableControl();
R2_GLOBALS._player.hide();
@@ -4565,7 +4705,7 @@ void Scene325::setMessage(int resNum, int lineNum) {
_palette.loadPalette(160);
_sceneMode = 11;
- BF_GLOBALS._scenePalette.addFader(&_palette._palette[0], 256, 5, this);
+ R2_GLOBALS._scenePalette.addFader(&_palette._palette[0], 256, 5, this);
}
}
@@ -4587,15 +4727,16 @@ Common::String Scene325::parseMessage(const Common::String &msg) {
return Common::String(msgP);
}
+
/*--------------------------------------------------------------------------
* Scene 400 - Science Lab
*
*--------------------------------------------------------------------------*/
bool Scene400::Terminal::startAction(CursorType action, Event &event) {
- Scene400 *scene = (Scene400 *)R2_GLOBALS._sceneManager._scene;
-
if (action == CURSOR_USE) {
+ Scene400 *scene = (Scene400 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 402;
scene->setAction(&scene->_sequenceManager1, scene, 402, &R2_GLOBALS._player, this, NULL);
@@ -4609,9 +4750,9 @@ bool Scene400::Terminal::startAction(CursorType action, Event &event) {
/*--------------------------------------------------------------------------*/
bool Scene400::Door::startAction(CursorType action, Event &event) {
- Scene400 *scene = (Scene400 *)R2_GLOBALS._sceneManager._scene;
-
if (action == CURSOR_USE) {
+ Scene400 *scene = (Scene400 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 401;
scene->setAction(&scene->_sequenceManager1, scene, 401, &R2_GLOBALS._player, this, NULL);
@@ -4623,9 +4764,9 @@ bool Scene400::Door::startAction(CursorType action, Event &event) {
}
bool Scene400::Reader::startAction(CursorType action, Event &event) {
- Scene400 *scene = (Scene400 *)R2_GLOBALS._sceneManager._scene;
-
if (action == CURSOR_USE) {
+ Scene400 *scene = (Scene400 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 405;
scene->setAction(&scene->_sequenceManager1, scene, 405, &R2_GLOBALS._player, this, NULL);
@@ -4637,9 +4778,9 @@ bool Scene400::Reader::startAction(CursorType action, Event &event) {
}
bool Scene400::SensorProbe::startAction(CursorType action, Event &event) {
- Scene400 *scene = (Scene400 *)R2_GLOBALS._sceneManager._scene;
-
if (action == CURSOR_USE) {
+ Scene400 *scene = (Scene400 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 404;
scene->setAction(&scene->_sequenceManager1, scene, 404, &R2_GLOBALS._player, this, NULL);
@@ -4651,9 +4792,9 @@ bool Scene400::SensorProbe::startAction(CursorType action, Event &event) {
}
bool Scene400::AttractorUnit::startAction(CursorType action, Event &event) {
- Scene400 *scene = (Scene400 *)R2_GLOBALS._sceneManager._scene;
-
if (action == CURSOR_USE) {
+ Scene400 *scene = (Scene400 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 406;
scene->setAction(&scene->_sequenceManager1, scene, 406, &R2_GLOBALS._player, this, NULL);
@@ -4667,8 +4808,9 @@ bool Scene400::AttractorUnit::startAction(CursorType action, Event &event) {
/*--------------------------------------------------------------------------*/
void Scene400::postInit(SceneObjectList *OwnerList) {
- SceneExt::postInit();
loadScene(400);
+ SceneExt::postInit();
+
_sound1.play(20);
_door.postInit();
@@ -4832,9 +4974,9 @@ Scene500::PanelDialog::Button::Button() {
}
bool Scene500::ControlPanel::startAction(CursorType action, Event &event) {
- Scene500 *scene = (Scene500 *)R2_GLOBALS._sceneManager._scene;
-
if ((action == CURSOR_USE) && (R2_GLOBALS._player._characterIndex == R2_QUINN)) {
+ Scene500 *scene = (Scene500 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.disableControl();
if (R2_GLOBALS.getFlag(26)) {
@@ -4854,9 +4996,9 @@ bool Scene500::ControlPanel::startAction(CursorType action, Event &event) {
/*--------------------------------------------------------------------------*/
bool Scene500::Seeker::startAction(CursorType action, Event &event) {
- Scene500 *scene = (Scene500 *)R2_GLOBALS._sceneManager._scene;
-
if (action == CURSOR_TALK) {
+ Scene500 *scene = (Scene500 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.disableControl();
if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
scene->_stripNumber = R2_GLOBALS.getFlag(26) ? 1101 : 1103;
@@ -4927,9 +5069,9 @@ bool Scene500::Suit::startAction(CursorType action, Event &event) {
}
bool Scene500::Doorway::startAction(CursorType action, Event &event) {
- Scene500 *scene = (Scene500 *)R2_GLOBALS._sceneManager._scene;
-
if ((action == CURSOR_USE) && (R2_GLOBALS._player._characterIndex == R2_QUINN)) {
+ Scene500 *scene = (Scene500 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.disableControl();
if (R2_GLOBALS.getFlag(26)) {
@@ -4948,8 +5090,6 @@ bool Scene500::Doorway::startAction(CursorType action, Event &event) {
}
bool Scene500::OxygenTanks::startAction(CursorType action, Event &event) {
- Scene500 *scene = (Scene500 *)R2_GLOBALS._sceneManager._scene;
-
switch (action) {
case CURSOR_LOOK:
SceneItem::display2(500, R2_INVENTORY.getObjectScene(R2_REBREATHER_TANK) ? 50 : 49);
@@ -4961,6 +5101,8 @@ bool Scene500::OxygenTanks::startAction(CursorType action, Event &event) {
return true;
} else if ((R2_INVENTORY.getObjectScene(R2_REBREATHER_TANK) != 1) &&
(R2_GLOBALS._player._characterIndex != R2_SEEKER) && !R2_GLOBALS.getFlag(28)) {
+ Scene500 *scene = (Scene500 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.disableControl();
if (_position.y == 120) {
@@ -4984,9 +5126,9 @@ bool Scene500::OxygenTanks::startAction(CursorType action, Event &event) {
}
bool Scene500::AirLock::startAction(CursorType action, Event &event) {
- Scene500 *scene = (Scene500 *)R2_GLOBALS._sceneManager._scene;
-
if ((action == CURSOR_USE) && R2_GLOBALS.getFlag(26)) {
+ Scene500 *scene = (Scene500 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.disableControl();
scene->_sceneMode = (R2_GLOBALS._player._characterIndex == R2_QUINN) ? 521 : 522;
scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player,
@@ -4997,10 +5139,43 @@ bool Scene500::AirLock::startAction(CursorType action, Event &event) {
}
}
-bool Scene500::Aerosol::startAction(CursorType action, Event &event) {
- Scene500 *scene = (Scene500 *)R2_GLOBALS._sceneManager._scene;
+void Scene500::TransparentDoor::draw() {
+ // Determine the area of the screen to be updated
+ Rect destRect = _bounds;
+ destRect.translate(-g_globals->_sceneManager._scene->_sceneBounds.left,
+ -g_globals->_sceneManager._scene->_sceneBounds.top);
+
+ // Get the frame to be drawn
+ GfxSurface frame = getFrame();
+
+ Graphics::Surface s = frame.lockSurface();
+ Graphics::Surface screen = g_globals->gfxManager().getSurface().lockSurface();
+
+ for (int yp = 0; yp < s.h; ++yp) {
+ byte *frameSrcP = (byte *)s.getBasePtr(0, yp);
+ byte *screenP = (byte *)screen.getBasePtr(destRect.left, destRect.top + yp);
+
+ for (int xp = 0; xp < s.w; ++xp, ++frameSrcP, ++screenP) {
+ if (*frameSrcP != frame._transColor && *frameSrcP < 6) {
+ *frameSrcP = R2_GLOBALS._fadePaletteMap[*frameSrcP][*screenP];
+ }
+ }
+ }
+ // Finished updating the frame
+ frame.unlockSurface();
+ g_globals->gfxManager().getSurface().unlockSurface();
+
+ // Draw the processed frame
+ Region *priorityRegion = g_globals->_sceneManager._scene->_priorities.find(_priority);
+ g_globals->gfxManager().copyFrom(frame, destRect, priorityRegion);
+
+}
+
+bool Scene500::Aerosol::startAction(CursorType action, Event &event) {
if (action == CURSOR_USE) {
+ Scene500 *scene = (Scene500 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 503;
scene->setAction(&scene->_sequenceManager1, scene, 503, &R2_GLOBALS._player, this, NULL);
@@ -5011,9 +5186,9 @@ bool Scene500::Aerosol::startAction(CursorType action, Event &event) {
}
bool Scene500::SonicStunner::startAction(CursorType action, Event &event) {
- Scene500 *scene = (Scene500 *)R2_GLOBALS._sceneManager._scene;
-
if ((action == CURSOR_USE) && (R2_GLOBALS._player._characterIndex == R2_QUINN)) {
+ Scene500 *scene = (Scene500 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.disableControl();
scene->_sceneMode = R2_GLOBALS.getFlag(26) ? 520 : 502;
scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player, this, NULL);
@@ -5024,9 +5199,9 @@ bool Scene500::SonicStunner::startAction(CursorType action, Event &event) {
}
bool Scene500::Locker1::startAction(CursorType action, Event &event) {
- Scene500 *scene = (Scene500 *)R2_GLOBALS._sceneManager._scene;
-
if ((action == CURSOR_USE) && (R2_GLOBALS._player._characterIndex == R2_QUINN)) {
+ Scene500 *scene = (Scene500 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.disableControl();
if (R2_GLOBALS.getFlag(11))
@@ -5042,9 +5217,9 @@ bool Scene500::Locker1::startAction(CursorType action, Event &event) {
}
bool Scene500::Locker2::startAction(CursorType action, Event &event) {
- Scene500 *scene = (Scene500 *)R2_GLOBALS._sceneManager._scene;
-
if ((action == CURSOR_USE) && (R2_GLOBALS._player._characterIndex == R2_QUINN)) {
+ Scene500 *scene = (Scene500 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.disableControl();
if (R2_GLOBALS.getFlag(12))
@@ -5061,7 +5236,7 @@ bool Scene500::Locker2::startAction(CursorType action, Event &event) {
/*--------------------------------------------------------------------------*/
-void Scene500::PanelDialog::setDetails(int visage, int strip, int frameNumber,
+void Scene500::PanelDialog::setDetails(int visage, int strip, int frameNumber,
const Common::Point &pt) {
SceneAreaObject::setDetails(visage, strip, frameNumber, pt);
SceneAreaObject::setDetails(500, 43, 32, 45);
@@ -5072,7 +5247,7 @@ void Scene500::PanelDialog::setDetails(int visage, int strip, int frameNumber,
}
void Scene500::PanelDialog::remove() {
- Scene500 *scene = (Scene500 *)BF_GLOBALS._sceneManager._scene;
+ Scene500 *scene = (Scene500 *)R2_GLOBALS._sceneManager._scene;
scene->_sceneAreas.remove(&_button1);
scene->_sceneAreas.remove(&_button2);
scene->_sceneAreas.remove(&_button3);
@@ -5117,7 +5292,7 @@ void Scene500::PanelDialog::Button::setupButton(int buttonId) {
break;
}
- Scene500 *scene = (Scene500 *)BF_GLOBALS._sceneManager._scene;
+ Scene500 *scene = (Scene500 *)R2_GLOBALS._sceneManager._scene;
scene->_sceneAreas.push_front(this);
}
@@ -5129,7 +5304,7 @@ void Scene500::PanelDialog::Button::synchronize(Serializer &s) {
}
void Scene500::PanelDialog::Button::process(Event &event) {
- if ((event.eventType == EVENT_BUTTON_DOWN) &&
+ if ((event.eventType == EVENT_BUTTON_DOWN) &&
(R2_GLOBALS._events.getCursor() == CURSOR_USE) &&
_bounds.contains(event.mousePos) && !_buttonDown) {
_buttonDown = true;
@@ -5147,58 +5322,60 @@ void Scene500::PanelDialog::Button::process(Event &event) {
}
void Scene500::PanelDialog::Button::doButtonPress() {
- Scene500 *scene = (Scene500 *)R2_GLOBALS._sceneManager._scene;
-
if (R2_GLOBALS.getFlag(28)) {
SceneItem::display2(500, 48);
} else {
+ Scene500 *scene = (Scene500 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.disableControl();
scene->_sceneMode = _buttonId;
switch (_buttonId) {
case 1:
+ // Rotate Left
if (--R2_GLOBALS._landerSuitNumber == 0)
- R2_GLOBALS._landerSuitNumber = 3;
+ R2_GLOBALS._landerSuitNumber = R2_MIRANDA;
if (R2_GLOBALS.getFlag(35)) {
scene->_sceneMode = 5;
- scene->setAction(&scene->_sequenceManager1, scene, 509, &scene->_object1,
- &scene->_suit, &scene->_object8, NULL);
+ scene->setAction(&scene->_sequenceManager1, scene, 509, &scene->_suits,
+ &scene->_suit, &scene->_transparentDoor, NULL);
} else {
scene->_sound1.play(127);
- scene->_object1.animate(ANIM_MODE_6, scene);
+ scene->_suits.animate(ANIM_MODE_6, scene);
}
break;
case 2:
+ // Rotate Right
if (++R2_GLOBALS._landerSuitNumber == 4)
- R2_GLOBALS._flubMazeArea = 1;
+ R2_GLOBALS._landerSuitNumber = R2_QUINN;
if (R2_GLOBALS.getFlag(35)) {
scene->_sceneMode = 6;
- scene->setAction(&scene->_sequenceManager1, scene, 509, &scene->_object1,
- &scene->_suit, &scene->_object8, NULL);
+ scene->setAction(&scene->_sequenceManager1, scene, 509, &scene->_suits,
+ &scene->_suit, &scene->_transparentDoor, NULL);
} else {
scene->_sound1.play(127);
- scene->_object1.animate(ANIM_MODE_6, scene);
+ scene->_suits.animate(ANIM_MODE_5, scene);
}
break;
-
+
case 3:
if (R2_GLOBALS.getFlag(35)) {
scene->_sceneMode = 509;
- scene->setAction(&scene->_sequenceManager1, scene, 509, &scene->_object1,
- &scene->_suit, &scene->_object8, NULL);
+ scene->setAction(&scene->_sequenceManager1, scene, 509, &scene->_suits,
+ &scene->_suit, &scene->_transparentDoor, NULL);
} else {
scene->_suit.postInit();
scene->_suit.hide();
- scene->_suit._effect = 1;
+ scene->_suit._effect = EFFECT_SHADED;
scene->_suit.setDetails(500, -1, -1, -1, 2, (SceneItem *)NULL);
scene->_suit.setup(502, R2_GLOBALS._landerSuitNumber + 2, 1);
scene->setAction(&scene->_sequenceManager1, scene, 508,
- &R2_GLOBALS._player, &scene->_object1, &scene->_suit,
- &scene->_object8, NULL);
+ &R2_GLOBALS._player, &scene->_suits, &scene->_suit,
+ &scene->_transparentDoor, NULL);
R2_GLOBALS.setFlag(35);
}
break;
@@ -5212,10 +5389,9 @@ void Scene500::PanelDialog::Button::doButtonPress() {
/*--------------------------------------------------------------------------*/
void Scene500::postInit(SceneObjectList *OwnerList) {
- SceneExt::postInit();
loadScene(500);
+ SceneExt::postInit();
- Common::fill(&_buffer[0], &_buffer[2710], 0);
_stripManager.setColors(60, 255);
_stripManager.setFontNumber(50);
_stripManager.addSpeaker(&_seekerSpeaker);
@@ -5228,14 +5404,14 @@ void Scene500::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._walkRegions.enableRegion(1);
_seeker.postInit();
- _seeker._effect = 1;
+ _seeker._effect = EFFECT_SHADED;
_seeker.setup(1505, 1, 1);
_seeker._moveDiff.x = 5;
_seeker.setPosition(Common::Point(42, 151));
_seeker.setDetails(500, 34, 35, 36, 1, (SceneItem *)NULL);
} else if (R2_GLOBALS._player._characterScene[R2_QUINN] == 500) {
_seeker.postInit();
- _seeker._effect = 1;
+ _seeker._effect = EFFECT_SHADED;
_seeker.setup(R2_GLOBALS.getFlag(26) ? 1500 : 10, 1, 1);
_seeker.setPosition(Common::Point(42, 151));
@@ -5309,22 +5485,22 @@ void Scene500::postInit(SceneObjectList *OwnerList) {
_sonicStunner.setDetails(500, 21, 22, 23, 1, (SceneItem *)NULL);
}
- _object1.postInit();
- _object1._effect = 1;
- _object1.setup(502, 1, 1);
- _object1.setPosition(Common::Point(258, 99));
- _object1.fixPriority(50);
+ _suits.postInit();
+ _suits._effect = EFFECT_SHADED;
+ _suits.setup(502, 1, 1);
+ _suits.setPosition(Common::Point(258, 99));
+ _suits.fixPriority(50);
- _object8.postInit();
- _object8.setPosition(Common::Point(250, 111));
+ _transparentDoor.postInit();
+ _transparentDoor.setPosition(Common::Point(250, 111));
if (!R2_GLOBALS.getFlag(35)) {
- _object8.setup(501, 3, 1);
+ _transparentDoor.setup(501, 3, 1);
} else {
- _object8.setup(500, 8, 7);
+ _transparentDoor.setup(500, 8, 7);
_suit.postInit();
- _suit._effect = 1;
+ _suit._effect = EFFECT_SHADED;
_suit.setPosition(Common::Point(247, 52));
_suit.setDetails(500, -1, -1, -1, 2, (SceneItem *)NULL);
@@ -5343,7 +5519,7 @@ void Scene500::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player._moveDiff.x = 5;
_controlPanel.setDetails(Rect(175, 62, 191, 80), 500, 31, 32, 33, 1, (SceneItem *)NULL);
- _item2.setDetails(Rect(13, 58, 70, 118), 500, 12, -1, -1, 1, (SceneItem *)NULL);
+ _airlockCorridor.setDetails(Rect(13, 58, 70, 118), 500, 12, -1, -1, 1, (SceneItem *)NULL);
_background.setDetails(Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT), 500, 0, -1, -1, 1, (SceneItem *)NULL);
if ((R2_GLOBALS._player._characterIndex == R2_QUINN) && (R2_GLOBALS._sceneManager._previousScene == 700)) {
@@ -5375,7 +5551,7 @@ void Scene500::signal() {
case 5:
_sceneMode = 12;
_sound1.play(127);
- _object1.animate(ANIM_MODE_6, this);
+ _suits.animate(ANIM_MODE_6, this);
R2_GLOBALS.clearFlag(35);
_suit.remove();
@@ -5384,7 +5560,7 @@ void Scene500::signal() {
case 6:
_sceneMode = 11;
_sound1.play(127);
- _object1.animate(ANIM_MODE_5, this);
+ _suits.animate(ANIM_MODE_5, this);
R2_GLOBALS.clearFlag(35);
_suit.remove();
@@ -5392,7 +5568,7 @@ void Scene500::signal() {
break;
case 7:
_sound1.play(126);
- _object8.animate(ANIM_MODE_6, this);
+ _transparentDoor.animate(ANIM_MODE_6, this);
R2_GLOBALS.clearFlag(35);
_suit.remove();
@@ -5488,6 +5664,7 @@ void Scene500::signal() {
* Scene 525 - Cutscene - Walking in hall
*
*--------------------------------------------------------------------------*/
+
void Scene525::postInit(SceneObjectList *OwnerList) {
loadScene(525);
R2_GLOBALS._uiElements._active = false;
@@ -5496,7 +5673,7 @@ void Scene525::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._sound1.play(105);
_actor1.postInit();
- _actor1._effect = 1;
+ _actor1._effect = EFFECT_SHADED;
R2_GLOBALS._player.postInit();
R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
@@ -5518,23 +5695,23 @@ bool Scene600::CompartmentHotspot::startAction(CursorType action, Event &event)
if ((action != R2_NEGATOR_GUN) || (!R2_GLOBALS.getFlag(5)) || (R2_GLOBALS.getFlag(8)))
return SceneHotspot::startAction(action, event);
- SceneItem::display(600, 32, SET_WIDTH, 280, SET_X, 160, SET_POS_MODE, ALIGN_CENTER,
+ SceneItem::display(600, 32, SET_WIDTH, 280, SET_X, 160, SET_POS_MODE, ALIGN_CENTER,
SET_Y, 20, SET_EXT_BGCOLOR, 7, LIST_END);
return true;
}
-bool Scene600::Item4::startAction(CursorType action, Event &event) {
+bool Scene600::EngineCompartment::startAction(CursorType action, Event &event) {
if ((action != R2_NEGATOR_GUN) || (!R2_GLOBALS.getFlag(1)))
return SceneHotspot::startAction(action, event);
if ((R2_GLOBALS.getFlag(5)) && (!R2_GLOBALS.getFlag(8))) {
- SceneItem::display(600, 32, SET_WIDTH, 280, SET_X, 160, SET_POS_MODE, ALIGN_CENTER,
+ SceneItem::display(600, 32, SET_WIDTH, 280, SET_X, 160, SET_POS_MODE, ALIGN_CENTER,
SET_Y, 20, SET_EXT_BGCOLOR, 7, LIST_END);
return true;
}
if (!R2_GLOBALS.getFlag(5)) {
- SceneItem::display(600, 30, SET_WIDTH, 280, SET_X, 160, SET_POS_MODE, ALIGN_CENTER,
+ SceneItem::display(600, 30, SET_WIDTH, 280, SET_X, 160, SET_POS_MODE, ALIGN_CENTER,
SET_Y, 20, SET_EXT_BGCOLOR, 7, LIST_END);
return true;
}
@@ -5546,12 +5723,18 @@ bool Scene600::Item4::startAction(CursorType action, Event &event) {
Scene600 *scene = (Scene600 *)R2_GLOBALS._sceneManager._scene;
- scene->_object1.setup2(603, 3, 1, 239, 54, 10, 0);
+ scene->_stasisArea.setup(603, 3, 1, 239, 54, 10);
scene->_stasisField.postInit();
scene->_computer.postInit();
scene->_sceneMode = 612;
scene->setAction(&scene->_sequenceManager1, scene, 612, &scene->_stasisField, &scene->_computer, &R2_GLOBALS._player, NULL);
+
+ // WORKAROUND: For ScummVM, we use a SceneActor rather than BackgroundSceneObject
+ // for the stasis field since it doesn't work properly. We override the priority for
+ // the stasis field here so that the stasis field dissolve will show up
+ scene->_stasisField.fixPriority(12);
+
return true;
}
@@ -5605,7 +5788,7 @@ bool Scene600::Doorway::startAction(CursorType action, Event &event) {
scene->_laser.setDetails(600, 11, -1, -1, 3, (SceneItem *) NULL);
R2_GLOBALS.setFlag(6);
scene->_sceneMode = 609;
- scene->setAction(&scene->_sequenceManager1, scene, 609, &R2_GLOBALS._player, &scene->_doorway, &scene->_laser, &scene->_actor1, NULL);
+ scene->setAction(&scene->_sequenceManager1, scene, 609, &R2_GLOBALS._player, &scene->_doorway, &scene->_laser, &scene->_laserBeam, NULL);
return true;
}
@@ -5620,7 +5803,7 @@ bool Scene600::Doorway::startAction(CursorType action, Event &event) {
}
if ((R2_GLOBALS.getFlag(9)) && (R2_INVENTORY.getObjectScene(R2_COM_SCANNER) == 600))
- SceneItem::display(600, 31, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ SceneItem::display(600, 31, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, LIST_END);
else {
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 601;
@@ -5638,7 +5821,7 @@ bool Scene600::Laser::startAction(CursorType action, Event &event) {
// If laser is destroyed
if (R2_GLOBALS.getFlag(6)) {
if (R2_GLOBALS.getFlag(8)) {
- SceneItem::display(600, 29, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ SceneItem::display(600, 29, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, LIST_END);
return true;
} else {
R2_GLOBALS._player.disableControl();
@@ -5654,7 +5837,7 @@ bool Scene600::Laser::startAction(CursorType action, Event &event) {
break;
case R2_AEROSOL:
if (R2_GLOBALS.getFlag(5)) {
- SceneItem::display(600, 28, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ SceneItem::display(600, 28, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, LIST_END);
return true;
} else {
R2_GLOBALS._player.disableControl();
@@ -5663,7 +5846,7 @@ bool Scene600::Laser::startAction(CursorType action, Event &event) {
scene->_smoke.postInit();
scene->_smoke.setup(601, 3, 1);
- scene->_smoke._effect = 3;
+ scene->_smoke._effect = EFFECT_3;
scene->_smoke._moveDiff = Common::Point(1, 1);
scene->_smoke._moveRate = 2;
scene->_smoke._numFrames = 3;
@@ -5696,7 +5879,7 @@ bool Scene600::Laser::startAction(CursorType action, Event &event) {
} else {
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 610;
- scene->setAction(&scene->_sequenceManager1, scene, 610, &scene->_actor1, &R2_GLOBALS._player, NULL);
+ scene->setAction(&scene->_sequenceManager1, scene, 610, &scene->_laserBeam, &R2_GLOBALS._player, NULL);
return true;
}
} else
@@ -5704,13 +5887,13 @@ bool Scene600::Laser::startAction(CursorType action, Event &event) {
}
bool Scene600::Aerosol::startAction(CursorType action, Event &event) {
- Scene600 *scene = (Scene600 *)R2_GLOBALS._sceneManager._scene;
-
// Only action cursors
if (action < CURSOR_WALK)
return false;
if (action == CURSOR_USE) {
+ Scene600 *scene = (Scene600 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 614;
scene->setAction(&scene->_sequenceManager1, scene, 614, &R2_GLOBALS._player, &scene->_aerosol, NULL);
@@ -5723,14 +5906,14 @@ bool Scene600::Aerosol::startAction(CursorType action, Event &event) {
/*--------------------------------------------------------------------------*/
Scene600::Scene600() {
- _field412 = 0;
+ _roomState = 0;
Common::fill(&_pixelMap[0], &_pixelMap[256], 0);
}
void Scene600::synchronize(Serializer &s) {
SceneExt::synchronize(s);
- s.syncAsSint16LE(_field412);
+ s.syncAsSint16LE(_roomState);
for (int i = 0; i < 256; i++)
s.syncAsByte(_pixelMap[i]);
}
@@ -5758,7 +5941,7 @@ void Scene600::postInit(SceneObjectList *OwnerList) {
SceneExt::postInit();
R2_GLOBALS.setFlag(39);
R2_GLOBALS._walkRegions.disableRegion(3);
- _field412 = 0;
+ _roomState = 0;
// Initialize pixel map for the obscuring effect
ScenePalette &pal = R2_GLOBALS._scenePalette;
@@ -5809,14 +5992,14 @@ void Scene600::postInit(SceneObjectList *OwnerList) {
_laser.setup(600, 2, 1);
_laser.setDetails(600, 10, -1, -1, 1, (SceneItem *) NULL);
- _actor1.postInit();
- _actor1.setup(600, 3, 5);
- _actor1.setPosition(Common::Point(223, 51));
- _actor1.fixPriority(200);
+ _laserBeam.postInit();
+ _laserBeam.setup(600, 3, 5);
+ _laserBeam.setPosition(Common::Point(223, 51));
+ _laserBeam.fixPriority(200);
}
if (! R2_GLOBALS.getFlag(9))
- _object1.setup2(603, 1, 1, 244, 50, 10, 0);
+ _stasisArea.setup(603, 1, 1, 244, 50, 10);
if (R2_GLOBALS.getFlag(5)) {
if (R2_INVENTORY.getObjectScene(R2_AEROSOL) == 600) {
@@ -5844,7 +6027,7 @@ void Scene600::postInit(SceneObjectList *OwnerList) {
_smoke._numFrames = 3;
_smoke.animate(ANIM_MODE_2, NULL);
_smoke.fixPriority(130);
- _smoke._effect = 3;
+ _smoke._effect = EFFECT_3;
_smoke.setDetails(600, 24, 25, 26, 1, (SceneItem *) NULL);
_smoke.signal();
}
@@ -5855,25 +6038,25 @@ void Scene600::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
R2_GLOBALS._player.disableControl();
- _item2.setDetails(12, 600, 17, -1, 19);
- _item3.setDetails(11, 600, 14, -1, -1);
+ _quantumRegulator.setDetails(12, 600, 17, -1, 19);
+ _powerNode.setDetails(11, 600, 14, -1, -1);
if (R2_GLOBALS.getFlag(9)) {
- _background.setDetails(Rect(159, 3, 315, 95), 600, 7, -1, -1, 1, NULL);
+ _quantumDrive.setDetails(Rect(159, 3, 315, 95), 600, 7, -1, -1, 1, NULL);
} else {
- _item4.setDetails(Rect(173, 15, 315, 45), 600, 21, -1, 23, 1, NULL);
- _background.setDetails(Rect(159, 3, 315, 95), 600, 6, -1, -1, 1, NULL);
+ _engineCompartment.setDetails(Rect(173, 15, 315, 45), 600, 21, -1, 23, 1, NULL);
+ _quantumDrive.setDetails(Rect(159, 3, 315, 95), 600, 6, -1, -1, 1, NULL);
}
- _item5.setDetails(Rect(0, 0, 320, 200), 600, 0, -1, -1, 1, NULL);
+ _background.setDetails(Rect(0, 0, 320, 200), 600, 0, -1, -1, 1, NULL);
_sceneMode = 600;
if (R2_GLOBALS._sceneManager._previousScene == 700) {
if (R2_GLOBALS.getFlag(6)) {
setAction(&_sequenceManager1, this, 600, &R2_GLOBALS._player, &_doorway, NULL);
} else if (R2_GLOBALS.getFlag(5)) {
- setAction(&_sequenceManager1, this, 603, &R2_GLOBALS._player, &_doorway, &_laser, &_actor1, NULL);
+ setAction(&_sequenceManager1, this, 603, &R2_GLOBALS._player, &_doorway, &_laser, &_laserBeam, NULL);
} else {
- setAction(&_sequenceManager1, this, 602, &R2_GLOBALS._player, &_doorway, &_laser, &_actor1, NULL);
+ setAction(&_sequenceManager1, this, 602, &R2_GLOBALS._player, &_doorway, &_laser, &_laserBeam, NULL);
}
} else if (R2_GLOBALS.getFlag(5)) {
R2_GLOBALS._player.setPosition(Common::Point(50, 140));
@@ -5915,7 +6098,7 @@ void Scene600::signal() {
R2_INVENTORY.setObjectScene(R2_AEROSOL, 600);
R2_GLOBALS.setFlag(5);
- _smoke._effect = 3;
+ _smoke._effect = EFFECT_3;
_smoke.signal();
break;
case 606:
@@ -5941,9 +6124,10 @@ void Scene600::signal() {
// Deactivate stasis field
R2_GLOBALS.setFlag(9);
_stasisField.remove();
- R2_GLOBALS._sceneItems.remove(&_item4);
- _computer.setDetails(600, 21, -1, 23, 4, &_item4);
- _background.setDetails(600, 7, -1, -1, 3, (SceneItem *) NULL);
+ R2_GLOBALS._sceneItems.remove(&_engineCompartment);
+ _computer.setDetails(600, 21, -1, 23, 4, &_engineCompartment);
+ _engineCompartment.setDetails(600, 7, -1, -1, 3, (SceneItem *) NULL);
+ _quantumDrive._lookLineNum = 7;
R2_GLOBALS._player.enableControl(CURSOR_USE);
break;
case 614:
@@ -5960,7 +6144,7 @@ void Scene600::signal() {
R2_GLOBALS._player.enableControl();
break;
default:
- _field412 = 0;
+ _roomState = 0;
_sceneMode = 0;
R2_GLOBALS._player.enableControl();
break;
@@ -5968,15 +6152,15 @@ void Scene600::signal() {
}
void Scene600::process(Event &event) {
- if (R2_GLOBALS._player._canWalk && (!R2_GLOBALS.getFlag(6)) && (event.eventType == EVENT_BUTTON_DOWN)
+ if (R2_GLOBALS._player._canWalk && (!R2_GLOBALS.getFlag(6)) && (event.eventType == EVENT_BUTTON_DOWN)
&& (R2_GLOBALS._events.getCursor() == CURSOR_WALK)) {
if (!_doorway.contains(event.mousePos) || (_doorway._frame <= 1)) {
if (R2_GLOBALS.getFlag(5)) {
- _field412 += 10;
+ _roomState += 10;
} else {
R2_GLOBALS._player.disableControl();
_sceneMode = 604;
- setAction(&_sequenceManager1, this, 604, &_actor1, &R2_GLOBALS._player, NULL);
+ setAction(&_sequenceManager1, this, 604, &_laserBeam, &R2_GLOBALS._player, NULL);
event.handled = true;
}
} else {
@@ -5985,36 +6169,36 @@ void Scene600::process(Event &event) {
setAction(&_sequenceManager1, this, 613, &R2_GLOBALS._player, &_laser, NULL);
event.handled = true;
}
- } else if ((!R2_GLOBALS.getFlag(6)) && (R2_GLOBALS._player._mover) && (_field412 < 10)){
- _field412 += 10;
+ } else if ((!R2_GLOBALS.getFlag(6)) && (R2_GLOBALS._player._mover) && (_roomState < 10)){
+ _roomState += 10;
}
Scene::process(event);
}
void Scene600::dispatch() {
- if ((_field412 != 0) && (_sceneMode != 600) && (_sceneMode != 603) && (_sceneMode != 602)) {
+ if ((_roomState != 0) && (_sceneMode != 600) && (_sceneMode != 603) && (_sceneMode != 602)) {
if ( ((_laser._strip == 4) && (_laser._frame > 1))
|| (_sceneMode == 601)
|| ((_sceneMode == 616) && (_doorway._frame > 1)) )
- _field412 = 0;
+ _roomState = 0;
else {
- _field412--;
- if (_field412 % 10 == 0) {
- _actor1.setAction(&_sequenceManager2, NULL, 611, &_actor1, NULL);
+ _roomState--;
+ if (_roomState % 10 == 0) {
+ _laserBeam.setAction(&_sequenceManager2, NULL, 611, &_laserBeam, NULL);
}
- if ((_field412 == 0) && (R2_GLOBALS._player._mover))
- _field412 = 10;
+ if ((_roomState == 0) && (R2_GLOBALS._player._mover))
+ _roomState = 10;
}
}
- if (_actor1._frame == 2)
- _aSound1.play(40);
+ if (_laserBeam._frame == 2)
+ _sound1.play(40);
Scene::dispatch();
if ((_smoke._strip == 3) && (_smoke._frame == 3)) {
- _actor1.setStrip(4);
- _actor1.setFrame(1);
+ _laserBeam.setStrip(4);
+ _laserBeam.setFrame(1);
}
}
@@ -6022,6 +6206,10 @@ void Scene600::dispatch() {
* Scene 700 - Lander Bay 2
*
*--------------------------------------------------------------------------*/
+
+#define CABLE700_X 26
+#define CABLE700_Y -5
+
Scene700::Scene700() {
_rotation = NULL;
}
@@ -6031,7 +6219,7 @@ void Scene700::synchronize(Serializer &s) {
SYNC_POINTER(_rotation);
}
-bool Scene700::Item11::startAction(CursorType action, Event &event) {
+bool Scene700::Loft::startAction(CursorType action, Event &event) {
if ((action == CURSOR_USE) && (R2_GLOBALS._player._position.x < 100))
return false;
@@ -6069,15 +6257,15 @@ bool Scene700::HandGrip::startAction(CursorType action, Event &event) {
return true;
}
-bool Scene700::Actor2::startAction(CursorType action, Event &event) {
- Scene700 *scene = (Scene700 *)R2_GLOBALS._sceneManager._scene;
-
+bool Scene700::LiftDoor::startAction(CursorType action, Event &event) {
if (action != CURSOR_USE)
return SceneActor::startAction(action, event);
if (R2_GLOBALS._player._position.y <= 100)
return false;
+ Scene700 *scene = (Scene700 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 701;
scene->setAction(&scene->_sequenceManager, scene, 701, &R2_GLOBALS._player, this, NULL);
@@ -6085,15 +6273,15 @@ bool Scene700::Actor2::startAction(CursorType action, Event &event) {
return true;
}
-bool Scene700::Actor3::startAction(CursorType action, Event &event) {
- Scene700 *scene = (Scene700 *)R2_GLOBALS._sceneManager._scene;
-
+bool Scene700::SuitRoomDoor::startAction(CursorType action, Event &event) {
if (action != CURSOR_USE)
return SceneActor::startAction(action, event);
if (R2_GLOBALS._player._position.y <= 100)
return false;
+ Scene700 *scene = (Scene700 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 702;
scene->setAction(&scene->_sequenceManager, scene, 702, &R2_GLOBALS._player, this, NULL);
@@ -6101,15 +6289,15 @@ bool Scene700::Actor3::startAction(CursorType action, Event &event) {
return true;
}
-bool Scene700::Actor4::startAction(CursorType action, Event &event) {
- Scene700 *scene = (Scene700 *)R2_GLOBALS._sceneManager._scene;
-
+bool Scene700::ControlPanel::startAction(CursorType action, Event &event) {
if (action != CURSOR_USE)
return SceneActor::startAction(action, event);
if (R2_GLOBALS._player._position.y <= 100)
return false;
+ Scene700 *scene = (Scene700 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 704;
scene->setAction(&scene->_sequenceManager, scene, 704, &R2_GLOBALS._player, this, NULL);
@@ -6169,12 +6357,12 @@ bool Scene700::Cable::startAction(CursorType action, Event &event) {
return true;
}
-bool Scene700::Actor6::startAction(CursorType action, Event &event) {
- Scene700 *scene = (Scene700 *)R2_GLOBALS._sceneManager._scene;
-
+bool Scene700::LoftDoor::startAction(CursorType action, Event &event) {
if ((action != CURSOR_USE) || (R2_GLOBALS._player._position.y >= 100))
return SceneActor::startAction(action, event);
+ Scene700 *scene = (Scene700 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 1;
Common::Point pt(_position.x, 69);
@@ -6188,51 +6376,49 @@ void Scene700::postInit(SceneObjectList *OwnerList) {
loadScene(700);
if (R2_GLOBALS._sceneManager._previousScene == 900)
_sceneBounds = Rect(160, 0, 480, 200);
-
- R2_GLOBALS._v558B6.set(60, 0, 260, 200);
SceneExt::postInit();
_rotation = R2_GLOBALS._scenePalette.addRotation(237, 246, -1);
_rotation->setDelay(5);
_rotation->_countdown = 1;
- _actor2.postInit();
- _actor2.setVisage(700);
- _actor2.setPosition(Common::Point(21, 128));
- _actor2.fixPriority(10);
- _actor2.setDetails(700, 3, -1, -1, 1, (SceneItem *) NULL);
+ _liftDoor.postInit();
+ _liftDoor.setVisage(700);
+ _liftDoor.setPosition(Common::Point(21, 128));
+ _liftDoor.fixPriority(10);
+ _liftDoor.setDetails(700, 3, -1, -1, 1, (SceneItem *) NULL);
- _actor3.postInit();
- _actor3.setup(700, 2, 1);
- _actor3.setPosition(Common::Point(217, 120));
- _actor3.fixPriority(10);
- _actor3.setDetails(700, 15, -1, -1, 1, (SceneItem *) NULL);
+ _suitRoomDoor.postInit();
+ _suitRoomDoor.setup(700, 2, 1);
+ _suitRoomDoor.setPosition(Common::Point(217, 120));
+ _suitRoomDoor.fixPriority(10);
+ _suitRoomDoor.setDetails(700, 15, -1, -1, 1, (SceneItem *) NULL);
- _actor1.postInit();
- _actor1.setup(700, 4, 1);
- _actor1.setPosition(Common::Point(355 - ((R2_GLOBALS._electromagnetZoom * 8) / 5), ((R2_GLOBALS._electromagnetChangeAmount + 20 ) / 5) - 12));
- _actor1.fixPriority(10);
- _actor1.setDetails(700, 12, -1, 14, 1, (SceneItem *) NULL);
-
- _actor6.postInit();
- _actor6.setup(700, 8, 1);
- _actor6.setPosition(Common::Point(85, 53));
- _actor6.setDetails(700, 33, -1, 35, 1, (SceneItem *) NULL);
-
- _actor7.postInit();
- _actor7.setup(700, 8, 1);
- _actor7.setPosition(Common::Point(164, 53));
- _actor7.setDetails(700, 33, -1, 35, 1, (SceneItem *) NULL);
-
- _actor8.postInit();
- _actor8.setup(700, 8, 1);
- _actor8.setPosition(Common::Point(243, 53));
- _actor8.setDetails(700, 33, -1, 35, 1, (SceneItem *) NULL);
-
- _actor9.postInit();
- _actor9.setup(700, 8, 1);
- _actor9.setPosition(Common::Point(324, 53));
- _actor9.setDetails(700, 33, -1, 35, 1, (SceneItem *) NULL);
+ _electromagnet.postInit();
+ _electromagnet.setup(700, 4, 1);
+ _electromagnet.setPosition(Common::Point(355 - ((R2_GLOBALS._electromagnetZoom * 8) / 5), ((R2_GLOBALS._electromagnetChangeAmount + 20 ) / 5) - 12));
+ _electromagnet.fixPriority(10);
+ _electromagnet.setDetails(700, 12, -1, 14, 1, (SceneItem *) NULL);
+
+ _loftDoor1.postInit();
+ _loftDoor1.setup(700, 8, 1);
+ _loftDoor1.setPosition(Common::Point(85, 53));
+ _loftDoor1.setDetails(700, 33, -1, 35, 1, (SceneItem *) NULL);
+
+ _loftDoor2.postInit();
+ _loftDoor2.setup(700, 8, 1);
+ _loftDoor2.setPosition(Common::Point(164, 53));
+ _loftDoor2.setDetails(700, 33, -1, 35, 1, (SceneItem *) NULL);
+
+ _loftDoor3.postInit();
+ _loftDoor3.setup(700, 8, 1);
+ _loftDoor3.setPosition(Common::Point(243, 53));
+ _loftDoor3.setDetails(700, 33, -1, 35, 1, (SceneItem *) NULL);
+
+ _loftDoor4.postInit();
+ _loftDoor4.setup(700, 8, 1);
+ _loftDoor4.setPosition(Common::Point(324, 53));
+ _loftDoor4.setDetails(700, 33, -1, 35, 1, (SceneItem *) NULL);
if ((R2_INVENTORY.getObjectScene(R2_CABLE_HARNESS) != 1) && (R2_INVENTORY.getObjectScene(R2_ATTRACTOR_CABLE_HARNESS) != 1)) {
_cable.postInit();
@@ -6247,7 +6433,7 @@ void Scene700::postInit(SceneObjectList *OwnerList) {
break;
case 700:
_cable.setup(701, 3, 1);
- _cable.setPosition(Common::Point(356 - (R2_GLOBALS._v565EB * 8), 148 - (((R2_GLOBALS._v565E9 + 10) / 5) * 4)));
+ _cable.setPosition(Common::Point(356 - (CABLE700_X * 8), 148 - (((CABLE700_Y + 10) / 5) * 4)));
_cable.setDetails(700, 37, -1, -1, 1, (SceneItem *) NULL);
break;
default:
@@ -6257,7 +6443,7 @@ void Scene700::postInit(SceneObjectList *OwnerList) {
case 700:
switch (R2_INVENTORY.getObjectScene(R2_CABLE_HARNESS)) {
case 0:
- if ((R2_GLOBALS._v565E5 != 0) && (R2_GLOBALS._electromagnetChangeAmount == 20) && (R2_GLOBALS._electromagnetZoom == 70))
+ if (R2_GLOBALS._tractorField && (R2_GLOBALS._electromagnetChangeAmount == 20) && (R2_GLOBALS._electromagnetZoom == 70))
_cable.setup(701, 2, 1);
else
_cable.setup(701, 2, 8);
@@ -6267,11 +6453,11 @@ void Scene700::postInit(SceneObjectList *OwnerList) {
break;
case 700:
_cable.setup(701, 1, 8);
- if (R2_GLOBALS._v565E7 == 0) {
- _cable.setPosition(Common::Point(356 - (R2_GLOBALS._v565EB * 8), 148 - (((R2_GLOBALS._v565E9 + 10) / 5) * 4)));
+ if (!R2_GLOBALS._cableAttached) {
+ _cable.setPosition(Common::Point(356 - (CABLE700_X * 8), 148 - (((CABLE700_Y + 10) / 5) * 4)));
} else {
_cable.setup(701, 1, 1);
- _cable.setPosition(Common::Point(_actor1._position.x + 1, _actor1._position.y + 120));
+ _cable.setPosition(Common::Point(_electromagnet._position.x + 1, _electromagnet._position.y + 120));
}
_cable.setDetails(700, 38, -1, -1, 1, (SceneItem *) NULL);
break;
@@ -6283,23 +6469,23 @@ void Scene700::postInit(SceneObjectList *OwnerList) {
}
}
- _actor4.postInit();
- _actor4.setup(700, 3, 1);
- _actor4.setPosition(Common::Point(454, 117));
- _actor4.setDetails(700, 27, -1, -1, 1, (SceneItem *) NULL);
+ _controlPanel.postInit();
+ _controlPanel.setup(700, 3, 1);
+ _controlPanel.setPosition(Common::Point(454, 117));
+ _controlPanel.setDetails(700, 27, -1, -1, 1, (SceneItem *) NULL);
_handGrip.setDetails(Rect(234, 90, 252, 110), 700, 39, -1, -1, 1, NULL);
- _item6.setDetails(Rect(91, 158, 385, 167), 700, 6, -1, 8, 1, NULL);
- _item2.setDetails(Rect(47, 115, 149, 124), 700, 40, -1, 41, 1, NULL);
- _item3.setDetails(Rect(151, 108, 187, 124), 700, 40, -1, 41, 1, NULL);
- _item4.setDetails(Rect(247, 108, 275, 124), 700, 40, -1, 41, 1, NULL);
- _item5.setDetails(Rect(300, 105, 321, 124), 700, 40, -1, 41, 1, NULL);
- _item7.setDetails(Rect(255, 74, 368, 115), 700, 9, -1, 11, 1, NULL);
- _item8.setDetails(Rect(69, 74, 182, 115), 700, 9, -1, 11, 1, NULL);
- _item9.setDetails(Rect(370, 58, 475, 103), 700, 18, -1, -1, 1, NULL);
- _item10.setDetails(Rect(17, 11, 393, 31), 700, 24, -1, -1, 1, NULL);
- _item11.setDetails(Rect(42, 32, 368, 66), 700, 30, -1, 32, 1, NULL);
- _item1.setDetails(Rect(0, 0, 480, 200), 700, 0, -1, -1, 1, NULL);
+ _restraintCollar.setDetails(Rect(91, 158, 385, 167), 700, 6, -1, 8, 1, NULL);
+ _debris1.setDetails(Rect(47, 115, 149, 124), 700, 40, -1, 41, 1, NULL);
+ _debris2.setDetails(Rect(151, 108, 187, 124), 700, 40, -1, 41, 1, NULL);
+ _debris3.setDetails(Rect(247, 108, 275, 124), 700, 40, -1, 41, 1, NULL);
+ _debris4.setDetails(Rect(300, 105, 321, 124), 700, 40, -1, 41, 1, NULL);
+ _storage2.setDetails(Rect(255, 74, 368, 115), 700, 9, -1, 11, 1, NULL);
+ _storage1.setDetails(Rect(69, 74, 182, 115), 700, 9, -1, 11, 1, NULL);
+ _stars.setDetails(Rect(370, 58, 475, 103), 700, 18, -1, -1, 1, NULL);
+ _light.setDetails(Rect(17, 11, 393, 31), 700, 24, -1, -1, 1, NULL);
+ _loft.setDetails(Rect(42, 32, 368, 66), 700, 30, -1, 32, 1, NULL);
+ _background.setDetails(Rect(0, 0, 480, 200), 700, 0, -1, -1, 1, NULL);
R2_GLOBALS._player.postInit();
R2_GLOBALS._player.setVisage(11);
@@ -6313,14 +6499,14 @@ void Scene700::postInit(SceneObjectList *OwnerList) {
switch (R2_GLOBALS._sceneManager._previousScene) {
case 250:
- setAction(&_sequenceManager, this, 700, &R2_GLOBALS._player, &_actor2, NULL);
+ setAction(&_sequenceManager, this, 700, &R2_GLOBALS._player, &_liftDoor, NULL);
break;
case 500:
- setAction(&_sequenceManager, this, 703, &R2_GLOBALS._player, &_actor3, NULL);
+ setAction(&_sequenceManager, this, 703, &R2_GLOBALS._player, &_suitRoomDoor, NULL);
break;
case 600: {
_sceneMode = 4;
- _actor7.setFrame(5);
+ _loftDoor2.setFrame(5);
R2_GLOBALS._player.setPosition(Common::Point(164, 74));
R2_GLOBALS._player.setStrip2(3);
Common::Point pt(164, 69);
@@ -6329,7 +6515,7 @@ void Scene700::postInit(SceneObjectList *OwnerList) {
}
break;
case 900:
- setAction(&_sequenceManager, this, 705, &R2_GLOBALS._player, &_actor4, NULL);
+ setAction(&_sequenceManager, this, 705, &R2_GLOBALS._player, &_controlPanel, NULL);
break;
default:
if (R2_GLOBALS.getFlag(41))
@@ -6344,11 +6530,7 @@ void Scene700::postInit(SceneObjectList *OwnerList) {
void Scene700::remove() {
R2_GLOBALS._sound1.play(10);
-// CHECKME: Present in the original... But it crashes badly.
-// The instruction was removed as it's not used in other scene coded the same way
-// and reversed by dreammaster. A double check is required in order to verify it doesn't hide
-// a memory leak
-// _rotation->remove();
+
SceneExt::remove();
}
@@ -6358,11 +6540,11 @@ void Scene700::signal() {
_sceneMode = 2;
R2_GLOBALS._player.setStrip(4);
if (R2_GLOBALS._player._position.x != 164) {
- SceneItem::display(700, 36, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ SceneItem::display(700, 36, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, LIST_END);
R2_GLOBALS._player.enableControl();
} else {
R2_GLOBALS._sound2.play(19);
- _actor7.animate(ANIM_MODE_5, this);
+ _loftDoor2.animate(ANIM_MODE_5, this);
}
break;
case 2: {
@@ -6381,7 +6563,7 @@ void Scene700::signal() {
R2_GLOBALS._player.setStrip2(-1);
R2_GLOBALS._player.setObjectWrapper(new SceneObjectWrapper());
R2_GLOBALS._sound2.play(19);
- _actor7.animate(ANIM_MODE_6, this);
+ _loftDoor2.animate(ANIM_MODE_6, this);
R2_GLOBALS._player.setStrip(3);
R2_GLOBALS.setFlag(41);
break;
@@ -6420,12 +6602,12 @@ void Scene700::signal() {
_sceneMode = 17;
_cable.setup(701, 1, 8);
_cable.setDetails(700, 38, -1, -1, 3, (SceneItem *) NULL);
- if ((R2_GLOBALS._v565E5 != 0) && (_cable._position.x == _actor1._position.x + 1) && (_cable._position.x == 148 - (((R2_GLOBALS._electromagnetChangeAmount + 10) / 5) * 4))) {
+ if (R2_GLOBALS._tractorField && (_cable._position.x == _electromagnet._position.x + 1) && (_cable._position.x == 148 - (((R2_GLOBALS._electromagnetChangeAmount + 10) / 5) * 4))) {
_cable.animate(ANIM_MODE_6, NULL);
- Common::Point pt(_cable._position.x, _actor1._position.y + 120);
+ Common::Point pt(_cable._position.x, _electromagnet._position.y + 120);
NpcMover *mover = new NpcMover();
_cable.addMover(mover, &pt, NULL);
- R2_GLOBALS._v565E7 = 1;
+ R2_GLOBALS._cableAttached = true;
}
R2_GLOBALS._player.animate(ANIM_MODE_6, this);
break;
@@ -6445,7 +6627,7 @@ void Scene700::signal() {
break;
case 21:
_cable.fixPriority(77);
- if ((R2_GLOBALS._v565E5 != 0) && (R2_GLOBALS._electromagnetChangeAmount == 20) && (R2_GLOBALS._electromagnetZoom == 70))
+ if (R2_GLOBALS._tractorField && (R2_GLOBALS._electromagnetChangeAmount == 20) && (R2_GLOBALS._electromagnetZoom == 70))
_cable.animate(ANIM_MODE_6, NULL);
R2_INVENTORY.setObjectScene(R2_ATTRACTOR_CABLE_HARNESS, 700);
@@ -6463,7 +6645,7 @@ void Scene700::signal() {
case 706:
_cable.setDetails(700, 38, -1, -1, 3, (SceneItem *) NULL);
_cable.fixPriority(77);
- if ((R2_GLOBALS._v565E5 != 0) && (R2_GLOBALS._electromagnetChangeAmount == 20) && (R2_GLOBALS._electromagnetZoom == 70))
+ if (R2_GLOBALS._tractorField && (R2_GLOBALS._electromagnetChangeAmount == 20) && (R2_GLOBALS._electromagnetZoom == 70))
_cable.animate(ANIM_MODE_6, NULL);
R2_INVENTORY.setObjectScene(R2_ATTRACTOR_UNIT, 0);
R2_INVENTORY.setObjectScene(R2_ATTRACTOR_CABLE_HARNESS, 700);
@@ -6491,11 +6673,11 @@ void Scene700::signal() {
*--------------------------------------------------------------------------*/
bool Scene800::Button::startAction(CursorType action, Event &event) {
- Scene800 *scene = (Scene800 *)R2_GLOBALS._sceneManager._scene;
-
if (action != CURSOR_USE) {
return NamedHotspot::startAction(action, event);
} else {
+ Scene800 *scene = (Scene800 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 802;
scene->setAction(&scene->_sequenceManager1, scene, 802, &R2_GLOBALS._player, &scene->_autodocCover, NULL);
@@ -6504,11 +6686,11 @@ bool Scene800::Button::startAction(CursorType action, Event &event) {
}
bool Scene800::CableJunction::startAction(CursorType action, Event &event) {
- Scene800 *scene = (Scene800 *)R2_GLOBALS._sceneManager._scene;
-
if (action != R2_OPTICAL_FIBRE) {
return NamedHotspot::startAction(action, event);
} else {
+ Scene800 *scene = (Scene800 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.disableControl();
scene->_opticalFibre.postInit();
scene->_sceneMode = 803;
@@ -6545,10 +6727,10 @@ bool Scene800::DeviceSlot::startAction(CursorType action, Event &event) {
scene->_sceneMode = 804;
if (R2_INVENTORY.getObjectScene(R2_OPTICAL_FIBRE) == 800) {
- scene->setAction(&scene->_sequenceManager1, scene, 814, &R2_GLOBALS._player,
+ scene->setAction(&scene->_sequenceManager1, scene, 814, &R2_GLOBALS._player,
&scene->_reader, &scene->_opticalFibre, NULL);
} else {
- scene->setAction(&scene->_sequenceManager1, scene, 804, &R2_GLOBALS._player,
+ scene->setAction(&scene->_sequenceManager1, scene, 804, &R2_GLOBALS._player,
&scene->_reader, NULL);
}
return true;
@@ -6562,24 +6744,25 @@ bool Scene800::DeviceSlot::startAction(CursorType action, Event &event) {
/*--------------------------------------------------------------------------*/
bool Scene800::Door::startAction(CursorType action, Event &event) {
- Scene800 *scene = (Scene800 *)R2_GLOBALS._sceneManager._scene;
-
switch (action) {
- case CURSOR_USE:
+ case CURSOR_USE: {
+ Scene800 *scene = (Scene800 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 801;
scene->setAction(&scene->_sequenceManager1, scene, 801, &R2_GLOBALS._player, &scene->_door, NULL);
return true;
+ }
default:
return SceneActor::startAction(action, event);
}
}
bool Scene800::Tray::startAction(CursorType action, Event &event) {
- Scene800 *scene = (Scene800 *)R2_GLOBALS._sceneManager._scene;
-
switch (action) {
- case CURSOR_USE:
+ case CURSOR_USE: {
+ Scene800 *scene = (Scene800 *)R2_GLOBALS._sceneManager._scene;
+
if (!R2_GLOBALS.getFlag(10)) {
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 806;
@@ -6594,16 +6777,17 @@ bool Scene800::Tray::startAction(CursorType action, Event &event) {
scene->setAction(&scene->_sequenceManager1, scene, 807, &R2_GLOBALS._player, &scene->_tray, NULL);
}
return true;
+ }
default:
return SceneActor::startAction(action, event);
}
}
bool Scene800::ComScanner::startAction(CursorType action, Event &event) {
- Scene800 *scene = (Scene800 *)R2_GLOBALS._sceneManager._scene;
-
switch (action) {
- case CURSOR_USE:
+ case CURSOR_USE: {
+ Scene800 *scene = (Scene800 *)R2_GLOBALS._sceneManager._scene;
+
if (scene->_cabinet._frame == 1)
return false;
@@ -6611,6 +6795,7 @@ bool Scene800::ComScanner::startAction(CursorType action, Event &event) {
scene->_sceneMode = 811;
scene->setAction(&scene->_sequenceManager1, scene, 811, &R2_GLOBALS._player, &scene->_comScanner, NULL);
return true;
+ }
case CURSOR_TALK:
SceneItem::display2(800, 35);
return true;
@@ -6620,10 +6805,10 @@ bool Scene800::ComScanner::startAction(CursorType action, Event &event) {
}
bool Scene800::Cabinet::startAction(CursorType action, Event &event) {
- Scene800 *scene = (Scene800 *)R2_GLOBALS._sceneManager._scene;
-
switch (action) {
- case CURSOR_USE:
+ case CURSOR_USE: {
+ Scene800 *scene = (Scene800 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.disableControl();
if (scene->_cabinet._frame == 1) {
@@ -6636,6 +6821,7 @@ bool Scene800::Cabinet::startAction(CursorType action, Event &event) {
R2_GLOBALS.clearFlag(56);
}
return true;
+ }
default:
return SceneActor::startAction(action, event);
}
@@ -6789,21 +6975,19 @@ void Scene800::signal() {
Scene825::Button::Button(): SceneObject() {
_buttonId = 0;
- _v2 = 0;
_buttonDown = false;
}
void Scene825::Button::synchronize(Serializer &s) {
SceneObject::synchronize(s);
s.syncAsSint16LE(_buttonId);
- s.syncAsSint16LE(_v2);
s.syncAsSint16LE(_buttonDown);
}
void Scene825::Button::process(Event &event) {
- Scene825 *scene = (Scene825 *)R2_GLOBALS._sceneManager._scene;
-
if (!event.handled) {
+ Scene825 *scene = (Scene825 *)R2_GLOBALS._sceneManager._scene;
+
if ((event.eventType == EVENT_BUTTON_DOWN) && _bounds.contains(event.mousePos) && !_buttonDown) {
scene->_sound1.play(14);
setFrame(2);
@@ -6830,7 +7014,6 @@ bool Scene825::Button::startAction(CursorType action, Event &event) {
void Scene825::Button::setButton(int buttonId) {
SceneObject::postInit();
- _v2 = buttonId;
_buttonDown = 0;
_sceneText._color1 = 92;
_sceneText._color2 = 0;
@@ -6868,14 +7051,14 @@ void Scene825::Button::setButton(int buttonId) {
}
void Scene825::Button::setText(int textId) {
- Scene825 *scene = (Scene825 *)R2_GLOBALS._sceneManager._scene;
-
_buttonId = textId;
_lookLineNum = textId;
_sceneText.remove();
- if (_buttonId != 0)
+ if (_buttonId != 0) {
+ Scene825 *scene = (Scene825 *)R2_GLOBALS._sceneManager._scene;
_sceneText.setup(scene->_autodocItems[textId - 1]);
+ }
}
/*--------------------------------------------------------------------------*/
@@ -6898,18 +7081,19 @@ Scene825::Scene825(): SceneExt() {
}
void Scene825::postInit(SceneObjectList *OwnerList) {
- SceneExt::postInit();
loadScene(825);
- R2_GLOBALS._player._uiEnabled = false;
- BF_GLOBALS._interfaceY = 200;
+ R2_GLOBALS._uiElements._active = false;
+ SceneExt::postInit();
+ R2_GLOBALS._interfaceY = SCREEN_HEIGHT;
R2_GLOBALS._player.postInit();
- R2_GLOBALS._player._effect = 0;
+ R2_GLOBALS._player._effect = EFFECT_NONE;
R2_GLOBALS._player.setVisage(10);
R2_GLOBALS._player.hide();
R2_GLOBALS._player.disableControl();
- _item2.setDetails(1, 825, 3, 4, 5);
+
+ _console.setDetails(1, 825, 3, 4, 5);
_background.setDetails(Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT), 825, 0, -1, -1, 1, NULL);
_sceneMode = 10;
@@ -6956,7 +7140,7 @@ void Scene825::signal() {
R2_GLOBALS._player._canWalk = false;
break;
case 825:
- _object5.remove();
+ _vertLine5.remove();
_sceneText._color1 = 92;
_sceneText._color2 = 0;
_sceneText._width = 200;
@@ -6974,7 +7158,7 @@ void Scene825::signal() {
R2_GLOBALS._player._canWalk = false;
break;
case 827:
- _object5.remove();
+ _vertLine5.remove();
R2_INVENTORY.setObjectScene(R2_OPTO_DISK, 825);
_sceneText.setPosition(Common::Point(108, 75));
_sceneText.setup(FOREIGN_OBJECT_EXTRACTED);
@@ -7002,19 +7186,19 @@ void Scene825::process(Event &event) {
}
void Scene825::dispatch() {
- if (R2_GLOBALS._sceneObjects->contains(&_object4) &&
- ((_object4._frame == 1) || (_object4._frame == 3)) &&
- (_object4._frame != _frame1)) {
+ if (R2_GLOBALS._sceneObjects->contains(&_vertLine4) &&
+ ((_vertLine4._frame == 1) || (_vertLine4._frame == 3)) &&
+ (_vertLine4._frame != _frame1)) {
_sound2.play(25);
}
- if (R2_GLOBALS._sceneObjects->contains(&_object1) &&
- (_object1._frame == 3) && (_object1._frame != _frame2)) {
+ if (R2_GLOBALS._sceneObjects->contains(&_vertLine1) &&
+ (_vertLine1._frame == 3) && (_vertLine1._frame != _frame2)) {
_sound3.play(26);
}
- _frame1 = _object4._frame;
- _frame2 = _object1._frame;
+ _frame1 = _vertLine4._frame;
+ _frame2 = _vertLine1._frame;
Scene::dispatch();
}
@@ -7031,9 +7215,9 @@ void Scene825::doButtonPress(int buttonId) {
switch (buttonId) {
case 2:
R2_GLOBALS._player.disableControl();
- _object5.postInit();
+ _vertLine5.postInit();
_sceneMode = 825;
- setAction(&_sequenceManager1, this, 825, &R2_GLOBALS._player, &_object5, NULL);
+ setAction(&_sequenceManager1, this, 825, &R2_GLOBALS._player, &_vertLine5, NULL);
break;
case 3:
R2_GLOBALS._player.disableControl();
@@ -7055,9 +7239,9 @@ void Scene825::doButtonPress(int buttonId) {
} else {
_button6._buttonId = 5;
_sceneMode = 827;
- _object5.postInit();
+ _vertLine5.postInit();
- setAction(&_sequenceManager1, this, 827, &_object5, NULL);
+ setAction(&_sequenceManager1, this, 827, &_vertLine5, NULL);
}
} else {
R2_GLOBALS.setFlag(2);
@@ -7081,44 +7265,44 @@ void Scene825::doButtonPress(int buttonId) {
_sound4.play(27);
_button6._buttonId = 5;
- _object1.postInit();
- _object1.setup(826, 7, 1);
- _object1.setPosition(Common::Point(112, 67));
- _object1._numFrames = 1;
- _object1.animate(ANIM_MODE_2);
-
- _object2.postInit();
- _object2.setup(826, 5, 1);
- _object2.setPosition(Common::Point(158, 67));
- _object2._numFrames = 5;
- _object2.animate(ANIM_MODE_2);
-
- _object3.postInit();
- _object3.setup(826, 6, 1);
- _object3.setPosition(Common::Point(206, 67));
- _object3._numFrames = 1;
- _object3.animate(ANIM_MODE_2);
-
- _object4.postInit();
- _object4.setup(826, 8, 1);
- _object4.setPosition(Common::Point(158, 84));
- _object4._numFrames = 1;
- _object4.animate(ANIM_MODE_2);
-
- _object5.postInit();
- _object5.setup(826, 4, 1);
- _object5.setPosition(Common::Point(161, 110));
+ _vertLine1.postInit();
+ _vertLine1.setup(826, 7, 1);
+ _vertLine1.setPosition(Common::Point(112, 67));
+ _vertLine1._numFrames = 1;
+ _vertLine1.animate(ANIM_MODE_2);
+
+ _vertLine2.postInit();
+ _vertLine2.setup(826, 5, 1);
+ _vertLine2.setPosition(Common::Point(158, 67));
+ _vertLine2._numFrames = 5;
+ _vertLine2.animate(ANIM_MODE_2);
+
+ _vertLine3.postInit();
+ _vertLine3.setup(826, 6, 1);
+ _vertLine3.setPosition(Common::Point(206, 67));
+ _vertLine3._numFrames = 1;
+ _vertLine3.animate(ANIM_MODE_2);
+
+ _vertLine4.postInit();
+ _vertLine4.setup(826, 8, 1);
+ _vertLine4.setPosition(Common::Point(158, 84));
+ _vertLine4._numFrames = 1;
+ _vertLine4.animate(ANIM_MODE_2);
+
+ _vertLine5.postInit();
+ _vertLine5.setup(826, 4, 1);
+ _vertLine5.setPosition(Common::Point(161, 110));
break;
case 5:
R2_GLOBALS._player.disableControl();
if (_menuId == 4) {
_menuId = 0;
- _object1.remove();
- _object2.remove();
- _object3.remove();
- _object4.remove();
- _object5.remove();
+ _vertLine1.remove();
+ _vertLine2.remove();
+ _vertLine3.remove();
+ _vertLine4.remove();
+ _vertLine5.remove();
_sound2.stop();
_sound3.stop();
@@ -7163,11 +7347,11 @@ void Scene825::doButtonPress(int buttonId) {
*--------------------------------------------------------------------------*/
bool Scene850::Indicator::startAction(CursorType action, Event &event) {
- Scene850 *scene = (Scene850 *)R2_GLOBALS._sceneManager._scene;
-
if ((action != CURSOR_USE) || (R2_INVENTORY.getObjectScene(R2_OPTICAL_FIBRE) != 850))
return NamedHotspot::startAction(action, event);
else {
+ Scene850 *scene = (Scene850 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 851;
scene->setAction(&scene->_sequenceManager1, scene, 851, &R2_GLOBALS._player, &scene->_fibre, NULL);
@@ -7178,11 +7362,11 @@ bool Scene850::Indicator::startAction(CursorType action, Event &event) {
/*--------------------------------------------------------------------------*/
bool Scene850::LiftDoor::startAction(CursorType action, Event &event) {
- Scene850 *scene = (Scene850 *)R2_GLOBALS._sceneManager._scene;
-
if (action != CURSOR_USE)
return SceneActor::startAction(action, event);
else {
+ Scene850 *scene = (Scene850 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 202;
scene->setAction(&scene->_sequenceManager1, scene, 202, &R2_GLOBALS._player, this, NULL);
@@ -7191,11 +7375,11 @@ bool Scene850::LiftDoor::startAction(CursorType action, Event &event) {
}
bool Scene850::SickBayDoor::startAction(CursorType action, Event &event) {
- Scene850 *scene = (Scene850 *)R2_GLOBALS._sceneManager._scene;
-
if (action != CURSOR_USE)
return SceneActor::startAction(action, event);
else {
+ Scene850 *scene = (Scene850 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 204;
scene->setAction(&scene->_sequenceManager1, scene, 204, &R2_GLOBALS._player, this, NULL);
@@ -7204,30 +7388,32 @@ bool Scene850::SickBayDoor::startAction(CursorType action, Event &event) {
}
bool Scene850::Clamp::startAction(CursorType action, Event &event) {
- Scene850 *scene = (Scene850 *)R2_GLOBALS._sceneManager._scene;
-
if (!R2_GLOBALS.getFlag(7))
return false;
else if (action != CURSOR_USE)
return SceneActor::startAction(action, event);
else {
+ Scene850 *scene = (Scene850 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.disableControl();
- scene->_object1.postInit();
+ scene->_spark.postInit();
scene->_sceneMode = 850;
- scene->setAction(&scene->_sequenceManager1, scene, 850, &R2_GLOBALS._player, this, &scene->_object1, NULL);
+ scene->setAction(&scene->_sequenceManager1, scene, 850, &R2_GLOBALS._player, this,
+ &scene->_spark, NULL);
return true;
}
}
bool Scene850::Panel::startAction(CursorType action, Event &event) {
- Scene850 *scene = (Scene850 *)R2_GLOBALS._sceneManager._scene;
-
if ((action != CURSOR_USE) || R2_GLOBALS.getFlag(7))
return SceneActor::startAction(action, event);
else {
+ Scene850 *scene = (Scene850 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 852;
- scene->setAction(&scene->_sequenceManager1, scene, 852, &R2_GLOBALS._player, this, &scene->_object1, NULL);
+ scene->setAction(&scene->_sequenceManager1, scene, 852, &R2_GLOBALS._player,
+ this, &scene->_spark, NULL);
return true;
}
}
@@ -7313,7 +7499,7 @@ void Scene850::signal() {
case 850:
R2_INVENTORY.setObjectScene(R2_CLAMP, 1);
_clamp.remove();
- _object1.remove();
+ _spark.remove();
R2_GLOBALS._player.enableControl();
break;
case 851:
@@ -7354,7 +7540,7 @@ void Scene900::Button::initButton(int buttonId) {
}
Scene900::Scene900() {
- _field412 = 0;
+ _controlsScreenNumber = 0;
_magnetChangeAmount.x = 0;
_magnetChangeAmount.y = 0;
}
@@ -7362,7 +7548,7 @@ Scene900::Scene900() {
void Scene900::synchronize(Serializer &s) {
SceneExt::synchronize(s);
- s.syncAsSint16LE(_field412);
+ s.syncAsSint16LE(_controlsScreenNumber);
s.syncAsSint16LE(_magnetChangeAmount.x);
s.syncAsSint16LE(_magnetChangeAmount.y);
}
@@ -7374,46 +7560,46 @@ bool Scene900::Button::startAction(CursorType action, Event &event) {
R2_GLOBALS._sound2.play(14);
switch (_buttonId) {
case 2:
- if (scene->_field412 == 1) {
+ if (scene->_controlsScreenNumber == 1) {
scene->_sceneMode = 2;
scene->signal();
- } else if (scene->_field412 == 2) {
- if (R2_GLOBALS._v565E5 == 0) {
+ } else if (scene->_controlsScreenNumber == 2) {
+ if (!R2_GLOBALS._tractorField) {
scene->_aSound1.play(30);
setup(900, 3, 11);
- R2_GLOBALS._v565E5 = 1;
- if ((R2_INVENTORY.getObjectScene(R2_CABLE_HARNESS) == 0) && (R2_INVENTORY.getObjectScene(R2_ATTRACTOR_CABLE_HARNESS == 700)) && (R2_GLOBALS._electromagnetChangeAmount == 20) && (R2_GLOBALS._electromagnetZoom == 70) && (scene->_actor2._animateMode != ANIM_MODE_6)) {
- scene->_actor2.animate(ANIM_MODE_6, NULL);
+ R2_GLOBALS._tractorField = true;
+ if ((R2_INVENTORY.getObjectScene(R2_CABLE_HARNESS) == 0) && (R2_INVENTORY.getObjectScene(R2_ATTRACTOR_CABLE_HARNESS == 700)) && (R2_GLOBALS._electromagnetChangeAmount == 20) && (R2_GLOBALS._electromagnetZoom == 70) && (scene->_cable._animateMode != ANIM_MODE_6)) {
+ scene->_cable.animate(ANIM_MODE_6, NULL);
} else {
- if (((scene->_electromagnet._percent * 49) / 100) + scene->_electromagnet._position.x == scene->_actor2._position.x) {
- if (scene->_actor2._position.x == 166 - (R2_GLOBALS._electromagnetZoom / 15)) {
+ if (((scene->_electromagnet._percent * 49) / 100) + scene->_electromagnet._position.x == scene->_cable._position.x) {
+ if (scene->_cable._position.x == 166 - (R2_GLOBALS._electromagnetZoom / 15)) {
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 4;
- scene->_actor2._moveDiff.y = (scene->_actor2._position.y - (scene->_electromagnet._position.y + ((scene->_electromagnet._percent * 3) / 10) - 2)) / 9;
+ scene->_cable._moveDiff.y = (scene->_cable._position.y - (scene->_electromagnet._position.y + ((scene->_electromagnet._percent * 3) / 10) - 2)) / 9;
Common::Point pt(scene->_electromagnet._position.x + ((scene->_electromagnet._percent * 49) / 100), scene->_electromagnet._position.y + ((scene->_electromagnet._percent * 3) / 10) - 2);
NpcMover *mover = new NpcMover();
- scene->_actor2.addMover(mover, &pt, this);
- scene->_actor2.animate(ANIM_MODE_6, NULL);
+ scene->_cable.addMover(mover, &pt, this);
+ scene->_cable.animate(ANIM_MODE_6, NULL);
}
}
}
} else {
scene->_aSound1.play(53);
setup(900, 3, 9);
- R2_GLOBALS._v565E5 = 0;
+ R2_GLOBALS._tractorField = false;
- if ((R2_INVENTORY.getObjectScene(R2_CABLE_HARNESS) == 0) && (R2_INVENTORY.getObjectScene(R2_ATTRACTOR_CABLE_HARNESS) == 700) && (scene->_actor2._frame < 8) && (scene->_actor2._animateMode != ANIM_MODE_5)) {
- scene->_actor2.animate(ANIM_MODE_5, NULL);
- } else if ((R2_INVENTORY.getObjectScene(R2_CABLE_HARNESS) == 700) && (R2_INVENTORY.getObjectScene(R2_ATTRACTOR_CABLE_HARNESS) == 700) && (scene->_actor2._frame < 8)) {
- R2_GLOBALS._v565E7 = 0;
- if (scene->_actor2._animateMode != 5) {
+ if ((R2_INVENTORY.getObjectScene(R2_CABLE_HARNESS) == 0) && (R2_INVENTORY.getObjectScene(R2_ATTRACTOR_CABLE_HARNESS) == 700) && (scene->_cable._frame < 8) && (scene->_cable._animateMode != ANIM_MODE_5)) {
+ scene->_cable.animate(ANIM_MODE_5, NULL);
+ } else if ((R2_INVENTORY.getObjectScene(R2_CABLE_HARNESS) == 700) && (R2_INVENTORY.getObjectScene(R2_ATTRACTOR_CABLE_HARNESS) == 700) && (scene->_cable._frame < 8)) {
+ R2_GLOBALS._cableAttached = false;
+ if (scene->_cable._animateMode != 5) {
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 5;
- scene->_actor2.animate(ANIM_MODE_5, NULL);
- scene->_actor2._moveDiff.y = (166 - scene->_actor2._position.y) / 9;
- Common::Point pt(scene->_actor2._position.x, 166 - (R2_GLOBALS._electromagnetZoom / 15));
+ scene->_cable.animate(ANIM_MODE_5, NULL);
+ scene->_cable._moveDiff.y = (166 - scene->_cable._position.y) / 9;
+ Common::Point pt(scene->_cable._position.x, 166 - (R2_GLOBALS._electromagnetZoom / 15));
NpcMover *mover = new NpcMover();
- scene->_actor2.addMover(mover, &pt, this);
+ scene->_cable.addMover(mover, &pt, this);
}
}
}
@@ -7421,7 +7607,7 @@ bool Scene900::Button::startAction(CursorType action, Event &event) {
return true;
break;
case 3:
- if (scene->_field412 == 1) {
+ if (scene->_controlsScreenNumber == 1) {
scene->_sceneMode = 3;
scene->signal();
}
@@ -7456,15 +7642,15 @@ bool Scene900::Button::startAction(CursorType action, Event &event) {
return true;
break;
case 8:
- SceneItem::display(5, 11, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ SceneItem::display(5, 11, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, LIST_END);
return true;
break;
case 9:
- SceneItem::display(5, 12, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ SceneItem::display(5, 12, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, LIST_END);
return true;
break;
default:
- if (scene->_field412 == 1) {
+ if (scene->_controlsScreenNumber == 1) {
R2_GLOBALS._player.disableControl();
scene->_button2.remove();
scene->_button3.remove();
@@ -7474,8 +7660,8 @@ bool Scene900::Button::startAction(CursorType action, Event &event) {
scene->_button7.remove();
R2_GLOBALS._sound2.play(37);
scene->_sceneMode = 901;
- scene->setAction(&scene->_sequenceManager1, scene, 901, &scene->_actor1, this ,NULL);
- } else if ((scene->_field412 == 2) || (scene->_field412 == 3)) {
+ scene->setAction(&scene->_sequenceManager1, scene, 901, &scene->_controls, this ,NULL);
+ } else if ((scene->_controlsScreenNumber == 2) || (scene->_controlsScreenNumber == 3)) {
scene->_sceneMode = 1;
scene->signal();
}
@@ -7484,8 +7670,8 @@ bool Scene900::Button::startAction(CursorType action, Event &event) {
break;
}
} else if (action == CURSOR_LOOK) {
- SceneItem::display(900, ((_buttonId == 2) && (scene->_field412 == 2)) ? 21 : _buttonId + 11,
- SET_WIDTH, 280, SET_X, 160, SET_POS_MODE, 1, SET_Y, 20, SET_EXT_BGCOLOR, 7, -999);
+ SceneItem::display(900, ((_buttonId == 2) && (scene->_controlsScreenNumber == 2)) ? 21 : _buttonId + 11,
+ SET_WIDTH, 280, SET_X, 160, SET_POS_MODE, 1, SET_Y, 20, SET_EXT_BGCOLOR, 7, LIST_END);
return true;
} else {
return SceneActor::startAction(action, event);
@@ -7502,8 +7688,8 @@ void Scene900::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player.hide();
R2_GLOBALS._player.disableControl();
- _actor1.postInit();
- _actor1.setDetails(900, 3, -1, -1, 1, (SceneItem *) NULL);
+ _controls.postInit();
+ _controls.setDetails(900, 3, -1, -1, 1, (SceneItem *) NULL);
_magnetChangeAmount.x = 0;
_magnetChangeAmount.y = 0;
@@ -7512,37 +7698,38 @@ void Scene900::postInit(SceneObjectList *OwnerList) {
_electromagnet.fixPriority(1);
_electromagnet.setup(900, 1, 2);
_electromagnet.setPosition(Common::Point(89, 0));
- _electromagnet._effect = 1;
+ _electromagnet._effect = EFFECT_SHADED;
_electromagnet.setDetails(900, 6, -1, 8, 1, (SceneItem *) NULL);
if ((R2_INVENTORY.getObjectScene(R2_CABLE_HARNESS) != 1) && (R2_INVENTORY.getObjectScene(R2_ATTRACTOR_CABLE_HARNESS) != 1)) {
- _actor2.postInit();
- _actor2.setPosition(Common::Point(0, 0));
- _actor2.fixPriority(1);
+ _cable.postInit();
+ _cable.setPosition(Common::Point(0, 0));
+ _cable.fixPriority(1);
if (R2_INVENTORY.getObjectScene(R2_CABLE_HARNESS) == 0) {
if (R2_INVENTORY.getObjectScene(R2_ATTRACTOR_CABLE_HARNESS) != 700) {
- _actor2.setup(901, 3, 2);
- } else if ((R2_GLOBALS._v565E5 != 0) && (R2_GLOBALS._electromagnetChangeAmount == 20) && (R2_GLOBALS._electromagnetZoom == 70)) {
- _actor2.setup(901, 2, 1);
+ _cable.setup(901, 3, 2);
+ } else if (R2_GLOBALS._tractorField && (R2_GLOBALS._electromagnetChangeAmount == 20) && (R2_GLOBALS._electromagnetZoom == 70)) {
+ _cable.setup(901, 2, 1);
} else {
- _actor2.setup(901, 2, 8);
+ _cable.setup(901, 2, 8);
}
- _actor2.setPosition(Common::Point(171, 145));
- _actor2.setDetails(700, -1, -1, -1, 1, (SceneItem *) NULL);
+ _cable.setPosition(Common::Point(171, 145));
+ _cable.setDetails(700, -1, -1, -1, 1, (SceneItem *) NULL);
} else {
- _actor2.setDetails(700, -1, -1, -1, 1, (SceneItem *) NULL);
- if (R2_GLOBALS._v565E7 == 0) {
- _actor2.setup(901, 1, 8);
+ _cable.setDetails(700, -1, -1, -1, 1, (SceneItem *) NULL);
+ if (!R2_GLOBALS._cableAttached) {
+ _cable.setup(901, 1, 8);
// Original set two times the same values: skipped
- _actor2.setPosition(Common::Point((((100 - ((R2_GLOBALS._v565EB * 350) / 100)) * 49) / 100) + ((R2_GLOBALS._v565E9 * _electromagnet._percent * 6) / 100) + 89, 166 - (R2_GLOBALS._v565EB / 3)));
- _actor2.changeZoom(((100 - ((R2_GLOBALS._v565EB * 350) / 100) + 52) / 10) * 10);
+ _cable.setPosition(Common::Point((((100 - ((CABLE700_X * 350) / 100)) * 49) / 100) + ((CABLE700_Y * _electromagnet._percent * 6) / 100) + 89, 166 - (CABLE700_X / 3)));
+ _cable.changeZoom(((100 - ((CABLE700_X * 350) / 100) + 52) / 10) * 10);
}
}
}
- _item1.setDetails(Rect(0, 0, 320, 200), 900, 0, -1, -1, 1, NULL);
+
+ _background.setDetails(Rect(0, 0, 320, 200), 900, 0, -1, -1, 1, NULL);
_sceneMode = 900;
- setAction(&_sequenceManager1, this, 900, &_actor1, NULL);
+ setAction(&_sequenceManager1, this, 900, &_controls, NULL);
}
void Scene900::remove() {
@@ -7555,7 +7742,7 @@ void Scene900::remove() {
void Scene900::signal() {
switch (_sceneMode) {
case 1:
- _field412 = 1;
+ _controlsScreenNumber = 1;
R2_GLOBALS._sound2.play(37);
_button2.remove();
@@ -7574,13 +7761,13 @@ void Scene900::signal() {
_button3.setPosition(Common::Point(117, 166));
break;
case 2:
- _field412 = 2;
+ _controlsScreenNumber = 2;
_button2.remove();
_button3.remove();
_button2.initButton(2);
- if (R2_GLOBALS._v565E5 == 0)
+ if (!R2_GLOBALS._tractorField)
_button2.setup(900, 3, 9);
else
_button2.setup(900, 3, 11);
@@ -7604,7 +7791,7 @@ void Scene900::signal() {
break;
case 3:
- _field412 = 3;
+ _controlsScreenNumber = 3;
_button2.remove();
_button3.remove();
@@ -7625,13 +7812,13 @@ void Scene900::signal() {
_sceneMode = 0;
R2_GLOBALS._player.enableControl();
R2_GLOBALS._player._canWalk = false;
- R2_GLOBALS._v565E7 = 1;
+ R2_GLOBALS._cableAttached = true;
break;
case 900:
R2_GLOBALS._player.enableControl(CURSOR_USE);
R2_GLOBALS._player._canWalk = false;
- _actor1.setup(900, 1, 1);
+ _controls.setup(900, 1, 1);
_button1.initButton(1);
_button1.setup(900, 1, 3);
@@ -7674,27 +7861,27 @@ void Scene900::dispatch() {
}
}
- if (R2_GLOBALS._sceneObjects->contains(&_actor2)) {
- if ((R2_GLOBALS._v565E5 != 0) && (R2_INVENTORY.getObjectScene(R2_CABLE_HARNESS) == 0) && (R2_INVENTORY.getObjectScene(R2_ATTRACTOR_CABLE_HARNESS) == 700) && (R2_GLOBALS._electromagnetChangeAmount == 20) && (R2_GLOBALS._electromagnetZoom == 70)) {
- if ((_actor2._frame > 1) && (_actor2._animateMode != ANIM_MODE_6))
- _actor2.animate(ANIM_MODE_6, NULL);
+ if (R2_GLOBALS._sceneObjects->contains(&_cable)) {
+ if (R2_GLOBALS._tractorField && (R2_INVENTORY.getObjectScene(R2_CABLE_HARNESS) == 0) && (R2_INVENTORY.getObjectScene(R2_ATTRACTOR_CABLE_HARNESS) == 700) && (R2_GLOBALS._electromagnetChangeAmount == 20) && (R2_GLOBALS._electromagnetZoom == 70)) {
+ if ((_cable._frame > 1) && (_cable._animateMode != ANIM_MODE_6))
+ _cable.animate(ANIM_MODE_6, NULL);
} else {
- if ((_actor2._frame < 8) && (_actor2._animateMode != ANIM_MODE_5) && (R2_GLOBALS._v565E7 == 0) && (R2_INVENTORY.getObjectScene(R2_CABLE_HARNESS) == 0) && (R2_INVENTORY.getObjectScene(R2_ATTRACTOR_CABLE_HARNESS) == 700) && (_sceneMode != 4))
- _actor2.animate(ANIM_MODE_5, NULL);
+ if ((_cable._frame < 8) && (_cable._animateMode != ANIM_MODE_5) && !R2_GLOBALS._cableAttached && (R2_INVENTORY.getObjectScene(R2_CABLE_HARNESS) == 0) && (R2_INVENTORY.getObjectScene(R2_ATTRACTOR_CABLE_HARNESS) == 700) && (_sceneMode != 4))
+ _cable.animate(ANIM_MODE_5, NULL);
}
}
_electromagnet.changeZoom(100 - ((R2_GLOBALS._electromagnetZoom * 70) / 100));
_electromagnet.setPosition(Common::Point(((_electromagnet._percent * R2_GLOBALS._electromagnetChangeAmount * 6) / 100) + 89, R2_GLOBALS._electromagnetZoom));
- if ((R2_GLOBALS._sceneObjects->contains(&_actor2)) && (R2_GLOBALS._v565E7 != 0) && (!_actor2._mover) && (_actor2._animateMode == ANIM_MODE_NONE)) {
- _actor2.setPosition(Common::Point(_electromagnet._position.x + ((_electromagnet._percent * 49) / 100), _electromagnet._position.y + ((_electromagnet._percent * 3) / 10)));
+ if ((R2_GLOBALS._sceneObjects->contains(&_cable)) && R2_GLOBALS._cableAttached && (!_cable._mover) && (_cable._animateMode == ANIM_MODE_NONE)) {
+ _cable.setPosition(Common::Point(_electromagnet._position.x + ((_electromagnet._percent * 49) / 100), _electromagnet._position.y + ((_electromagnet._percent * 3) / 10)));
if (R2_GLOBALS._electromagnetZoom >= 75) {
- _actor2.setup(901, 1, 1);
- _actor2.changeZoom(((_electromagnet._percent + 52) / 10) * 10);
+ _cable.setup(901, 1, 1);
+ _cable.changeZoom(((_electromagnet._percent + 52) / 10) * 10);
} else {
- _actor2.setup(901, 5, 1);
- _actor2.changeZoom(((_electromagnet._percent / 10) * 10) + 30);
+ _cable.setup(901, 5, 1);
+ _cable.changeZoom(((_electromagnet._percent / 10) * 10) + 30);
}
}
Scene::dispatch();
diff --git a/engines/tsage/ringworld2/ringworld2_scenes0.h b/engines/tsage/ringworld2/ringworld2_scenes0.h
index df0b4d8fc6..216039a348 100644
--- a/engines/tsage/ringworld2/ringworld2_scenes0.h
+++ b/engines/tsage/ringworld2/ringworld2_scenes0.h
@@ -85,7 +85,7 @@ class Scene100: public SceneExt {
public:
NamedHotspot _background, _duct, _bed, _desk;
Terminal _terminal;
- SceneActor _bedLights1, _bedLights2, _object3, _object4, _object5;
+ SceneActor _bedLights1, _bedLights2, _tableLocker, _wardrobeTopAnim, _wardrobeColorAnim;
SceneActor _wardrobe;
Door _door;
Table _table;
@@ -109,9 +109,9 @@ class Scene125: public SceneExt {
class Icon: public SceneActor {
public:
- int _lookLineNum, _field98;
+ int _lookLineNum, _iconId;
bool _pressed;
- SceneObject _object1, _object2;
+ SceneObject _glyph, _horizLine;
SceneText _sceneText1, _sceneText2;
Icon();
@@ -136,7 +136,8 @@ public:
ASoundExt _sound1;
NamedHotspot _background, _item2, _item3;
DiskSlot _diskSlot;
- SceneActor _object1, _object2, _object3, _object4, _food, _foodDispenser, _infoDisk;
+ SceneActor _starchart1, _starchart2, _starchart3, _starchart4;
+ SceneActor _food, _foodDispenser, _infoDisk;
Icon _icon1, _icon2, _icon3, _icon4, _icon5, _icon6;
SequenceManager _sequenceManager;
SceneText _sceneText;
@@ -175,7 +176,6 @@ public:
ASound _sound1;
Action1 _action1;
int _frameNumber, _yChange;
- SceneObject _object1, _object2, _object3;
int _lineNum;
SynchronizedList<SceneText *> _creditsList;
public:
@@ -197,11 +197,11 @@ class Scene180: public SceneExt {
private:
void setSceneDelay(int v);
public:
- SpeakerWebbster _webbsterSpeaker;
- SpeakerDutyOfficer _dutyOfficerSpeaker;
- SpeakerTeal _tealSpeaker;
+ SpeakerWebbster180 _webbsterSpeaker;
+ SpeakerDutyOfficer180 _dutyOfficerSpeaker;
+ SpeakerTeal180 _tealSpeaker;
SpeakerGameText _gameTextSpeaker;
- SceneActor _object1, _object2, _object3, _object4, _object5;
+ SceneActor _dutyOfficer, _teal, _webbster, _door, _shipDisplay;
ScenePalette _palette;
SceneText _textList[20];
AnimationPlayerExt _animationPlayer;
@@ -210,10 +210,9 @@ public:
ASoundExt _sound1;
int _frameNumber;
- int _field412, _field480;
- int _field482, _frameInc;
+ bool _helpEnabled;
+ int _frameInc;
int _fontNumber, _fontHeight;
- int _scene180Mode;
public:
Scene180();
@@ -263,6 +262,13 @@ public:
virtual void signal();
};
+class Star: public SceneObject {
+public:
+ int _x100, _y100;
+public:
+ virtual Common::String getClassName() { return "Scene205_Star"; }
+};
+
class Scene205: public SceneExt {
/* Actions */
class Action1: public Action {
@@ -271,26 +277,18 @@ class Scene205: public SceneExt {
public:
virtual void signal();
};
-
- /* Objects */
- class Object: public SceneObject {
- public:
- int _x100, _y100;
- public:
- // TODO: Check if this derives from DataManager? and flesh out
- };
private:
void setup();
- void processList(Object **ObjList, int count, const Common::Rect &bounds,
+ void processList(Star **ObjList, int count, const Common::Rect &bounds,
int xMultiply, int yMultiply, int xCenter, int yCenter);
void handleText();
public:
AnimationPlayer _animationPlayer;
int _fontHeight;
SceneText _textList[15];
- Object *_objList1[3];
- Object *_objList2[3];
- Object *_objList3[4];
+ Star *_starList1[3];
+ Star *_starList2[3];
+ Star *_starList3[4];
ASound _sound1;
Action1 _action1;
int _yp;
@@ -306,6 +304,23 @@ public:
virtual void dispatch();
};
+class Scene205Demo: public SceneExt {
+ /* Actions */
+ class Action1: public Action {
+ public:
+ virtual void signal();
+ };
+private:
+ void leaveScene();
+public:
+ VisualSpeaker _animationPlayer;
+ ASound _sound1;
+ Action1 _action1;
+public:
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void remove();
+ virtual void process(Event &event);
+};
class Scene250: public SceneExt {
class Button: public SceneActor {
@@ -320,8 +335,8 @@ class Scene250: public SceneExt {
public:
int _currButtonY, _destButtonY, _elevatorSpeed;
bool _skippingFl, _skippableFl;
- NamedHotspot _background, _item2, _item3, _item4;
- Button _button1, _currentFloor;
+ NamedHotspot _background, _door, _directionIndicator;
+ Button _destinationFloor, _currentFloor;
Button _floor1, _floor2, _floor3, _floor4, _floor5;
Button _floor6, _floor7, _floor8, _floor9;
ASoundExt _sound1;
@@ -403,8 +418,8 @@ public:
QuinnWorkstation _quinnWorkstation1, _quinnWorkstation2;
SeekerWorkstation _seekerWorkstation;
MirandaWorkstation _mirandaWorkstation1, _mirandaWorkstation2;
- SceneActor _object1, _object2, _object3, _object4, _protocolDisplay;
- SceneActor _object6, _object7, _object8, _object9;
+ SceneActor _atmosphereLeftWindow, _atmosphereRightWindow, _leftVerticalBarsAnim, _rightVerticalBarsAnim, _protocolDisplay;
+ SceneActor _rightTextDisplay, _mirandaScreen, _leftTextDisplay, _quinnScreen;
SceneActor _teal, _soldier, _object12;
Doorway _doorway;
Miranda _miranda;
@@ -429,9 +444,9 @@ public:
class Scene325: public SceneExt {
class Icon: public SceneActor {
public:
- int _lookLineNum, _field98;
+ int _lookLineNum, _iconId;
bool _pressed;
- SceneObject _object1, _object2;
+ SceneObject _glyph, _horizLine;
SceneText _sceneText1, _sceneText2;
Icon();
@@ -451,16 +466,17 @@ private:
void setMessage(int resNum, int lineNum);
Common::String parseMessage(const Common::String &msg);
public:
- int _field412, _iconFontNumber, _field416, _field418;
- int _field41A, _field41C, _field41E, _scannerLocation;
+ int _consoleAction, _iconFontNumber, _databasePage, _priorConsoleAction;
+ int _moveCounter, _yChange, _yDirection, _scannerLocation;
int _soundCount, _soundIndex;
int _soundQueue[10];
SpeakerQuinn _quinnSpeaker;
ScenePalette _palette;
- SceneHotspot _background, _item2;
- SceneObject _object1, _object2, _object3, _object4, _object5;
- SceneObject _object6, _object7, _object8, _object9, _object10;
- SceneObject _object11, _object12, _scannerTab;
+ SceneHotspot _background, _terminal;
+ SceneObject _starGrid1, _starGrid2, _starGrid3; // Both starchart & scan grid objects
+ SceneObject _starGrid4, _starGrid5, _starGrid6, _starGrid7;
+ SceneObject _starGrid8, _starGrid9, _starGrid10, _starGrid11;
+ SceneObject _starGrid12, _starGrid13;
SceneObject _objList[4];
Icon _icon1, _icon2, _icon3, _icon4, _icon5, _icon6;
ASoundExt _sound1;
@@ -477,7 +493,6 @@ public:
virtual void dispatch();
};
-
class Scene400: public SceneExt {
/* Items */
class Terminal: public NamedHotspot {
@@ -532,7 +547,7 @@ class Scene500: public SceneExt {
int _buttonId;
bool _buttonDown;
- void doButtonPress();
+ void doButtonPress();
public:
Button();
virtual Common::String getClassName() { return "Scene500_Button"; }
@@ -577,8 +592,9 @@ class Scene500: public SceneExt {
public:
virtual bool startAction(CursorType action, Event &event);
};
- class Object8: public SceneActor {
- // This classes uses a custom draw method
+ class TransparentDoor: public SceneActor {
+ public:
+ virtual void draw();
};
class Aerosol: public SceneActor {
public:
@@ -598,18 +614,17 @@ class Scene500: public SceneExt {
};
public:
int _stripNumber;
- byte _buffer[2710];
SpeakerSeeker500 _seekerSpeaker;
SpeakerQuinn500 _quinnSpeaker;
- SceneHotspot _background, _item2;
+ SceneHotspot _background, _airlockCorridor;
ControlPanel _controlPanel;
- SceneActor _object1;
+ SceneActor _suits;
Seeker _seeker;
Suit _suit;
Doorway _doorway;
OxygenTanks _tanks1, _tanks2;
AirLock _airLock;
- Object8 _object8;
+ TransparentDoor _transparentDoor;
Aerosol _aerosol;
SonicStunner _sonicStunner;
Locker1 _locker1;
@@ -630,7 +645,6 @@ public:
virtual void postInit(SceneObjectList *OwnerList = NULL);
virtual void signal();
-
};
class Scene600 : public SceneExt {
@@ -638,7 +652,7 @@ class Scene600 : public SceneExt {
public:
virtual bool startAction(CursorType action, Event &event);
};
- class Item4 : public NamedHotspot {
+ class EngineCompartment : public NamedHotspot {
public:
virtual bool startAction(CursorType action, Event &event);
};
@@ -666,14 +680,14 @@ class Scene600 : public SceneExt {
virtual bool startAction(CursorType action, Event &event);
};
public:
- int _field412;
+ int _roomState;
+ CompartmentHotspot _quantumDrive;
+ CompartmentHotspot _quantumRegulator;
+ CompartmentHotspot _powerNode;
+ EngineCompartment _engineCompartment;
CompartmentHotspot _background;
- CompartmentHotspot _item2;
- CompartmentHotspot _item3;
- Item4 _item4;
- CompartmentHotspot _item5;
- BackgroundSceneObject _object1;
- SceneActor _actor1;
+ SceneActor _stasisArea;
+ SceneActor _laserBeam;
SceneActor _computer;
SceneActor _stasisField;
Smoke _smoke;
@@ -681,7 +695,7 @@ public:
Laser _laser;
Aerosol _aerosol;
Scanner _scanner;
- ASoundExt _aSound1;
+ ASoundExt _sound1;
SequenceManager _sequenceManager1;
SequenceManager _sequenceManager2;
byte _pixelMap[256];
@@ -696,7 +710,7 @@ public:
};
class Scene700: public SceneExt {
- class Item11 : public NamedHotspot {
+ class Loft : public NamedHotspot {
public:
virtual bool startAction(CursorType action, Event &event);
};
@@ -705,15 +719,15 @@ class Scene700: public SceneExt {
virtual bool startAction(CursorType action, Event &event);
};
- class Actor2 : public SceneActor {
+ class LiftDoor : public SceneActor {
public:
virtual bool startAction(CursorType action, Event &event);
};
- class Actor3 : public SceneActor {
+ class SuitRoomDoor : public SceneActor {
public:
virtual bool startAction(CursorType action, Event &event);
};
- class Actor4 : public SceneActor {
+ class ControlPanel : public SceneActor {
public:
virtual bool startAction(CursorType action, Event &event);
};
@@ -721,35 +735,34 @@ class Scene700: public SceneExt {
public:
virtual bool startAction(CursorType action, Event &event);
};
- class Actor6 : public SceneActor {
+ class LoftDoor : public SceneActor {
public:
virtual bool startAction(CursorType action, Event &event);
};
public:
- NamedHotspot _item1;
- NamedHotspot _item2;
- NamedHotspot _item3;
- NamedHotspot _item4;
- NamedHotspot _item5;
- NamedHotspot _item6;
- NamedHotspot _item7;
- NamedHotspot _item8;
- NamedHotspot _item9;
- NamedHotspot _item10;
- Item11 _item11;
+ NamedHotspot _background;
+ NamedHotspot _debris1;
+ NamedHotspot _debris2;
+ NamedHotspot _debris3;
+ NamedHotspot _debris4;
+ NamedHotspot _restraintCollar;
+ NamedHotspot _storage2;
+ NamedHotspot _storage1;
+ NamedHotspot _stars;
+ NamedHotspot _light;
+ Loft _loft;
HandGrip _handGrip;
- SceneActor _actor1;
- Actor2 _actor2;
- Actor3 _actor3;
- Actor4 _actor4;
+ SceneActor _electromagnet;
+ LiftDoor _liftDoor;
+ SuitRoomDoor _suitRoomDoor;
+ ControlPanel _controlPanel;
Cable _cable;
- Actor6 _actor6;
- Actor6 _actor7;
- Actor6 _actor8;
- Actor6 _actor9;
+ LoftDoor _loftDoor1;
+ LoftDoor _loftDoor2;
+ LoftDoor _loftDoor3;
+ LoftDoor _loftDoor4;
SequenceManager _sequenceManager;
PaletteRotation *_rotation;
- int _field100E;
Scene700();
virtual void postInit(SceneObjectList *OwnerList = NULL);
@@ -811,7 +824,7 @@ class Scene825: public SceneExt {
/* Objects */
class Button: public SceneObject {
public:
- int _buttonId, _v2;
+ int _buttonId;
bool _buttonDown;
SceneText _sceneText;
public:
@@ -824,8 +837,8 @@ class Scene825: public SceneExt {
virtual bool startAction(CursorType action, Event &event);
};
public:
- NamedHotspot _background, _item2;
- SceneActor _object1, _object2, _object3, _object4, _object5;
+ NamedHotspot _background, _console;
+ SceneActor _vertLine1, _vertLine2, _vertLine3, _vertLine4, _vertLine5;
Button _button1, _button2, _button3, _button4, _button5, _button6;
ASoundExt _sound1, _sound2, _sound3, _sound4;
SequenceManager _sequenceManager1;
@@ -872,7 +885,7 @@ public:
NamedHotspot _background, _eastDoor, _compartment, _sickBayIndicator;
NamedHotspot _liftControls;
Indicator _indicator;
- SceneActor _object1, _fibre;
+ SceneActor _spark, _fibre;
LiftDoor _liftDoor;
SickBayDoor _sickBayDoor;
Clamp _clamp;
@@ -894,11 +907,11 @@ class Scene900 : public SceneExt {
virtual bool startAction(CursorType action, Event &event);
};
public:
- int _field412;
+ int _controlsScreenNumber;
Common::Point _magnetChangeAmount;
- NamedHotspot _item1;
- SceneActor _actor1;
- SceneActor _actor2;
+ NamedHotspot _background;
+ SceneActor _controls;
+ SceneActor _cable;
SceneActor _electromagnet;
Button _button1;
Button _button2;
diff --git a/engines/tsage/ringworld2/ringworld2_scenes1.cpp b/engines/tsage/ringworld2/ringworld2_scenes1.cpp
index 29bef2ccb2..50341e3d0e 100644
--- a/engines/tsage/ringworld2/ringworld2_scenes1.cpp
+++ b/engines/tsage/ringworld2/ringworld2_scenes1.cpp
@@ -20,6 +20,8 @@
*
*/
+#include "graphics/cursorman.h"
+
#include "tsage/scenes.h"
#include "tsage/tsage.h"
#include "tsage/staticres.h"
@@ -100,10 +102,10 @@ void Scene1000::remove() {
void Scene1000::signal() {
ScenePalette scenePalette1, scenePalette2;
uint32 black = 0;
-
+
switch (_sceneMode++) {
case 0:
- // TODO: Sort out values
+ // TODO: Determine correct colors
R2_GLOBALS._gfxColors.foreground = 191;
R2_GLOBALS._gfxColors.background = 144;
R2_GLOBALS._fontColors.background = 224;
@@ -117,7 +119,7 @@ void Scene1000::signal() {
_animationPlayer.dispatch();
_forceCheckAnimationFl = true;
-
+
R2_GLOBALS._scenePalette.fade((const byte *)&black, true, 0);
for (int percent = 0; percent < 100; percent += 5)
R2_GLOBALS._scenePalette.fade((const byte *)&black, true, percent);
@@ -128,7 +130,7 @@ void Scene1000::signal() {
case 1:
R2_GLOBALS._sound1.fadeOut2(NULL);
- // TODO: Sort out values
+ // TODO: Determine correct colors
R2_GLOBALS._gfxColors.foreground = 191;
R2_GLOBALS._gfxColors.background = 144;
R2_GLOBALS._fontColors.background = 224;
@@ -146,9 +148,9 @@ void Scene1000::signal() {
break;
case 2:
- if (R2_GLOBALS._speechSubtitles & SPEECH_TEXT) {
+ if (R2_GLOBALS._speechSubtitles & SPEECH_TEXT)
setAction(&_sequenceManager1, this, 1, &R2_GLOBALS._player, NULL);
- } else {
+ else {
if (++_animCounter < 3)
_sceneMode = 2;
@@ -157,7 +159,7 @@ void Scene1000::signal() {
break;
case 3:
- // TODO: Sort out values
+ // TODO: Determine correct colors
R2_GLOBALS._gfxColors.foreground = 191;
R2_GLOBALS._gfxColors.background = 144;
R2_GLOBALS._fontColors.background = 224;
@@ -184,7 +186,7 @@ void Scene1000::signal() {
break;
case 4:
- // TODO: Sort out values
+ // TODO: Determine correct colors
R2_GLOBALS._gfxColors.foreground = 191;
R2_GLOBALS._gfxColors.background = 144;
R2_GLOBALS._fontColors.background = 224;
@@ -334,7 +336,7 @@ void Scene1000::signal() {
case 60:
R2_GLOBALS._sound1.play(333);
-
+
for (int percent = 100; percent >= 0; percent -= 5)
R2_GLOBALS._scenePalette.fade((const byte *)&black, true, percent);
@@ -443,7 +445,7 @@ void Scene1000::signal() {
R2_GLOBALS._scenePalette.fade((const byte *)&black, 1, 0);
for (int percent = 0; percent < 100; percent += 5)
R2_GLOBALS._scenePalette.fade((const byte *)&black, true, percent);
- break;
+ break;
case 101:
R2_GLOBALS._sound1.fadeOut2(NULL);
@@ -463,9 +465,8 @@ void Scene1000::dispatch() {
if (_sceneMode == 52)
_animationPlayer._endAction = this;
- } else {
+ } else
_animationPlayer.dispatch();
- }
}
Scene::dispatch();
@@ -478,10 +479,11 @@ void Scene1000::dispatch() {
*--------------------------------------------------------------------------*/
void Scene1010::postInit(SceneObjectList *OwnerList) {
- SceneExt::postInit();
loadScene(1010);
-
R2_GLOBALS._uiElements._active = false;
+ SceneExt::postInit();
+ R2_GLOBALS._interfaceY = SCREEN_HEIGHT;
+
setZoomPercents(100, 1, 160, 100);
R2_GLOBALS._player.postInit();
R2_GLOBALS._player.setObjectWrapper(NULL);
@@ -533,18 +535,19 @@ void Scene1010::signal() {
}
/*--------------------------------------------------------------------------
- * Scene 1020 -
+ * Scene 1020 - Cutscene - trip in space 2
*
*--------------------------------------------------------------------------*/
+
void Scene1020::postInit(SceneObjectList *OwnerList) {
- SceneExt::postInit();
loadScene(1020);
+ R2_GLOBALS._uiElements._active = false;
+ SceneExt::postInit();
if (R2_GLOBALS._sceneManager._previousScene == 1010)
- g_globals->gfxManager()._bounds.moveTo(Common::Point(160, 0));
+ _sceneBounds = Rect(160, 0, SCREEN_WIDTH + 160, 200);
- R2_GLOBALS._v558B6.set(160, 0, 160, 161);
- R2_GLOBALS._uiElements._active = false;
+ R2_GLOBALS._interfaceY = SCREEN_HEIGHT;
R2_GLOBALS._player.postInit();
if (R2_GLOBALS._sceneManager._previousScene == 1010) {
@@ -658,9 +661,10 @@ void Scene1020::dispatch() {
}
/*--------------------------------------------------------------------------
- * Scene 1100 -
+ * Scene 1100 - Canyon
*
*--------------------------------------------------------------------------*/
+
Scene1100::Scene1100() {
_nextStripNum = 0;
_paletteRefreshStatus = 0;
@@ -674,12 +678,13 @@ void Scene1100::synchronize(Serializer &s) {
}
bool Scene1100::Seeker::startAction(CursorType action, Event &event) {
- Scene1100 *scene = (Scene1100 *)R2_GLOBALS._sceneManager._scene;
-
if (action != CURSOR_TALK)
return SceneActor::startAction(action, event);
+ Scene1100 *scene = (Scene1100 *)R2_GLOBALS._sceneManager._scene;
+
if (R2_GLOBALS.getFlag(52)) {
+ // The trouper is dead
R2_GLOBALS._player.disableControl();
if (R2_GLOBALS._player._characterIndex == R2_QUINN)
scene->_nextStripNum = 327;
@@ -688,15 +693,16 @@ bool Scene1100::Seeker::startAction(CursorType action, Event &event) {
scene->_sceneMode = 53;
scene->setAction(&scene->_sequenceManager1, scene, 1122, &R2_GLOBALS._player, NULL);
} else {
+ // The trouper is not dead
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 55;
- if (R2_GLOBALS._v565AE >= 3) {
+ if (R2_GLOBALS._stripModifier >= 3) {
if (R2_GLOBALS._player._characterIndex == R2_QUINN)
scene->_stripManager.start3(329, scene, R2_GLOBALS._stripManager_lookupList);
else
scene->_stripManager.start3(330, scene, R2_GLOBALS._stripManager_lookupList);
} else {
- ++R2_GLOBALS._v565AE;
+ ++R2_GLOBALS._stripModifier;
R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
if (R2_GLOBALS._player._characterIndex == R2_QUINN)
scene->_stripManager.start3(304, scene, R2_GLOBALS._stripManager_lookupList);
@@ -713,18 +719,19 @@ bool Scene1100::Trooper::startAction(CursorType action, Event &event) {
switch (action) {
case R2_NEGATOR_GUN:
if (_visage == 1105) {
+ // Trooper wears the stasis shield
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 1114;
scene->setAction(&scene->_sequenceManager1, scene, 1114, &R2_GLOBALS._player, &scene->_trooper, NULL);
return true;
- } else {
+ } else
return SceneActor::startAction(action, event);
- }
break;
case R2_SONIC_STUNNER:
// No break on purpose
case R2_PHOTON_STUNNER:
if (_visage == 1105) {
+ // If trooper wears the stasis shield
R2_GLOBALS._player.disableControl();
if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
scene->_sceneMode = 1112;
@@ -735,17 +742,16 @@ bool Scene1100::Trooper::startAction(CursorType action, Event &event) {
}
return true;
} else if (_strip == 2) {
+ // Trooper wears his black uniform
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 1113;
- if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
scene->setAction(&scene->_sequenceManager1, scene, 1113, &R2_GLOBALS._player, &scene->_trooper, NULL);
- } else {
+ else
scene->setAction(&scene->_sequenceManager1, scene, 1118, &R2_GLOBALS._player, &scene->_trooper, NULL);
- }
return true;
- } else {
+ } else
return SceneActor::startAction(action, event);
- }
break;
default:
return SceneActor::startAction(action, event);
@@ -754,9 +760,11 @@ bool Scene1100::Trooper::startAction(CursorType action, Event &event) {
}
bool Scene1100::Chief::startAction(CursorType action, Event &event) {
- Scene1100 *scene = (Scene1100 *)R2_GLOBALS._sceneManager._scene;
-
+ // CHECKME: Flag 54 is never set. Guess: the flag means "Chief is dead"
if ((action == CURSOR_TALK) && (!R2_GLOBALS.getFlag(54)) && (R2_GLOBALS.getFlag(52))) {
+ // Talk to chief after the trooper dies
+ Scene1100 *scene = (Scene1100 *)R2_GLOBALS._sceneManager._scene;
+
scene->_nextStripNum = 0;
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 53;
@@ -773,20 +781,14 @@ void Scene1100::postInit(SceneObjectList *OwnerList) {
else
loadScene(1100);
- if ((R2_GLOBALS._sceneManager._previousScene == 1000) && (!R2_GLOBALS.getFlag(44))) {
+ if ((R2_GLOBALS._sceneManager._previousScene == 1000) && (!R2_GLOBALS.getFlag(44)))
R2_GLOBALS._uiElements._active = false;
- R2_GLOBALS._v5589E.left = 0;
- R2_GLOBALS._v5589E.right = 200;
- }
if (R2_GLOBALS._player._characterScene[R2_QUINN] == 1100)
R2_GLOBALS._sceneManager._previousScene = 1100;
- if (R2_GLOBALS._sceneManager._previousScene == -1) {
+ if (R2_GLOBALS._sceneManager._previousScene == -1)
R2_GLOBALS._uiElements._active = false;
- R2_GLOBALS._v5589E.left = 0;
- R2_GLOBALS._v5589E.right = 200;
- }
SceneExt::postInit();
@@ -801,16 +803,16 @@ void Scene1100::postInit(SceneObjectList *OwnerList) {
scalePalette(65, 65, 65);
- _actor2.postInit();
- _actor2.setup(1100, 1, 1);
- _actor2.fixPriority(10);
+ _cloud.postInit();
+ _cloud.setup(1100, 1, 1);
+ _cloud.fixPriority(10);
R2_GLOBALS._scrollFollower = NULL;
- _item3.setDetails(Rect(56, 47, 68, 83), 1100, 7, -1, -1, 1, NULL);
- _item4.setDetails(Rect(167, 132, 183, 167), 1100, 7, -1, -1, 1, NULL);
- _item5.setDetails(Rect(26, 112, 87, 145), 1100, 13, -1, -1, 1, NULL);
- _item7.setDetails(Rect(4, 70, 79, 167), 1100, 16, -1, -1, 1, NULL);
+ _fuana1.setDetails(Rect(56, 47, 68, 83), 1100, 7, -1, -1, 1, NULL);
+ _fauna2.setDetails(Rect(167, 132, 183, 167), 1100, 7, -1, -1, 1, NULL);
+ _bouldersBlockingCave.setDetails(Rect(26, 112, 87, 145), 1100, 13, -1, -1, 1, NULL);
+ _trail.setDetails(Rect(4, 70, 79, 167), 1100, 16, -1, -1, 1, NULL);
R2_GLOBALS._sound1.stop();
@@ -819,7 +821,7 @@ void Scene1100::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player._characterIndex = R2_QUINN;
R2_GLOBALS._player._characterScene[R2_QUINN] = 1100;
R2_GLOBALS._player._characterScene[R2_SEEKER] = 1100;
- _actor2.setPosition(Common::Point(150, 30));
+ _cloud.setPosition(Common::Point(150, 30));
R2_GLOBALS._sound1.play(93);
R2_GLOBALS._player.postInit();
R2_GLOBALS._player.hide();
@@ -843,29 +845,30 @@ void Scene1100::postInit(SceneObjectList *OwnerList) {
_chief.setDetails(1100, 3, -1, -1, 1, (SceneItem *) NULL);
_trooper.postInit();
+ // Trooper wears his stasis shield
_trooper.setup(1105, 3, 1);
_trooper.setPosition(Common::Point(312, 165));
_trooper._numFrames = 5;
_trooper.setDetails(1100, 22, 23, 24, 1, (SceneItem *) NULL);
- _actor1.postInit();
- _actor1.setup(1512, 1, 1);
- _actor1.setPosition(Common::Point(187, -25));
- _actor1.fixPriority(48);
- _actor1._moveDiff.y = 1;
- _actor1.setDetails(1100, 37, -1, -1, 1, (SceneItem *) NULL);
+ _ship.postInit();
+ _ship.setup(1512, 1, 1);
+ _ship.setPosition(Common::Point(187, -25));
+ _ship.fixPriority(48);
+ _ship._moveDiff.y = 1;
+ _ship.setDetails(1100, 37, -1, -1, 1, (SceneItem *) NULL);
_sceneMode = 20;
setAction(&_sequenceManager1, this, 1, &R2_GLOBALS._player, NULL);
} else if (R2_GLOBALS._sceneManager._previousScene == 1000) {
- _actor2.setPosition(Common::Point(50, 30));
+ _cloud.setPosition(Common::Point(50, 30));
_paletteRefreshStatus = 0;
_palette1.loadPalette(1101);
R2_GLOBALS._player.postInit();
R2_GLOBALS._player.disableControl();
- R2_GLOBALS._player._effect = 5;
- R2_GLOBALS._player._field9C = _field312;
+ R2_GLOBALS._player._effect = EFFECT_SHADOW_MAP;
+ R2_GLOBALS._player._shadowMap = _shadowPaletteMap;
R2_GLOBALS._player.setup(1102, 3, 2);
R2_GLOBALS._player.setObjectWrapper(NULL);
R2_GLOBALS._player.setPosition(Common::Point(111,-20));
@@ -873,8 +876,8 @@ void Scene1100::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player._moveRate = 30;
R2_GLOBALS._player._moveDiff = Common::Point(16, 2);
- _rightLandslide.setup2(1104, 2, 1, 175, 125, 102, 1);
- _object2.setup2(1102, 5, 1, 216, 167, 1, 0);
+ _rightLandslide.setup2(1104, 2, 1, 175, 125, 102, EFFECT_SHADED);
+ _purplePlant.setup2(1102, 5, 1, 216, 167, 1, EFFECT_NONE);
_leftImpacts.postInit();
_leftImpacts.setup(1113, 2, 1);
@@ -890,8 +893,8 @@ void Scene1100::postInit(SceneObjectList *OwnerList) {
_shipFormationShadow.setup(1102, 6, 2);
_shipFormationShadow._moveRate = 30;
_shipFormationShadow._moveDiff.x = 2;
- _shipFormationShadow._effect = 5;
- _shipFormationShadow._field9C = _field312;
+ _shipFormationShadow._effect = EFFECT_SHADOW_MAP;
+ _shipFormationShadow._shadowMap = _shadowPaletteMap;
R2_GLOBALS._sound1.play(86);
@@ -899,10 +902,12 @@ void Scene1100::postInit(SceneObjectList *OwnerList) {
setAction(&_sequenceManager1, this, 1, &R2_GLOBALS._player, NULL);
} else {
- _actor2.setPosition(Common::Point(180, 30));
+ _cloud.setPosition(Common::Point(180, 30));
if (R2_GLOBALS.getFlag(52))
+ // Trooper is dead
R2_GLOBALS._sound1.play(98);
else
+ // Trooper is alive
R2_GLOBALS._sound1.play(95);
R2_GLOBALS._player.postInit();
@@ -911,6 +916,7 @@ void Scene1100::postInit(SceneObjectList *OwnerList) {
_seeker.postInit();
if (R2_GLOBALS.getFlag(52)) {
+ // Trooper is dead
if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
R2_GLOBALS._player.setup(19, 7, 1);
_seeker.setup(29, 6, 1);
@@ -922,6 +928,7 @@ void Scene1100::postInit(SceneObjectList *OwnerList) {
_seeker.setPosition(Common::Point(237, 134));
R2_GLOBALS._player.enableControl();
} else {
+ // Trooper is alive
if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
R2_GLOBALS._player.setup(1107, 2, 1);
_seeker.setup(1107, 4, 1);
@@ -953,32 +960,37 @@ void Scene1100::postInit(SceneObjectList *OwnerList) {
_chief.setDetails(1100, 3, -1, -1, 1, (SceneItem *) NULL);
if (!R2_GLOBALS.getFlag(52)) {
+ // If trooper is alive, initialize him
_trooper.postInit();
if (R2_GLOBALS.getFlag(53))
+ // Trooper wears his black uniform
_trooper.setup(1106, 2, 4);
else
+ // Trooper wears a stasis shield
_trooper.setup(1105, 4, 4);
_trooper.setPosition(Common::Point(17, 54));
_trooper._numFrames = 5;
if (R2_GLOBALS.getFlag(53))
+ // Trooper isn't wearing the stasis shield
_trooper.setDetails(1100, 28, -1, -1, 1, (SceneItem *) NULL);
else
_trooper.setDetails(1100, 22, 23, 24, 1, (SceneItem *) NULL);
_trooper.fixPriority(200);
}
- _actor1.postInit();
- _actor1.setup(1512, 1, 1);
- _actor1.setPosition(Common::Point(187, 45));
- _actor1.fixPriority(48);
- _actor1._moveDiff.y = 1;
- _actor1.setDetails(1100, 37, -1, -1, 1, (SceneItem *) NULL);
+ _ship.postInit();
+ _ship.setup(1512, 1, 1);
+ _ship.setPosition(Common::Point(187, 45));
+ _ship.fixPriority(48);
+ _ship._moveDiff.y = 1;
+ _ship.setDetails(1100, 37, -1, -1, 1, (SceneItem *) NULL);
}
- _item6.setDetails(Rect(123, 69, 222, 105), 1100, 13, -1, -1, 1, NULL);
- _item2.setDetails(Rect(0, 0, 480, 46), 1100, 0, -1, -1, 1, NULL);
- _item1.setDetails(Rect(0, 0, 480, 200), 1100, 40, 41, 42, 1, NULL);
+
+ _boulders.setDetails(Rect(123, 69, 222, 105), 1100, 13, -1, -1, 1, NULL);
+ _sky.setDetails(Rect(0, 0, 480, 46), 1100, 0, -1, -1, 1, NULL);
+ _background.setDetails(Rect(0, 0, 480, 200), 1100, 40, 41, 42, 1, NULL);
}
void Scene1100::remove() {
@@ -1033,12 +1045,12 @@ void Scene1100::signal() {
break;
case 5:
_runningGuy1.postInit();
- _runningGuy1._effect = 6;
+ _runningGuy1._effect = EFFECT_SHADED2;
_runningGuy1.setup(1103, 3, 1);
_runningGuy1._moveRate = 30;
_runningGuy2.postInit();
- _runningGuy2._effect = 6;
+ _runningGuy2._effect = EFFECT_SHADED2;
_runningGuy2.setup(1103, 4, 1);
_runningGuy2._moveRate = 25;
@@ -1058,7 +1070,7 @@ void Scene1100::signal() {
setAction(&_sequenceManager1, this, 1103, &_chief, &_laserShot, NULL);
break;
case 8:
- R2_GLOBALS._player._effect = 0;
+ R2_GLOBALS._player._effect = EFFECT_NONE;
_animation.postInit();
setAction(&_sequenceManager1, this, 1105, &R2_GLOBALS._player, &_laserShot, &_animation, &_chief, NULL);
break;
@@ -1079,7 +1091,7 @@ void Scene1100::signal() {
case 11: {
setAction(&_sequenceManager1, this, 1106, &_animation, &_laserShot, &_leftImpacts, NULL);
- R2_GLOBALS._player._effect = 5;
+ R2_GLOBALS._player._effect = EFFECT_SHADOW_MAP;
R2_GLOBALS._player.setup(1102, 3, 2);
R2_GLOBALS._player.setPosition(Common::Point(-50, 131));
R2_GLOBALS._sound2.play(84);
@@ -1112,7 +1124,7 @@ void Scene1100::signal() {
case 20: {
Common::Point pt(187, -13);
NpcMover *mover = new NpcMover();
- _actor1.addMover(mover, &pt, this);
+ _ship.addMover(mover, &pt, this);
}
break;
case 21: {
@@ -1120,7 +1132,7 @@ void Scene1100::signal() {
_trooper.animate(ANIM_MODE_5, NULL);
Common::Point pt(187, 45);
NpcMover *mover = new NpcMover();
- _actor1.addMover(mover, &pt, this);
+ _ship.addMover(mover, &pt, this);
}
break;
case 22:
@@ -1164,6 +1176,7 @@ void Scene1100::signal() {
R2_GLOBALS._player._canWalk = false;
break;
case 51:
+ // Trooper no longer wears a statis shield
R2_GLOBALS.setFlag(53);
_trooper.setDetails(1100, 28, -1, -1, 3, (SceneItem *) NULL);
@@ -1171,6 +1184,7 @@ void Scene1100::signal() {
R2_GLOBALS._player._canWalk = false;
break;
case 52:
+ // Trooper is shot to death
R2_GLOBALS._sound1.play(98);
R2_GLOBALS.setFlag(52);
R2_GLOBALS._player.disableControl();
@@ -1188,21 +1202,13 @@ void Scene1100::signal() {
R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
if (_nextStripNum == 0) {
R2_GLOBALS.setFlag(55);
- if (R2_GLOBALS.getFlag(55)) {
- if (R2_GLOBALS._player._characterIndex == R2_QUINN)
- _stripManager.start(318, this);
- else
- _stripManager.start(323, this);
- } else {
- // This part is totally useless as flag 55 has been set right before the check
- if (R2_GLOBALS._player._characterIndex == R2_QUINN)
- _stripManager.start(317, this);
- else
- _stripManager.start(322, this);
- }
- } else {
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
+ _stripManager.start(318, this);
+ else
+ _stripManager.start(323, this);
+ } else
_stripManager.start3(_nextStripNum, this, _stripManager._lookupList);
- }
+
break;
case 54:
if (_stripManager._exitMode == 1) {
@@ -1259,7 +1265,7 @@ void Scene1100::signal() {
R2_GLOBALS._sound1.play(101);
Common::Point pt(187, -13);
NpcMover *mover = new NpcMover();
- _actor1.addMover(mover, &pt, this);
+ _ship.addMover(mover, &pt, this);
}
break;
default:
@@ -1270,6 +1276,15 @@ void Scene1100::signal() {
}
void Scene1100::dispatch() {
+ // WORKAROUND: This fixes a problem with an overhang that gets blasted re-appearing
+ if (_animation._frame > 5 && _sceneMode == 13) {
+ _animation._endFrame = 9;
+ if (_animation._frame == 9)
+ // Use one of the scene's background scene objects to copy the scene to the background.
+ // This fixes the problem with the cliff overhang still appearing during the cutscene
+ _rightLandslide.copySceneToBackground();
+ }
+
if ((g_globals->_sceneObjects->contains(&_laserShot)) && (_laserShot._visage == 1102) && (_laserShot._strip == 4) && (_laserShot._frame == 1) && (_laserShot._flags & OBJFLAG_HIDING)) {
if (_paletteRefreshStatus == 1) {
_paletteRefreshStatus = 2;
@@ -1342,7 +1357,7 @@ void Scene1200::LaserPanel::Jumper::init(int state) {
switch (_state) {
case 1:
- switch (R2_GLOBALS._v56AA6) {
+ switch (R2_GLOBALS._ductMazePanel1State) {
case 1:
setFrame2(2);
setPosition(Common::Point(129, 101));
@@ -1356,7 +1371,7 @@ void Scene1200::LaserPanel::Jumper::init(int state) {
}
break;
case 2:
- switch (R2_GLOBALS._v56AA7) {
+ switch (R2_GLOBALS._ductMazePanel2State) {
case 1:
setFrame2(2);
setPosition(Common::Point(152, 101));
@@ -1374,7 +1389,7 @@ void Scene1200::LaserPanel::Jumper::init(int state) {
}
break;
case 3:
- switch (R2_GLOBALS._v56AA8) {
+ switch (R2_GLOBALS._ductMazePanel3State) {
case 1:
setFrame2(3);
setPosition(Common::Point(158, 95));
@@ -1401,22 +1416,22 @@ bool Scene1200::LaserPanel::Jumper::startAction(CursorType action, Event &event)
R2_GLOBALS._sound2.play(260);
switch (_state) {
case 1:
- if (R2_GLOBALS._v56AA6 == 1) {
- R2_GLOBALS._v56AA6 = 2;
+ if (R2_GLOBALS._ductMazePanel1State == 1) {
+ R2_GLOBALS._ductMazePanel1State = 2;
setFrame2(3);
setPosition(Common::Point(135, 95));
} else {
- R2_GLOBALS._v56AA6 = 1;
+ R2_GLOBALS._ductMazePanel1State = 1;
setFrame2(2);
setPosition(Common::Point(129, 101));
}
break;
case 2:
- ++R2_GLOBALS._v56AA7;
- if (R2_GLOBALS._v56AA7 == 4)
- R2_GLOBALS._v56AA7 = 1;
+ ++R2_GLOBALS._ductMazePanel2State;
+ if (R2_GLOBALS._ductMazePanel2State == 4)
+ R2_GLOBALS._ductMazePanel2State = 1;
- switch (R2_GLOBALS._v56AA7) {
+ switch (R2_GLOBALS._ductMazePanel2State) {
case 1:
setFrame2(2);
setPosition(Common::Point(152, 101));
@@ -1434,12 +1449,12 @@ bool Scene1200::LaserPanel::Jumper::startAction(CursorType action, Event &event)
}
break;
case 3:
- if (R2_GLOBALS._v56AA8 == 1) {
- R2_GLOBALS._v56AA8 = 2;
+ if (R2_GLOBALS._ductMazePanel3State == 1) {
+ R2_GLOBALS._ductMazePanel3State = 2;
setFrame2(2);
setPosition(Common::Point(175, 101));
} else {
- R2_GLOBALS._v56AA8 = 1;
+ R2_GLOBALS._ductMazePanel3State = 1;
setFrame2(3);
setPosition(Common::Point(158, 95));
}
@@ -1451,13 +1466,13 @@ bool Scene1200::LaserPanel::Jumper::startAction(CursorType action, Event &event)
Scene1200 *scene = (Scene1200 *)R2_GLOBALS._sceneManager._scene;
scene->_field418 = 0;
- if ((R2_GLOBALS._v56AA6 == 1) && (R2_GLOBALS._v56AA7 == 1) && (R2_GLOBALS._v56AA8 == 1))
+ if ((R2_GLOBALS._ductMazePanel1State == 1) && (R2_GLOBALS._ductMazePanel2State == 1) && (R2_GLOBALS._ductMazePanel3State == 1))
scene->_field418 = 1;
- else if ((R2_GLOBALS._v56AA6 == 2) && (R2_GLOBALS._v56AA7 == 1) && (R2_GLOBALS._v56AA8 == 1))
+ else if ((R2_GLOBALS._ductMazePanel1State == 2) && (R2_GLOBALS._ductMazePanel2State == 1) && (R2_GLOBALS._ductMazePanel3State == 1))
scene->_field418 = 2;
- else if ((R2_GLOBALS._v56AA6 == 2) && (R2_GLOBALS._v56AA7 == 1) && (R2_GLOBALS._v56AA8 == 2))
+ else if ((R2_GLOBALS._ductMazePanel1State == 2) && (R2_GLOBALS._ductMazePanel2State == 1) && (R2_GLOBALS._ductMazePanel3State == 2))
scene->_field418 = 3;
- else if ((R2_GLOBALS._v56AA6 == 2) && (R2_GLOBALS._v56AA7 == 3) && (R2_GLOBALS._v56AA8 == 1))
+ else if ((R2_GLOBALS._ductMazePanel1State == 2) && (R2_GLOBALS._ductMazePanel2State == 3) && (R2_GLOBALS._ductMazePanel3State == 1))
scene->_field418 = 4;
return true;
@@ -1468,8 +1483,8 @@ void Scene1200::LaserPanel::postInit(SceneObjectList *OwnerList) {
scene->_field41A = 1;
R2_GLOBALS._events.setCursor(CURSOR_USE);
- proc12(1003, 1, 1, 100, 40);
- proc13(1200, 11, -1, -1);
+ setup2(1003, 1, 1, 100, 40);
+ setup3(1200, 11, -1, -1);
R2_GLOBALS._sound2.play(259);
_jumper1.init(1);
_jumper2.init(2);
@@ -1506,13 +1521,13 @@ void Scene1200::postInit(SceneObjectList *OwnerList) {
_field418 = 0;
_field41A = 0;
- if ((R2_GLOBALS._v56AA6 == 1) && (R2_GLOBALS._v56AA7 == 1) && (R2_GLOBALS._v56AA8 == 1))
+ if ((R2_GLOBALS._ductMazePanel1State == 1) && (R2_GLOBALS._ductMazePanel2State == 1) && (R2_GLOBALS._ductMazePanel3State == 1))
_field418 = 1;
- else if ((R2_GLOBALS._v56AA6 == 2) && (R2_GLOBALS._v56AA7 == 1) && (R2_GLOBALS._v56AA8 == 1))
+ else if ((R2_GLOBALS._ductMazePanel1State == 2) && (R2_GLOBALS._ductMazePanel2State == 1) && (R2_GLOBALS._ductMazePanel3State == 1))
_field418 = 2;
- else if ((R2_GLOBALS._v56AA6 == 2) && (R2_GLOBALS._v56AA7 == 1) && (R2_GLOBALS._v56AA8 == 2))
+ else if ((R2_GLOBALS._ductMazePanel1State == 2) && (R2_GLOBALS._ductMazePanel2State == 1) && (R2_GLOBALS._ductMazePanel3State == 2))
_field418 = 3;
- else if ((R2_GLOBALS._v56AA6 == 2) && (R2_GLOBALS._v56AA7 == 3) && (R2_GLOBALS._v56AA8 == 1))
+ else if ((R2_GLOBALS._ductMazePanel1State == 2) && (R2_GLOBALS._ductMazePanel2State == 3) && (R2_GLOBALS._ductMazePanel3State == 1))
_field418 = 4;
R2_GLOBALS._player.postInit();
@@ -1547,7 +1562,7 @@ void Scene1200::signal() {
// No break on purpose
case 1203:
R2_GLOBALS._player.enableControl();
- warning("_eventManager.waitEvent()");
+ // CHECKME: The original is calling _eventManager.waitEvent();
_sceneMode = 2;
break;
case 10:
@@ -1769,7 +1784,7 @@ void Scene1200::signal() {
R2_GLOBALS._player.animate(ANIM_MODE_6, this);
break;
default:
- warning("_eventManager.waitEvent()");
+ // CHECKME: The original is walling _eventManager.waitEvent();
_sceneMode = 2;
break;
}
@@ -1838,10 +1853,10 @@ void Scene1200::process(Event &event) {
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, -999);
+ 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, -999);
+ SceneItem::display(1200, 5, 0, 280, 1, 160, 9, 1, 2, 20, 7, 154, LIST_END);
break;
}
event.handled = true;
@@ -1854,7 +1869,7 @@ void Scene1200::process(Event &event) {
switch (cellPos.x) {
case 3:
// It was your cell.
- SceneItem::display(1200, 8, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ SceneItem::display(1200, 8, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, LIST_END);
break;
case 9:
R2_GLOBALS._sceneManager.changeScene(3240);
@@ -1864,7 +1879,7 @@ void Scene1200::process(Event &event) {
R2_GLOBALS._sceneManager.changeScene(3210);
else
// A vent grill
- SceneItem::display(1200, 10, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ SceneItem::display(1200, 10, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, LIST_END);
break;
case 17:
switch (cellPos.y) {
@@ -1879,21 +1894,22 @@ void Scene1200::process(Event &event) {
break;
default:
// A vent grill
- SceneItem::display(1200, 10, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ 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, -999);
+ 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, -999);
+ SceneItem::display(1200, 9, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, LIST_END);
}
break;
case CURSOR_TALK:
@@ -1930,9 +1946,8 @@ void Scene1200::process(Event &event) {
return;
break;
}
- } else {
+ } else
return;
- }
}
void Scene1200::dispatch() {
@@ -2189,65 +2204,86 @@ void Scene1200::startCrawling(CrawlDirection dir) {
*
*--------------------------------------------------------------------------*/
-Scene1337::unkObj1337sub1::unkObj1337sub1() {
- _field34 = 0;
- _field36 = Common::Point(0, 0);
+Scene1337::Card::Card() {
+ _cardId = 0;
+ _stationPos = Common::Point(0, 0);
+}
+
+void Scene1337::Card::synchronize(Serializer &s) {
+ warning("STUBBED: Card::synchronize()");
}
-void Scene1337::unkObj1337sub1::synchronize(Serializer &s) {
- warning("STUBBED: unkObj1337sub1::synchronize()");
+bool Scene1337::Card::isIn(Common::Point pt) {
+ if ((_stationPos.x > pt.x) || (_stationPos.x + 24 < pt.x))
+ return false;
+
+ if ((_stationPos.y > pt.y) || (_stationPos.y + 24 < pt.y))
+ return false;
+
+ return true;
}
-Scene1337::unkObj1337_1::unkObj1337_1() {
- _fieldB94 = Common::Point(0, 0);
- _fieldB98 = Common::Point(0, 0);
- _fieldB9C = Common::Point(0, 0);
- _fieldBA0 = Common::Point(0, 0);
- _fieldBA4 = 0;
+Scene1337::GameBoardSide::GameBoardSide() {
+ _card1Pos = Common::Point(0, 0);
+ _card2Pos = Common::Point(0, 0);
+ _card3Pos = Common::Point(0, 0);
+ _card4Pos = Common::Point(0, 0);
+ _frameNum = 0;
}
-void Scene1337::unkObj1337_1::synchronize(Serializer &s) {
- warning("STUBBED: unkObj1337_1::synchronize()");
+void Scene1337::GameBoardSide::synchronize(Serializer &s) {
+ warning("STUBBED: GameBoardSide::synchronize()");
}
Scene1337::Scene1337() {
_autoplay = false;
- _field3E24 = 0;
- _field3E26 = 0;
+ _cardsAvailableNumb = 0;
+ _currentDiscardIndex = 0;
for (int i = 0; i < 100; i++)
- _field3E28[i] = 0;
+ _availableCardsPile[i] = 0;
- _field423C = 0;
- _field423E = 0;
- _field4240 = 0;
- _field4242 = 0;
- _field4244 = 0;
- _field4246 = 0;
- _field4248 = 0;
- _field424A = 0;
- _field424C = 0;
- _field424E = 0;
+ _shuffleEndedFl = false;
+ _currentPlayerNumb = 0;
+ _actionIdx1 = 0;
+ _actionIdx2 = 0;
+ _showPlayerTurn = false;
+ _displayHelpFl = false;
+ _winnerId = -1;
+ _instructionsDisplayedFl = false;
+ _instructionsWaitCount = 0;
+
+ _delayedFunction = nullptr;
+ _actionCard1 = nullptr;
+ _actionCard2 = nullptr;
+ _actionCard3 = nullptr;
+
+ _cursorCurRes = 0;
+ _cursorCurStrip = 0;
+ _cursorCurFrame = 0;
}
void Scene1337::synchronize(Serializer &s) {
warning("STUBBED: Scene1337::synchronize()");
}
-void Scene1337::Action1337::subD18B5(int resNum, int stripNum, int frameNum) {
- warning("STUBBED: Action1337::subD18B5()");
-}
-
-void Scene1337::Action1337::skipFrames(int32 skipCount) {
+void Scene1337::Action1337::waitFrames(int32 frameCount) {
uint32 firstFrameNumber = g_globals->_events.getFrameNumber();
- uint32 tmpFrameNumber = firstFrameNumber;
-
- while (tmpFrameNumber < firstFrameNumber + skipCount)
- tmpFrameNumber = g_globals->_events.getFrameNumber();
+ uint32 curFrame = firstFrameNumber;
+ uint32 destFrame = firstFrameNumber + frameCount;
- warning("_eventManager.waitEvent(-1)");
+ while ((curFrame < destFrame) && !g_vm->shouldQuit()) {
+ TsAGE::Event event;
+ g_globals->_events.getEvent(event);
+ curFrame = g_globals->_events.getFrameNumber();
+ }
+
+ // CHECKME: The original is calling _eventManager.waitEvent();
}
+/**
+ * Display instructions
+ */
void Scene1337::Action1::signal() {
Scene1337 *scene = (Scene1337 *)R2_GLOBALS._sceneManager._scene;
@@ -2258,393 +2294,396 @@ void Scene1337::Action1::signal() {
scene->actionDisplay(1331, 7, 159, 10, 1, 200, 0, 7, 0, 154, 154);
scene->actionDisplay(1331, 8, 159, 10, 1, 200, 0, 7, 0, 154, 154);
- scene->_arrunkObj1337[1]._arr2[0]._field34 = 2;
- scene->_arrunkObj1337[1]._arr2[0]._object1.postInit();
- scene->_arrunkObj1337[1]._arr2[0]._object1.setVisage(1332);
- scene->_arrunkObj1337[1]._arr2[0]._object1.setPosition(scene->_arrunkObj1337[1]._arr2[0]._field36, 0);
- scene->_arrunkObj1337[1]._arr2[0]._object1.setStrip(2);
- scene->_arrunkObj1337[1]._arr2[0]._object1.setFrame(scene->_arrunkObj1337[1]._arr2[0]._field34);
- scene->_arrunkObj1337[1]._arr2[0]._object1.fixPriority(170);
- scene->setAnimationInfo(&scene->_arrunkObj1337[1]._arr2[0]);
-
- scene->_arrunkObj1337[1]._arr2[1]._field34 = 3;
- scene->_arrunkObj1337[1]._arr2[1]._object1.postInit();
- scene->_arrunkObj1337[1]._arr2[1]._object1.setVisage(1332);
- scene->_arrunkObj1337[1]._arr2[1]._object1.setPosition(scene->_arrunkObj1337[1]._arr2[1]._field36, 0);
- scene->_arrunkObj1337[1]._arr2[1]._object1.setStrip(2);
- scene->_arrunkObj1337[1]._arr2[1]._object1.setFrame(scene->_arrunkObj1337[1]._arr2[1]._field34);
- scene->_arrunkObj1337[1]._arr2[1]._object1.fixPriority(170);
- scene->setAnimationInfo(&scene->_arrunkObj1337[1]._arr2[1]);
-
- scene->_arrunkObj1337[2]._arr2[0]._field34 = 4;
- scene->_arrunkObj1337[2]._arr2[0]._object1.postInit();
- scene->_arrunkObj1337[2]._arr2[0]._object1.setVisage(1332);
- scene->_arrunkObj1337[2]._arr2[0]._object1.setPosition(scene->_arrunkObj1337[2]._arr2[0]._field36, 0);
- scene->_arrunkObj1337[2]._arr2[0]._object1.setStrip(2);
- scene->_arrunkObj1337[2]._arr2[0]._object1.setFrame(scene->_arrunkObj1337[2]._arr2[0]._field34);
- scene->_arrunkObj1337[2]._arr2[0]._object1.fixPriority(170);
- scene->setAnimationInfo(&scene->_arrunkObj1337[2]._arr2[0]);
-
- scene->_arrunkObj1337[3]._arr2[0]._field34 = 5;
- scene->_arrunkObj1337[3]._arr2[0]._object1.postInit();
- scene->_arrunkObj1337[3]._arr2[0]._object1.setVisage(1332);
- scene->_arrunkObj1337[3]._arr2[0]._object1.setPosition(scene->_arrunkObj1337[3]._arr2[0]._field36, 0);
- scene->_arrunkObj1337[3]._arr2[0]._object1.setStrip(2);
- scene->_arrunkObj1337[3]._arr2[0]._object1.setFrame(scene->_arrunkObj1337[3]._arr2[0]._field34);
- scene->_arrunkObj1337[3]._arr2[0]._object1.fixPriority(170);
- scene->setAnimationInfo(&scene->_arrunkObj1337[3]._arr2[0]);
-
- scene->_arrunkObj1337[3]._arr2[1]._field34 = 6;
- scene->_arrunkObj1337[3]._arr2[1]._object1.postInit();
- scene->_arrunkObj1337[3]._arr2[1]._object1.setVisage(1332);
- scene->_arrunkObj1337[3]._arr2[1]._object1.setPosition(scene->_arrunkObj1337[3]._arr2[1]._field36, 0);
- scene->_arrunkObj1337[3]._arr2[1]._object1.setStrip(2);
- scene->_arrunkObj1337[3]._arr2[1]._object1.setFrame(scene->_arrunkObj1337[3]._arr2[1]._field34);
- scene->_arrunkObj1337[3]._arr2[1]._object1.fixPriority(170);
- scene->setAnimationInfo(&scene->_arrunkObj1337[3]._arr2[1]);
-
- scene->_arrunkObj1337[3]._arr2[2]._field34 = 7;
- scene->_arrunkObj1337[3]._arr2[2]._object1.postInit();
- scene->_arrunkObj1337[3]._arr2[2]._object1.setVisage(1332);
- scene->_arrunkObj1337[3]._arr2[2]._object1.setPosition(scene->_arrunkObj1337[3]._arr2[2]._field36, 0);
- scene->_arrunkObj1337[3]._arr2[2]._object1.setStrip(2);
- scene->_arrunkObj1337[3]._arr2[2]._object1.setFrame(scene->_arrunkObj1337[3]._arr2[2]._field34);
- scene->_arrunkObj1337[3]._arr2[2]._object1.fixPriority(170);
- scene->setAnimationInfo(&scene->_arrunkObj1337[3]._arr2[2]);
-
- scene->_arrunkObj1337[0]._arr2[0]._field34 = 8;
- scene->_arrunkObj1337[0]._arr2[0]._object1.postInit();
- scene->_arrunkObj1337[0]._arr2[0]._object1.setVisage(1332);
- scene->_arrunkObj1337[0]._arr2[0]._object1.setPosition(scene->_arrunkObj1337[0]._arr2[0]._field36, 0);
- scene->_arrunkObj1337[0]._arr2[0]._object1.setStrip(2);
- scene->_arrunkObj1337[0]._arr2[0]._object1.setFrame(scene->_arrunkObj1337[0]._arr2[0]._field34);
- scene->_arrunkObj1337[0]._arr2[0]._object1.fixPriority(170);
- scene->setAnimationInfo(&scene->_arrunkObj1337[0]._arr2[0]);
-
- scene->_arrunkObj1337[0]._arr2[1]._field34 = 9;
- scene->_arrunkObj1337[0]._arr2[1]._object1.postInit();
- scene->_arrunkObj1337[0]._arr2[1]._object1.setVisage(1332);
- scene->_arrunkObj1337[0]._arr2[1]._object1.setPosition(scene->_arrunkObj1337[0]._arr2[1]._field36, 0);
- scene->_arrunkObj1337[0]._arr2[1]._object1.setStrip(2);
- scene->_arrunkObj1337[0]._arr2[1]._object1.setFrame(scene->_arrunkObj1337[0]._arr2[1]._field34);
- scene->_arrunkObj1337[0]._arr2[1]._object1.fixPriority(170);
- scene->setAnimationInfo(&scene->_arrunkObj1337[0]._arr2[1]);
+ scene->_gameBoardSide[1]._outpostStation[0]._cardId = 2;
+ scene->_gameBoardSide[1]._outpostStation[0]._card.postInit();
+ scene->_gameBoardSide[1]._outpostStation[0]._card.setVisage(1332);
+ scene->_gameBoardSide[1]._outpostStation[0]._card.setPosition(scene->_gameBoardSide[1]._outpostStation[0]._stationPos, 0);
+ scene->_gameBoardSide[1]._outpostStation[0]._card.setStrip(2);
+ scene->_gameBoardSide[1]._outpostStation[0]._card.setFrame(scene->_gameBoardSide[1]._outpostStation[0]._cardId);
+ scene->_gameBoardSide[1]._outpostStation[0]._card.fixPriority(170);
+ scene->setAnimationInfo(&scene->_gameBoardSide[1]._outpostStation[0]);
+
+ scene->_gameBoardSide[1]._outpostStation[1]._cardId = 3;
+ scene->_gameBoardSide[1]._outpostStation[1]._card.postInit();
+ scene->_gameBoardSide[1]._outpostStation[1]._card.setVisage(1332);
+ scene->_gameBoardSide[1]._outpostStation[1]._card.setPosition(scene->_gameBoardSide[1]._outpostStation[1]._stationPos, 0);
+ scene->_gameBoardSide[1]._outpostStation[1]._card.setStrip(2);
+ scene->_gameBoardSide[1]._outpostStation[1]._card.setFrame(scene->_gameBoardSide[1]._outpostStation[1]._cardId);
+ scene->_gameBoardSide[1]._outpostStation[1]._card.fixPriority(170);
+ scene->setAnimationInfo(&scene->_gameBoardSide[1]._outpostStation[1]);
+
+ scene->_gameBoardSide[2]._outpostStation[0]._cardId = 4;
+ scene->_gameBoardSide[2]._outpostStation[0]._card.postInit();
+ scene->_gameBoardSide[2]._outpostStation[0]._card.setVisage(1332);
+ scene->_gameBoardSide[2]._outpostStation[0]._card.setPosition(scene->_gameBoardSide[2]._outpostStation[0]._stationPos, 0);
+ scene->_gameBoardSide[2]._outpostStation[0]._card.setStrip(2);
+ scene->_gameBoardSide[2]._outpostStation[0]._card.setFrame(scene->_gameBoardSide[2]._outpostStation[0]._cardId);
+ scene->setAnimationInfo(&scene->_gameBoardSide[2]._outpostStation[0]);
+
+ scene->_gameBoardSide[3]._outpostStation[0]._cardId = 5;
+ scene->_gameBoardSide[3]._outpostStation[0]._card.postInit();
+ scene->_gameBoardSide[3]._outpostStation[0]._card.setVisage(1332);
+ scene->_gameBoardSide[3]._outpostStation[0]._card.setPosition(scene->_gameBoardSide[3]._outpostStation[0]._stationPos, 0);
+ scene->_gameBoardSide[3]._outpostStation[0]._card.setStrip(2);
+ scene->_gameBoardSide[3]._outpostStation[0]._card.setFrame(scene->_gameBoardSide[3]._outpostStation[0]._cardId);
+ scene->_gameBoardSide[3]._outpostStation[0]._card.fixPriority(170);
+ scene->setAnimationInfo(&scene->_gameBoardSide[3]._outpostStation[0]);
+
+ scene->_gameBoardSide[3]._outpostStation[1]._cardId = 6;
+ scene->_gameBoardSide[3]._outpostStation[1]._card.postInit();
+ scene->_gameBoardSide[3]._outpostStation[1]._card.setVisage(1332);
+ scene->_gameBoardSide[3]._outpostStation[1]._card.setPosition(scene->_gameBoardSide[3]._outpostStation[1]._stationPos, 0);
+ scene->_gameBoardSide[3]._outpostStation[1]._card.setStrip(2);
+ scene->_gameBoardSide[3]._outpostStation[1]._card.setFrame(scene->_gameBoardSide[3]._outpostStation[1]._cardId);
+ scene->_gameBoardSide[3]._outpostStation[1]._card.fixPriority(170);
+ scene->setAnimationInfo(&scene->_gameBoardSide[3]._outpostStation[1]);
+
+ scene->_gameBoardSide[3]._outpostStation[2]._cardId = 7;
+ scene->_gameBoardSide[3]._outpostStation[2]._card.postInit();
+ scene->_gameBoardSide[3]._outpostStation[2]._card.setVisage(1332);
+ scene->_gameBoardSide[3]._outpostStation[2]._card.setPosition(scene->_gameBoardSide[3]._outpostStation[2]._stationPos, 0);
+ scene->_gameBoardSide[3]._outpostStation[2]._card.setStrip(2);
+ scene->_gameBoardSide[3]._outpostStation[2]._card.setFrame(scene->_gameBoardSide[3]._outpostStation[2]._cardId);
+ scene->_gameBoardSide[3]._outpostStation[2]._card.fixPriority(170);
+ scene->setAnimationInfo(&scene->_gameBoardSide[3]._outpostStation[2]);
+
+ scene->_gameBoardSide[0]._outpostStation[0]._cardId = 8;
+ scene->_gameBoardSide[0]._outpostStation[0]._card.postInit();
+ scene->_gameBoardSide[0]._outpostStation[0]._card.setVisage(1332);
+ scene->_gameBoardSide[0]._outpostStation[0]._card.setPosition(scene->_gameBoardSide[0]._outpostStation[0]._stationPos, 0);
+ scene->_gameBoardSide[0]._outpostStation[0]._card.setStrip(2);
+ scene->_gameBoardSide[0]._outpostStation[0]._card.setFrame(scene->_gameBoardSide[0]._outpostStation[0]._cardId);
+ scene->_gameBoardSide[0]._outpostStation[0]._card.fixPriority(170);
+ scene->setAnimationInfo(&scene->_gameBoardSide[0]._outpostStation[0]);
+
+ scene->_gameBoardSide[0]._outpostStation[1]._cardId = 9;
+ scene->_gameBoardSide[0]._outpostStation[1]._card.postInit();
+ scene->_gameBoardSide[0]._outpostStation[1]._card.setVisage(1332);
+ scene->_gameBoardSide[0]._outpostStation[1]._card.setPosition(scene->_gameBoardSide[0]._outpostStation[1]._stationPos, 0);
+ scene->_gameBoardSide[0]._outpostStation[1]._card.setStrip(2);
+ scene->_gameBoardSide[0]._outpostStation[1]._card.setFrame(scene->_gameBoardSide[0]._outpostStation[1]._cardId);
+ scene->_gameBoardSide[0]._outpostStation[1]._card.fixPriority(170);
+ scene->setAnimationInfo(&scene->_gameBoardSide[0]._outpostStation[1]);
R2_GLOBALS._sceneObjects->draw();
- skipFrames(60);
+ waitFrames(60);
scene->actionDisplay(1331, 9, 159, 10, 1, 200, 0, 7, 0, 154, 154);
- scene->_arrunkObj1337[2]._arr2[1]._field34 = 2;
- scene->_arrunkObj1337[2]._arr2[1]._object1.postInit();
- scene->_arrunkObj1337[2]._arr2[1]._object1.setVisage(1332);
- scene->_arrunkObj1337[2]._arr2[1]._object1.setPosition(scene->_arrunkObj1337[2]._arr2[1]._field36, 0);
- scene->_arrunkObj1337[2]._arr2[1]._object1.setStrip(2);
- scene->_arrunkObj1337[2]._arr2[1]._object1.setFrame(scene->_arrunkObj1337[2]._arr2[1]._field34);
- scene->_arrunkObj1337[2]._arr2[1]._object1.fixPriority(170);
- scene->setAnimationInfo(&scene->_arrunkObj1337[2]._arr2[1]);
-
- scene->_arrunkObj1337[2]._arr2[2]._field34 = 3;
- scene->_arrunkObj1337[2]._arr2[2]._object1.postInit();
- scene->_arrunkObj1337[2]._arr2[2]._object1.setVisage(1332);
- scene->_arrunkObj1337[2]._arr2[2]._object1.setPosition(scene->_arrunkObj1337[2]._arr2[2]._field36, 0);
- scene->_arrunkObj1337[2]._arr2[2]._object1.setStrip(2);
- scene->_arrunkObj1337[2]._arr2[2]._object1.setFrame(scene->_arrunkObj1337[2]._arr2[2]._field34);
- scene->_arrunkObj1337[2]._arr2[2]._object1.fixPriority(170);
- scene->setAnimationInfo(&scene->_arrunkObj1337[2]._arr2[2]);
-
- scene->_arrunkObj1337[2]._arr2[3]._field34 = 5;
- scene->_arrunkObj1337[2]._arr2[3]._object1.postInit();
- scene->_arrunkObj1337[2]._arr2[3]._object1.setVisage(1332);
- scene->_arrunkObj1337[2]._arr2[3]._object1.setPosition(scene->_arrunkObj1337[2]._arr2[3]._field36, 0);
- scene->_arrunkObj1337[2]._arr2[3]._object1.setStrip(2);
- scene->_arrunkObj1337[2]._arr2[3]._object1.setFrame(scene->_arrunkObj1337[2]._arr2[3]._field34);
- scene->_arrunkObj1337[2]._arr2[3]._object1.fixPriority(170);
- scene->setAnimationInfo(&scene->_arrunkObj1337[2]._arr2[3]);
-
- scene->_arrunkObj1337[2]._arr2[4]._field34 = 6;
- scene->_arrunkObj1337[2]._arr2[4]._object1.postInit();
- scene->_arrunkObj1337[2]._arr2[4]._object1.setVisage(1332);
- scene->_arrunkObj1337[2]._arr2[4]._object1.setPosition(scene->_arrunkObj1337[2]._arr2[4]._field36, 0);
- scene->_arrunkObj1337[2]._arr2[4]._object1.setStrip(2);
- scene->_arrunkObj1337[2]._arr2[4]._object1.setFrame(scene->_arrunkObj1337[2]._arr2[4]._field34);
- scene->_arrunkObj1337[2]._arr2[4]._object1.fixPriority(170);
- scene->setAnimationInfo(&scene->_arrunkObj1337[2]._arr2[4]);
-
- scene->_arrunkObj1337[2]._arr2[5]._field34 = 7;
- scene->_arrunkObj1337[2]._arr2[5]._object1.postInit();
- scene->_arrunkObj1337[2]._arr2[5]._object1.setVisage(1332);
- scene->_arrunkObj1337[2]._arr2[5]._object1.setPosition(scene->_arrunkObj1337[2]._arr2[5]._field36, 0);
- scene->_arrunkObj1337[2]._arr2[5]._object1.setStrip(2);
- scene->_arrunkObj1337[2]._arr2[5]._object1.setFrame(scene->_arrunkObj1337[2]._arr2[5]._field34);
- scene->_arrunkObj1337[2]._arr2[5]._object1.fixPriority(170);
- scene->setAnimationInfo(&scene->_arrunkObj1337[2]._arr2[5]);
-
- scene->_arrunkObj1337[2]._arr2[6]._field34 = 8;
- scene->_arrunkObj1337[2]._arr2[6]._object1.postInit();
- scene->_arrunkObj1337[2]._arr2[6]._object1.setVisage(1332);
- scene->_arrunkObj1337[2]._arr2[6]._object1.setPosition(scene->_arrunkObj1337[2]._arr2[6]._field36, 0);
- scene->_arrunkObj1337[2]._arr2[6]._object1.setStrip(2);
- scene->_arrunkObj1337[2]._arr2[6]._object1.setFrame(scene->_arrunkObj1337[2]._arr2[6]._field34);
- scene->_arrunkObj1337[2]._arr2[6]._object1.fixPriority(170);
- scene->setAnimationInfo(&scene->_arrunkObj1337[2]._arr2[6]);
-
- scene->_arrunkObj1337[2]._arr2[7]._field34 = 9;
- scene->_arrunkObj1337[2]._arr2[7]._object1.postInit();
- scene->_arrunkObj1337[2]._arr2[7]._object1.setVisage(1332);
- scene->_arrunkObj1337[2]._arr2[7]._object1.setPosition(scene->_arrunkObj1337[2]._arr2[7]._field36, 0);
- scene->_arrunkObj1337[2]._arr2[7]._object1.setStrip(2);
- scene->_arrunkObj1337[2]._arr2[7]._object1.setFrame(scene->_arrunkObj1337[2]._arr2[7]._field34);
- scene->_arrunkObj1337[2]._arr2[7]._object1.fixPriority(170);
- scene->setAnimationInfo(&scene->_arrunkObj1337[2]._arr2[7]);
+ scene->_gameBoardSide[2]._outpostStation[1]._cardId = 2;
+ scene->_gameBoardSide[2]._outpostStation[1]._card.postInit();
+ scene->_gameBoardSide[2]._outpostStation[1]._card.setVisage(1332);
+ scene->_gameBoardSide[2]._outpostStation[1]._card.setPosition(scene->_gameBoardSide[2]._outpostStation[1]._stationPos, 0);
+ scene->_gameBoardSide[2]._outpostStation[1]._card.setStrip(2);
+ scene->_gameBoardSide[2]._outpostStation[1]._card.setFrame(scene->_gameBoardSide[2]._outpostStation[1]._cardId);
+ scene->_gameBoardSide[2]._outpostStation[1]._card.fixPriority(170);
+ scene->setAnimationInfo(&scene->_gameBoardSide[2]._outpostStation[1]);
+
+ scene->_gameBoardSide[2]._outpostStation[2]._cardId = 3;
+ scene->_gameBoardSide[2]._outpostStation[2]._card.postInit();
+ scene->_gameBoardSide[2]._outpostStation[2]._card.setVisage(1332);
+ scene->_gameBoardSide[2]._outpostStation[2]._card.setPosition(scene->_gameBoardSide[2]._outpostStation[2]._stationPos, 0);
+ scene->_gameBoardSide[2]._outpostStation[2]._card.setStrip(2);
+ scene->_gameBoardSide[2]._outpostStation[2]._card.setFrame(scene->_gameBoardSide[2]._outpostStation[2]._cardId);
+ scene->_gameBoardSide[2]._outpostStation[2]._card.fixPriority(170);
+ scene->setAnimationInfo(&scene->_gameBoardSide[2]._outpostStation[2]);
+
+ scene->_gameBoardSide[2]._outpostStation[3]._cardId = 5;
+ scene->_gameBoardSide[2]._outpostStation[3]._card.postInit();
+ scene->_gameBoardSide[2]._outpostStation[3]._card.setVisage(1332);
+ scene->_gameBoardSide[2]._outpostStation[3]._card.setPosition(scene->_gameBoardSide[2]._outpostStation[3]._stationPos, 0);
+ scene->_gameBoardSide[2]._outpostStation[3]._card.setStrip(2);
+ scene->_gameBoardSide[2]._outpostStation[3]._card.setFrame(scene->_gameBoardSide[2]._outpostStation[3]._cardId);
+ scene->_gameBoardSide[2]._outpostStation[3]._card.fixPriority(170);
+ scene->setAnimationInfo(&scene->_gameBoardSide[2]._outpostStation[3]);
+
+ scene->_gameBoardSide[2]._outpostStation[4]._cardId = 6;
+ scene->_gameBoardSide[2]._outpostStation[4]._card.postInit();
+ scene->_gameBoardSide[2]._outpostStation[4]._card.setVisage(1332);
+ scene->_gameBoardSide[2]._outpostStation[4]._card.setPosition(scene->_gameBoardSide[2]._outpostStation[4]._stationPos, 0);
+ scene->_gameBoardSide[2]._outpostStation[4]._card.setStrip(2);
+ scene->_gameBoardSide[2]._outpostStation[4]._card.setFrame(scene->_gameBoardSide[2]._outpostStation[4]._cardId);
+ scene->_gameBoardSide[2]._outpostStation[4]._card.fixPriority(170);
+ scene->setAnimationInfo(&scene->_gameBoardSide[2]._outpostStation[4]);
+
+ scene->_gameBoardSide[2]._outpostStation[5]._cardId = 7;
+ scene->_gameBoardSide[2]._outpostStation[5]._card.postInit();
+ scene->_gameBoardSide[2]._outpostStation[5]._card.setVisage(1332);
+ scene->_gameBoardSide[2]._outpostStation[5]._card.setPosition(scene->_gameBoardSide[2]._outpostStation[5]._stationPos, 0);
+ scene->_gameBoardSide[2]._outpostStation[5]._card.setStrip(2);
+ scene->_gameBoardSide[2]._outpostStation[5]._card.setFrame(scene->_gameBoardSide[2]._outpostStation[5]._cardId);
+ scene->_gameBoardSide[2]._outpostStation[5]._card.fixPriority(170);
+ scene->setAnimationInfo(&scene->_gameBoardSide[2]._outpostStation[5]);
+
+ scene->_gameBoardSide[2]._outpostStation[6]._cardId = 8;
+ scene->_gameBoardSide[2]._outpostStation[6]._card.postInit();
+ scene->_gameBoardSide[2]._outpostStation[6]._card.setVisage(1332);
+ scene->_gameBoardSide[2]._outpostStation[6]._card.setPosition(scene->_gameBoardSide[2]._outpostStation[6]._stationPos, 0);
+ scene->_gameBoardSide[2]._outpostStation[6]._card.setStrip(2);
+ scene->_gameBoardSide[2]._outpostStation[6]._card.setFrame(scene->_gameBoardSide[2]._outpostStation[6]._cardId);
+ scene->_gameBoardSide[2]._outpostStation[6]._card.fixPriority(170);
+ scene->setAnimationInfo(&scene->_gameBoardSide[2]._outpostStation[6]);
+
+ scene->_gameBoardSide[2]._outpostStation[7]._cardId = 9;
+ scene->_gameBoardSide[2]._outpostStation[7]._card.postInit();
+ scene->_gameBoardSide[2]._outpostStation[7]._card.setVisage(1332);
+ scene->_gameBoardSide[2]._outpostStation[7]._card.setPosition(scene->_gameBoardSide[2]._outpostStation[7]._stationPos, 0);
+ scene->_gameBoardSide[2]._outpostStation[7]._card.setStrip(2);
+ scene->_gameBoardSide[2]._outpostStation[7]._card.setFrame(scene->_gameBoardSide[2]._outpostStation[7]._cardId);
+ scene->_gameBoardSide[2]._outpostStation[7]._card.fixPriority(170);
+ scene->setAnimationInfo(&scene->_gameBoardSide[2]._outpostStation[7]);
scene->_aSound1.play(62);
R2_GLOBALS._sceneObjects->draw();
- skipFrames(120);
- scene->_arrunkObj1337[2]._arr2[0]._object1.remove();
- scene->_arrunkObj1337[2]._arr2[1]._object1.remove();
- scene->_arrunkObj1337[2]._arr2[2]._object1.remove();
- scene->_arrunkObj1337[2]._arr2[3]._object1.remove();
- scene->_arrunkObj1337[2]._arr2[4]._object1.remove();
- scene->_arrunkObj1337[2]._arr2[5]._object1.remove();
- scene->_arrunkObj1337[2]._arr2[6]._object1.remove();
- scene->_arrunkObj1337[2]._arr2[7]._object1.remove();
-
- scene->_arrunkObj1337[1]._arr2[0]._object1.remove();
- scene->_arrunkObj1337[1]._arr2[1]._object1.remove();
-
- scene->_arrunkObj1337[3]._arr2[0]._object1.remove();
- scene->_arrunkObj1337[3]._arr2[1]._object1.remove();
- scene->_arrunkObj1337[3]._arr2[2]._object1.remove();
-
- scene->_arrunkObj1337[0]._arr2[0]._object1.remove();
- scene->_arrunkObj1337[0]._arr2[1]._object1.remove();
-
- scene->_background2.setup2(1332, 5, 1, 165, 95, 110, 1);
-
- scene->_arrunkObj1337[1]._arr1[0]._object1.postInit();
- scene->_arrunkObj1337[1]._arr1[0]._object1.setVisage(1332);
- scene->_arrunkObj1337[1]._arr1[0]._object1.setPosition(scene->_arrunkObj1337[1]._arr1[0]._field36, 0);
- scene->_arrunkObj1337[1]._arr1[0]._object1.setStrip(1);
- scene->_arrunkObj1337[1]._arr1[0]._object1.setFrame(4);
- scene->_arrunkObj1337[1]._arr1[0]._object1.fixPriority(170);
-
- scene->_arrunkObj1337[1]._arr1[1]._object1.postInit();
- scene->_arrunkObj1337[1]._arr1[1]._object1.setVisage(1332);
- scene->_arrunkObj1337[1]._arr1[1]._object1.setPosition(scene->_arrunkObj1337[1]._arr1[1]._field36, 0);
- scene->_arrunkObj1337[1]._arr1[1]._object1.setStrip(1);
- scene->_arrunkObj1337[1]._arr1[1]._object1.setFrame(4);
- scene->_arrunkObj1337[1]._arr1[1]._object1.fixPriority(170);
-
- scene->_arrunkObj1337[1]._arr1[2]._object1.postInit();
- scene->_arrunkObj1337[1]._arr1[2]._object1.setVisage(1332);
- scene->_arrunkObj1337[1]._arr1[2]._object1.setPosition(scene->_arrunkObj1337[1]._arr1[2]._field36, 0);
- scene->_arrunkObj1337[1]._arr1[2]._object1.setStrip(1);
- scene->_arrunkObj1337[1]._arr1[2]._object1.setFrame(4);
- scene->_arrunkObj1337[1]._arr1[2]._object1.fixPriority(170);
-
- scene->_arrunkObj1337[2]._arr1[0]._field34 = 30;
- scene->_arrunkObj1337[2]._arr1[0]._object1.postInit();
- scene->_arrunkObj1337[2]._arr1[0]._object1.setVisage(1332);
- scene->_arrunkObj1337[2]._arr1[0]._object1.setPosition(scene->_arrunkObj1337[2]._arr1[0]._field36, 0);
- scene->_arrunkObj1337[2]._arr1[0]._object1.setStrip(1);
- scene->_arrunkObj1337[2]._arr1[0]._object1.setFrame(2);
- scene->_arrunkObj1337[2]._arr1[0]._object1.fixPriority(170);
- scene->setAnimationInfo(&scene->_arrunkObj1337[2]._arr1[0]);
-
- scene->_arrunkObj1337[2]._arr1[1]._field34 = 16;
- scene->_arrunkObj1337[2]._arr1[1]._object1.postInit();
- scene->_arrunkObj1337[2]._arr1[1]._object1.setVisage(1332);
- scene->_arrunkObj1337[2]._arr1[1]._object1.setPosition(scene->_arrunkObj1337[2]._arr1[1]._field36, 0);
- scene->_arrunkObj1337[2]._arr1[1]._object1.setStrip(1);
- scene->_arrunkObj1337[2]._arr1[1]._object1.setFrame(2);
- scene->_arrunkObj1337[2]._arr1[1]._object1.fixPriority(170);
- scene->setAnimationInfo(&scene->_arrunkObj1337[2]._arr1[1]);
-
- scene->_arrunkObj1337[2]._arr1[2]._field34 = 1;
- scene->_arrunkObj1337[2]._arr1[2]._object1.postInit();
- scene->_arrunkObj1337[2]._arr1[2]._object1.setVisage(1332);
- scene->_arrunkObj1337[2]._arr1[2]._object1.setPosition(scene->_arrunkObj1337[2]._arr1[2]._field36, 0);
- scene->_arrunkObj1337[2]._arr1[2]._object1.setStrip(1);
- scene->_arrunkObj1337[2]._arr1[2]._object1.setFrame(2);
- scene->_arrunkObj1337[2]._arr1[2]._object1.fixPriority(170);
- scene->setAnimationInfo(&scene->_arrunkObj1337[2]._arr1[2]);
-
- scene->_arrunkObj1337[3]._arr1[0]._object1.postInit();
- scene->_arrunkObj1337[3]._arr1[0]._object1.setVisage(1332);
- scene->_arrunkObj1337[3]._arr1[0]._object1.setPosition(scene->_arrunkObj1337[3]._arr1[0]._field36, 0);
- scene->_arrunkObj1337[3]._arr1[0]._object1.setStrip(1);
- scene->_arrunkObj1337[3]._arr1[0]._object1.setFrame(3);
- scene->_arrunkObj1337[3]._arr1[0]._object1.fixPriority(170);
-
- scene->_arrunkObj1337[3]._arr1[1]._object1.postInit();
- scene->_arrunkObj1337[3]._arr1[1]._object1.setVisage(1332);
- scene->_arrunkObj1337[3]._arr1[1]._object1.setPosition(scene->_arrunkObj1337[3]._arr1[1]._field36, 0);
- scene->_arrunkObj1337[3]._arr1[1]._object1.setStrip(1);
- scene->_arrunkObj1337[3]._arr1[1]._object1.setFrame(3);
- scene->_arrunkObj1337[3]._arr1[1]._object1.fixPriority(170);
-
- scene->_arrunkObj1337[3]._arr1[2]._object1.postInit();
- scene->_arrunkObj1337[3]._arr1[2]._object1.setVisage(1332);
- scene->_arrunkObj1337[3]._arr1[2]._object1.setPosition(scene->_arrunkObj1337[3]._arr1[2]._field36, 0);
- scene->_arrunkObj1337[3]._arr1[2]._object1.setStrip(1);
- scene->_arrunkObj1337[3]._arr1[2]._object1.setFrame(3);
- scene->_arrunkObj1337[3]._arr1[2]._object1.fixPriority(170);
-
- scene->_arrunkObj1337[0]._arr1[0]._object1.postInit();
- scene->_arrunkObj1337[0]._arr1[0]._object1.setVisage(1332);
- scene->_arrunkObj1337[0]._arr1[0]._object1.setPosition(scene->_arrunkObj1337[0]._arr1[0]._field36, 0);
- scene->_arrunkObj1337[0]._arr1[0]._object1.setStrip(1);
- scene->_arrunkObj1337[0]._arr1[0]._object1.setFrame(2);
- scene->_arrunkObj1337[0]._arr1[0]._object1.fixPriority(170);
-
- scene->_arrunkObj1337[0]._arr1[1]._object1.postInit();
- scene->_arrunkObj1337[0]._arr1[1]._object1.setVisage(1332);
- scene->_arrunkObj1337[0]._arr1[1]._object1.setPosition(scene->_arrunkObj1337[0]._arr1[1]._field36, 0);
- scene->_arrunkObj1337[0]._arr1[1]._object1.setStrip(1);
- scene->_arrunkObj1337[0]._arr1[1]._object1.setFrame(2);
- scene->_arrunkObj1337[0]._arr1[1]._object1.fixPriority(170);
-
- scene->_arrunkObj1337[0]._arr1[2]._object1.postInit();
- scene->_arrunkObj1337[0]._arr1[2]._object1.setVisage(1332);
- scene->_arrunkObj1337[0]._arr1[2]._object1.setPosition(scene->_arrunkObj1337[0]._arr1[2]._field36, 0);
- scene->_arrunkObj1337[0]._arr1[2]._object1.setStrip(1);
- scene->_arrunkObj1337[0]._arr1[2]._object1.setFrame(2);
- scene->_arrunkObj1337[0]._arr1[2]._object1.fixPriority(170);
+ waitFrames(120);
+ scene->_gameBoardSide[2]._outpostStation[0]._card.remove();
+ scene->_gameBoardSide[2]._outpostStation[1]._card.remove();
+ scene->_gameBoardSide[2]._outpostStation[2]._card.remove();
+ scene->_gameBoardSide[2]._outpostStation[3]._card.remove();
+ scene->_gameBoardSide[2]._outpostStation[4]._card.remove();
+ scene->_gameBoardSide[2]._outpostStation[5]._card.remove();
+ scene->_gameBoardSide[2]._outpostStation[6]._card.remove();
+ scene->_gameBoardSide[2]._outpostStation[7]._card.remove();
+
+ scene->_gameBoardSide[1]._outpostStation[0]._card.remove();
+ scene->_gameBoardSide[1]._outpostStation[1]._card.remove();
+
+ scene->_gameBoardSide[3]._outpostStation[0]._card.remove();
+ scene->_gameBoardSide[3]._outpostStation[1]._card.remove();
+ scene->_gameBoardSide[3]._outpostStation[2]._card.remove();
+
+ scene->_gameBoardSide[0]._outpostStation[0]._card.remove();
+ scene->_gameBoardSide[0]._outpostStation[1]._card.remove();
+
+ scene->_stockPile.setup(1332, 5, 1);
+ scene->_stockPile.setPosition(Common::Point(165, 95));
+ scene->_stockPile.setPriority(110);
+ scene->_stockPile._effect = EFFECT_SHADED;
+ scene->_stockPile.show();
+
+ scene->_gameBoardSide[1]._handCard[0]._card.postInit();
+ scene->_gameBoardSide[1]._handCard[0]._card.setVisage(1332);
+ scene->_gameBoardSide[1]._handCard[0]._card.setPosition(scene->_gameBoardSide[1]._handCard[0]._stationPos, 0);
+ scene->_gameBoardSide[1]._handCard[0]._card.setStrip(1);
+ scene->_gameBoardSide[1]._handCard[0]._card.setFrame(4);
+ scene->_gameBoardSide[1]._handCard[0]._card.fixPriority(170);
+
+ scene->_gameBoardSide[1]._handCard[1]._card.postInit();
+ scene->_gameBoardSide[1]._handCard[1]._card.setVisage(1332);
+ scene->_gameBoardSide[1]._handCard[1]._card.setPosition(scene->_gameBoardSide[1]._handCard[1]._stationPos, 0);
+ scene->_gameBoardSide[1]._handCard[1]._card.setStrip(1);
+ scene->_gameBoardSide[1]._handCard[1]._card.setFrame(4);
+ scene->_gameBoardSide[1]._handCard[1]._card.fixPriority(170);
+
+ scene->_gameBoardSide[1]._handCard[2]._card.postInit();
+ scene->_gameBoardSide[1]._handCard[2]._card.setVisage(1332);
+ scene->_gameBoardSide[1]._handCard[2]._card.setPosition(scene->_gameBoardSide[1]._handCard[2]._stationPos, 0);
+ scene->_gameBoardSide[1]._handCard[2]._card.setStrip(1);
+ scene->_gameBoardSide[1]._handCard[2]._card.setFrame(4);
+ scene->_gameBoardSide[1]._handCard[2]._card.fixPriority(170);
+
+ scene->_gameBoardSide[2]._handCard[0]._cardId = 30;
+ scene->_gameBoardSide[2]._handCard[0]._card.postInit();
+ scene->_gameBoardSide[2]._handCard[0]._card.setVisage(1332);
+ scene->_gameBoardSide[2]._handCard[0]._card.setPosition(scene->_gameBoardSide[2]._handCard[0]._stationPos, 0);
+ scene->_gameBoardSide[2]._handCard[0]._card.setStrip(1);
+ scene->_gameBoardSide[2]._handCard[0]._card.setFrame(2);
+ scene->_gameBoardSide[2]._handCard[0]._card.fixPriority(170);
+ scene->setAnimationInfo(&scene->_gameBoardSide[2]._handCard[0]);
+
+ scene->_gameBoardSide[2]._handCard[1]._cardId = 16;
+ scene->_gameBoardSide[2]._handCard[1]._card.postInit();
+ scene->_gameBoardSide[2]._handCard[1]._card.setVisage(1332);
+ scene->_gameBoardSide[2]._handCard[1]._card.setPosition(scene->_gameBoardSide[2]._handCard[1]._stationPos, 0);
+ scene->_gameBoardSide[2]._handCard[1]._card.setStrip(1);
+ scene->_gameBoardSide[2]._handCard[1]._card.setFrame(2);
+ scene->_gameBoardSide[2]._handCard[1]._card.fixPriority(170);
+ scene->setAnimationInfo(&scene->_gameBoardSide[2]._handCard[1]);
+
+ scene->_gameBoardSide[2]._handCard[2]._cardId = 1;
+ scene->_gameBoardSide[2]._handCard[2]._card.postInit();
+ scene->_gameBoardSide[2]._handCard[2]._card.setVisage(1332);
+ scene->_gameBoardSide[2]._handCard[2]._card.setPosition(scene->_gameBoardSide[2]._handCard[2]._stationPos, 0);
+ scene->_gameBoardSide[2]._handCard[2]._card.setStrip(1);
+ scene->_gameBoardSide[2]._handCard[2]._card.setFrame(2);
+ scene->_gameBoardSide[2]._handCard[2]._card.fixPriority(170);
+ scene->setAnimationInfo(&scene->_gameBoardSide[2]._handCard[2]);
+
+ scene->_gameBoardSide[3]._handCard[0]._card.postInit();
+ scene->_gameBoardSide[3]._handCard[0]._card.setVisage(1332);
+ scene->_gameBoardSide[3]._handCard[0]._card.setPosition(scene->_gameBoardSide[3]._handCard[0]._stationPos, 0);
+ scene->_gameBoardSide[3]._handCard[0]._card.setStrip(1);
+ scene->_gameBoardSide[3]._handCard[0]._card.setFrame(3);
+ scene->_gameBoardSide[3]._handCard[0]._card.fixPriority(170);
+
+ scene->_gameBoardSide[3]._handCard[1]._card.postInit();
+ scene->_gameBoardSide[3]._handCard[1]._card.setVisage(1332);
+ scene->_gameBoardSide[3]._handCard[1]._card.setPosition(scene->_gameBoardSide[3]._handCard[1]._stationPos, 0);
+ scene->_gameBoardSide[3]._handCard[1]._card.setStrip(1);
+ scene->_gameBoardSide[3]._handCard[1]._card.setFrame(3);
+ scene->_gameBoardSide[3]._handCard[1]._card.fixPriority(170);
+
+ scene->_gameBoardSide[3]._handCard[2]._card.postInit();
+ scene->_gameBoardSide[3]._handCard[2]._card.setVisage(1332);
+ scene->_gameBoardSide[3]._handCard[2]._card.setPosition(scene->_gameBoardSide[3]._handCard[2]._stationPos, 0);
+ scene->_gameBoardSide[3]._handCard[2]._card.setStrip(1);
+ scene->_gameBoardSide[3]._handCard[2]._card.setFrame(3);
+ scene->_gameBoardSide[3]._handCard[2]._card.fixPriority(170);
+
+ scene->_gameBoardSide[0]._handCard[0]._card.postInit();
+ scene->_gameBoardSide[0]._handCard[0]._card.setVisage(1332);
+ scene->_gameBoardSide[0]._handCard[0]._card.setPosition(scene->_gameBoardSide[0]._handCard[0]._stationPos, 0);
+ scene->_gameBoardSide[0]._handCard[0]._card.setStrip(1);
+ scene->_gameBoardSide[0]._handCard[0]._card.setFrame(2);
+ scene->_gameBoardSide[0]._handCard[0]._card.fixPriority(170);
+
+ scene->_gameBoardSide[0]._handCard[1]._card.postInit();
+ scene->_gameBoardSide[0]._handCard[1]._card.setVisage(1332);
+ scene->_gameBoardSide[0]._handCard[1]._card.setPosition(scene->_gameBoardSide[0]._handCard[1]._stationPos, 0);
+ scene->_gameBoardSide[0]._handCard[1]._card.setStrip(1);
+ scene->_gameBoardSide[0]._handCard[1]._card.setFrame(2);
+ scene->_gameBoardSide[0]._handCard[1]._card.fixPriority(170);
+
+ scene->_gameBoardSide[0]._handCard[2]._card.postInit();
+ scene->_gameBoardSide[0]._handCard[2]._card.setVisage(1332);
+ scene->_gameBoardSide[0]._handCard[2]._card.setPosition(scene->_gameBoardSide[0]._handCard[2]._stationPos, 0);
+ scene->_gameBoardSide[0]._handCard[2]._card.setStrip(1);
+ scene->_gameBoardSide[0]._handCard[2]._card.setFrame(2);
+ scene->_gameBoardSide[0]._handCard[2]._card.fixPriority(170);
R2_GLOBALS._sceneObjects->draw();
scene->actionDisplay(1331, 10, 159, 10, 1, 200, 0, 7, 0, 154, 154);
- scene->_item2._object1.setPosition(Common::Point(162, 95), 0);
- scene->_item2._object1.show();
+ scene->_animatedCard._card.setPosition(Common::Point(162, 95), 0);
+ scene->_animatedCard._card.show();
scene->_aSound2.play(61);
Common::Point pt(91, 174);
NpcMover *mover = new NpcMover();
- scene->_item2._object1.addMover(mover, &pt, this);
+ scene->_animatedCard._card.addMover(mover, &pt, this);
}
break;
case 2: {
- scene->_arrunkObj1337[2]._arr1[3]._field34 = 2;
- scene->_arrunkObj1337[2]._arr1[3]._object1.postInit();
- scene->_arrunkObj1337[2]._arr1[3]._object1.setVisage(1332);
- scene->_arrunkObj1337[2]._arr1[3]._object1.setPosition(scene->_arrunkObj1337[2]._arr1[3]._field36, 0);
- scene->_arrunkObj1337[2]._arr1[3]._object1.setStrip(1);
- scene->_arrunkObj1337[2]._arr1[3]._object1.setFrame(2);
- scene->_arrunkObj1337[2]._arr1[3]._object1.fixPriority(170);
+ scene->_gameBoardSide[2]._handCard[3]._cardId = 2;
+ scene->_gameBoardSide[2]._handCard[3]._card.postInit();
+ scene->_gameBoardSide[2]._handCard[3]._card.setVisage(1332);
+ scene->_gameBoardSide[2]._handCard[3]._card.setPosition(scene->_gameBoardSide[2]._handCard[3]._stationPos, 0);
+ scene->_gameBoardSide[2]._handCard[3]._card.setStrip(1);
+ scene->_gameBoardSide[2]._handCard[3]._card.setFrame(2);
+ scene->_gameBoardSide[2]._handCard[3]._card.fixPriority(170);
- scene->_item2._object1.hide();
- scene->setAnimationInfo(&scene->_arrunkObj1337[2]._arr1[3]);
+ scene->_animatedCard._card.hide();
+ scene->setAnimationInfo(&scene->_gameBoardSide[2]._handCard[3]);
R2_GLOBALS._sceneObjects->draw();
- skipFrames(60);
+ waitFrames(60);
scene->actionDisplay(1331, 11, 159, 10, 1, 200, 0, 7, 0, 154, 154);
scene->actionDisplay(1331, 12, 159, 10, 1, 200, 0, 7, 0, 154, 154);
- scene->_arrunkObj1337[2]._arr2[1]._field34 = 1;
- scene->_arrunkObj1337[2]._arr2[1]._object1.postInit();
- scene->_arrunkObj1337[2]._arr2[1]._object1.setVisage(1332);
- scene->_arrunkObj1337[2]._arr2[1]._object1.setPosition(scene->_arrunkObj1337[2]._arr2[1]._field36, 0);
- scene->_arrunkObj1337[2]._arr2[1]._object1.hide();
+ scene->_gameBoardSide[2]._outpostStation[1]._cardId = 1;
+ scene->_gameBoardSide[2]._outpostStation[1]._card.postInit();
+ scene->_gameBoardSide[2]._outpostStation[1]._card.setVisage(1332);
+ scene->_gameBoardSide[2]._outpostStation[1]._card.setPosition(scene->_gameBoardSide[2]._outpostStation[1]._stationPos, 0);
+ scene->_gameBoardSide[2]._outpostStation[1]._card.hide();
- scene->_item2._object1.setStrip(scene->_arrunkObj1337[2]._arr1[2]._object1._strip);
- scene->_item2._object1.setFrame(scene->_arrunkObj1337[2]._arr1[2]._object1._frame);
- scene->_item2._object1.animate(ANIM_MODE_NONE, NULL);
+ scene->_animatedCard._card.setStrip(scene->_gameBoardSide[2]._handCard[2]._card._strip);
+ scene->_animatedCard._card.setFrame(scene->_gameBoardSide[2]._handCard[2]._card._frame);
+ scene->_animatedCard._card.animate(ANIM_MODE_NONE, NULL);
- scene->_arrunkObj1337[2]._arr1[2]._field34 = 0;
- scene->_arrunkObj1337[2]._arr1[2]._object1.remove();
+ scene->_gameBoardSide[2]._handCard[2]._cardId = 0;
+ scene->_gameBoardSide[2]._handCard[2]._card.remove();
- scene->_item2._object1.setPosition(scene->_arrunkObj1337[2]._arr1[2]._field36, 0);
- scene->_item2._object1.show();
+ scene->_animatedCard._card.setPosition(scene->_gameBoardSide[2]._handCard[2]._stationPos, 0);
+ scene->_animatedCard._card.show();
NpcMover *mover = new NpcMover();
- scene->_item2._object1.addMover(mover, &scene->_arrunkObj1337[2]._arr2[1]._field36, this);
+ scene->_animatedCard._card.addMover(mover, &scene->_gameBoardSide[2]._outpostStation[1]._stationPos, this);
}
break;
case 3: {
- scene->_item2._object1.hide();
- scene->setAnimationInfo(&scene->_arrunkObj1337[2]._arr2[1]);
+ scene->_animatedCard._card.hide();
+ scene->setAnimationInfo(&scene->_gameBoardSide[2]._outpostStation[1]);
scene->_aSound1.play(59);
R2_GLOBALS._sceneObjects->draw();
- skipFrames(60);
+ waitFrames(60);
scene->actionDisplay(1331, 13, 159, 10, 1, 200, 0, 7, 0, 154, 154);
- scene->_arrunkObj1337[2]._arr2[1]._field34 = scene->_arrunkObj1337[2]._arr1[3]._field34;
+ scene->_gameBoardSide[2]._outpostStation[1]._cardId = scene->_gameBoardSide[2]._handCard[3]._cardId;
- scene->_item2._object1.setStrip(scene->_arrunkObj1337[2]._arr1[3]._object1._strip);
- scene->_item2._object1.setFrame(scene->_arrunkObj1337[2]._arr1[3]._object1._frame);
+ scene->_animatedCard._card.setStrip(scene->_gameBoardSide[2]._handCard[3]._card._strip);
+ scene->_animatedCard._card.setFrame(scene->_gameBoardSide[2]._handCard[3]._card._frame);
- scene->_arrunkObj1337[2]._arr1[3]._field34 = 0;
- scene->_arrunkObj1337[2]._arr1[3]._object1.remove();
+ scene->_gameBoardSide[2]._handCard[3]._cardId = 0;
+ scene->_gameBoardSide[2]._handCard[3]._card.remove();
- scene->_item2._object1.setPosition(scene->_arrunkObj1337[2]._arr1[3]._field36, 0);
- scene->_item2._object1.show();
+ scene->_animatedCard._card.setPosition(scene->_gameBoardSide[2]._handCard[3]._stationPos, 0);
+ scene->_animatedCard._card.show();
NpcMover *mover = new NpcMover();
- scene->_item2._object1.addMover(mover, &scene->_arrunkObj1337[2]._arr2[1]._field36, this);
+ scene->_animatedCard._card.addMover(mover, &scene->_gameBoardSide[2]._outpostStation[1]._stationPos, this);
}
break;
case 4: {
- scene->_item2._object1.hide();
- scene->setAnimationInfo(&scene->_arrunkObj1337[2]._arr2[1]);
+ scene->_animatedCard._card.hide();
+ scene->setAnimationInfo(&scene->_gameBoardSide[2]._outpostStation[1]);
scene->_aSound1.play(59);
- scene->_item7._field34 = 1;
- scene->_item7._object1.hide();
+ scene->_discardPile._cardId = 1;
+ scene->_discardPile._card.hide();
- scene->_item2._object1.setStrip(5);
- scene->_item2._object1.setFrame(1);
- scene->_item2._object1.animate(ANIM_MODE_2, NULL);
- scene->_item2._object1.setPosition(scene->_arrunkObj1337[2]._arr2[1]._field36, 0);
- scene->_item2._object1.show();
+ scene->_animatedCard._card.setStrip(5);
+ scene->_animatedCard._card.setFrame(1);
+ scene->_animatedCard._card.animate(ANIM_MODE_2, NULL);
+ scene->_animatedCard._card.setPosition(scene->_gameBoardSide[2]._outpostStation[1]._stationPos, 0);
+ scene->_animatedCard._card.show();
NpcMover *mover = new NpcMover();
- scene->_item2._object1.addMover(mover, &scene->_item7._field36, this);
+ scene->_animatedCard._card.addMover(mover, &scene->_discardPile._stationPos, this);
}
break;
case 5: {
- scene->_item2._object1.hide();
+ scene->_animatedCard._card.hide();
- scene->_item7._object1.postInit();
- scene->_item7._object1.setVisage(1332);
- scene->_item7._object1.setPosition(scene->_item7._field36, 0);
- scene->setAnimationInfo(&scene->_item7);
+ scene->_discardPile._card.postInit();
+ scene->_discardPile._card.setVisage(1332);
+ scene->_discardPile._card.setPosition(scene->_discardPile._stationPos, 0);
+ scene->setAnimationInfo(&scene->_discardPile);
scene->_aSound2.play(61);
R2_GLOBALS._sceneObjects->draw();
- skipFrames(60);
+ waitFrames(60);
scene->actionDisplay(1331, 14, 159, 10, 1, 200, 0, 7, 0, 154, 154);
- scene->_arrunkObj1337[2]._arr3[0]._object1.postInit();
- scene->_arrunkObj1337[2]._arr3[0]._object1.setVisage(1332);
- scene->_arrunkObj1337[2]._arr3[0]._object1.setPosition(scene->_arrunkObj1337[2]._arr3[0]._field36, 0);
- scene->_arrunkObj1337[2]._arr3[0]._object1.hide();
+ scene->_gameBoardSide[2]._delayCard._card.postInit();
+ scene->_gameBoardSide[2]._delayCard._card.setVisage(1332);
+ scene->_gameBoardSide[2]._delayCard._card.setPosition(scene->_gameBoardSide[2]._delayCard._stationPos, 0);
+ scene->_gameBoardSide[2]._delayCard._card.hide();
- scene->_arrunkObj1337[3]._arr1[2]._field34 = 0;
- scene->_arrunkObj1337[3]._arr1[2].remove();
+ scene->_gameBoardSide[3]._handCard[2]._cardId = 0;
+ scene->_gameBoardSide[3]._handCard[2].remove();
- scene->_item2._object1.setPosition(scene->_arrunkObj1337[3]._arr1[2]._field36, 0);
- scene->_item2._object1.show();
+ scene->_animatedCard._card.setPosition(scene->_gameBoardSide[3]._handCard[2]._stationPos, 0);
+ scene->_animatedCard._card.show();
NpcMover *mover = new NpcMover();
- scene->_item2._object1.addMover(mover, &scene->_arrunkObj1337[2]._arr3[0]._field36, this);
+ scene->_animatedCard._card.addMover(mover, &scene->_gameBoardSide[2]._delayCard._stationPos, this);
}
break;
case 6: {
- scene->_item2._object1.hide();
- scene->_arrunkObj1337[2]._arr3[0]._field34 = 21;
- scene->setAnimationInfo(&scene->_arrunkObj1337[2]._arr3[0]);
+ scene->_animatedCard._card.hide();
+ scene->_gameBoardSide[2]._delayCard._cardId = 21;
+ scene->setAnimationInfo(&scene->_gameBoardSide[2]._delayCard);
scene->_aSound1.play(57);
R2_GLOBALS._sceneObjects->draw();
- skipFrames(60);
+ waitFrames(60);
scene->actionDisplay(1331, 15, 159, 10, 1, 200, 0, 7, 0, 154, 154);
int tmpVal = 15;
@@ -2653,89 +2692,89 @@ void Scene1337::Action1::signal() {
for (i = 0; i <= 7; i++) {
tmpVal += 29;
- scene->_arrObject1[i].postInit();
- scene->_arrObject1[i].setVisage(1332);
- scene->_arrObject1[i].setPosition(Common::Point(tmpVal, 90), 0);
- scene->_arrObject1[i].setStrip(3);
- scene->_arrObject1[i].fixPriority(190);
-
- scene->_arrObject2[i].postInit();
- scene->_arrObject2[i].setVisage(1332);
- scene->_arrObject2[i].setPosition(Common::Point(tmpVal, 90), 0);
- scene->_arrObject2[i].setStrip(7);
- scene->_arrObject2[i].setFrame(1);
- scene->_arrObject2[i].fixPriority(180);
- }
-
- scene->_arrObject1[0].setFrame(1);
- scene->_arrObject1[1].setFrame(3);
- scene->_arrObject1[2].setFrame(6);
- scene->_arrObject1[3].setFrame(8);
- scene->_arrObject1[4].setFrame(9);
- scene->_arrObject1[5].setFrame(10);
- scene->_arrObject1[6].setFrame(11);
- scene->_arrObject1[7].setFrame(12);
+ scene->_upperDisplayCard[i].postInit();
+ scene->_upperDisplayCard[i].setVisage(1332);
+ scene->_upperDisplayCard[i].setPosition(Common::Point(tmpVal, 90), 0);
+ scene->_upperDisplayCard[i].setStrip(3);
+ scene->_upperDisplayCard[i].fixPriority(190);
+
+ scene->_lowerDisplayCard[i].postInit();
+ scene->_lowerDisplayCard[i].setVisage(1332);
+ scene->_lowerDisplayCard[i].setPosition(Common::Point(tmpVal, 90), 0);
+ scene->_lowerDisplayCard[i].setStrip(7);
+ scene->_lowerDisplayCard[i].setFrame(1);
+ scene->_lowerDisplayCard[i].fixPriority(180);
+ }
+
+ scene->_upperDisplayCard[0].setFrame(1);
+ scene->_upperDisplayCard[1].setFrame(3);
+ scene->_upperDisplayCard[2].setFrame(6);
+ scene->_upperDisplayCard[3].setFrame(8);
+ scene->_upperDisplayCard[4].setFrame(9);
+ scene->_upperDisplayCard[5].setFrame(10);
+ scene->_upperDisplayCard[6].setFrame(11);
+ scene->_upperDisplayCard[7].setFrame(12);
R2_GLOBALS._sceneObjects->draw();
- skipFrames(240);
+ waitFrames(240);
- scene->_arrObject1[0].remove();
- scene->_arrObject1[1].remove();
- scene->_arrObject1[2].remove();
- scene->_arrObject1[3].remove();
- scene->_arrObject1[4].remove();
- scene->_arrObject1[5].remove();
- scene->_arrObject1[6].remove();
- scene->_arrObject1[7].remove();
+ scene->_upperDisplayCard[0].remove();
+ scene->_upperDisplayCard[1].remove();
+ scene->_upperDisplayCard[2].remove();
+ scene->_upperDisplayCard[3].remove();
+ scene->_upperDisplayCard[4].remove();
+ scene->_upperDisplayCard[5].remove();
+ scene->_upperDisplayCard[6].remove();
+ scene->_upperDisplayCard[7].remove();
- scene->_arrObject2[0].remove();
- scene->_arrObject2[1].remove();
- scene->_arrObject2[2].remove();
- scene->_arrObject2[3].remove();
- scene->_arrObject2[4].remove();
- scene->_arrObject2[5].remove();
- scene->_arrObject2[6].remove();
- scene->_arrObject2[7].remove();
+ scene->_lowerDisplayCard[0].remove();
+ scene->_lowerDisplayCard[1].remove();
+ scene->_lowerDisplayCard[2].remove();
+ scene->_lowerDisplayCard[3].remove();
+ scene->_lowerDisplayCard[4].remove();
+ scene->_lowerDisplayCard[5].remove();
+ scene->_lowerDisplayCard[6].remove();
+ scene->_lowerDisplayCard[7].remove();
- scene->_item7._field34 = scene->_arrunkObj1337[2]._arr3[0]._field34;
+ scene->_discardPile._cardId = scene->_gameBoardSide[2]._delayCard._cardId;
- scene->_arrunkObj1337[2]._arr3[0]._field34 = 0;
- scene->_arrunkObj1337[2]._arr3[0]._object1.remove();
+ scene->_gameBoardSide[2]._delayCard._cardId = 0;
+ scene->_gameBoardSide[2]._delayCard._card.remove();
- scene->_item2._object1.setPosition(scene->_arrunkObj1337[2]._arr3[0]._field36, 0);
- scene->_item2._object1.show();
+ scene->_animatedCard._card.setPosition(scene->_gameBoardSide[2]._delayCard._stationPos, 0);
+ scene->_animatedCard._card.show();
NpcMover *mover = new NpcMover();
- scene->_item2._object1.addMover(mover, &scene->_item7._field36, this);
+ scene->_animatedCard._card.addMover(mover, &scene->_discardPile._stationPos, this);
}
break;
case 7: {
- scene->_item2._object1.hide();
- scene->setAnimationInfo(&scene->_item7);
+ scene->_animatedCard._card.hide();
+ scene->setAnimationInfo(&scene->_discardPile);
scene->_aSound2.play(61);
R2_GLOBALS._sceneObjects->draw();
- scene->_arrunkObj1337[2]._arr3[0]._object1.postInit();
- scene->_arrunkObj1337[2]._arr3[0]._object1.setVisage(1332);
- scene->_arrunkObj1337[2]._arr3[0]._object1.setPosition(scene->_arrunkObj1337[2]._arr3[0]._field36, 0);
- scene->_arrunkObj1337[2]._arr3[0]._object1.hide();
+ scene->_gameBoardSide[2]._delayCard._card.postInit();
+ scene->_gameBoardSide[2]._delayCard._card.setVisage(1332);
+ scene->_gameBoardSide[2]._delayCard._card.setPosition(scene->_gameBoardSide[2]._delayCard._stationPos, 0);
+ scene->_gameBoardSide[2]._delayCard._card.hide();
- scene->_arrunkObj1337[3]._arr1[1]._field34 = 0;
- scene->_arrunkObj1337[3]._arr1[1].remove();
+ scene->_gameBoardSide[3]._handCard[1]._cardId = 0;
+ scene->_gameBoardSide[3]._handCard[1].remove();
- scene->_item2._object1.setPosition(scene->_arrunkObj1337[3]._arr1[1]._field36, 0);
- scene->_item2._object1.show();
+ scene->_animatedCard._card.setPosition(scene->_gameBoardSide[3]._handCard[1]._stationPos, 0);
+ scene->_animatedCard._card.show();
NpcMover *mover = new NpcMover();
- scene->_item2._object1.addMover(mover, &scene->_arrunkObj1337[2]._arr3[0]._field36, this);
+ scene->_animatedCard._card.addMover(mover, &scene->_gameBoardSide[2]._delayCard._stationPos, this);
}
break;
case 8: {
- scene->_item2._object1.hide();
- scene->_arrunkObj1337[2]._arr3[0]._field34 = 14;
- scene->setAnimationInfo(&scene->_arrunkObj1337[2]._arr3[0]);
+ scene->_animatedCard._card.hide();
+ scene->_gameBoardSide[2]._delayCard._cardId = 14;
+ scene->setAnimationInfo(&scene->_gameBoardSide[2]._delayCard);
scene->_aSound1.play(57);
R2_GLOBALS._sceneObjects->draw();
@@ -2746,219 +2785,219 @@ void Scene1337::Action1::signal() {
for (i = 0; i <= 3; i++) {
tmpVal += 29;
- scene->_arrObject1[i].postInit();
- scene->_arrObject1[i].setVisage(1332);
- scene->_arrObject1[i].setPosition(Common::Point(tmpVal, 71), 0);
- scene->_arrObject1[i].setStrip(3);
- scene->_arrObject1[i].fixPriority(190);
+ scene->_upperDisplayCard[i].postInit();
+ scene->_upperDisplayCard[i].setVisage(1332);
+ scene->_upperDisplayCard[i].setPosition(Common::Point(tmpVal, 71), 0);
+ scene->_upperDisplayCard[i].setStrip(3);
+ scene->_upperDisplayCard[i].fixPriority(190);
- scene->_arrObject2[i].postInit();
- scene->_arrObject2[i].setVisage(1332);
- scene->_arrObject2[i].setPosition(Common::Point(tmpVal, 71), 0);
- scene->_arrObject2[i].setStrip(7);
- scene->_arrObject2[i].setFrame(1);
- scene->_arrObject2[i].fixPriority(180);
+ scene->_lowerDisplayCard[i].postInit();
+ scene->_lowerDisplayCard[i].setVisage(1332);
+ scene->_lowerDisplayCard[i].setPosition(Common::Point(tmpVal, 71), 0);
+ scene->_lowerDisplayCard[i].setStrip(7);
+ scene->_lowerDisplayCard[i].setFrame(1);
+ scene->_lowerDisplayCard[i].fixPriority(180);
}
- scene->_arrObject1[0].setFrame(2);
- scene->_arrObject1[1].setFrame(5);
- scene->_arrObject1[2].setFrame(7);
- scene->_arrObject1[3].setFrame(15);
+ scene->_upperDisplayCard[0].setFrame(2);
+ scene->_upperDisplayCard[1].setFrame(5);
+ scene->_upperDisplayCard[2].setFrame(7);
+ scene->_upperDisplayCard[3].setFrame(15);
R2_GLOBALS._sceneObjects->draw();
- skipFrames(240);
+ waitFrames(240);
scene->actionDisplay(1331, 17, 159, 10, 1, 200, 0, 7, 0, 154, 154);
tmpVal = 72;
for (i = 4; i <= 7; i++) {
tmpVal += 29;
- scene->_arrObject1[i].postInit();
- scene->_arrObject1[i].setVisage(1332);
- scene->_arrObject1[i].setPosition(Common::Point(tmpVal, 100), 0);
- scene->_arrObject1[i].setStrip(4);
- scene->_arrObject1[i].fixPriority(190);
+ scene->_upperDisplayCard[i].postInit();
+ scene->_upperDisplayCard[i].setVisage(1332);
+ scene->_upperDisplayCard[i].setPosition(Common::Point(tmpVal, 100), 0);
+ scene->_upperDisplayCard[i].setStrip(4);
+ scene->_upperDisplayCard[i].fixPriority(190);
- scene->_arrObject2[i].postInit();
- scene->_arrObject2[i].setVisage(1332);
- scene->_arrObject2[i].setPosition(Common::Point(tmpVal, 100), 0);
- scene->_arrObject2[i].setStrip(7);
- scene->_arrObject2[i].setFrame(1);
- scene->_arrObject2[i].fixPriority(180);
+ scene->_lowerDisplayCard[i].postInit();
+ scene->_lowerDisplayCard[i].setVisage(1332);
+ scene->_lowerDisplayCard[i].setPosition(Common::Point(tmpVal, 100), 0);
+ scene->_lowerDisplayCard[i].setStrip(7);
+ scene->_lowerDisplayCard[i].setFrame(1);
+ scene->_lowerDisplayCard[i].fixPriority(180);
}
- scene->_arrObject1[4].setFrame(1);
- scene->_arrObject1[5].setFrame(5);
- scene->_arrObject1[6].setFrame(7);
- scene->_arrObject1[7].setFrame(3);
+ scene->_upperDisplayCard[4].setFrame(1);
+ scene->_upperDisplayCard[5].setFrame(5);
+ scene->_upperDisplayCard[6].setFrame(7);
+ scene->_upperDisplayCard[7].setFrame(3);
R2_GLOBALS._sceneObjects->draw();
- skipFrames(240);
+ waitFrames(240);
- scene->_arrObject1[0].remove();
- scene->_arrObject1[1].remove();
- scene->_arrObject1[2].remove();
- scene->_arrObject1[3].remove();
- scene->_arrObject1[4].remove();
- scene->_arrObject1[5].remove();
- scene->_arrObject1[6].remove();
- scene->_arrObject1[7].remove();
+ scene->_upperDisplayCard[0].remove();
+ scene->_upperDisplayCard[1].remove();
+ scene->_upperDisplayCard[2].remove();
+ scene->_upperDisplayCard[3].remove();
+ scene->_upperDisplayCard[4].remove();
+ scene->_upperDisplayCard[5].remove();
+ scene->_upperDisplayCard[6].remove();
+ scene->_upperDisplayCard[7].remove();
- scene->_arrObject2[0].remove();
- scene->_arrObject2[1].remove();
- scene->_arrObject2[2].remove();
- scene->_arrObject2[3].remove();
- scene->_arrObject2[4].remove();
- scene->_arrObject2[5].remove();
- scene->_arrObject2[6].remove();
- scene->_arrObject2[7].remove();
+ scene->_lowerDisplayCard[0].remove();
+ scene->_lowerDisplayCard[1].remove();
+ scene->_lowerDisplayCard[2].remove();
+ scene->_lowerDisplayCard[3].remove();
+ scene->_lowerDisplayCard[4].remove();
+ scene->_lowerDisplayCard[5].remove();
+ scene->_lowerDisplayCard[6].remove();
+ scene->_lowerDisplayCard[7].remove();
- scene->_item7._field34 = scene->_arrunkObj1337[2]._arr1[0]._field34;
+ scene->_discardPile._cardId = scene->_gameBoardSide[2]._handCard[0]._cardId;
- scene->_item2._object1.setStrip(scene->_arrunkObj1337[2]._arr1[0]._object1._strip);
- scene->_item2._object1.setFrame(scene->_arrunkObj1337[2]._arr1[0]._object1._frame);
- scene->_item2._object1.animate(ANIM_MODE_NONE, NULL);
+ scene->_animatedCard._card.setStrip(scene->_gameBoardSide[2]._handCard[0]._card._strip);
+ scene->_animatedCard._card.setFrame(scene->_gameBoardSide[2]._handCard[0]._card._frame);
+ scene->_animatedCard._card.animate(ANIM_MODE_NONE, NULL);
- scene->_arrunkObj1337[2]._arr1[0]._field34 = 0;
- scene->_arrunkObj1337[2]._arr1[0]._object1.remove();
+ scene->_gameBoardSide[2]._handCard[0]._cardId = 0;
+ scene->_gameBoardSide[2]._handCard[0]._card.remove();
- scene->_item2._object1.setPosition(scene->_arrunkObj1337[2]._arr1[0]._field36, 0);
- scene->_item2._object1.show();
+ scene->_animatedCard._card.setPosition(scene->_gameBoardSide[2]._handCard[0]._stationPos, 0);
+ scene->_animatedCard._card.show();
NpcMover *mover = new NpcMover();
- scene->_item2._object1.addMover(mover, &scene->_arrunkObj1337[2]._arr3[0]._field36, this);
+ scene->_animatedCard._card.addMover(mover, &scene->_gameBoardSide[2]._delayCard._stationPos, this);
}
break;
case 9: {
scene->_aSound1.play(58);
- scene->_arrunkObj1337[2]._arr3[0]._field34 = 0;
- scene->_arrunkObj1337[2]._arr3[0].remove();
- scene->_item2._object1.setStrip(5);
- scene->_item2._object1.setFrame(1);
- scene->_item2._object1.animate(ANIM_MODE_2, NULL);
- scene->_item2._object1.setPosition(scene->_arrunkObj1337[2]._arr3[0]._field36, 0);
- scene->_item2._object1.show();
+ scene->_gameBoardSide[2]._delayCard._cardId = 0;
+ scene->_gameBoardSide[2]._delayCard.remove();
+ scene->_animatedCard._card.setStrip(5);
+ scene->_animatedCard._card.setFrame(1);
+ scene->_animatedCard._card.animate(ANIM_MODE_2, NULL);
+ scene->_animatedCard._card.setPosition(scene->_gameBoardSide[2]._delayCard._stationPos, 0);
+ scene->_animatedCard._card.show();
NpcMover *mover = new NpcMover();
- scene->_item2._object1.addMover(mover, &scene->_item7._field36, this);
+ scene->_animatedCard._card.addMover(mover, &scene->_discardPile._stationPos, this);
}
break;
case 10: {
- scene->_item2._object1.hide();
- scene->setAnimationInfo(&scene->_item7);
+ scene->_animatedCard._card.hide();
+ scene->setAnimationInfo(&scene->_discardPile);
scene->_aSound2.play(61);
R2_GLOBALS._sceneObjects->draw();
scene->actionDisplay(1331, 18, 159, 10, 1, 200, 0, 7, 0, 154, 154);
- scene->_arrObject1[0].postInit();
- scene->_arrObject1[0].setVisage(1332);
- scene->_arrObject1[0].setPosition(Common::Point(131, 71), 0);
- scene->_arrObject1[0].fixPriority(190);
- scene->_arrObject1[0].setStrip(3);
- scene->_arrObject1[0].setFrame(4);
-
- scene->_arrObject2[0].postInit();
- scene->_arrObject2[0].setVisage(1332);
- scene->_arrObject2[0].setPosition(Common::Point(131, 71), 0);
- scene->_arrObject2[0].setStrip(7);
- scene->_arrObject2[0].setFrame(1);
- scene->_arrObject2[0].fixPriority(180);
-
- scene->_arrObject1[1].postInit();
- scene->_arrObject1[1].setVisage(1332);
- scene->_arrObject1[1].setPosition(Common::Point(160, 71), 0);
- scene->_arrObject1[1].fixPriority(190);
- scene->_arrObject1[1].setStrip(3);
- scene->_arrObject1[1].setFrame(16);
-
- scene->_arrObject2[1].postInit();
- scene->_arrObject2[1].setVisage(1332);
- scene->_arrObject2[1].setPosition(Common::Point(160, 71), 0);
- scene->_arrObject2[1].setStrip(7);
- scene->_arrObject2[1].setFrame(1);
- scene->_arrObject2[1].fixPriority(180);
-
- scene->_arrObject1[2].postInit();
- scene->_arrObject1[2].setVisage(1332);
- scene->_arrObject1[2].setPosition(Common::Point(131, 100), 0);
- scene->_arrObject1[2].fixPriority(190);
- scene->_arrObject1[2].setStrip(4);
- scene->_arrObject1[2].setFrame(4);
-
- scene->_arrObject2[2].postInit();
- scene->_arrObject2[2].setVisage(1332);
- scene->_arrObject2[2].setPosition(Common::Point(131, 100), 0);
- scene->_arrObject2[2].setStrip(7);
- scene->_arrObject2[2].setFrame(1);
- scene->_arrObject2[2].fixPriority(180);
-
- scene->_arrObject1[3].postInit();
- scene->_arrObject1[3].setVisage(1332);
- scene->_arrObject1[3].setPosition(Common::Point(160, 100), 0);
- scene->_arrObject1[3].fixPriority(190);
- scene->_arrObject1[3].setStrip(4);
- scene->_arrObject1[3].setFrame(2);
-
- scene->_arrObject2[3].postInit();
- scene->_arrObject2[3].setVisage(1332);
- scene->_arrObject2[3].setPosition(Common::Point(160, 100), 0);
- scene->_arrObject2[3].setStrip(7);
- scene->_arrObject2[3].setFrame(1);
- scene->_arrObject2[3].fixPriority(180);
+ scene->_upperDisplayCard[0].postInit();
+ scene->_upperDisplayCard[0].setVisage(1332);
+ scene->_upperDisplayCard[0].setPosition(Common::Point(131, 71), 0);
+ scene->_upperDisplayCard[0].fixPriority(190);
+ scene->_upperDisplayCard[0].setStrip(3);
+ scene->_upperDisplayCard[0].setFrame(4);
+
+ scene->_lowerDisplayCard[0].postInit();
+ scene->_lowerDisplayCard[0].setVisage(1332);
+ scene->_lowerDisplayCard[0].setPosition(Common::Point(131, 71), 0);
+ scene->_lowerDisplayCard[0].setStrip(7);
+ scene->_lowerDisplayCard[0].setFrame(1);
+ scene->_lowerDisplayCard[0].fixPriority(180);
+
+ scene->_upperDisplayCard[1].postInit();
+ scene->_upperDisplayCard[1].setVisage(1332);
+ scene->_upperDisplayCard[1].setPosition(Common::Point(160, 71), 0);
+ scene->_upperDisplayCard[1].fixPriority(190);
+ scene->_upperDisplayCard[1].setStrip(3);
+ scene->_upperDisplayCard[1].setFrame(16);
+
+ scene->_lowerDisplayCard[1].postInit();
+ scene->_lowerDisplayCard[1].setVisage(1332);
+ scene->_lowerDisplayCard[1].setPosition(Common::Point(160, 71), 0);
+ scene->_lowerDisplayCard[1].setStrip(7);
+ scene->_lowerDisplayCard[1].setFrame(1);
+ scene->_lowerDisplayCard[1].fixPriority(180);
+
+ scene->_upperDisplayCard[2].postInit();
+ scene->_upperDisplayCard[2].setVisage(1332);
+ scene->_upperDisplayCard[2].setPosition(Common::Point(131, 100), 0);
+ scene->_upperDisplayCard[2].fixPriority(190);
+ scene->_upperDisplayCard[2].setStrip(4);
+ scene->_upperDisplayCard[2].setFrame(4);
+
+ scene->_lowerDisplayCard[2].postInit();
+ scene->_lowerDisplayCard[2].setVisage(1332);
+ scene->_lowerDisplayCard[2].setPosition(Common::Point(131, 100), 0);
+ scene->_lowerDisplayCard[2].setStrip(7);
+ scene->_lowerDisplayCard[2].setFrame(1);
+ scene->_lowerDisplayCard[2].fixPriority(180);
+
+ scene->_upperDisplayCard[3].postInit();
+ scene->_upperDisplayCard[3].setVisage(1332);
+ scene->_upperDisplayCard[3].setPosition(Common::Point(160, 100), 0);
+ scene->_upperDisplayCard[3].fixPriority(190);
+ scene->_upperDisplayCard[3].setStrip(4);
+ scene->_upperDisplayCard[3].setFrame(2);
+
+ scene->_lowerDisplayCard[3].postInit();
+ scene->_lowerDisplayCard[3].setVisage(1332);
+ scene->_lowerDisplayCard[3].setPosition(Common::Point(160, 100), 0);
+ scene->_lowerDisplayCard[3].setStrip(7);
+ scene->_lowerDisplayCard[3].setFrame(1);
+ scene->_lowerDisplayCard[3].fixPriority(180);
R2_GLOBALS._sceneObjects->draw();
- skipFrames(240);
+ waitFrames(240);
- scene->_arrObject1[0].remove();
- scene->_arrObject1[1].remove();
- scene->_arrObject1[2].remove();
- scene->_arrObject1[3].remove();
+ scene->_upperDisplayCard[0].remove();
+ scene->_upperDisplayCard[1].remove();
+ scene->_upperDisplayCard[2].remove();
+ scene->_upperDisplayCard[3].remove();
- scene->_arrObject2[0].remove();
- scene->_arrObject2[1].remove();
- scene->_arrObject2[2].remove();
- scene->_arrObject2[3].remove();
+ scene->_lowerDisplayCard[0].remove();
+ scene->_lowerDisplayCard[1].remove();
+ scene->_lowerDisplayCard[2].remove();
+ scene->_lowerDisplayCard[3].remove();
- scene->_object1.setFrame(1);
- scene->_object1.show();
- scene->_object1.animate(ANIM_MODE_2, NULL);
+ scene->_currentPlayerArrow.setFrame(1);
+ scene->_currentPlayerArrow.show();
+ scene->_currentPlayerArrow.animate(ANIM_MODE_2, NULL);
R2_GLOBALS._sceneObjects->draw();
scene->actionDisplay(1331, 19, 159, 10, 1, 220, 0, 7, 0, 154, 154);
- scene->_object1.hide();
+ scene->_currentPlayerArrow.hide();
scene->actionDisplay(1331, 20, 159, 10, 1, 220, 0, 7, 0, 154, 154);
scene->actionDisplay(1331, 21, 159, 10, 1, 220, 0, 7, 0, 154, 154);
- scene->_item7._field34 = scene->_arrunkObj1337[2]._arr1[1]._field34;
+ scene->_discardPile._cardId = scene->_gameBoardSide[2]._handCard[1]._cardId;
- scene->_item2._object1.setStrip(scene->_arrunkObj1337[2]._arr1[1]._object1._strip);
- scene->_item2._object1.setFrame(scene->_arrunkObj1337[2]._arr1[1]._object1._frame);
- scene->_item2._object1.animate(ANIM_MODE_NONE, NULL);
+ scene->_animatedCard._card.setStrip(scene->_gameBoardSide[2]._handCard[1]._card._strip);
+ scene->_animatedCard._card.setFrame(scene->_gameBoardSide[2]._handCard[1]._card._frame);
+ scene->_animatedCard._card.animate(ANIM_MODE_NONE, NULL);
- scene->_arrunkObj1337[2]._arr1[1]._field34 = 0;
- scene->_arrunkObj1337[2]._arr1[1]._object1.remove();
+ scene->_gameBoardSide[2]._handCard[1]._cardId = 0;
+ scene->_gameBoardSide[2]._handCard[1]._card.remove();
- scene->_item2._object1.setPosition(scene->_arrunkObj1337[2]._arr1[1]._field36, 0);
- scene->_item2._object1.show();
+ scene->_animatedCard._card.setPosition(scene->_gameBoardSide[2]._handCard[1]._stationPos, 0);
+ scene->_animatedCard._card.show();
NpcMover *mover = new NpcMover();
- scene->_item2._object1.addMover(mover, &scene->_item7._field36, this);
+ scene->_animatedCard._card.addMover(mover, &scene->_discardPile._stationPos, this);
}
break;
case 11: {
- scene->_item2._object1.hide();
- scene->setAnimationInfo(&scene->_item7);
+ scene->_animatedCard._card.hide();
+ scene->setAnimationInfo(&scene->_discardPile);
scene->_aSound2.play(61);
- scene->_item2._object1.setStrip(5);
- scene->_item2._object1.setFrame(1);
- scene->_item2._object1.animate(ANIM_MODE_2, NULL);
+ scene->_animatedCard._card.setStrip(5);
+ scene->_animatedCard._card.setFrame(1);
+ scene->_animatedCard._card.animate(ANIM_MODE_2, NULL);
R2_GLOBALS._sceneObjects->draw();
@@ -2966,40 +3005,40 @@ void Scene1337::Action1::signal() {
int i = -1;
for (i = 0; i <= 3; i ++) {
- scene->_arrunkObj1337[3]._arr1[i]._field34 = 0;
- scene->_arrunkObj1337[3]._arr1[i]._object1.remove();
+ scene->_gameBoardSide[3]._handCard[i]._cardId = 0;
+ scene->_gameBoardSide[3]._handCard[i]._card.remove();
- scene->_arrunkObj1337[2]._arr1[i]._field34 = 0;
- scene->_arrunkObj1337[2]._arr1[i]._object1.remove();
+ scene->_gameBoardSide[2]._handCard[i]._cardId = 0;
+ scene->_gameBoardSide[2]._handCard[i]._card.remove();
- scene->_arrunkObj1337[0]._arr1[i]._field34 = 0;
- scene->_arrunkObj1337[0]._arr1[i]._object1.remove();
+ scene->_gameBoardSide[0]._handCard[i]._cardId = 0;
+ scene->_gameBoardSide[0]._handCard[i]._card.remove();
- scene->_arrunkObj1337[1]._arr1[i]._field34 = 0;
- scene->_arrunkObj1337[1]._arr1[i]._object1.remove();
+ scene->_gameBoardSide[1]._handCard[i]._cardId = 0;
+ scene->_gameBoardSide[1]._handCard[i]._card.remove();
}
for (i = 0; i <= 7; i++) {
- scene->_arrunkObj1337[3]._arr2[i]._field34 = 0;
- scene->_arrunkObj1337[3]._arr2[i]._object1.remove();
+ scene->_gameBoardSide[3]._outpostStation[i]._cardId = 0;
+ scene->_gameBoardSide[3]._outpostStation[i]._card.remove();
- scene->_arrunkObj1337[2]._arr2[i]._field34 = 0;
- scene->_arrunkObj1337[2]._arr2[i]._object1.remove();
+ scene->_gameBoardSide[2]._outpostStation[i]._cardId = 0;
+ scene->_gameBoardSide[2]._outpostStation[i]._card.remove();
- scene->_arrunkObj1337[0]._arr2[i]._field34 = 0;
- scene->_arrunkObj1337[0]._arr2[i]._object1.remove();
+ scene->_gameBoardSide[0]._outpostStation[i]._cardId = 0;
+ scene->_gameBoardSide[0]._outpostStation[i]._card.remove();
- scene->_arrunkObj1337[1]._arr2[i]._field34 = 0;
- scene->_arrunkObj1337[1]._arr2[i]._object1.remove();
+ scene->_gameBoardSide[1]._outpostStation[i]._cardId = 0;
+ scene->_gameBoardSide[1]._outpostStation[i]._card.remove();
}
- scene->_arrunkObj1337[2]._arr3[0]._field34 = 0;
- scene->_arrunkObj1337[2]._arr3[0]._object1.remove();
+ scene->_gameBoardSide[2]._delayCard._cardId = 0;
+ scene->_gameBoardSide[2]._delayCard._card.remove();
- scene->_item7._field34 = 0;
- scene->_item7._object1.remove();
+ scene->_discardPile._cardId = 0;
+ scene->_discardPile._card.remove();
- scene->_background2.remove();
+ scene->_stockPile.remove();
}
// No break on purpose
case 0:
@@ -3015,473 +3054,484 @@ void Scene1337::Action1::signal() {
}
}
+/**
+ * Shuffle cards animation
+ */
void Scene1337::Action2::signal() {
Scene1337 *scene = (Scene1337 *)R2_GLOBALS._sceneManager._scene;
switch (_actionIndex++) {
case 0:
- scene->_item3._object1.postInit();
- scene->_item3._object1.setVisage(1332);
- scene->_item3._object1.setStrip(8);
- scene->_item3._object1.setFrame(1);
- scene->_item3._object1.fixPriority(300);
- scene->_item3._object1.setPosition(Common::Point(156, 108));
+ scene->_shuffleAnimation._card.postInit();
+ scene->_shuffleAnimation._card.setVisage(1332);
+ scene->_shuffleAnimation._card.setStrip(8);
+ scene->_shuffleAnimation._card.setFrame(1);
+ scene->_shuffleAnimation._card.fixPriority(300);
+ scene->_shuffleAnimation._card.setPosition(Common::Point(156, 108));
- scene->_item7._object1.remove();
- scene->_item7._field34 = 0;
+ scene->_discardPile._card.remove();
+ scene->_discardPile._cardId = 0;
scene->_aSound1.play(60);
- scene->_item3._object1.animate(ANIM_MODE_5, this);
+ scene->_shuffleAnimation._card.animate(ANIM_MODE_5, this);
break;
case 1:
- scene->_item3._object1.setFrame(1);
+ scene->_shuffleAnimation._card.setFrame(1);
scene->_aSound1.play(60);
- scene->_item3._object1.animate(ANIM_MODE_5, this);
+ scene->_shuffleAnimation._card.animate(ANIM_MODE_5, this);
break;
case 2: {
Common::Point pt(156, 108);
NpcMover *mover = new NpcMover();
- scene->_item3._object1.addMover(mover, &pt, this);
+ scene->_shuffleAnimation._card.addMover(mover, &pt, this);
}
break;
case 3:
- scene->_item3._object1.remove();
- scene->_background2.setup2(1332, 5, 1, 162, 95, 110, 1);
- scene->_field423C = 1;
+ scene->_shuffleAnimation._card.remove();
+ scene->_stockPile.setup(1332, 5, 1);
+ scene->_stockPile.setPosition(Common::Point(162, 95));
+ scene->_stockPile.setPriority(110);
+ scene->_stockPile._effect = EFFECT_SHADED;
+ scene->_stockPile.show();
+ scene->_shuffleEndedFl = true;
break;
default:
break;
}
}
+/**
+ * Deal cards
+ */
void Scene1337::Action3::signal() {
Scene1337 *scene = (Scene1337 *)R2_GLOBALS._sceneManager._scene;
- scene->_item2._object1.setPosition(Common::Point(162, 95), 0);
+ scene->_animatedCard._card.setPosition(Common::Point(162, 95), 0);
switch (_actionIndex++) {
case 0: {
- scene->_item2._object1._moveDiff = Common::Point(30, 30);
- scene->_item2._object1.setVisage(1332);
- scene->_item2._object1.setStrip(5);
- scene->_item2._object1.setFrame(1);
- scene->_item2._object1.fixPriority(400);
- scene->_item2._object1.animate(ANIM_MODE_2, NULL);
+ scene->_animatedCard._card._moveDiff = Common::Point(30, 30);
+ scene->_animatedCard._card.setVisage(1332);
+ scene->_animatedCard._card.setStrip(5);
+ scene->_animatedCard._card.setFrame(1);
+ scene->_animatedCard._card.fixPriority(400);
+ scene->_animatedCard._card.animate(ANIM_MODE_2, NULL);
scene->_aSound2.play(61);
Common::Point pt(283, 146);
NpcMover *mover = new NpcMover();
- scene->_item2._object1.addMover(mover, &pt, this);
+ scene->_animatedCard._card.addMover(mover, &pt, this);
- scene->_item2._object1.show();
- scene->_arrunkObj1337[1]._arr1[0]._field34 = scene->_field3E28[scene->_field3E24];
+ scene->_animatedCard._card.show();
+ scene->_gameBoardSide[1]._handCard[0]._cardId = scene->_availableCardsPile[scene->_cardsAvailableNumb];
}
break;
case 1: {
- scene->_arrunkObj1337[1]._arr1[0]._object1.postInit();
- scene->_arrunkObj1337[1]._arr1[0]._object1._moveDiff = Common::Point(30, 30);
- scene->_arrunkObj1337[1]._arr1[0]._object1.setVisage(1332);
- scene->_arrunkObj1337[1]._arr1[0]._object1.setPosition(scene->_arrunkObj1337[1]._arr1[0]._field36, 0);
- scene->_arrunkObj1337[1]._arr1[0]._object1.setStrip(1);
- scene->_arrunkObj1337[1]._arr1[0]._object1.setFrame(4);
- scene->_arrunkObj1337[1]._arr1[0]._object1.fixPriority(170);
+ scene->_gameBoardSide[1]._handCard[0]._card.postInit();
+ scene->_gameBoardSide[1]._handCard[0]._card._moveDiff = Common::Point(30, 30);
+ scene->_gameBoardSide[1]._handCard[0]._card.setVisage(1332);
+ scene->_gameBoardSide[1]._handCard[0]._card.setPosition(scene->_gameBoardSide[1]._handCard[0]._stationPos, 0);
+ scene->_gameBoardSide[1]._handCard[0]._card.setStrip(1);
+ scene->_gameBoardSide[1]._handCard[0]._card.setFrame(4);
+ scene->_gameBoardSide[1]._handCard[0]._card.fixPriority(170);
scene->_aSound2.play(61);
Common::Point pt(10, 174);
NpcMover *mover = new NpcMover();
- scene->_item2._object1.addMover(mover, &pt, this);
+ scene->_animatedCard._card.addMover(mover, &pt, this);
- scene->_arrunkObj1337[2]._arr1[0]._field34 = scene->_field3E28[scene->_field3E24];
+ scene->_gameBoardSide[2]._handCard[0]._cardId = scene->_availableCardsPile[scene->_cardsAvailableNumb];
}
break;
case 2: {
- scene->_arrunkObj1337[2]._arr1[0]._object1.postInit();
- scene->_arrunkObj1337[2]._arr1[0]._object1._moveDiff = Common::Point(30, 30);
- scene->_arrunkObj1337[2]._arr1[0]._object1.setVisage(1332);
- scene->_arrunkObj1337[2]._arr1[0]._object1.setPosition(scene->_arrunkObj1337[2]._arr1[0]._field36, 0);
- scene->_arrunkObj1337[2]._arr1[0]._object1.fixPriority(170);
- if (scene->_arrunkObj1337[2]._arr1[0]._field34 > 9) {
- if (scene->_arrunkObj1337[2]._arr1[0]._field34 > 25) {
- scene->_arrunkObj1337[2]._arr1[0]._object1.setStrip(4);
- scene->_arrunkObj1337[2]._arr1[0]._object1.setFrame(scene->_arrunkObj1337[2]._arr1[0]._field34 - 25);
- } else {
- scene->_arrunkObj1337[2]._arr1[0]._object1.setStrip(3);
- scene->_arrunkObj1337[2]._arr1[0]._object1.setFrame(scene->_arrunkObj1337[2]._arr1[0]._field34 - 9);
- }
+ scene->_gameBoardSide[2]._handCard[0]._card.postInit();
+ scene->_gameBoardSide[2]._handCard[0]._card._moveDiff = Common::Point(30, 30);
+ scene->_gameBoardSide[2]._handCard[0]._card.setVisage(1332);
+ scene->_gameBoardSide[2]._handCard[0]._card.setPosition(scene->_gameBoardSide[2]._handCard[0]._stationPos, 0);
+ scene->_gameBoardSide[2]._handCard[0]._card.fixPriority(170);
+ if (scene->_gameBoardSide[2]._handCard[0]._cardId > 25) {
+ scene->_gameBoardSide[2]._handCard[0]._card.setStrip(4);
+ scene->_gameBoardSide[2]._handCard[0]._card.setFrame(scene->_gameBoardSide[2]._handCard[0]._cardId - 25);
+ } else if (scene->_gameBoardSide[2]._handCard[0]._cardId > 9) {
+ scene->_gameBoardSide[2]._handCard[0]._card.setStrip(3);
+ scene->_gameBoardSide[2]._handCard[0]._card.setFrame(scene->_gameBoardSide[2]._handCard[0]._cardId - 9);
} else {
- scene->_arrunkObj1337[2]._arr1[0]._object1.setStrip(2);
- scene->_arrunkObj1337[2]._arr1[0]._object1.setFrame(scene->_arrunkObj1337[2]._arr1[0]._field34);
+ scene->_gameBoardSide[2]._handCard[0]._card.setStrip(2);
+ scene->_gameBoardSide[2]._handCard[0]._card.setFrame(scene->_gameBoardSide[2]._handCard[0]._cardId);
}
scene->_aSound2.play(61);
Common::Point pt(14, 14);
NpcMover *mover = new NpcMover();
- scene->_item2._object1.addMover(mover, &pt, this);
+ scene->_animatedCard._card.addMover(mover, &pt, this);
- scene->_arrunkObj1337[3]._arr1[0]._field34 = scene->_field3E28[scene->_field3E24];
+ scene->_gameBoardSide[3]._handCard[0]._cardId = scene->_availableCardsPile[scene->_cardsAvailableNumb];
}
break;
case 3: {
- scene->_arrunkObj1337[3]._arr1[0]._object1.postInit();
- scene->_arrunkObj1337[3]._arr1[0]._object1._moveDiff = Common::Point(30, 30);
- scene->_arrunkObj1337[3]._arr1[0]._object1.setVisage(1332);
- scene->_arrunkObj1337[3]._arr1[0]._object1.setPosition(scene->_arrunkObj1337[3]._arr1[0]._field36, 0);
- scene->_arrunkObj1337[3]._arr1[0]._object1.setStrip(1);
- scene->_arrunkObj1337[3]._arr1[0]._object1.setFrame(3);
- scene->_arrunkObj1337[3]._arr1[0]._object1.fixPriority(170);
+ scene->_gameBoardSide[3]._handCard[0]._card.postInit();
+ scene->_gameBoardSide[3]._handCard[0]._card._moveDiff = Common::Point(30, 30);
+ scene->_gameBoardSide[3]._handCard[0]._card.setVisage(1332);
+ scene->_gameBoardSide[3]._handCard[0]._card.setPosition(scene->_gameBoardSide[3]._handCard[0]._stationPos, 0);
+ scene->_gameBoardSide[3]._handCard[0]._card.setStrip(1);
+ scene->_gameBoardSide[3]._handCard[0]._card.setFrame(3);
+ scene->_gameBoardSide[3]._handCard[0]._card.fixPriority(170);
scene->_aSound2.play(61);
Common::Point pt(280, 5);
NpcMover *mover = new NpcMover();
- scene->_item2._object1.addMover(mover, &pt, this);
+ scene->_animatedCard._card.addMover(mover, &pt, this);
- scene->_arrunkObj1337[0]._arr1[0]._field34 = scene->_field3E28[scene->_field3E24];
+ scene->_gameBoardSide[0]._handCard[0]._cardId = scene->_availableCardsPile[scene->_cardsAvailableNumb];
}
break;
case 4: {
- scene->_arrunkObj1337[0]._arr1[0]._object1.postInit();
- scene->_arrunkObj1337[0]._arr1[0]._object1._moveDiff = Common::Point(30,30);
- scene->_arrunkObj1337[0]._arr1[0]._object1.setVisage(1332);
- scene->_arrunkObj1337[0]._arr1[0]._object1.setPosition(scene->_arrunkObj1337[0]._arr1[0]._field36, 0);
- scene->_arrunkObj1337[0]._arr1[0]._object1.setStrip(5);
- scene->_arrunkObj1337[0]._arr1[0]._object1.setFrame(1);
- scene->_arrunkObj1337[0]._arr1[0]._object1.fixPriority(170);
+ scene->_gameBoardSide[0]._handCard[0]._card.postInit();
+ scene->_gameBoardSide[0]._handCard[0]._card._moveDiff = Common::Point(30,30);
+ scene->_gameBoardSide[0]._handCard[0]._card.setVisage(1332);
+ scene->_gameBoardSide[0]._handCard[0]._card.setPosition(scene->_gameBoardSide[0]._handCard[0]._stationPos, 0);
+ scene->_gameBoardSide[0]._handCard[0]._card.setStrip(5);
+ scene->_gameBoardSide[0]._handCard[0]._card.setFrame(1);
+ scene->_gameBoardSide[0]._handCard[0]._card.fixPriority(170);
scene->_aSound2.play(61);
Common::Point pt(283, 124);
NpcMover *mover = new NpcMover();
- scene->_item2._object1.addMover(mover, &pt, this);
+ scene->_animatedCard._card.addMover(mover, &pt, this);
- scene->_arrunkObj1337[1]._arr1[1]._field34 = scene->_field3E28[scene->_field3E24];
+ scene->_gameBoardSide[1]._handCard[1]._cardId = scene->_availableCardsPile[scene->_cardsAvailableNumb];
}
break;
case 5: {
- scene->_arrunkObj1337[1]._arr1[1]._object1.postInit();
- scene->_arrunkObj1337[1]._arr1[1]._object1._moveDiff = Common::Point(30, 30);
- scene->_arrunkObj1337[1]._arr1[1]._object1.setVisage(1332);
- scene->_arrunkObj1337[1]._arr1[1]._object1.setPosition(scene->_arrunkObj1337[1]._arr1[1]._field36, 0);
- scene->_arrunkObj1337[1]._arr1[1]._object1.setStrip(1);
- scene->_arrunkObj1337[1]._arr1[1]._object1.setFrame(4);
- scene->_arrunkObj1337[1]._arr1[1]._object1.fixPriority(170);
+ scene->_gameBoardSide[1]._handCard[1]._card.postInit();
+ scene->_gameBoardSide[1]._handCard[1]._card._moveDiff = Common::Point(30, 30);
+ scene->_gameBoardSide[1]._handCard[1]._card.setVisage(1332);
+ scene->_gameBoardSide[1]._handCard[1]._card.setPosition(scene->_gameBoardSide[1]._handCard[1]._stationPos, 0);
+ scene->_gameBoardSide[1]._handCard[1]._card.setStrip(1);
+ scene->_gameBoardSide[1]._handCard[1]._card.setFrame(4);
+ scene->_gameBoardSide[1]._handCard[1]._card.fixPriority(170);
scene->_aSound2.play(61);
Common::Point pt(37, 174);
NpcMover *mover = new NpcMover();
- scene->_item2._object1.addMover(mover, &pt, this);
+ scene->_animatedCard._card.addMover(mover, &pt, this);
- scene->_arrunkObj1337[2]._arr1[1]._field34 = scene->_field3E28[scene->_field3E24];
+ scene->_gameBoardSide[2]._handCard[1]._cardId = scene->_availableCardsPile[scene->_cardsAvailableNumb];
}
break;
case 6: {
- scene->_arrunkObj1337[2]._arr1[1]._object1.postInit();
- scene->_arrunkObj1337[2]._arr1[1]._object1._moveDiff = Common::Point(30, 30);
- scene->_arrunkObj1337[2]._arr1[1]._object1.setVisage(1332);
- scene->_arrunkObj1337[2]._arr1[1]._object1.setPosition(scene->_arrunkObj1337[2]._arr1[1]._field36, 0);
- scene->_arrunkObj1337[2]._arr1[1]._object1.fixPriority(170);
-
- if (scene->_arrunkObj1337[2]._arr1[1]._field34 > 9) {
- if (scene->_arrunkObj1337[2]._arr1[1]._field34 > 25) {
- scene->_arrunkObj1337[2]._arr1[1]._object1.setStrip(4);
- scene->_arrunkObj1337[2]._arr1[1]._object1.setFrame(scene->_arrunkObj1337[2]._arr1[1]._field34 - 25);
- } else {
- scene->_arrunkObj1337[2]._arr1[1]._object1.setStrip(3);
- scene->_arrunkObj1337[2]._arr1[1]._object1.setFrame(scene->_arrunkObj1337[2]._arr1[1]._field34 - 9);
- }
+ scene->_gameBoardSide[2]._handCard[1]._card.postInit();
+ scene->_gameBoardSide[2]._handCard[1]._card._moveDiff = Common::Point(30, 30);
+ scene->_gameBoardSide[2]._handCard[1]._card.setVisage(1332);
+ scene->_gameBoardSide[2]._handCard[1]._card.setPosition(scene->_gameBoardSide[2]._handCard[1]._stationPos, 0);
+ scene->_gameBoardSide[2]._handCard[1]._card.fixPriority(170);
+
+ if (scene->_gameBoardSide[2]._handCard[1]._cardId > 25) {
+ scene->_gameBoardSide[2]._handCard[1]._card.setStrip(4);
+ scene->_gameBoardSide[2]._handCard[1]._card.setFrame(scene->_gameBoardSide[2]._handCard[1]._cardId - 25);
+ } else if (scene->_gameBoardSide[2]._handCard[1]._cardId > 9) {
+ scene->_gameBoardSide[2]._handCard[1]._card.setStrip(3);
+ scene->_gameBoardSide[2]._handCard[1]._card.setFrame(scene->_gameBoardSide[2]._handCard[1]._cardId - 9);
} else {
- scene->_arrunkObj1337[2]._arr1[1]._object1.setStrip(2);
- scene->_arrunkObj1337[2]._arr1[1]._object1.setFrame(scene->_arrunkObj1337[2]._arr1[1]._field34);
+ scene->_gameBoardSide[2]._handCard[1]._card.setStrip(2);
+ scene->_gameBoardSide[2]._handCard[1]._card.setFrame(scene->_gameBoardSide[2]._handCard[1]._cardId);
}
scene->_aSound2.play(61);
Common::Point pt(14, 36);
NpcMover *mover = new NpcMover();
- scene->_item2._object1.addMover(mover, &pt, this);
+ scene->_animatedCard._card.addMover(mover, &pt, this);
- scene->_arrunkObj1337[3]._arr1[1]._field34 = scene->_field3E28[scene->_field3E24];
+ scene->_gameBoardSide[3]._handCard[1]._cardId = scene->_availableCardsPile[scene->_cardsAvailableNumb];
}
break;
case 7: {
- scene->_arrunkObj1337[3]._arr1[1]._object1.postInit();
- scene->_arrunkObj1337[3]._arr1[1]._object1._moveDiff = Common::Point(30, 30);
- scene->_arrunkObj1337[3]._arr1[1]._object1.setVisage(1332);
- scene->_arrunkObj1337[3]._arr1[1]._object1.setPosition(scene->_arrunkObj1337[3]._arr1[1]._field36);
- scene->_arrunkObj1337[3]._arr1[1]._object1.setStrip(1);
- scene->_arrunkObj1337[3]._arr1[1]._object1.setFrame(3);
- scene->_arrunkObj1337[3]._arr1[1]._object1.fixPriority(170);
+ scene->_gameBoardSide[3]._handCard[1]._card.postInit();
+ scene->_gameBoardSide[3]._handCard[1]._card._moveDiff = Common::Point(30, 30);
+ scene->_gameBoardSide[3]._handCard[1]._card.setVisage(1332);
+ scene->_gameBoardSide[3]._handCard[1]._card.setPosition(scene->_gameBoardSide[3]._handCard[1]._stationPos);
+ scene->_gameBoardSide[3]._handCard[1]._card.setStrip(1);
+ scene->_gameBoardSide[3]._handCard[1]._card.setFrame(3);
+ scene->_gameBoardSide[3]._handCard[1]._card.fixPriority(170);
scene->_aSound2.play(61);
Common::Point pt(253, 5);
NpcMover *mover = new NpcMover();
- scene->_item2._object1.addMover(mover, &pt, this);
+ scene->_animatedCard._card.addMover(mover, &pt, this);
- scene->_arrunkObj1337[0]._arr1[1]._field34 = scene->_field3E28[scene->_field3E24];
+ scene->_gameBoardSide[0]._handCard[1]._cardId = scene->_availableCardsPile[scene->_cardsAvailableNumb];
}
break;
case 8: {
- scene->_arrunkObj1337[0]._arr1[1]._object1.postInit();
- scene->_arrunkObj1337[0]._arr1[1]._object1._moveDiff = Common::Point(30, 30);
- scene->_arrunkObj1337[0]._arr1[1]._object1.setVisage(1332);
- scene->_arrunkObj1337[0]._arr1[1]._object1.setPosition(scene->_arrunkObj1337[0]._arr1[1]._field36, 0);
- scene->_arrunkObj1337[0]._arr1[1]._object1.setStrip(5);
- scene->_arrunkObj1337[0]._arr1[1]._object1.setFrame(1);
- scene->_arrunkObj1337[0]._arr1[1]._object1.fixPriority(170);
+ scene->_gameBoardSide[0]._handCard[1]._card.postInit();
+ scene->_gameBoardSide[0]._handCard[1]._card._moveDiff = Common::Point(30, 30);
+ scene->_gameBoardSide[0]._handCard[1]._card.setVisage(1332);
+ scene->_gameBoardSide[0]._handCard[1]._card.setPosition(scene->_gameBoardSide[0]._handCard[1]._stationPos, 0);
+ scene->_gameBoardSide[0]._handCard[1]._card.setStrip(5);
+ scene->_gameBoardSide[0]._handCard[1]._card.setFrame(1);
+ scene->_gameBoardSide[0]._handCard[1]._card.fixPriority(170);
scene->_aSound2.play(61);
Common::Point pt(283, 102);
NpcMover *mover = new NpcMover();
- scene->_item2._object1.addMover(mover, &pt, this);
+ scene->_animatedCard._card.addMover(mover, &pt, this);
- scene->_arrunkObj1337[1]._arr1[2]._field34 = scene->_field3E28[scene->_field3E24];
+ scene->_gameBoardSide[1]._handCard[2]._cardId = scene->_availableCardsPile[scene->_cardsAvailableNumb];
}
break;
case 9: {
- scene->_arrunkObj1337[1]._arr1[2]._object1.postInit();
- scene->_arrunkObj1337[1]._arr1[2]._object1._moveDiff = Common::Point(30, 30);
- scene->_arrunkObj1337[1]._arr1[2]._object1.setVisage(1332);
- scene->_arrunkObj1337[1]._arr1[2]._object1.setPosition(scene->_arrunkObj1337[1]._arr1[2]._field36, 0);
- scene->_arrunkObj1337[1]._arr1[2]._object1.setStrip(1);
- scene->_arrunkObj1337[1]._arr1[2]._object1.setFrame(4);
- scene->_arrunkObj1337[1]._arr1[2]._object1.fixPriority(170);
+ scene->_gameBoardSide[1]._handCard[2]._card.postInit();
+ scene->_gameBoardSide[1]._handCard[2]._card._moveDiff = Common::Point(30, 30);
+ scene->_gameBoardSide[1]._handCard[2]._card.setVisage(1332);
+ scene->_gameBoardSide[1]._handCard[2]._card.setPosition(scene->_gameBoardSide[1]._handCard[2]._stationPos, 0);
+ scene->_gameBoardSide[1]._handCard[2]._card.setStrip(1);
+ scene->_gameBoardSide[1]._handCard[2]._card.setFrame(4);
+ scene->_gameBoardSide[1]._handCard[2]._card.fixPriority(170);
scene->_aSound2.play(61);
Common::Point pt(64, 174);
NpcMover *mover = new NpcMover();
- scene->_item2._object1.addMover(mover, &pt, this);
+ scene->_animatedCard._card.addMover(mover, &pt, this);
- scene->_arrunkObj1337[2]._arr1[2]._field34 = scene->_field3E28[scene->_field3E24];
+ scene->_gameBoardSide[2]._handCard[2]._cardId = scene->_availableCardsPile[scene->_cardsAvailableNumb];
}
break;
case 10: {
- scene->_arrunkObj1337[2]._arr1[2]._object1.postInit();
- scene->_arrunkObj1337[2]._arr1[2]._object1._moveDiff = Common::Point(30, 30);
- scene->_arrunkObj1337[2]._arr1[2]._object1.setVisage(1332);
- scene->_arrunkObj1337[2]._arr1[2]._object1.setPosition(scene->_arrunkObj1337[2]._arr1[2]._field36, 0);
- scene->_arrunkObj1337[2]._arr1[2]._object1.fixPriority(170);
-
- if (scene->_arrunkObj1337[2]._arr1[2]._field34 > 9) {
- if (scene->_arrunkObj1337[2]._arr1[2]._field34 > 25) {
- scene->_arrunkObj1337[2]._arr1[2]._object1.setStrip(4);
- scene->_arrunkObj1337[2]._arr1[2]._object1.setFrame(scene->_arrunkObj1337[2]._arr1[2]._field34 - 25);
- } else {
- scene->_arrunkObj1337[2]._arr1[2]._object1.setStrip(3);
- scene->_arrunkObj1337[2]._arr1[2]._object1.setFrame(scene->_arrunkObj1337[2]._arr1[2]._field34 - 9);
- }
+ scene->_gameBoardSide[2]._handCard[2]._card.postInit();
+ scene->_gameBoardSide[2]._handCard[2]._card._moveDiff = Common::Point(30, 30);
+ scene->_gameBoardSide[2]._handCard[2]._card.setVisage(1332);
+ scene->_gameBoardSide[2]._handCard[2]._card.setPosition(scene->_gameBoardSide[2]._handCard[2]._stationPos, 0);
+ scene->_gameBoardSide[2]._handCard[2]._card.fixPriority(170);
+
+ if (scene->_gameBoardSide[2]._handCard[2]._cardId > 25) {
+ scene->_gameBoardSide[2]._handCard[2]._card.setStrip(4);
+ scene->_gameBoardSide[2]._handCard[2]._card.setFrame(scene->_gameBoardSide[2]._handCard[2]._cardId - 25);
+ } else if (scene->_gameBoardSide[2]._handCard[2]._cardId > 9) {
+ scene->_gameBoardSide[2]._handCard[2]._card.setStrip(3);
+ scene->_gameBoardSide[2]._handCard[2]._card.setFrame(scene->_gameBoardSide[2]._handCard[2]._cardId - 9);
} else {
- scene->_arrunkObj1337[2]._arr1[2]._object1.setStrip(2);
- scene->_arrunkObj1337[2]._arr1[2]._object1.setFrame(scene->_arrunkObj1337[2]._arr1[2]._field34);
+ scene->_gameBoardSide[2]._handCard[2]._card.setStrip(2);
+ scene->_gameBoardSide[2]._handCard[2]._card.setFrame(scene->_gameBoardSide[2]._handCard[2]._cardId);
}
scene->_aSound2.play(61);
Common::Point pt(14, 58);
NpcMover *mover = new NpcMover();
- scene->_item2._object1.addMover(mover, &pt, this);
+ scene->_animatedCard._card.addMover(mover, &pt, this);
- scene->_arrunkObj1337[3]._arr1[2]._field34 = scene->_field3E28[scene->_field3E24];
+ scene->_gameBoardSide[3]._handCard[2]._cardId = scene->_availableCardsPile[scene->_cardsAvailableNumb];
}
break;
case 11: {
- scene->_arrunkObj1337[3]._arr1[2]._object1.postInit();
- scene->_arrunkObj1337[3]._arr1[2]._object1._moveDiff = Common::Point(30, 30);
- scene->_arrunkObj1337[3]._arr1[2]._object1.setVisage(1332);
- scene->_arrunkObj1337[3]._arr1[2]._object1.setPosition(scene->_arrunkObj1337[3]._arr1[2]._field36, 0);
- scene->_arrunkObj1337[3]._arr1[2]._object1.setStrip(1);
- scene->_arrunkObj1337[3]._arr1[2]._object1.setFrame(3);
- scene->_arrunkObj1337[3]._arr1[2]._object1.fixPriority(170);
+ scene->_gameBoardSide[3]._handCard[2]._card.postInit();
+ scene->_gameBoardSide[3]._handCard[2]._card._moveDiff = Common::Point(30, 30);
+ scene->_gameBoardSide[3]._handCard[2]._card.setVisage(1332);
+ scene->_gameBoardSide[3]._handCard[2]._card.setPosition(scene->_gameBoardSide[3]._handCard[2]._stationPos, 0);
+ scene->_gameBoardSide[3]._handCard[2]._card.setStrip(1);
+ scene->_gameBoardSide[3]._handCard[2]._card.setFrame(3);
+ scene->_gameBoardSide[3]._handCard[2]._card.fixPriority(170);
scene->_aSound2.play(61);
Common::Point pt(226, 5);
NpcMover *mover = new NpcMover();
- scene->_item2._object1.addMover(mover, &pt, this);
+ scene->_animatedCard._card.addMover(mover, &pt, this);
- scene->_arrunkObj1337[0]._arr1[2]._field34 = scene->_field3E28[scene->_field3E24];
+ scene->_gameBoardSide[0]._handCard[2]._cardId = scene->_availableCardsPile[scene->_cardsAvailableNumb];
}
break;
case 12:
- scene->_arrunkObj1337[0]._arr1[2]._object1.postInit();
- scene->_arrunkObj1337[0]._arr1[2]._object1._moveDiff = Common::Point(30, 30);
- scene->_arrunkObj1337[0]._arr1[2]._object1.setVisage(1332);
- scene->_arrunkObj1337[0]._arr1[2]._object1.setPosition(scene->_arrunkObj1337[0]._arr1[2]._field36, 0);
- scene->_arrunkObj1337[0]._arr1[2]._object1.setStrip(5);
- scene->_arrunkObj1337[0]._arr1[2]._object1.setFrame(1);
- scene->_arrunkObj1337[0]._arr1[2]._object1.fixPriority(170);
- scene->_arrunkObj1337[0]._arr1[2]._object1.hide();
+ scene->_gameBoardSide[0]._handCard[2]._card.postInit();
+ scene->_gameBoardSide[0]._handCard[2]._card._moveDiff = Common::Point(30, 30);
+ scene->_gameBoardSide[0]._handCard[2]._card.setVisage(1332);
+ scene->_gameBoardSide[0]._handCard[2]._card.setPosition(scene->_gameBoardSide[0]._handCard[2]._stationPos, 0);
+ scene->_gameBoardSide[0]._handCard[2]._card.setStrip(5);
+ scene->_gameBoardSide[0]._handCard[2]._card.setFrame(1);
+ scene->_gameBoardSide[0]._handCard[2]._card.fixPriority(170);
+ scene->_animatedCard._card.hide();
default:
break;
}
if (_actionIndex > 12) {
- scene->_field423E = 0;
+ scene->_currentPlayerNumb = 0;
R2_GLOBALS._sceneObjects->draw();
scene->actionDisplay(1330, 0, 159, 10, 1, 200, 0, 7, 0, 154, 154);
- scene->subC20F9();
+ scene->handleNextTurn();
} else if (_actionIndex >= 1) {
- scene->_field3E28[scene->_field3E24] = 0;
- scene->_field3E24--;
+ scene->_availableCardsPile[scene->_cardsAvailableNumb] = 0;
+ scene->_cardsAvailableNumb--;
}
}
+/**
+ * Action used to handle the other players' turn
+ */
void Scene1337::Action4::signal() {
Scene1337 *scene = (Scene1337 *)R2_GLOBALS._sceneManager._scene;
switch (_actionIndex++) {
case 0:
- if ((scene->_arrunkObj1337[scene->_field423E]._arr1[0]._field34 == 0) && (scene->subC264B(scene->_arrunkObj1337[scene->_field423E]._arr3[0]._field34))) {
- if (scene->_field3E24 < 0)
- scene->subC264B(scene->_arrunkObj1337[scene->_field423E]._arr3[0]._field34);
- scene->_item2._object1.setPosition(Common::Point(162, 95), 0);
- scene->_item2._object1.show();
+ if ( (scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[0]._cardId == 0)
+ && (!scene->isStationCard(scene->_gameBoardSide[scene->_currentPlayerNumb]._delayCard._cardId))) {
+ if (scene->_cardsAvailableNumb < 0)
+ scene->shuffleCards();
+ scene->_animatedCard._card.setPosition(Common::Point(162, 95), 0);
+ scene->_animatedCard._card.show();
scene->_aSound2.play(61);
NpcMover *mover = new NpcMover();
- scene->_item2._object1.addMover(mover, &scene->_arrunkObj1337[scene->_field423E]._fieldB94, this);
+ scene->_animatedCard._card.addMover(mover, &scene->_gameBoardSide[scene->_currentPlayerNumb]._card1Pos, this);
- scene->_arrunkObj1337[scene->_field423E]._arr1[0]._field34 = scene->_field3E28[scene->_field3E24];
- scene->_field3E28[scene->_field3E24] = 0;
- scene->_field3E24--;
+ scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[0]._cardId = scene->_availableCardsPile[scene->_cardsAvailableNumb];
+ scene->_availableCardsPile[scene->_cardsAvailableNumb] = 0;
+ scene->_cardsAvailableNumb--;
- if (scene->_field3E24 < 0)
- scene->_background2.remove();
+ if (scene->_cardsAvailableNumb < 0)
+ scene->_stockPile.remove();
} else {
// Self call, forcing next actionIndex
signal();
}
break;
case 1:
- if ( ( scene->_item2._object1._position.x == scene->_arrunkObj1337[scene->_field423E]._fieldB94.x)
- && ( scene->_item2._object1._position.y == scene->_arrunkObj1337[scene->_field423E]._fieldB94.y) ) {
- scene->_arrunkObj1337[scene->_field423E]._arr1[0]._object1.postInit();
- scene->_arrunkObj1337[scene->_field423E]._arr1[0]._object1._moveDiff = Common::Point(30, 30);
- scene->_arrunkObj1337[scene->_field423E]._arr1[0]._object1.setVisage(1332);
- scene->_arrunkObj1337[scene->_field423E]._arr1[0]._object1.setPosition(scene->_arrunkObj1337[scene->_field423E]._arr1[0]._field36, 0);
- scene->_arrunkObj1337[scene->_field423E]._arr1[0]._object1.setStrip(1);
- scene->_arrunkObj1337[scene->_field423E]._arr1[0]._object1.setFrame(scene->_arrunkObj1337[scene->_field423E]._fieldBA4);
- scene->_arrunkObj1337[scene->_field423E]._arr1[0]._object1.fixPriority(170);
- }
-
- if ((scene->_field4248 == 1) || (scene->_field423E == 2))
- scene->setAnimationInfo(&scene->_arrunkObj1337[scene->_field423E]._arr1[0]);
-
- scene->_item2._object1.hide();
- if ((scene->_arrunkObj1337[scene->_field423E]._arr1[0]._field34 == 0) && (scene->subC264B(scene->_arrunkObj1337[scene->_field423E]._arr3[0]._field34 == 0))) {
- if (scene->_field3E24 < 0)
+ if ( (scene->_animatedCard._card._position.x == scene->_gameBoardSide[scene->_currentPlayerNumb]._card1Pos.x)
+ && (scene->_animatedCard._card._position.y == scene->_gameBoardSide[scene->_currentPlayerNumb]._card1Pos.y) ) {
+ scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[0]._card.postInit();
+ scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[0]._card._moveDiff = Common::Point(30, 30);
+ scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[0]._card.setVisage(1332);
+ scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[0]._card.setPosition(scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[0]._stationPos, 0);
+ scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[0]._card.setStrip(1);
+ scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[0]._card.setFrame(scene->_gameBoardSide[scene->_currentPlayerNumb]._frameNum);
+ scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[0]._card.fixPriority(170);
+ }
+
+ if ((R2_GLOBALS._debugCardGame) || (scene->_currentPlayerNumb == 2))
+ scene->setAnimationInfo(&scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[0]);
+
+ scene->_animatedCard._card.hide();
+ if ( (scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[0]._cardId == 0)
+ && (!scene->isStationCard(scene->_gameBoardSide[scene->_currentPlayerNumb]._delayCard._cardId))) {
+ if (scene->_cardsAvailableNumb < 0)
scene->shuffleCards();
- scene->_item2._object1.setPosition(Common::Point(162, 95));
- scene->_item2._object1.show();
+ scene->_animatedCard._card.setPosition(Common::Point(162, 95));
+ scene->_animatedCard._card.show();
scene->_aSound2.play(61);
NpcMover *mover = new NpcMover();
- scene->_item2._object1.addMover(mover, &scene->_arrunkObj1337[scene->_field423E]._fieldB98, this);
+ scene->_animatedCard._card.addMover(mover, &scene->_gameBoardSide[scene->_currentPlayerNumb]._card2Pos, this);
- scene->_arrunkObj1337[scene->_field423E]._arr1[1]._field34 = scene->_field3E28[scene->_field3E24];
- scene->_field3E28[scene->_field3E24] = 0;
- scene->_field3E24--;
- if (scene->_field3E24 < 0)
- scene->_background2.remove();
+ scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[1]._cardId = scene->_availableCardsPile[scene->_cardsAvailableNumb];
+ scene->_availableCardsPile[scene->_cardsAvailableNumb] = 0;
+ scene->_cardsAvailableNumb--;
+ if (scene->_cardsAvailableNumb < 0)
+ scene->_stockPile.remove();
} else
signal();
break;
case 2:
- if ( ( scene->_item2._object1._position.x == scene->_arrunkObj1337[scene->_field423E]._fieldB98.x)
- && ( scene->_item2._object1._position.y == scene->_arrunkObj1337[scene->_field423E]._fieldB98.y) ) {
- scene->_arrunkObj1337[scene->_field423E]._arr1[1]._object1.postInit();
- scene->_arrunkObj1337[scene->_field423E]._arr1[1]._object1._moveDiff = Common::Point(30, 30);
- scene->_arrunkObj1337[scene->_field423E]._arr1[1]._object1.setVisage(1332);
- scene->_arrunkObj1337[scene->_field423E]._arr1[1]._object1.setPosition(scene->_arrunkObj1337[scene->_field423E]._arr1[1]._field36, 0);
- scene->_arrunkObj1337[scene->_field423E]._arr1[1]._object1.setStrip(1);
- scene->_arrunkObj1337[scene->_field423E]._arr1[1]._object1.setFrame(scene->_arrunkObj1337[scene->_field423E]._fieldBA4);
- scene->_arrunkObj1337[scene->_field423E]._arr1[1]._object1.fixPriority(170);
- }
-
- if ((scene->_field4248 == 1) || (scene->_field423E == 2))
- scene->setAnimationInfo(&scene->_arrunkObj1337[scene->_field423E]._arr1[1]);
-
- scene->_item2._object1.hide();
- if ((scene->_arrunkObj1337[scene->_field423E]._arr1[2]._field34 == 0) && (scene->subC264B(scene->_arrunkObj1337[scene->_field423E]._arr3[0]._field34 == 0))) {
- if (scene->_field3E24 < 0)
+ if ( (scene->_animatedCard._card._position.x == scene->_gameBoardSide[scene->_currentPlayerNumb]._card2Pos.x)
+ && (scene->_animatedCard._card._position.y == scene->_gameBoardSide[scene->_currentPlayerNumb]._card2Pos.y) ) {
+ scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[1]._card.postInit();
+ scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[1]._card._moveDiff = Common::Point(30, 30);
+ scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[1]._card.setVisage(1332);
+ scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[1]._card.setPosition(scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[1]._stationPos, 0);
+ scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[1]._card.setStrip(1);
+ scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[1]._card.setFrame(scene->_gameBoardSide[scene->_currentPlayerNumb]._frameNum);
+ scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[1]._card.fixPriority(170);
+ }
+
+ if ((R2_GLOBALS._debugCardGame) || (scene->_currentPlayerNumb == 2))
+ scene->setAnimationInfo(&scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[1]);
+
+ scene->_animatedCard._card.hide();
+ if ( (scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[2]._cardId == 0)
+ && (!scene->isStationCard(scene->_gameBoardSide[scene->_currentPlayerNumb]._delayCard._cardId))) {
+ if (scene->_cardsAvailableNumb < 0)
scene->shuffleCards();
- scene->_item2._object1.setPosition(Common::Point(162, 95));
- scene->_item2._object1.show();
+ scene->_animatedCard._card.setPosition(Common::Point(162, 95));
+ scene->_animatedCard._card.show();
scene->_aSound2.play(61);
NpcMover *mover = new NpcMover();
- scene->_item2._object1.addMover(mover, &scene->_arrunkObj1337[scene->_field423E]._fieldB9C, this);
+ scene->_animatedCard._card.addMover(mover, &scene->_gameBoardSide[scene->_currentPlayerNumb]._card3Pos, this);
- scene->_arrunkObj1337[scene->_field423E]._arr1[2]._field34 = scene->_field3E28[scene->_field3E24];
- scene->_field3E28[scene->_field3E24] = 0;
- scene->_field3E24--;
- if (scene->_field3E24 < 0)
- scene->_background2.remove();
+ scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[2]._cardId = scene->_availableCardsPile[scene->_cardsAvailableNumb];
+ scene->_availableCardsPile[scene->_cardsAvailableNumb] = 0;
+ scene->_cardsAvailableNumb--;
+ if (scene->_cardsAvailableNumb < 0)
+ scene->_stockPile.remove();
} else
signal();
break;
case 3:
- if ( ( scene->_item2._object1._position.x == scene->_arrunkObj1337[scene->_field423E]._fieldB9C.x)
- && ( scene->_item2._object1._position.y == scene->_arrunkObj1337[scene->_field423E]._fieldB9C.y) ) {
- scene->_arrunkObj1337[scene->_field423E]._arr1[2]._object1.postInit();
- scene->_arrunkObj1337[scene->_field423E]._arr1[2]._object1._moveDiff = Common::Point(30, 30);
- scene->_arrunkObj1337[scene->_field423E]._arr1[2]._object1.setVisage(1332);
- scene->_arrunkObj1337[scene->_field423E]._arr1[2]._object1.setPosition(scene->_arrunkObj1337[scene->_field423E]._arr1[2]._field36, 0);
- scene->_arrunkObj1337[scene->_field423E]._arr1[2]._object1.setStrip(1);
- scene->_arrunkObj1337[scene->_field423E]._arr1[2]._object1.setFrame(scene->_arrunkObj1337[scene->_field423E]._fieldBA4);
- scene->_arrunkObj1337[scene->_field423E]._arr1[2]._object1.fixPriority(170);
- }
-
- if ((scene->_field4248 == 1) || (scene->_field423E == 2))
- scene->setAnimationInfo(&scene->_arrunkObj1337[scene->_field423E]._arr1[2]);
-
- scene->_item2._object1.hide();
- if ((scene->_arrunkObj1337[scene->_field423E]._arr1[3]._field34 == 0) && (scene->subC264B(scene->_arrunkObj1337[scene->_field423E]._arr3[0]._field34 == 0))) {
- if (scene->_field3E24 < 0)
+ if ( (scene->_animatedCard._card._position.x == scene->_gameBoardSide[scene->_currentPlayerNumb]._card3Pos.x)
+ && (scene->_animatedCard._card._position.y == scene->_gameBoardSide[scene->_currentPlayerNumb]._card3Pos.y) ) {
+ scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[2]._card.postInit();
+ scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[2]._card._moveDiff = Common::Point(30, 30);
+ scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[2]._card.setVisage(1332);
+ scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[2]._card.setPosition(scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[2]._stationPos, 0);
+ scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[2]._card.setStrip(1);
+ scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[2]._card.setFrame(scene->_gameBoardSide[scene->_currentPlayerNumb]._frameNum);
+ scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[2]._card.fixPriority(170);
+ }
+
+ if ((R2_GLOBALS._debugCardGame) || (scene->_currentPlayerNumb == 2))
+ scene->setAnimationInfo(&scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[2]);
+
+ scene->_animatedCard._card.hide();
+ if ( (scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[3]._cardId == 0)
+ && (!scene->isStationCard(scene->_gameBoardSide[scene->_currentPlayerNumb]._delayCard._cardId))) {
+ if (scene->_cardsAvailableNumb < 0)
scene->shuffleCards();
- scene->_item2._object1.setPosition(Common::Point(162, 95));
- scene->_item2._object1.show();
+ scene->_animatedCard._card.setPosition(Common::Point(162, 95));
+ scene->_animatedCard._card.show();
scene->_aSound2.play(61);
NpcMover *mover = new NpcMover();
- scene->_item2._object1.addMover(mover, &scene->_arrunkObj1337[scene->_field423E]._fieldBA0, this);
+ scene->_animatedCard._card.addMover(mover, &scene->_gameBoardSide[scene->_currentPlayerNumb]._card4Pos, this);
- scene->_arrunkObj1337[scene->_field423E]._arr1[3]._field34 = scene->_field3E28[scene->_field3E24];
- scene->_field3E28[scene->_field3E24] = 0;
- scene->_field3E24--;
- if (scene->_field3E24 < 0)
- scene->_background2.remove();
+ scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[3]._cardId = scene->_availableCardsPile[scene->_cardsAvailableNumb];
+ scene->_availableCardsPile[scene->_cardsAvailableNumb] = 0;
+ scene->_cardsAvailableNumb--;
+ if (scene->_cardsAvailableNumb < 0)
+ scene->_stockPile.remove();
} else
signal();
break;
case 4:
- if ( ( scene->_item2._object1._position.x == scene->_arrunkObj1337[scene->_field423E]._fieldBA0.x)
- && ( scene->_item2._object1._position.y == scene->_arrunkObj1337[scene->_field423E]._fieldBA0.y) ) {
- scene->_arrunkObj1337[scene->_field423E]._arr1[3]._object1.postInit();
- scene->_arrunkObj1337[scene->_field423E]._arr1[3]._object1._moveDiff = Common::Point(30, 30);
- scene->_arrunkObj1337[scene->_field423E]._arr1[3]._object1.setVisage(1332);
- scene->_arrunkObj1337[scene->_field423E]._arr1[3]._object1.setPosition(scene->_arrunkObj1337[scene->_field423E]._arr1[3]._field36, 0);
- scene->_arrunkObj1337[scene->_field423E]._arr1[3]._object1.setStrip(1);
- scene->_arrunkObj1337[scene->_field423E]._arr1[3]._object1.setFrame(scene->_arrunkObj1337[scene->_field423E]._fieldBA4);
- scene->_arrunkObj1337[scene->_field423E]._arr1[3]._object1.fixPriority(170);
- }
-
- if ((scene->_field4248 == 1) || (scene->_field423E == 2))
- scene->setAnimationInfo(&scene->_arrunkObj1337[scene->_field423E]._arr1[3]);
-
- scene->_item2._object1.hide();
- switch (scene->_field423E) {
+ if ( (scene->_animatedCard._card._position.x == scene->_gameBoardSide[scene->_currentPlayerNumb]._card4Pos.x)
+ && (scene->_animatedCard._card._position.y == scene->_gameBoardSide[scene->_currentPlayerNumb]._card4Pos.y) ) {
+ scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[3]._card.postInit();
+ scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[3]._card._moveDiff = Common::Point(30, 30);
+ scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[3]._card.setVisage(1332);
+ scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[3]._card.setPosition(scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[3]._stationPos, 0);
+ scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[3]._card.setStrip(1);
+ scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[3]._card.setFrame(scene->_gameBoardSide[scene->_currentPlayerNumb]._frameNum);
+ scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[3]._card.fixPriority(170);
+ }
+
+ if ((R2_GLOBALS._debugCardGame) || (scene->_currentPlayerNumb == 2))
+ scene->setAnimationInfo(&scene->_gameBoardSide[scene->_currentPlayerNumb]._handCard[3]);
+
+ scene->_animatedCard._card.hide();
+ switch (scene->_currentPlayerNumb) {
case 0:
- scene->subCF979();
+ scene->handlePlayer0();
break;
case 1:
- scene->subCF31D();
+ scene->handlePlayer1();
break;
case 2:
- scene->subD0281();
+ scene->handleAutoplayPlayer2();
break;
case 3:
- scene->subC2C2F();
+ scene->handlePlayer3();
break;
default:
break;
@@ -3492,115 +3542,124 @@ void Scene1337::Action4::signal() {
}
}
+/**
+ * Animations for discarding a card
+ */
void Scene1337::Action5::signal() {
Scene1337 *scene = (Scene1337 *)R2_GLOBALS._sceneManager._scene;
switch (_actionIndex++) {
case 0: {
- scene->_field3E28[scene->_field3E26] = scene->_field3EF0->_field34;
- scene->_field3E26--;
- if (!g_globals->_sceneObjects->contains(&scene->_item7._object1)) {
- scene->_item7._object1.postInit();
- scene->_item7._object1.hide();
- scene->_item7._object1.setVisage(1332);
- scene->_item7._object1.setPosition(scene->_item7._field36, 0);
- scene->_item7._object1.fixPriority(170);
- }
-
- scene->_item7._field34 = scene->_field3EF0->_field34;
- scene->_field3EF0->_field34 = 0;
- scene->_field3EF0->_object1.remove();
-
- if (scene->_field3EF0 == &scene->_item6) {
- subD18B5(5, 1, 4);
+ scene->_availableCardsPile[scene->_currentDiscardIndex] = scene->_actionCard1->_cardId;
+ scene->_currentDiscardIndex--;
+ if (!g_globals->_sceneObjects->contains(&scene->_discardPile._card)) {
+ // The first discarded card makes the pile appear
+ scene->_discardPile._card.postInit();
+ scene->_discardPile._card.hide();
+ scene->_discardPile._card.setVisage(1332);
+ scene->_discardPile._card.setPosition(scene->_discardPile._stationPos, 0);
+ scene->_discardPile._card.fixPriority(170);
+ }
+
+ scene->_discardPile._cardId = scene->_actionCard1->_cardId;
+ scene->_actionCard1->_cardId = 0;
+ scene->_actionCard1->_card.remove();
+
+ if (scene->_actionCard1 == &scene->_selectedCard) {
+ scene->setCursorData(5, 1, 4);
scene->subC4CEC();
}
- scene->_item2._object1.setPosition(scene->_field3EF0->_field36, 0);
- scene->_item2._object1.show();
+ scene->_animatedCard._card.setPosition(scene->_actionCard1->_stationPos, 0);
+ scene->_animatedCard._card.show();
Common::Point pt(128, 95);
NpcMover *mover = new NpcMover();
- scene->_item2._object1.addMover(mover, &pt, this);
+ scene->_animatedCard._card.addMover(mover, &pt, this);
}
break;
case 1:
- scene->_item2._object1.hide();
- scene->setAnimationInfo(&scene->_item7);
+ scene->_animatedCard._card.hide();
+ scene->setAnimationInfo(&scene->_discardPile);
scene->_aSound2.play(61);
- scene->subC20F9();
+ scene->handleNextTurn();
break;
default:
break;
}
}
+/**
+ * Animations for playing a platform card
+ */
void Scene1337::Action6::signal() {
Scene1337 *scene = (Scene1337 *)R2_GLOBALS._sceneManager._scene;
switch (_actionIndex++) {
case 0: {
- scene->_field3EF4->_field34 = 1;
- scene->_field3EF4->_object1.postInit();
- scene->_field3EF4->_object1.hide();
- scene->_field3EF4->_object1.setVisage(1332);
- scene->_field3EF4->_object1.setPosition(scene->_field3EF4->_field36);
- scene->_field3EF4->_object1.fixPriority(170);
+ scene->_actionCard2->_cardId = 1;
+ scene->_actionCard2->_card.postInit();
+ scene->_actionCard2->_card.hide();
+ scene->_actionCard2->_card.setVisage(1332);
+ scene->_actionCard2->_card.setPosition(scene->_actionCard2->_stationPos);
+ scene->_actionCard2->_card.fixPriority(170);
- scene->_field3EF0->_field34 = 0;
- scene->_field3EF0->_object1.remove();
+ scene->_actionCard1->_cardId = 0;
+ scene->_actionCard1->_card.remove();
- scene->_item2._object1.setPosition(scene->_field3EF0->_field36);
- scene->_item2._object1.show();
+ scene->_animatedCard._card.setPosition(scene->_actionCard1->_stationPos);
+ scene->_animatedCard._card.show();
NpcMover *mover = new NpcMover();
- scene->_item2._object1.addMover(mover, &scene->_field3EF4->_field36, this);
+ scene->_animatedCard._card.addMover(mover, &scene->_actionCard2->_stationPos, this);
}
break;
case 1:
- scene->_item2._object1.hide();
- scene->setAnimationInfo(scene->_field3EF4);
+ scene->_animatedCard._card.hide();
+ scene->setAnimationInfo(scene->_actionCard2);
scene->_aSound1.play(59);
- if (scene->_field3EF0 == &scene->_item6) {
- subD18B5(5, 1, 4);
+ if (scene->_actionCard1 == &scene->_selectedCard) {
+ scene->setCursorData(5, 1, 4);
scene->subC4CEC();
}
- scene->subC20F9();
+ scene->handleNextTurn();
break;
default:
break;
}
}
+/**
+ * Upgrade platform to station by playing a station card on top of it
+ */
void Scene1337::Action7::signal() {
Scene1337 *scene = (Scene1337 *)R2_GLOBALS._sceneManager._scene;
switch (_actionIndex++) {
case 0: {
- scene->_field3EF4->_field34 = scene->_field3EF0->_field34;
+ scene->_actionCard2->_cardId = scene->_actionCard1->_cardId;
- scene->_field3EF0->_field34 = 0;
- scene->_field3EF0->_object1.remove();
+ scene->_actionCard1->_cardId = 0;
+ scene->_actionCard1->_card.remove();
- scene->_item2._object1.setPosition(scene->_field3EF0->_field36, 0);
- scene->_item2._object1.show();
+ scene->_animatedCard._card.setPosition(scene->_actionCard1->_stationPos, 0);
+ scene->_animatedCard._card.show();
NpcMover *mover = new NpcMover();
- scene->_item2._object1.addMover(mover, &scene->_field3EF4->_field36, this);
+ scene->_animatedCard._card.addMover(mover, &scene->_actionCard2->_stationPos, this);
}
break;
case 1:
- if (scene->_field3EF0 == &scene->_item6) {
- subD18B5(5, 1, 4);
+ if (scene->_actionCard1 == &scene->_selectedCard) {
+ scene->setCursorData(5, 1, 4);
scene->subC4CEC();
}
- scene->setAnimationInfo(scene->_field3EF4);
+ scene->setAnimationInfo(scene->_actionCard2);
scene->_aSound1.play(59);
- scene->_item5._field34 = 1;
- scene->_item5._field36.x = scene->_field3EF4->_field36.x;
- scene->_item5._field36.y = scene->_field3EF4->_field36.y;
- scene->_item5._object1.postInit();
- scene->_item5._object1.hide();
- scene->_item5._object1._flags = 0x200;
+ scene->_discardedPlatformCard._cardId = 1;
+ scene->_discardedPlatformCard._stationPos = scene->_actionCard2->_stationPos;
+ scene->_discardedPlatformCard._card.postInit();
+ scene->_discardedPlatformCard._card.hide();
+ scene->_discardedPlatformCard._card._flags = OBJFLAG_HIDING;
- scene->subC4A39(&scene->_item5);
+ scene->discardCard(&scene->_discardedPlatformCard);
break;
default:
break;
@@ -3612,112 +3671,114 @@ void Scene1337::Action8::signal() {
switch (_actionIndex++) {
case 0: {
- scene->_field3E28[scene->_field3E26] = scene->_field3EF4->_field34;
- scene->_field3E26--;
+ scene->_availableCardsPile[scene->_currentDiscardIndex] = scene->_actionCard2->_cardId;
+ scene->_currentDiscardIndex--;
- scene->_field3EF4->_field34 = scene->_field3EF0->_field34;
- scene->_field3EF0->_object1.remove();
+ scene->_actionCard2->_cardId = scene->_actionCard1->_cardId;
+ scene->_actionCard1->_card.remove();
- scene->_item2._object1.setPosition(scene->_field3EF0->_field36, 0);
- scene->_item2._object1.show();
+ scene->_animatedCard._card.setPosition(scene->_actionCard1->_stationPos, 0);
+ scene->_animatedCard._card.show();
NpcMover *mover = new NpcMover();
- scene->_item2._object1.addMover(mover, &scene->_field3EF4->_field36, this);
+ scene->_animatedCard._card.addMover(mover, &scene->_actionCard2->_stationPos, this);
}
break;
case 1:
- scene->_item2._object1.hide();
+ scene->_animatedCard._card.hide();
- if (scene->_field3EF0 == &scene->_item6) {
- subD18B5(5, 1, 4);
+ if (scene->_actionCard1 == &scene->_selectedCard) {
+ scene->setCursorData(5, 1, 4);
scene->subC4CEC();
}
- scene->setAnimationInfo(scene->_field3EF4);
+ scene->setAnimationInfo(scene->_actionCard2);
scene->_aSound1.play(58);
- scene->subC4A39(scene->_field3EF4);
+ scene->discardCard(scene->_actionCard2);
break;
default:
break;
}
}
+// Play delay card
void Scene1337::Action9::signal() {
Scene1337 *scene = (Scene1337 *)R2_GLOBALS._sceneManager._scene;
switch (_actionIndex++) {
case 0: {
- scene->_field3EF4->_field34 = scene->_field3EF0->_field34;
- scene->_field3EF4->_object1.postInit();
- scene->_field3EF4->_object1.hide();
- scene->_field3EF4->_object1.setVisage(1332);
- scene->_field3EF4->_object1.setPosition(scene->_field3EF4->_field36, 0);
- scene->_field3EF4->_object1.fixPriority(170);
+ scene->_actionCard2->_cardId = scene->_actionCard1->_cardId;
+ scene->_actionCard2->_card.postInit();
+ scene->_actionCard2->_card.hide();
+ scene->_actionCard2->_card.setVisage(1332);
+ scene->_actionCard2->_card.setPosition(scene->_actionCard2->_stationPos, 0);
+ scene->_actionCard2->_card.fixPriority(170);
- scene->_field3EF0->_field34 = 0;
- scene->_field3EF0->_object1.remove();
+ scene->_actionCard1->_cardId = 0;
+ scene->_actionCard1->_card.remove();
- scene->_item2._object1.setPosition(scene->_field3EF0->_field36, 0);
- scene->_item2._object1.show();
+ scene->_animatedCard._card.setPosition(scene->_actionCard1->_stationPos, 0);
+ scene->_animatedCard._card.show();
NpcMover *mover = new NpcMover();
- scene->_item2._object1.addMover(mover, &scene->_field3EF4->_field36, this);
+ scene->_animatedCard._card.addMover(mover, &scene->_actionCard2->_stationPos, this);
}
break;
case 1:
- scene->_item2._object1.hide();
- scene->setAnimationInfo(scene->_field3EF4);
+ scene->_animatedCard._card.hide();
+ scene->setAnimationInfo(scene->_actionCard2);
scene->_aSound1.play(57);
- if (scene->_field3EF0 == &scene->_item6) {
- subD18B5(5, 1, 4);
+ if (scene->_actionCard1 == &scene->_selectedCard) {
+ scene->setCursorData(5, 1, 4);
scene->subC4CEC();
}
- scene->subC20F9();
+ scene->handleNextTurn();
break;
default:
break;
}
}
+// Counter a trick with a card
void Scene1337::Action10::signal() {
Scene1337 *scene = (Scene1337 *)R2_GLOBALS._sceneManager._scene;
switch (_actionIndex++) {
case 0: {
- scene->_field3EF8->_object1.postInit();
- scene->_field3EF8->_object1.hide();
- scene->_field3EF8->_object1.setVisage(1332);
- scene->_field3EF8->_object1.setPosition(scene->_field3EF8->_field36, 0);
- scene->_field3EF8->_object1.fixPriority(170);
- scene->_field3EF8->_field34 = scene->_field3EF0->_field34;
-
- scene->_field3EF0->_field34 = 0;
- scene->_field3EF0->_object1.remove();
-
- if (scene->_field3EF0 == &scene->_item6) {
- subD18B5(5, 1, 4);
+ scene->_actionCard3->_card.postInit();
+ scene->_actionCard3->_card.hide();
+ scene->_actionCard3->_card.setVisage(1332);
+ scene->_actionCard3->_card.setPosition(scene->_actionCard3->_stationPos, 0);
+ scene->_actionCard3->_card.fixPriority(170);
+ scene->_actionCard3->_cardId = scene->_actionCard1->_cardId;
+
+ scene->_actionCard1->_cardId = 0;
+ scene->_actionCard1->_card.remove();
+
+ if (scene->_actionCard1 == &scene->_selectedCard) {
+ scene->setCursorData(5, 1, 4);
scene->subC4CEC();
}
- scene->_item2._object1.setPosition(scene->_field3EF0->_field36, 0);
- scene->_item2._object1.show();
+ scene->_animatedCard._card.setPosition(scene->_actionCard1->_stationPos, 0);
+ scene->_animatedCard._card.show();
NpcMover *mover = new NpcMover();
- scene->_item2._object1.addMover(mover, &scene->_field3EF8->_field36, this);
+ scene->_animatedCard._card.addMover(mover, &scene->_actionCard3->_stationPos, this);
}
break;
case 1: {
- scene->_item2._object1.hide();
- scene->setAnimationInfo(scene->_field3EF8);
+ scene->_animatedCard._card.hide();
+ scene->setAnimationInfo(scene->_actionCard3);
scene->_aSound1.play(57);
bool found = false;
int indexFound = -1;
- switch (scene->_field4240) {
+ switch (scene->_actionIdx1) {
case 0:
for (indexFound = 0; indexFound < 3; indexFound++) {
- if (scene->_arrunkObj1337[0]._arr1[indexFound]._field34 == 29) {
+ if (scene->_gameBoardSide[0]._handCard[indexFound]._cardId == 29) {
found = true;
break;
}
@@ -3725,7 +3786,7 @@ void Scene1337::Action10::signal() {
break;
case 1:
for (indexFound = 0; indexFound < 3; indexFound++) {
- if (scene->_arrunkObj1337[1]._arr1[indexFound]._field34 == 29) {
+ if (scene->_gameBoardSide[1]._handCard[indexFound]._cardId == 29) {
found = true;
break;
}
@@ -3733,7 +3794,7 @@ void Scene1337::Action10::signal() {
break;
case 2:
for (indexFound = 0; indexFound < 3; indexFound++) {
- if (scene->_arrunkObj1337[2]._arr1[indexFound]._field34 == 29) {
+ if (scene->_gameBoardSide[2]._handCard[indexFound]._cardId == 29) {
found = true;
break;
}
@@ -3741,7 +3802,7 @@ void Scene1337::Action10::signal() {
break;
case 3:
for (indexFound = 0; indexFound < 3; indexFound++) {
- if (scene->_arrunkObj1337[3]._arr1[indexFound]._field34 == 29) {
+ if (scene->_gameBoardSide[3]._handCard[indexFound]._cardId == 29) {
found = true;
break;
}
@@ -3754,13 +3815,13 @@ void Scene1337::Action10::signal() {
bool found2 = false;
if (found) {
- switch (scene->_field4240) {
+ switch (scene->_actionIdx1) {
case 0:
- scene->subC51A0(&scene->_arrunkObj1337[0]._arr1[indexFound], scene->_field3EF8);
+ scene->subC51A0(&scene->_gameBoardSide[0]._handCard[indexFound], scene->_actionCard3);
found2 = true;
break;
case 1:
- scene->subC51A0(&scene->_arrunkObj1337[1]._arr1[indexFound], scene->_field3EF8);
+ scene->subC51A0(&scene->_gameBoardSide[1]._handCard[indexFound], scene->_actionCard3);
found2 = true;
break;
case 2:
@@ -3768,12 +3829,12 @@ void Scene1337::Action10::signal() {
if (MessageDialog::show(USE_INTERCEPTOR, NO_MSG, YES_MSG) == 0)
scene->subC4CEC();
else {
- scene->subC51A0(&scene->_arrunkObj1337[2]._arr1[indexFound], scene->_field3EF8);
+ scene->subC51A0(&scene->_gameBoardSide[2]._handCard[indexFound], scene->_actionCard3);
found2 = true;
}
break;
case 3:
- scene->subC51A0(&scene->_arrunkObj1337[3]._arr1[indexFound], scene->_field3EF8);
+ scene->subC51A0(&scene->_gameBoardSide[3]._handCard[indexFound], scene->_actionCard3);
found2 = true;
break;
default:
@@ -3784,17 +3845,17 @@ void Scene1337::Action10::signal() {
if (!found2)
break;
- if (scene->_field4240 == 2) {
+ if (scene->_actionIdx1 == 2) {
int j = 0;
for (int i = 0; i <= 7; i++) {
- if (scene->_arrunkObj1337[2]._arr2[i]._field34 != 0)
+ if (scene->_gameBoardSide[2]._outpostStation[i]._cardId != 0)
++j;
}
if (j <= 1) {
for (int i = 0; i <= 7; i++) {
- if (scene->_arrunkObj1337[2]._arr2[i]._field34 != 0) {
- scene->_field3EF4 = &scene->_arrunkObj1337[2]._arr2[i];
+ if (scene->_gameBoardSide[2]._outpostStation[i]._cardId != 0) {
+ scene->_actionCard2 = &scene->_gameBoardSide[2]._outpostStation[i];
break;
}
}
@@ -3813,11 +3874,11 @@ void Scene1337::Action10::signal() {
g_globals->_events.delay(g_globals->_sceneHandler->_delayTicks);
}
- scene->_item6._field36 = event.mousePos;
+ scene->_selectedCard._stationPos = event.mousePos;
for (int i = 0; i <= 7; i++) {
- if ((scene->subC2BF8(&scene->_arrunkObj1337[2]._arr2[i], scene->_item6._field36) != 0) && (scene->_arrunkObj1337[2]._arr2[i]._field34 != 0)) {
- scene->_field3EF4 = &scene->_arrunkObj1337[2]._arr2[0];
+ if (scene->_gameBoardSide[2]._outpostStation[i].isIn(scene->_selectedCard._stationPos) && (scene->_gameBoardSide[2]._outpostStation[i]._cardId != 0)) {
+ scene->_actionCard2 = &scene->_gameBoardSide[2]._outpostStation[0];
found2 = true;
break;
}
@@ -3827,27 +3888,28 @@ void Scene1337::Action10::signal() {
}
}
- scene->_field3E28[scene->_field3E26] = scene->_field3EF4->_field34;
- scene->_field3E26--;
- scene->_field3EF4->_field34 = 0;
- scene->_field3EF4->_object1.remove();
+ scene->_availableCardsPile[scene->_currentDiscardIndex] = scene->_actionCard2->_cardId;
+ scene->_currentDiscardIndex--;
+ scene->_actionCard2->_cardId = 0;
+ scene->_actionCard2->_card.remove();
- scene->_item2._object1.setPosition(scene->_field3EF4->_field36, 0);
- scene->_item2._object1.show();
+ scene->_animatedCard._card.setPosition(scene->_actionCard2->_stationPos, 0);
+ scene->_animatedCard._card.show();
NpcMover *mover = new NpcMover();
- scene->_item2._object1.addMover(mover, &scene->_field3EF8->_field36, this);
+ scene->_animatedCard._card.addMover(mover, &scene->_actionCard3->_stationPos, this);
}
break;
case 2:
- scene->_item2._object1.hide();
- scene->subC4A39(scene->_field3EF8);
+ scene->_animatedCard._card.hide();
+ scene->discardCard(scene->_actionCard3);
break;
default:
break;
}
}
+// Use trick (card #25 - thieft ?) and pick a card from the opponent
void Scene1337::Action11::signal() {
Scene1337 *scene = (Scene1337 *)R2_GLOBALS._sceneManager._scene;
@@ -3855,115 +3917,115 @@ void Scene1337::Action11::signal() {
switch (_actionIndex++) {
case 0: {
- scene->_field3EF4->_object1.postInit();
- scene->_field3EF4->_object1.hide();
- scene->_field3EF4->_object1.setVisage(1332);
- scene->_field3EF4->_object1.setPosition(scene->_field3EF4->_field36, 0);
- scene->_field3EF4->_object1.fixPriority(170);
- scene->_field3EF4->_field34 = 25;
-
- if (scene->_field4240 == 2) {
- scene->_item2._object1.setPosition(scene->_field3EF4->_field36, 0);
- subD18B5(5, 1, 4);
+ scene->_actionCard2->_card.postInit();
+ scene->_actionCard2->_card.hide();
+ scene->_actionCard2->_card.setVisage(1332);
+ scene->_actionCard2->_card.setPosition(scene->_actionCard2->_stationPos, 0);
+ scene->_actionCard2->_card.fixPriority(170);
+ scene->_actionCard2->_cardId = 25;
+
+ if (scene->_actionIdx1 == 2) {
+ scene->_animatedCard._card.setPosition(scene->_actionCard2->_stationPos, 0);
+ scene->setCursorData(5, 1, 4);
} else {
- scene->_field3EF0->_field34 = 0;
- scene->_field3EF0->_object1.remove();
- scene->_item2._object1.setPosition(scene->_field3EF0->_field36, 0);
+ scene->_actionCard1->_cardId = 0;
+ scene->_actionCard1->_card.remove();
+ scene->_animatedCard._card.setPosition(scene->_actionCard1->_stationPos, 0);
}
- scene->_item2._object1.show();
+ scene->_animatedCard._card.show();
NpcMover *mover = new NpcMover();
- scene->_item2._object1.addMover(mover, &scene->_field3EF4->_field36, this);
+ scene->_animatedCard._card.addMover(mover, &scene->_actionCard2->_stationPos, this);
}
break;
case 1: {
- scene->_item2._object1.hide();
- scene->setAnimationInfo(scene->_field3EF4);
+ scene->_animatedCard._card.hide();
+ scene->setAnimationInfo(scene->_actionCard2);
scene->_aSound1.play(57);
bool found = false;
int i = -1;
- switch (scene->_field4242) {
+ switch (scene->_actionIdx2) {
case 0:
for (i = 0; i <= 3; i++) {
- if (scene->_arrunkObj1337[0]._arr1[i]._field34 == 27) {
+ if (scene->_gameBoardSide[0]._handCard[i]._cardId == 27) {
found = true;
break;
}
}
- if ((found) && (scene->subC3E92(scene->_field4240) != -1)) {
- scene->_field3EF0 = &scene->_arrunkObj1337[0]._arr1[i];
- scene->_field3EF4 = &scene->_arrunkObj1337[0]._arr4[0];
- if (scene->_field4240 != 0) {
- int tmpVal = scene->subC3E92(scene->_field4240);
- scene->_field3EF8 = &scene->_arrunkObj1337[scene->_field4240]._arr1[tmpVal];
+ if ((found) && (scene->getFreeHandCard(scene->_actionIdx1) != -1)) {
+ scene->_actionCard1 = &scene->_gameBoardSide[0]._handCard[i];
+ scene->_actionCard2 = &scene->_gameBoardSide[0]._emptyStationPos;
+ if (scene->_actionIdx1 != 0) {
+ int tmpVal = scene->getFreeHandCard(scene->_actionIdx1);
+ scene->_actionCard3 = &scene->_gameBoardSide[scene->_actionIdx1]._handCard[tmpVal];
}
- scene->_item1.setAction(&scene->_action12);
+ scene->_actionItem.setAction(&scene->_action12);
noAction = false;
}
break;
case 1:
for (i = 0; i <= 3; i++) {
- if (scene->_arrunkObj1337[1]._arr1[i]._field34 == 27) {
+ if (scene->_gameBoardSide[1]._handCard[i]._cardId == 27) {
found = true;
break;
}
}
- if ((found) && (scene->subC3E92(scene->_field4240) != -1)) {
- scene->_field3EF0 = &scene->_arrunkObj1337[1]._arr1[i];
- scene->_field3EF4 = &scene->_arrunkObj1337[1]._arr4[0];
- if (scene->_field4240 != 1) {
- int tmpVal = scene->subC3E92(scene->_field4240);
- scene->_field3EF8 = &scene->_arrunkObj1337[scene->_field4240]._arr1[tmpVal];
+ if ((found) && (scene->getFreeHandCard(scene->_actionIdx1) != -1)) {
+ scene->_actionCard1 = &scene->_gameBoardSide[1]._handCard[i];
+ scene->_actionCard2 = &scene->_gameBoardSide[1]._emptyStationPos;
+ if (scene->_actionIdx1 != 1) {
+ int tmpVal = scene->getFreeHandCard(scene->_actionIdx1);
+ scene->_actionCard3 = &scene->_gameBoardSide[scene->_actionIdx1]._handCard[tmpVal];
}
- scene->_item1.setAction(&scene->_action12);
+ scene->_actionItem.setAction(&scene->_action12);
noAction = false;
}
break;
case 2:
for (i = 0; i <= 3; i++) {
- if (scene->_arrunkObj1337[2]._arr1[i]._field34 == 27) {
+ if (scene->_gameBoardSide[2]._handCard[i]._cardId == 27) {
found = true;
break;
}
}
- if ((found) && (scene->subC3E92(scene->_field4240) != -1)) {
+ if ((found) && (scene->getFreeHandCard(scene->_actionIdx1) != -1)) {
scene->subC4CD2();
if (MessageDialog::show(USE_DOUBLE_AGENT, NO_MSG, YES_MSG) == 0)
scene->subC4CEC();
else {
scene->subC4CEC();
- scene->_field3EF0 = &scene->_arrunkObj1337[2]._arr1[i];
- scene->_field3EF4 = &scene->_arrunkObj1337[2]._arr4[0];
- if (scene->_field4240 != 2) {
- int tmpVal = scene->subC3E92(scene->_field4240);
- scene->_field3EF8 = &scene->_arrunkObj1337[scene->_field4240]._arr1[tmpVal];
+ scene->_actionCard1 = &scene->_gameBoardSide[2]._handCard[i];
+ scene->_actionCard2 = &scene->_gameBoardSide[2]._emptyStationPos;
+ if (scene->_actionIdx1 != 2) {
+ int tmpVal = scene->getFreeHandCard(scene->_actionIdx1);
+ scene->_actionCard3 = &scene->_gameBoardSide[scene->_actionIdx1]._handCard[tmpVal];
}
- scene->_item1.setAction(&scene->_action12);
+ scene->_actionItem.setAction(&scene->_action12);
noAction = false;
}
}
break;
case 3:
for (i = 0; i <= 3; i++) {
- if (scene->_arrunkObj1337[3]._arr1[i]._field34 == 27) {
+ if (scene->_gameBoardSide[3]._handCard[i]._cardId == 27) {
found = true;
break;
}
}
- if ((found) && (scene->subC3E92(scene->_field4240) != -1)) {
- scene->_field3EF0 = &scene->_arrunkObj1337[3]._arr1[i];
- scene->_field3EF4 = &scene->_arrunkObj1337[3]._arr4[0];
- if (scene->_field4240 != 3) {
- int tmpVal = scene->subC3E92(scene->_field4240);
- scene->_field3EF8 = &scene->_arrunkObj1337[scene->_field4240]._arr1[tmpVal];
+ if ((found) && (scene->getFreeHandCard(scene->_actionIdx1) != -1)) {
+ scene->_actionCard1 = &scene->_gameBoardSide[3]._handCard[i];
+ scene->_actionCard2 = &scene->_gameBoardSide[3]._emptyStationPos;
+ if (scene->_actionIdx1 != 3) {
+ int tmpVal = scene->getFreeHandCard(scene->_actionIdx1);
+ scene->_actionCard3 = &scene->_gameBoardSide[scene->_actionIdx1]._handCard[tmpVal];
}
- scene->_item1.setAction(&scene->_action12);
+ scene->_actionItem.setAction(&scene->_action12);
noAction = false;
}
break;
@@ -3974,11 +4036,11 @@ void Scene1337::Action11::signal() {
if (!noAction)
return;
- if (scene->_field4240 == 2) {
+ if (scene->_actionIdx1 == 2) {
int count = 0;
- if (scene->_field4242 != 2) {
+ if (scene->_actionIdx2 != 2) {
for (i = 0; i <= 3; i++) {
- if (scene->_arrunkObj1337[scene->_field4242]._arr1[i]._field34 == 0)
+ if (scene->_gameBoardSide[scene->_actionIdx2]._handCard[i]._cardId == 0)
++count;
}
}
@@ -3988,7 +4050,7 @@ void Scene1337::Action11::signal() {
found = false;
while (!found) {
- switch (scene->_field4242) {
+ switch (scene->_actionIdx2) {
case 0:
scene->actionDisplay(1330, 131, 159, 10, 1, 200, 0, 7, 0, 154, 154);
break;
@@ -4009,81 +4071,76 @@ void Scene1337::Action11::signal() {
g_globals->_events.delay(g_globals->_sceneHandler->_delayTicks);
}
- scene->_item6._field36 = event.mousePos;
+ scene->_selectedCard._stationPos = event.mousePos;
found = false;
- if (scene->_field4242 != 2) {
+ if (scene->_actionIdx2 != 2) {
for (i = 0; i <= 3; i++) {
- if ((scene->subC2BF8(&scene->_arrunkObj1337[scene->_field4242]._arr1[i], scene->_item6._field36) != 0) && (scene->_arrunkObj1337[scene->_field4242]._arr1[i]._field34 != 0)) {
- scene->_field3EF8 = &scene->_arrunkObj1337[scene->_field4242]._arr1[i];
+ if (scene->_gameBoardSide[scene->_actionIdx2]._handCard[i].isIn(scene->_selectedCard._stationPos) && (scene->_gameBoardSide[scene->_actionIdx2]._handCard[i]._cardId != 0)) {
+ scene->_actionCard3 = &scene->_gameBoardSide[scene->_actionIdx2]._handCard[i];
found = true;
break;
}
}
}
} // while
- scene->_field4246 = 1;
+ scene->_displayHelpFl = true;
scene->subC4CEC();
- } else {
- if (scene->_field4242 != 2) {
- int tmpVal = scene->subC3E92(scene->_field4242);
- scene->_field3EF8 = &scene->_arrunkObj1337[scene->_field4242]._arr1[tmpVal];
- }
+ } else if (scene->_actionIdx2 != 2) {
+ int tmpVal = scene->getFreeHandCard(scene->_actionIdx2);
+ scene->_actionCard3 = &scene->_gameBoardSide[scene->_actionIdx2]._handCard[tmpVal];
}
}
- scene->_field3EF0->_object1.postInit();
- scene->_field3EF0->_object1.hide();
- scene->_field3EF0->_object1.setVisage(1332);
- scene->_field3EF0->_object1.setPosition(scene->_field3EF0->_field36, 0);
- scene->_field3EF0->_object1.fixPriority(170);
- scene->_field3EF0->_object1.setStrip2(1);
- scene->_field3EF0->_field34 = scene->_field3EF8->_field34;
+ scene->_actionCard1->_card.postInit();
+ scene->_actionCard1->_card.hide();
+ scene->_actionCard1->_card.setVisage(1332);
+ scene->_actionCard1->_card.setPosition(scene->_actionCard1->_stationPos, 0);
+ scene->_actionCard1->_card.fixPriority(170);
+ scene->_actionCard1->_card.setStrip2(1);
+ scene->_actionCard1->_cardId = scene->_actionCard3->_cardId;
- scene->_field3EF8->_field34 = 0;
- scene->_field3EF8->_object1.remove();
+ scene->_actionCard3->_cardId = 0;
+ scene->_actionCard3->_card.remove();
- scene->_item2._object1.setPosition(scene->_field3EF8->_field36, 0);
- scene->_item2._object1.show();
+ scene->_animatedCard._card.setPosition(scene->_actionCard3->_stationPos, 0);
+ scene->_animatedCard._card.show();
NpcMover *mover = new NpcMover();
- scene->_item2._object1.addMover(mover, &scene->_field3EF0->_field36, this);
+ scene->_animatedCard._card.addMover(mover, &scene->_actionCard1->_stationPos, this);
}
break;
case 2:
- scene->_item2._object1.hide();
- switch (scene->_field4240) {
+ scene->_animatedCard._card.hide();
+ switch (scene->_actionIdx1) {
case 0:
- scene->_field3EF0->_object1.setFrame(2);
- scene->_field3EF0->_object1.show();
- scene->_field423E--;
- scene->_field4244 = 0;
+ scene->_actionCard1->_card.setFrame2(2);
+ scene->_actionCard1->_card.show();
break;
case 1:
- scene->_field3EF0->_object1.setFrame(4);
- scene->_field3EF0->_object1.show();
- scene->_field423E--;
- scene->_field4244 = 0;
+ scene->_actionCard1->_card.setFrame2(4);
+ scene->_actionCard1->_card.show();
break;
case 3:
- scene->_field3EF0->_object1.setFrame(3);
- scene->_field3EF0->_object1.show();
- scene->_field423E--;
- scene->_field4244 = 0;
+ scene->_actionCard1->_card.setFrame2(3);
+ scene->_actionCard1->_card.show();
break;
default:
- scene->setAnimationInfo(scene->_field3EF0);
+ scene->setAnimationInfo(scene->_actionCard1);
break;
}
- scene->subC4A39(scene->_field3EF4);
+ scene->_currentPlayerNumb--;
+ scene->_showPlayerTurn = false;
+ scene->discardCard(scene->_actionCard2);
break;
default:
break;
}
}
+// Pick a card in opponent hand
void Scene1337::Action12::signal() {
Scene1337 *scene = (Scene1337 *)R2_GLOBALS._sceneManager._scene;
@@ -4092,40 +4149,42 @@ void Scene1337::Action12::signal() {
signal();
break;
case 1: {
- scene->_field3E28[scene->_field3E26] = scene->_field3EF4->_field34;
- scene->_field3EF4->_field34 = scene->_field3EF0->_field34;
- scene->_field3EF0->_field34 = 0;
- scene->_field3EF0->_object1.remove();
- scene->_item2._object1.setPosition(scene->_field3EF0->_field36, 0);
- scene->_item2._object1.show();
+ scene->_availableCardsPile[scene->_currentDiscardIndex] = scene->_actionCard2->_cardId;
+ scene->_currentDiscardIndex++;
+ scene->_actionCard2->_cardId = scene->_actionCard1->_cardId;
+ scene->_actionCard1->_cardId = 0;
+ scene->_actionCard1->_card.remove();
+ scene->_animatedCard._card.setPosition(scene->_actionCard1->_stationPos, 0);
+ scene->_animatedCard._card.show();
NpcMover *mover = new NpcMover();
- scene->_item2._object1.addMover(mover, &scene->_field3EF4->_field36, this);
+ scene->_animatedCard._card.addMover(mover, &scene->_actionCard2->_stationPos, this);
}
break;
case 2:
- scene->_item2._object1.hide();
- scene->setAnimationInfo(scene->_field3EF4);
+ scene->_animatedCard._card.hide();
+ scene->setAnimationInfo(scene->_actionCard2);
scene->_aSound1.play(58);
- if (scene->_field4242 == 2) {
+ if (scene->_actionIdx2 == 2) {
int count = 0;
int i = -1;
- switch (scene->_field4240) {
+ switch (scene->_actionIdx1) {
case 0:
for (i = 0; i <= 3; i++) {
- if (scene->_arrunkObj1337[0]._arr1[i]._field34 != 0)
+ if (scene->_gameBoardSide[0]._handCard[i]._cardId != 0)
++count;
}
break;
case 1:
for (i = 0; i <= 3; i++) {
- if (scene->_arrunkObj1337[3]._arr1[i]._field34 != 0)
+ // The original game was counting in the hand of player 3, which is obviously wrong
+ if (scene->_gameBoardSide[1]._handCard[i]._cardId != 0)
++count;
}
break;
case 3:
for (i = 0; i <= 3; i++) {
- if (scene->_arrunkObj1337[3]._arr1[i]._field34 != 0)
+ if (scene->_gameBoardSide[3]._handCard[i]._cardId != 0)
++count;
}
break;
@@ -4139,7 +4198,7 @@ void Scene1337::Action12::signal() {
bool found = false;
while (!found) {
- switch (scene->_field4240) {
+ switch (scene->_actionIdx1) {
case 0:
scene->actionDisplay(1330, 131, 159, 10, 1, 200, 0, 7, 0, 154, 154);
break;
@@ -4160,95 +4219,94 @@ void Scene1337::Action12::signal() {
g_globals->_events.delay(g_globals->_sceneHandler->_delayTicks);
}
- scene->_item6._field36 = event.mousePos;
+ scene->_selectedCard._stationPos = event.mousePos;
- if (scene->_field4240 == 0) {
+ if (scene->_actionIdx1 == 0) {
for (i = 0; i <= 3; i++) {
- if ((scene->subC2BF8(&scene->_arrunkObj1337[0]._arr1[i], scene->_item6._field36) != 0) && (scene->_arrunkObj1337[0]._arr1[i]._field34 != 0)) {
+ if (scene->_gameBoardSide[0]._handCard[i].isIn(scene->_selectedCard._stationPos) && (scene->_gameBoardSide[0]._handCard[i]._cardId != 0)) {
found = true;
- scene->_field3EF8 = &scene->_arrunkObj1337[0]._arr1[i];
+ scene->_actionCard3 = &scene->_gameBoardSide[0]._handCard[i];
break;
}
}
}
- if (scene->_field4240 == 3) {
+ if (scene->_actionIdx1 == 3) {
for (i = 0; i <= 3; i++) {
- if ((scene->subC2BF8(&scene->_arrunkObj1337[3]._arr1[i], scene->_item6._field36) != 0) && (scene->_arrunkObj1337[3]._arr1[i]._field34 != 0)) {
+ if (scene->_gameBoardSide[3]._handCard[i].isIn(scene->_selectedCard._stationPos) && (scene->_gameBoardSide[3]._handCard[i]._cardId != 0)) {
found = true;
- scene->_field3EF8 = &scene->_arrunkObj1337[3]._arr1[i];
+ scene->_actionCard3 = &scene->_gameBoardSide[3]._handCard[i];
break;
}
}
}
- if (scene->_field4240 == 1) {
+ if (scene->_actionIdx1 == 1) {
for (i = 0; i <= 3; i++) {
- if ((scene->subC2BF8(&scene->_arrunkObj1337[1]._arr1[i], scene->_item6._field36) != 0) && (scene->_arrunkObj1337[1]._arr1[i]._field34 != 0)) {
+ if (scene->_gameBoardSide[1]._handCard[i].isIn(scene->_selectedCard._stationPos) && (scene->_gameBoardSide[1]._handCard[i]._cardId != 0)) {
found = true;
- scene->_field3EF8 = &scene->_arrunkObj1337[1]._arr1[i];
+ scene->_actionCard3 = &scene->_gameBoardSide[1]._handCard[i];
break;
}
}
}
}
scene->subC4CEC();
- } else {
- if (scene->_field4240 != 1) {
- switch (scene->_field4240) {
- case 0:
- scene->_field3EF8 = &scene->_arrunkObj1337[0]._arr1[scene->subC3E92(0)];
- break;
- case 3:
- scene->_field3EF8 = &scene->_arrunkObj1337[3]._arr1[scene->subC3E92(3)];
- break;
- default:
- break;
- }
- } else {
- scene->_field3EF8 = &scene->_arrunkObj1337[1]._arr1[scene->subC3E92(1)];
+ } else if (scene->_actionIdx1 != 1) {
+ switch (scene->_actionIdx1) {
+ case 0:
+ scene->_actionCard3 = &scene->_gameBoardSide[0]._handCard[scene->getFreeHandCard(0)];
+ break;
+ case 3:
+ scene->_actionCard3 = &scene->_gameBoardSide[3]._handCard[scene->getFreeHandCard(3)];
+ break;
+ default:
+ break;
}
+ } else {
+ scene->_actionCard3 = &scene->_gameBoardSide[1]._handCard[scene->getFreeHandCard(1)];
}
- scene->_field3EF0->_object1.postInit();
- scene->_field3EF0->_object1.hide();
- scene->_field3EF0->_object1.setVisage(1332);
- scene->_field3EF0->_object1.setPosition(scene->_field3EF0->_field36);
- scene->_field3EF0->_object1.fixPriority(170);
- scene->_field3EF0->_object1.setStrip2(1);
- scene->_field3EF0->_field34 = scene->_field3EF8->_field34;
+ scene->_actionCard1->_card.postInit();
+ scene->_actionCard1->_card.hide();
+ scene->_actionCard1->_card.setVisage(1332);
+ scene->_actionCard1->_card.setPosition(scene->_actionCard1->_stationPos);
+ scene->_actionCard1->_card.fixPriority(170);
+ scene->_actionCard1->_card.setStrip2(1);
+ scene->_actionCard1->_cardId = scene->_actionCard3->_cardId;
- scene->_field3EF8->_field34 = 0;
- scene->_field3EF8->_object1.remove();
+ scene->_actionCard3->_cardId = 0;
+ scene->_actionCard3->_card.remove();
- scene->_item2._object1.setPosition(scene->_field3EF8->_field36);
- scene->_item2._object1.show();
+ scene->_animatedCard._card.setPosition(scene->_actionCard3->_stationPos);
+ scene->_animatedCard._card.show();
scene->_aSound1.play(57);
NpcMover *mover = new NpcMover();
- scene->_item2._object1.addMover(mover, &scene->_field3EF0->_field36, this);
+ scene->_animatedCard._card.addMover(mover, &scene->_actionCard1->_stationPos, this);
}
break;
case 3:
- scene->_item2._object1.hide();
- switch (scene->_field4242) {
+ scene->_animatedCard._card.hide();
+ switch (scene->_actionIdx2) {
case 0:
- scene->_field3EF0->_object1.setFrame2(2);
- scene->_field3EF0->_object1.show();
+ scene->_actionCard1->_card.setFrame2(2);
+ scene->_actionCard1->_card.show();
break;
case 1:
- scene->_field3EF0->_object1.setFrame2(4);
- scene->_field3EF0->_object1.show();
+ scene->_actionCard1->_card.setFrame2(4);
+ scene->_actionCard1->_card.show();
break;
case 3:
- scene->_field3EF0->_object1.setFrame2(3);
- scene->_field3EF0->_object1.show();
+ scene->_actionCard1->_card.setFrame2(3);
+ scene->_actionCard1->_card.show();
break;
default:
- scene->setAnimationInfo(scene->_field3EF0);
+ scene->setAnimationInfo(scene->_actionCard1);
break;
}
- scene->subC4A39(scene->_field3EF4);
+ scene->discardCard(scene->_actionCard2);
+ scene->handleNextTurn();
break;
default:
break;
@@ -4260,29 +4318,29 @@ void Scene1337::Action13::signal() {
switch (_actionIndex++) {
case 0: {
- scene->_field3E28[scene->_field3E26] = scene->_field3EF4->_field34;
- scene->_field3E26--;
+ scene->_availableCardsPile[scene->_currentDiscardIndex] = scene->_actionCard2->_cardId;
+ scene->_currentDiscardIndex--;
- scene->_field3EF4->_field34 = scene->_field3EF0->_field34;
+ scene->_actionCard2->_cardId = scene->_actionCard1->_cardId;
- scene->_field3EF0->_field34 = 0;
- scene->_field3EF0->_object1.remove();
+ scene->_actionCard1->_cardId = 0;
+ scene->_actionCard1->_card.remove();
- scene->_item2._object1.setPosition(scene->_field3EF0->_field36, 0);
- scene->_item2._object1.show();
+ scene->_animatedCard._card.setPosition(scene->_actionCard1->_stationPos, 0);
+ scene->_animatedCard._card.show();
NpcMover *mover = new NpcMover();
- scene->_item2._object1.addMover(mover, &scene->_field3EF4->_field36, this);
+ scene->_animatedCard._card.addMover(mover, &scene->_actionCard2->_stationPos, this);
}
break;
case 1:
- scene->_item2._object1.hide();
- scene->setAnimationInfo(scene->_field3EF4);
+ scene->_animatedCard._card.hide();
+ scene->setAnimationInfo(scene->_actionCard2);
scene->_aSound1.play(58);
signal();
break;
case 2:
- scene->subC4A39(scene->_field3EF4);
+ scene->discardCard(scene->_actionCard2);
break;
default:
break;
@@ -4293,119 +4351,123 @@ void Scene1337::postInit(SceneObjectList *OwnerList) {
// In the original, may be found in subPostInit.
// Without it, enableControl asserts
loadScene(1330);
+ R2_GLOBALS._uiElements._active = false;
SceneExt::postInit();
//
// Hide the user interface
- R2_GLOBALS._uiElements._active = false;
- BF_GLOBALS._interfaceY = 200;
+ BF_GLOBALS._interfaceY = SCREEN_HEIGHT;
+ R2_GLOBALS._uiElements._visible = false;
R2_GLOBALS._player.enableControl();
R2_GLOBALS._player._canWalk = false;
-
- _unkFctPtr412 = NULL;
-
- _field3EF0 = NULL;
- _field3EF4 = NULL;
- _field3EF8 = NULL;
-
- _arrunkObj1337[2]._arr1[0]._field36 = Common::Point(10, 174);
- _arrunkObj1337[2]._arr1[1]._field36 = Common::Point(37, 174);
- _arrunkObj1337[2]._arr1[2]._field36 = Common::Point(64, 174);
- _arrunkObj1337[2]._arr1[3]._field36 = Common::Point(91, 174);
-
- _arrunkObj1337[2]._arr2[0]._field36 = Common::Point(119, 174);
- _arrunkObj1337[2]._arr2[1]._field36 = Common::Point(119, 148);
- _arrunkObj1337[2]._arr2[2]._field36 = Common::Point(119, 122);
- _arrunkObj1337[2]._arr2[3]._field36 = Common::Point(145, 122);
- _arrunkObj1337[2]._arr2[4]._field36 = Common::Point(171, 122);
- _arrunkObj1337[2]._arr2[5]._field36 = Common::Point(171, 148);
- _arrunkObj1337[2]._arr2[6]._field36 = Common::Point(171, 174);
- _arrunkObj1337[2]._arr2[7]._field36 = Common::Point(145, 174);
-
- _arrunkObj1337[2]._arr3[0]._field36 = Common::Point(199, 174);
-
- _arrunkObj1337[2]._arr4[0]._field36 = Common::Point(145, 148);
-
- _arrunkObj1337[2]._fieldB94 = Common::Point(10, 174);
- _arrunkObj1337[2]._fieldB98 = Common::Point(37, 174);
- _arrunkObj1337[2]._fieldB9C = Common::Point(64, 174);
- _arrunkObj1337[2]._fieldBA0 = Common::Point(91, 174);
- _arrunkObj1337[2]._fieldBA4 = 2;
-
- _arrunkObj1337[3]._arr1[0]._field36 = Common::Point(14, 14);
- _arrunkObj1337[3]._arr1[1]._field36 = Common::Point(14, 36);
- _arrunkObj1337[3]._arr1[2]._field36 = Common::Point(14, 58);
- _arrunkObj1337[3]._arr1[3]._field36 = Common::Point(14, 80);
-
- _arrunkObj1337[3]._arr2[0]._field36 = Common::Point(37, 66);
- _arrunkObj1337[3]._arr2[1]._field36 = Common::Point(63, 66);
- _arrunkObj1337[3]._arr2[2]._field36 = Common::Point(89, 66);
- _arrunkObj1337[3]._arr2[3]._field36 = Common::Point(89, 92);
- _arrunkObj1337[3]._arr2[4]._field36 = Common::Point(89, 118);
- _arrunkObj1337[3]._arr2[5]._field36 = Common::Point(63, 118);
- _arrunkObj1337[3]._arr2[6]._field36 = Common::Point(37, 118);
- _arrunkObj1337[3]._arr2[7]._field36 = Common::Point(37, 92);
-
- _arrunkObj1337[3]._arr3[0]._field36 = Common::Point(37, 145);
-
- _arrunkObj1337[3]._arr4[0]._field36 = Common::Point(63, 92);
-
- _arrunkObj1337[3]._fieldB94 = Common::Point(14, 14);
- _arrunkObj1337[3]._fieldB98 = Common::Point(14, 36);
- _arrunkObj1337[3]._fieldB9C = Common::Point(14, 58);
- _arrunkObj1337[3]._fieldBA0 = Common::Point(14, 80);
- _arrunkObj1337[3]._fieldBA4 = 3;
-
- _arrunkObj1337[0]._arr1[0]._field36 = Common::Point(280, 5);
- _arrunkObj1337[0]._arr1[1]._field36 = Common::Point(253, 5);
- _arrunkObj1337[0]._arr1[2]._field36 = Common::Point(226, 5);
- _arrunkObj1337[0]._arr1[3]._field36 = Common::Point(199, 5);
-
- _arrunkObj1337[0]._arr2[0]._field36 = Common::Point(171, 16);
- _arrunkObj1337[0]._arr2[1]._field36 = Common::Point(171, 42);
- _arrunkObj1337[0]._arr2[2]._field36 = Common::Point(171, 68);
- _arrunkObj1337[0]._arr2[3]._field36 = Common::Point(145, 68);
- _arrunkObj1337[0]._arr2[4]._field36 = Common::Point(119, 68);
- _arrunkObj1337[0]._arr2[5]._field36 = Common::Point(119, 42);
- _arrunkObj1337[0]._arr2[6]._field36 = Common::Point(119, 16);
- _arrunkObj1337[0]._arr2[7]._field36 = Common::Point(145, 16);
-
- _arrunkObj1337[0]._arr3[0]._field36 = Common::Point(91, 16);
-
- _arrunkObj1337[0]._arr4[0]._field36 = Common::Point(145, 42);
-
- _arrunkObj1337[0]._fieldB94 = Common::Point(280, 5);
- _arrunkObj1337[0]._fieldB98 = Common::Point(253, 5);
- _arrunkObj1337[0]._fieldB9C = Common::Point(226, 5);
- _arrunkObj1337[0]._fieldBA0 = Common::Point(199, 5);
- _arrunkObj1337[0]._fieldBA4 = 2;
-
- _arrunkObj1337[1]._arr1[0]._field36 = Common::Point(283, 146);
- _arrunkObj1337[1]._arr1[1]._field36 = Common::Point(283, 124);
- _arrunkObj1337[1]._arr1[2]._field36 = Common::Point(283, 102);
- _arrunkObj1337[1]._arr1[3]._field36 = Common::Point(283, 80);
-
- _arrunkObj1337[1]._arr2[0]._field36 = Common::Point(253, 122);
- _arrunkObj1337[1]._arr2[1]._field36 = Common::Point(227, 122);
- _arrunkObj1337[1]._arr2[2]._field36 = Common::Point(201, 122);
- _arrunkObj1337[1]._arr2[3]._field36 = Common::Point(201, 96);
- _arrunkObj1337[1]._arr2[4]._field36 = Common::Point(201, 70);
- _arrunkObj1337[1]._arr2[5]._field36 = Common::Point(227, 70);
- _arrunkObj1337[1]._arr2[6]._field36 = Common::Point(253, 70);
- _arrunkObj1337[1]._arr2[7]._field36 = Common::Point(253, 96);
-
- _arrunkObj1337[1]._arr3[0]._field36 = Common::Point(253, 43);
-
- _arrunkObj1337[1]._arr4[0]._field36 = Common::Point(227, 96);
-
- _arrunkObj1337[1]._fieldB94 = Common::Point(283, 146);
- _arrunkObj1337[1]._fieldB98 = Common::Point(283, 124);
- _arrunkObj1337[1]._fieldB9C = Common::Point(283, 102);
- _arrunkObj1337[1]._fieldBA0 = Common::Point(283, 80);
- _arrunkObj1337[1]._fieldBA4 = 4;
+ R2_GLOBALS._player._uiEnabled = false;
+
+ _delayedFunction = nullptr;
+
+ _actionCard1 = nullptr;
+ _actionCard2 = nullptr;
+ _actionCard3 = nullptr;
+
+ _gameBoardSide[2]._handCard[0]._stationPos = Common::Point(10, 174);
+ _gameBoardSide[2]._handCard[1]._stationPos = Common::Point(37, 174);
+ _gameBoardSide[2]._handCard[2]._stationPos = Common::Point(64, 174);
+ _gameBoardSide[2]._handCard[3]._stationPos = Common::Point(91, 174);
+
+ _gameBoardSide[2]._outpostStation[0]._stationPos = Common::Point(119, 174);
+ _gameBoardSide[2]._outpostStation[1]._stationPos = Common::Point(119, 148);
+ _gameBoardSide[2]._outpostStation[2]._stationPos = Common::Point(119, 122);
+ _gameBoardSide[2]._outpostStation[3]._stationPos = Common::Point(145, 122);
+ _gameBoardSide[2]._outpostStation[4]._stationPos = Common::Point(171, 122);
+ _gameBoardSide[2]._outpostStation[5]._stationPos = Common::Point(171, 148);
+ _gameBoardSide[2]._outpostStation[6]._stationPos = Common::Point(171, 174);
+ _gameBoardSide[2]._outpostStation[7]._stationPos = Common::Point(145, 174);
+
+ _gameBoardSide[2]._delayCard._stationPos = Common::Point(199, 174);
+
+ _gameBoardSide[2]._emptyStationPos._stationPos = Common::Point(145, 148);
+
+ _gameBoardSide[2]._card1Pos = Common::Point(10, 174);
+ _gameBoardSide[2]._card2Pos = Common::Point(37, 174);
+ _gameBoardSide[2]._card3Pos = Common::Point(64, 174);
+ _gameBoardSide[2]._card4Pos = Common::Point(91, 174);
+ _gameBoardSide[2]._frameNum = 2;
+
+ _gameBoardSide[3]._handCard[0]._stationPos = Common::Point(14, 14);
+ _gameBoardSide[3]._handCard[1]._stationPos = Common::Point(14, 36);
+ _gameBoardSide[3]._handCard[2]._stationPos = Common::Point(14, 58);
+ _gameBoardSide[3]._handCard[3]._stationPos = Common::Point(14, 80);
+
+ _gameBoardSide[3]._outpostStation[0]._stationPos = Common::Point(37, 66);
+ _gameBoardSide[3]._outpostStation[1]._stationPos = Common::Point(63, 66);
+ _gameBoardSide[3]._outpostStation[2]._stationPos = Common::Point(89, 66);
+ _gameBoardSide[3]._outpostStation[3]._stationPos = Common::Point(89, 92);
+ _gameBoardSide[3]._outpostStation[4]._stationPos = Common::Point(89, 118);
+ _gameBoardSide[3]._outpostStation[5]._stationPos = Common::Point(63, 118);
+ _gameBoardSide[3]._outpostStation[6]._stationPos = Common::Point(37, 118);
+ _gameBoardSide[3]._outpostStation[7]._stationPos = Common::Point(37, 92);
+
+ _gameBoardSide[3]._delayCard._stationPos = Common::Point(37, 145);
+
+ _gameBoardSide[3]._emptyStationPos._stationPos = Common::Point(63, 92);
+
+ _gameBoardSide[3]._card1Pos = Common::Point(14, 14);
+ _gameBoardSide[3]._card2Pos = Common::Point(14, 36);
+ _gameBoardSide[3]._card3Pos = Common::Point(14, 58);
+ _gameBoardSide[3]._card4Pos = Common::Point(14, 80);
+ _gameBoardSide[3]._frameNum = 3;
+
+ _gameBoardSide[0]._handCard[0]._stationPos = Common::Point(280, 5);
+ _gameBoardSide[0]._handCard[1]._stationPos = Common::Point(253, 5);
+ _gameBoardSide[0]._handCard[2]._stationPos = Common::Point(226, 5);
+ _gameBoardSide[0]._handCard[3]._stationPos = Common::Point(199, 5);
+
+ _gameBoardSide[0]._outpostStation[0]._stationPos = Common::Point(171, 16);
+ _gameBoardSide[0]._outpostStation[1]._stationPos = Common::Point(171, 42);
+ _gameBoardSide[0]._outpostStation[2]._stationPos = Common::Point(171, 68);
+ _gameBoardSide[0]._outpostStation[3]._stationPos = Common::Point(145, 68);
+ _gameBoardSide[0]._outpostStation[4]._stationPos = Common::Point(119, 68);
+ _gameBoardSide[0]._outpostStation[5]._stationPos = Common::Point(119, 42);
+ _gameBoardSide[0]._outpostStation[6]._stationPos = Common::Point(119, 16);
+ _gameBoardSide[0]._outpostStation[7]._stationPos = Common::Point(145, 16);
+
+ _gameBoardSide[0]._delayCard._stationPos = Common::Point(91, 16);
+
+ _gameBoardSide[0]._emptyStationPos._stationPos = Common::Point(145, 42);
+
+ _gameBoardSide[0]._card1Pos = Common::Point(280, 5);
+ _gameBoardSide[0]._card2Pos = Common::Point(253, 5);
+ _gameBoardSide[0]._card3Pos = Common::Point(226, 5);
+ _gameBoardSide[0]._card4Pos = Common::Point(199, 5);
+ _gameBoardSide[0]._frameNum = 2;
+
+ _gameBoardSide[1]._handCard[0]._stationPos = Common::Point(283, 146);
+ _gameBoardSide[1]._handCard[1]._stationPos = Common::Point(283, 124);
+ _gameBoardSide[1]._handCard[2]._stationPos = Common::Point(283, 102);
+ _gameBoardSide[1]._handCard[3]._stationPos = Common::Point(283, 80);
+
+ _gameBoardSide[1]._outpostStation[0]._stationPos = Common::Point(253, 122);
+ _gameBoardSide[1]._outpostStation[1]._stationPos = Common::Point(227, 122);
+ _gameBoardSide[1]._outpostStation[2]._stationPos = Common::Point(201, 122);
+ _gameBoardSide[1]._outpostStation[3]._stationPos = Common::Point(201, 96);
+ _gameBoardSide[1]._outpostStation[4]._stationPos = Common::Point(201, 70);
+ _gameBoardSide[1]._outpostStation[5]._stationPos = Common::Point(227, 70);
+ _gameBoardSide[1]._outpostStation[6]._stationPos = Common::Point(253, 70);
+ _gameBoardSide[1]._outpostStation[7]._stationPos = Common::Point(253, 96);
+
+ _gameBoardSide[1]._delayCard._stationPos = Common::Point(253, 43);
+
+ _gameBoardSide[1]._emptyStationPos._stationPos = Common::Point(227, 96);
+
+ _gameBoardSide[1]._card1Pos = Common::Point(283, 146);
+ _gameBoardSide[1]._card2Pos = Common::Point(283, 124);
+ _gameBoardSide[1]._card3Pos = Common::Point(283, 102);
+ _gameBoardSide[1]._card4Pos = Common::Point(283, 80);
+ _gameBoardSide[1]._frameNum = 4;
subPostInit();
+
+ _stockPile.postInit();
}
void Scene1337::remove() {
@@ -4415,25 +4477,26 @@ void Scene1337::remove() {
}
R2_GLOBALS._uiElements._active = true;
+ R2_GLOBALS._uiElements._visible = true;
SceneExt::remove();
}
void Scene1337::process(Event &event) {
if (event.eventType == EVENT_BUTTON_DOWN) {
- if (event.btnState != BTNSHIFT_RIGHT) {
- subD183F(R2_GLOBALS._v5780E, 1);
+ if (event.btnState == BTNSHIFT_RIGHT) {
+ updateCursorId(R2_GLOBALS._mouseCursorId, true);
event.handled = true;
- } else if (_unkFctPtr412) {
- FunctionPtrType tmpFctPtr = _unkFctPtr412;
- _unkFctPtr412 = NULL;
+ } else if (_delayedFunction) {
+ FunctionPtrType tmpFctPtr = _delayedFunction;
+ _delayedFunction = nullptr;
(this->*tmpFctPtr)();
event.handled = true;
}
} else if (event.eventType == EVENT_KEYPRESS) {
if (event.kbd.keycode == Common::KEYCODE_SPACE) {
- if (_unkFctPtr412) {
- FunctionPtrType tmpFctPtr = _unkFctPtr412;
- _unkFctPtr412 = NULL;
+ if (_delayedFunction) {
+ FunctionPtrType tmpFctPtr = _delayedFunction;
+ _delayedFunction = nullptr;
(this->*tmpFctPtr)();
event.handled = true;
}
@@ -4446,82 +4509,85 @@ void Scene1337::process(Event &event) {
}
void Scene1337::dispatch() {
- if (_field424C == 0) {
- ++_field424E;
- if (_field424E == 4) {
- _field424C = 1;
+ if (!_instructionsDisplayedFl) {
+ ++_instructionsWaitCount;
+ if (_instructionsWaitCount == 4) {
+ _instructionsDisplayedFl = true;
suggestInstructions();
}
}
+
+ // The following code is in the original in sceneHandler::process(),
+ // which is terrible as it's checked in every scene of the game.
+ setCursorData(5, _cursorCurStrip, _cursorCurFrame);
+ //
+
Scene::dispatch();
}
-void Scene1337::actionDisplay(int resNum, int lineNum, int x, int y, int arg5, int width, int textMode, int fontNum, int colFG, int colBGExt, int colFGExt) {
+void Scene1337::actionDisplay(int resNum, int lineNum, int x, int y, int keepOnScreen, int width, int textMode, int fontNum, int colFG, int colBGExt, int colFGExt) {
// TODO: Check if it's normal that arg5 is unused and replaced by an hardcoded 0 value
// May hide an original bug
- SceneItem::display(resNum, lineNum, SET_X, x, SET_Y, y, SET_KEEP_ONSCREEN, 0, SET_WIDTH, width, SET_POS_MODE, -1, SET_TEXT_MODE, textMode, SET_FONT, fontNum, SET_FG_COLOR, colFG, SET_EXT_BGCOLOR, colBGExt, SET_EXT_FGCOLOR, colFGExt, LIST_END);
+ SceneItem::display(resNum, lineNum, SET_X, x, SET_Y, y, SET_KEEP_ONSCREEN, 0,
+ SET_WIDTH, width, SET_POS_MODE, -1, SET_TEXT_MODE, textMode,
+ SET_FONT, fontNum, SET_FG_COLOR, colFG, SET_EXT_BGCOLOR, colBGExt,
+ SET_EXT_FGCOLOR, colFGExt, LIST_END);
}
-void Scene1337::setAnimationInfo(unkObj1337sub1 *subObj) {
- if (!subObj)
+void Scene1337::setAnimationInfo(Card *card) {
+ if (!card)
return;
- if (subObj->_field34 > 9) {
- if (subObj->_field34 > 25) {
- subObj->_object1.setStrip2(4);
- subObj->_object1.setFrame(subObj->_field34 - 25);
- } else {
- subObj->_object1.setStrip2(3);
- subObj->_object1.setFrame(subObj->_field34 - 9);
- }
+ if (card->_cardId > 25) {
+ card->_card.setStrip2(4);
+ card->_card.setFrame(card->_cardId - 25);
+ } else if (card->_cardId > 9) {
+ card->_card.setStrip2(3);
+ card->_card.setFrame(card->_cardId - 9);
} else {
- subObj->_object1.setStrip2(2);
- subObj->_object1.setFrame(subObj->_field34);
+ card->_card.setStrip2(2);
+ card->_card.setFrame(card->_cardId);
}
- subObj->_object1.show();
+ card->_card.show();
R2_GLOBALS._sceneObjects->draw();
}
-void Scene1337::subC20E5() {
- subC2586();
-}
-
-void Scene1337::subC20F9() {
- switch (_field424A) {
+void Scene1337::handleNextTurn() {
+ switch (_winnerId) {
case -1:
- ++_field423E;
- if (_field423E == 3)
- _field423E = 0;
+ ++_currentPlayerNumb;
+ if (_currentPlayerNumb > 3)
+ _currentPlayerNumb = 0;
- if (_field4244 == 1) {
- _object1.show();
- switch (_field423E) {
+ if (_showPlayerTurn) {
+ _currentPlayerArrow.show();
+ switch (_currentPlayerNumb) {
case 0:
- _object1.setStrip(3);
+ _currentPlayerArrow.setStrip(3);
break;
case 1:
- _object1.setStrip(4);
+ _currentPlayerArrow.setStrip(4);
break;
case 2:
subD1975(174, 107);
- _object1.setStrip(1);
+ _currentPlayerArrow.setStrip(1);
break;
case 3:
subC4CEC();
- _object1.setStrip(2);
+ _currentPlayerArrow.setStrip(2);
break;
default:
break;
}
if (!_autoplay)
- _unkFctPtr412 = &Scene1337::subC20E5;
+ _delayedFunction = &Scene1337::handlePlayerTurn;
else
- subC20E5();
+ handlePlayerTurn();
} else {
- subC20E5();
+ handlePlayerTurn();
}
break;
case 0:
@@ -4560,38 +4626,38 @@ void Scene1337::subC20F9() {
break;
}
- if (_field424A != -1)
+ if (_winnerId != -1)
R2_GLOBALS._sceneManager.changeScene(125);
}
-void Scene1337::subC2586() {
- if (_field4244 != 0)
- _object1.hide();
+void Scene1337::handlePlayerTurn() {
+ if (_showPlayerTurn)
+ _currentPlayerArrow.hide();
- switch (_field423E) {
+ switch (_currentPlayerNumb) {
case 2:
subC4CD2();
- if (_field4246 == 1)
+ if (_displayHelpFl)
actionDisplay(1330, 114, 159, 10, 1, 200, 0, 7, 0, 154, 154);
- _field4246 = 0;
+ _displayHelpFl = false;
// No break on purpose
case 0:
// No break on purpose
case 1:
// No break on purpose
case 3:
- _item1.setAction(&_action4);
+ _actionItem.setAction(&_action4);
default:
break;
}
- _field4244 = 1;
+ _showPlayerTurn = true;
}
-bool Scene1337::subC264B(int arg1) {
- switch (arg1) {
+bool Scene1337::isStationCard(int cardId) {
+ switch (cardId) {
case 10:
// No break on purpose
case 12:
@@ -4613,8 +4679,8 @@ bool Scene1337::subC264B(int arg1) {
}
}
-bool Scene1337::subC2687(int arg1) {
- switch (arg1) {
+bool Scene1337::isStopConstructionCard(int cardId) {
+ switch (cardId) {
case 11:
// No break on purpose
case 14:
@@ -4628,43 +4694,42 @@ bool Scene1337::subC2687(int arg1) {
}
}
-int Scene1337::subC26CB(int arg1, int arg2) {
- if ((_arrunkObj1337[arg1]._arr1[arg2]._field34 > 1) && (_arrunkObj1337[arg1]._arr1[arg2]._field34 <= 9)) {
- return arg2;
- }
+int Scene1337::getStationId(int playerId, int handCardId) {
+ if ((_gameBoardSide[playerId]._handCard[handCardId]._cardId > 1) && (_gameBoardSide[playerId]._handCard[handCardId]._cardId <= 9))
+ return handCardId;
return -1;
}
-int Scene1337::subC2719(int arg1) {
+int Scene1337::findPlatformCardInHand(int playerId) {
for (int i = 0; i <= 3; i++) {
- if (_arrunkObj1337[arg1]._arr1[i]._field34 == 1)
+ if (_gameBoardSide[playerId]._handCard[i]._cardId == 1)
return i;
}
return -1;
}
-int Scene1337::subC274D(int arg1) {
+int Scene1337::findCard13InHand(int playerId) {
for (int i = 0; i <= 3; i++) {
- if (_arrunkObj1337[arg1]._arr1[i]._field34 == 13)
+ if (_gameBoardSide[playerId]._handCard[i]._cardId == 13)
return i;
}
return -1;
}
-int Scene1337::subC2781(int arg1) {
+int Scene1337::checkThieftCard(int playerId) {
for (int i = 0; i <= 3; i++) {
- if (_arrunkObj1337[arg1]._arr1[i]._field34 == 25)
+ if (_gameBoardSide[playerId]._handCard[i]._cardId == 25)
return i;
}
return -1;
}
-int Scene1337::subC27B5(int arg1) {
- switch (arg1) {
+int Scene1337::isDelayCard(int cardId) {
+ switch (cardId) {
case 11:
// No break on purpose
case 14:
@@ -4672,7 +4737,7 @@ int Scene1337::subC27B5(int arg1) {
case 16:
// No break on purpose
case 24:
- return arg1;
+ return cardId;
break;
default:
return -1;
@@ -4680,8 +4745,8 @@ int Scene1337::subC27B5(int arg1) {
}
}
-int Scene1337::subC27F9(int arg1) {
- switch (arg1) {
+int Scene1337::getStationCardId(int cardId) {
+ switch (cardId) {
case 10:
// No break on purpose
case 12:
@@ -4697,377 +4762,143 @@ int Scene1337::subC27F9(int arg1) {
case 20:
// No break on purpose
case 21:
- return arg1;
+ return cardId;
default:
return -1;
}
}
-void Scene1337::subC2835(int arg1) {
- int i;
- bool found = false;
- switch (arg1) {
+void Scene1337::handlePlayer01Discard(int playerId) {
+ switch (playerId) {
case 0:
- for (i = 0; i <= 3; i++) {
- if (subC27F9(_arrunkObj1337[arg1]._arr1[i]._field34) != -1) {
- found = true;
- break;
+ for (int i = 0; i <= 3; i++) {
+ if (getStationCardId(_gameBoardSide[playerId]._handCard[i]._cardId) != -1) {
+ discardCard(&_gameBoardSide[playerId]._handCard[i]);
+ return;
}
}
- if (found)
- break;
-
- for (i = 0; i <= 3; i++) {
- if (subC27B5(_arrunkObj1337[arg1]._arr1[i]._field34) != -1) {
- found = true;
- break;
+ for (int i = 0; i <= 3; i++) {
+ if (isDelayCard(_gameBoardSide[playerId]._handCard[i]._cardId) != -1) {
+ discardCard(&_gameBoardSide[playerId]._handCard[i]);
+ return;
}
}
- if (found)
- break;
-
- for (i = 0; i <= 3; i++) {
- if ((_arrunkObj1337[arg1]._arr1[i]._field34 > 1) && (_arrunkObj1337[arg1]._arr1[i]._field34 <= 9)) {
- found = true;
- break;
+ for (int i = 0; i <= 3; i++) {
+ if ((_gameBoardSide[playerId]._handCard[i]._cardId > 1) && (_gameBoardSide[playerId]._handCard[i]._cardId <= 9)) {
+ discardCard(&_gameBoardSide[playerId]._handCard[i]);
+ return;
}
}
- if (found)
- break;
-
- for (i = 0; i <= 3; i++) {
- if ((_arrunkObj1337[arg1]._arr1[i]._field34 >= 26) && (_arrunkObj1337[arg1]._arr1[i]._field34 <= 33)) {
- found = true;
- break;
+ for (int i = 0; i <= 3; i++) {
+ if ((_gameBoardSide[playerId]._handCard[i]._cardId >= 26) && (_gameBoardSide[playerId]._handCard[i]._cardId <= 33)) {
+ discardCard(&_gameBoardSide[playerId]._handCard[i]);
+ return;
}
}
- if (found)
- break;
-
- for (i = 0; i <= 3; i++) {
- if (_arrunkObj1337[arg1]._arr1[i]._field34 == 1) {
- found = true;
- break;
+ for (int i = 0; i <= 3; i++) {
+ if (_gameBoardSide[playerId]._handCard[i]._cardId == 1) {
+ discardCard(&_gameBoardSide[playerId]._handCard[i]);
+ return;
}
}
- if (found)
- break;
-
- for (i = 0; i <= 3; i++) {
- if (_arrunkObj1337[arg1]._arr1[i]._field34 == 25) {
- found = true;
- break;
+ for (int i = 0; i <= 3; i++) {
+ if (_gameBoardSide[playerId]._handCard[i]._cardId == 25) {
+ discardCard(&_gameBoardSide[playerId]._handCard[i]);
+ return;
}
}
- if (found)
- break;
-
- for (i = 0; i <= 3; i++) {
- if (_arrunkObj1337[arg1]._arr1[i]._field34 == 13) {
- found = true;
- break;
+ for (int i = 0; i <= 3; i++) {
+ if (_gameBoardSide[playerId]._handCard[i]._cardId == 13) {
+ discardCard(&_gameBoardSide[playerId]._handCard[i]);
+ return;
}
}
break;
case 1:
- for (i = 0; i <= 3; i++) {
- if ((_arrunkObj1337[arg1]._arr1[i]._field34 >= 26) && (_arrunkObj1337[arg1]._arr1[i]._field34 <= 33)) {
- found = true;
- break;
+ for (int i = 0; i <= 3; i++) {
+ if ((_gameBoardSide[playerId]._handCard[i]._cardId >= 26) && (_gameBoardSide[playerId]._handCard[i]._cardId <= 33)) {
+ discardCard(&_gameBoardSide[playerId]._handCard[i]);
+ return;
}
}
- if (found)
- break;
-
- for (i = 0; i <= 3; i++) {
- if (_arrunkObj1337[arg1]._arr1[i]._field34 == 1) {
- found = true;
- break;
+ for (int i = 0; i <= 3; i++) {
+ if (_gameBoardSide[playerId]._handCard[i]._cardId == 1) {
+ discardCard(&_gameBoardSide[playerId]._handCard[i]);
+ return;
}
}
- if (found)
- break;
-
- for (i = 0; i <= 3; i++) {
- if ((_arrunkObj1337[arg1]._arr1[i]._field34 > 1) && (_arrunkObj1337[arg1]._arr1[i]._field34 <= 9)) {
- found = true;
- break;
+ for (int i = 0; i <= 3; i++) {
+ if ((_gameBoardSide[playerId]._handCard[i]._cardId > 1) && (_gameBoardSide[playerId]._handCard[i]._cardId <= 9)) {
+ discardCard(&_gameBoardSide[playerId]._handCard[i]);
+ return;
}
}
- if (found)
- break;
-
- for (i = 0; i <= 3; i++) {
- if (subC27F9(_arrunkObj1337[arg1]._arr1[i]._field34) != -1) {
- found = true;
- break;
+ for (int i = 0; i <= 3; i++) {
+ if (getStationCardId(_gameBoardSide[playerId]._handCard[i]._cardId) != -1) {
+ discardCard(&_gameBoardSide[playerId]._handCard[i]);
+ return;
}
}
- if (found)
- break;
-
- for (i = 0; i <= 3; i++) {
- if (subC27B5(_arrunkObj1337[arg1]._arr1[i]._field34) != -1) {
- found = true;
- break;
+ for (int i = 0; i <= 3; i++) {
+ if (isDelayCard(_gameBoardSide[playerId]._handCard[i]._cardId) != -1) {
+ discardCard(&_gameBoardSide[playerId]._handCard[i]);
+ return;
}
}
- if (found)
- break;
-
- for (i = 0; i <= 3; i++) {
- if (_arrunkObj1337[arg1]._arr1[i]._field34 == 25) {
- found = true;
- break;
+ for (int i = 0; i <= 3; i++) {
+ if (_gameBoardSide[playerId]._handCard[i]._cardId == 25) {
+ discardCard(&_gameBoardSide[playerId]._handCard[i]);
+ return;
}
}
- if (found)
- break;
-
- for (i = 0; i <= 3; i++) {
- if (_arrunkObj1337[arg1]._arr1[i]._field34 == 13) {
- found = true;
- break;
+ for (int i = 0; i <= 3; i++) {
+ if (_gameBoardSide[playerId]._handCard[i]._cardId == 13) {
+ discardCard(&_gameBoardSide[playerId]._handCard[i]);
+ return;
}
}
break;
default:
- return;
- }
-
- subC4A39(&_arrunkObj1337[arg1]._arr1[i]);
-}
-
-bool Scene1337::subC2BF8(unkObj1337sub1 *subObj1, Common::Point pt) {
- if ((subObj1->_field36.x > pt.x) || (subObj1->_field36.x + 24 < pt.x))
- return false;
-
- if ((subObj1->_field36.y > pt.y) || (subObj1->_field36.y + 24 < pt.y))
- return false;
-
- return true;
-}
-
-void Scene1337::subC2C2F() {
- bool found = true;
-
- if (_arrunkObj1337[3]._arr3[0]._field34 != 0) {
- switch (_arrunkObj1337[3]._arr3[0]._field34) {
- case 10:
- // No break on purpose
- case 12:
- // No break on purpose
- case 15:
- // No break on purpose
- case 17:
- // No break on purpose
- case 18:
- // No break on purpose
- case 19:
- // No break on purpose
- case 20:
- // No break on purpose
- case 21:
- subC4A39(&_arrunkObj1337[3]._arr3[0]);
- found = false;
- break;
- default:
- found = false;
- int i;
- for (i = 0; i <= 3; i++) {
- if (subC3386(_arrunkObj1337[3]._arr3[0]._field34, _arrunkObj1337[3]._arr1[i]._field34)) {
- found = true;
- break;
- }
- }
-
- if (found) {
- found = false;
- subC34A1(&_arrunkObj1337[3]._arr1[i], &_arrunkObj1337[3]._arr3[0]);
- }
- break;
- }
- }
-
- if (!found)
- return;
-
- int randIndx = R2_GLOBALS._randomSource.getRandomNumber(3);
-
- if (_arrunkObj1337[3]._arr1[randIndx]._field34 == 1) {
- found = false;
-
- for (int i = 0; i <= 7; i++) {
- if ((_arrunkObj1337[3]._arr2[i]._field34 == 0) && (!subC2687(_arrunkObj1337[3]._arr3[0]._field34))) {
- subC340B(&_arrunkObj1337[3]._arr1[randIndx], &_arrunkObj1337[3]._arr2[i]);
- found = true;
- break;
- }
- }
-
- if (found) {
- return;
- }
- } else if (_arrunkObj1337[3]._arr1[randIndx]._field34 <= 9) {
- found = false;
-
- for (int i = 0; i <= 7; i++) {
- if (_arrunkObj1337[3]._arr2[i]._field34 == _arrunkObj1337[3]._arr1[randIndx]._field34) {
- found = true;
- break;
- }
- }
-
- if (!found) {
- for (int i = 0; i <= 7; i++) {
- if ((_arrunkObj1337[3]._arr2[i]._field34 == 1) && (!subC2687(_arrunkObj1337[3]._arr3[i]._field34))) {
- int tmpVal = 0;
-
- for (int j = 0; j <= 7; j++) {
- if ((_arrunkObj1337[3]._arr2[j]._field34 > 1) && (_arrunkObj1337[3]._arr2[j]._field34 <= 9))
- ++tmpVal;
- }
-
- if (tmpVal == 7)
- _field424A = 3;
-
- subC33C0(&_arrunkObj1337[3]._arr1[randIndx], &_arrunkObj1337[3]._arr2[i]);
- found = true;
- break;
- }
- }
- if (found)
- return;
- }
- } else if (_arrunkObj1337[3]._arr1[randIndx]._field34 == 13) {
- int tmpVal = subC331B(3);
-
- if (tmpVal != -1) {
- subC358E(&_arrunkObj1337[3]._arr1[randIndx], tmpVal);
- return;
- }
- } else if (_arrunkObj1337[3]._arr1[randIndx]._field34 == 25) {
- int tmpVal = -1;
- found = false;
- int tmpRandIndx = R2_GLOBALS._randomSource.getRandomNumber(3);
-
- for (int i = 0; i <= 3; i++) {
- if ( (tmpRandIndx != 3)
- && ( (_arrunkObj1337[tmpRandIndx]._arr1[0]._field34 != 0)
- || (_arrunkObj1337[tmpRandIndx]._arr1[1]._field34 != 0)
- || (_arrunkObj1337[tmpRandIndx]._arr1[2]._field34 != 0)
- || (_arrunkObj1337[tmpRandIndx]._arr1[3]._field34 != 0) )) {
- tmpVal = tmpRandIndx;
- break;
- }
-
- ++tmpRandIndx;
- if (tmpRandIndx > 3)
- tmpRandIndx = 0;
- }
-
- if (tmpVal != -1) {
- subC318B(3, &_arrunkObj1337[3]._arr1[randIndx], tmpVal);
- return;
- }
- } else {
- switch (_arrunkObj1337[3]._arr1[randIndx]._field34) {
- case 10:
- // No break on purpose
- case 11:
- // No break on purpose
- case 12:
- // No break on purpose
- case 14:
- // No break on purpose
- case 15:
- // No break on purpose
- case 16:
- // No break on purpose
- case 17:
- // No break on purpose
- case 18:
- // No break on purpose
- case 19:
- // No break on purpose
- case 20:
- // No break on purpose
- case 21:
- // No break on purpose
- case 24: {
- int tmpVal = -1;
- int tmpRandIndx = R2_GLOBALS._randomSource.getRandomNumber(3);
-
- for (int i = 0; i <= 3; i++) {
- if (tmpRandIndx != 3) {
- // The variables 'i' and 'j' are not used in the inner code of the loop.
- // It's understandable for 'i', which helps making sure that tmpVal is used properly,
- // but it's suspect for j
- for (int j = 0; j <= 7; j++) {
- if ((_arrunkObj1337[tmpRandIndx]._arr3[0]._field34 == 0) && (subC32B1(tmpRandIndx, _arrunkObj1337[3]._arr1[randIndx]._field34))) {
- tmpVal = j;
- }
- }
- }
-
- ++tmpRandIndx;
- if (tmpRandIndx > 3)
- tmpRandIndx = 0;
-
- if (tmpVal != -1)
- break;
- }
-
- if (tmpVal != -1) {
- // Useless second identical check skipped
- subC3456(&_arrunkObj1337[3]._arr1[randIndx], &_arrunkObj1337[tmpVal]._arr3[0]);
- return;
- }
- }
- default:
- break;
- }
+ break;
}
-
- subC4A39(&_arrunkObj1337[3]._arr1[randIndx]);
}
-void Scene1337::subC318B(int arg1, unkObj1337sub1 *subObj1, int arg3) {
- _field4240 = arg1;
- _field4242 = arg3;
+void Scene1337::playThieftCard(int playerId, Card *card, int victimId) {
+ _actionIdx1 = playerId;
+ _actionIdx2 = victimId;
int randIndx;
for (;;) {
randIndx = R2_GLOBALS._randomSource.getRandomNumber(3);
- if (_arrunkObj1337[arg3]._arr1[randIndx]._field34 != 0)
+ if (_gameBoardSide[victimId]._handCard[randIndx]._cardId != 0)
break;
}
- _field3EF0 = subObj1;
- _field3EF4 = &_arrunkObj1337[arg3]._arr4[0];
- _field3EF8 = &_arrunkObj1337[arg3]._arr1[randIndx];
+ _actionCard1 = card;
+ _actionCard2 = &_gameBoardSide[victimId]._emptyStationPos;
+ _actionCard3 = &_gameBoardSide[victimId]._handCard[randIndx];
- _item1.setAction(&_action11);
+ _actionItem.setAction(&_action11);
}
-int Scene1337::subC3257(int arg1) {
+int Scene1337::getPreventionCardId(int cardId) {
int retVal;
- switch (arg1) {
+ switch (cardId) {
case 10:
retVal = 2;
break;
@@ -5099,152 +4930,147 @@ int Scene1337::subC3257(int arg1) {
return retVal;
}
-bool Scene1337::subC32B1(int arg1, int arg2) {
+bool Scene1337::isAttackPossible(int victimId, int cardId) {
for (int i = 0; i <= 7; i++) {
- if (_arrunkObj1337[arg1]._arr2[i]._field34 != 0) {
- int tmpVal = subC3257(arg2);
- if (tmpVal == _arrunkObj1337[arg1]._arr2[i]._field34)
+ if (_gameBoardSide[victimId]._outpostStation[i]._cardId != 0) {
+ if (getPreventionCardId(cardId) == _gameBoardSide[victimId]._outpostStation[i]._cardId)
return false;
}
}
return true;
}
-int Scene1337::subC331B(int arg1) {
- int randIndx = R2_GLOBALS._randomSource.getRandomNumber(3);
+int Scene1337::getPlayerWithOutpost(int playerId) {
+ int randPlayerId = R2_GLOBALS._randomSource.getRandomNumber(3);
for (int i = 0; i <= 3; i++) {
- if (randIndx != arg1) {
+ if (randPlayerId != playerId) {
for (int j = 0; j <= 7; j++) {
- if (_arrunkObj1337[randIndx]._arr2[j]._field34 != 0)
- return randIndx;
+ if (_gameBoardSide[randPlayerId]._outpostStation[j]._cardId != 0)
+ return randPlayerId;
}
}
- if (arg1 == 1) {
- randIndx--;
- if (randIndx < 0)
- randIndx = 3;
+ if (playerId == 1) {
+ randPlayerId--;
+ if (randPlayerId < 0)
+ randPlayerId = 3;
} else {
- ++randIndx;
- if (randIndx > 3)
- randIndx = 0;
+ ++randPlayerId;
+ if (randPlayerId > 3)
+ randPlayerId = 0;
}
}
return -1;
}
-bool Scene1337::subC3386(int arg1, int arg2) {
- if ((arg1 == 11) && (arg2 == 26))
+bool Scene1337::checkAntiDelayCard(int delayCardId, int cardId) {
+ if ((delayCardId == 11) && (cardId == 26))
return true;
- if ((arg1 == 14) && (arg2 == 30))
+ if ((delayCardId == 14) && (cardId == 30))
return true;
- if ((arg1 == 16) && (arg2 == 32))
+ if ((delayCardId == 16) && (cardId == 32))
return true;
- if ((arg1 == 24) && (arg2 == 28))
+ if ((delayCardId == 24) && (cardId == 28))
return true;
return false;
}
-void Scene1337::subC33C0(unkObj1337sub1 *subObj1, unkObj1337sub1 *subObj2) {
- _field3EF4 = subObj2;
- _field3EF0 = subObj1;
- _item1.setAction(&_action7);
+void Scene1337::playStationCard(Card *station, Card *platform) {
+ _actionCard1 = station;
+ _actionCard2 = platform;
+ _actionItem.setAction(&_action7);
}
-int Scene1337::subC3E92(int arg1) {
- if ( (_arrunkObj1337[arg1]._arr1[0]._field34 == 0)
- && (_arrunkObj1337[arg1]._arr1[1]._field34 == 0)
- && (_arrunkObj1337[arg1]._arr1[2]._field34 == 0)
- && (_arrunkObj1337[arg1]._arr1[3]._field34 == 0))
+int Scene1337::getFreeHandCard(int playerId) {
+ if ( (_gameBoardSide[playerId]._handCard[0]._cardId == 0)
+ && (_gameBoardSide[playerId]._handCard[1]._cardId == 0)
+ && (_gameBoardSide[playerId]._handCard[2]._cardId == 0)
+ && (_gameBoardSide[playerId]._handCard[3]._cardId == 0))
return -1;
int randIndx;
for (;;) {
randIndx = R2_GLOBALS._randomSource.getRandomNumber(3);
- if (_arrunkObj1337[arg1]._arr1[randIndx]._field34 == 0)
+ if (_gameBoardSide[playerId]._handCard[randIndx]._cardId == 0)
break;
}
return randIndx;
}
-void Scene1337::subC340B(unkObj1337sub1 *subObj1, unkObj1337sub1 *subObj2) {
- _field3EF0 = subObj1;
- _field3EF4 = subObj2;
+void Scene1337::playPlatformCard(Card *card, Card *dest) {
+ _actionCard1 = card;
+ _actionCard2 = dest;
- _item1.setAction(&_action6);
+ _actionItem.setAction(&_action6);
}
-void Scene1337::subC3456(unkObj1337sub1 *subObj1, unkObj1337sub1 *subObj2) {
- _field3EF0 = subObj1;
- _field3EF4 = subObj2;
+void Scene1337::playDelayCard(Card *card, Card *dest) {
+ _actionCard1 = card;
+ _actionCard2 = dest;
- _item1.setAction(&_action9);
+ _actionItem.setAction(&_action9);
}
-void Scene1337::subC34A1(unkObj1337sub1 *subObj1, unkObj1337sub1 *subObj2) {
- _field3EF0 = subObj1;
- _field3EF4 = subObj2;
+void Scene1337::playAntiDelayCard(Card *card, Card *dest) {
+ _actionCard1 = card;
+ _actionCard2 = dest;
+
+ _actionItem.setAction(&_action8);
- _item1.setAction(&_action8);
+ handleNextTurn();
}
-Scene1337::unkObj1337sub1 *Scene1337::subC34EC(int arg1) {
- for (int i = 0; i <= 7; i++) {
- if (_arrunkObj1337[arg1]._arr2[i]._field34 == 1) {
- return &_arrunkObj1337[arg1]._arr2[i];
- }
- }
+Scene1337::Card *Scene1337::getStationCard(int playerId) {
for (int i = 0; i <= 7; i++) {
- if ((_arrunkObj1337[arg1]._arr2[i]._field34 != 0) && (_arrunkObj1337[arg1]._arr2[i]._field34 < 10)) {
- return &_arrunkObj1337[arg1]._arr2[i];
- }
+ if ((_gameBoardSide[playerId]._outpostStation[i]._cardId >= 1) && (_gameBoardSide[playerId]._outpostStation[i]._cardId <= 9))
+ return &_gameBoardSide[playerId]._outpostStation[i];
}
- return NULL;
+ return nullptr;
}
-void Scene1337::subC358E(unkObj1337sub1 *subObj1, int arg2) {
- _field3EF0 = subObj1;
- _field3EF4 = subC34EC(arg2);
- _field3EF8 = &_arrunkObj1337[arg2]._arr4[0];
- _field4240 = arg2;
- _item1.setAction(&_action10);
+void Scene1337::playCounterTrickCard(Card *card, int playerId) {
+ _actionCard1 = card;
+ _actionCard2 = getStationCard(playerId);
+ _actionCard3 = &_gameBoardSide[playerId]._emptyStationPos;
+ _actionIdx1 = playerId;
+ _actionItem.setAction(&_action10);
+ handleNextTurn();
}
-void Scene1337::subC4A39(unkObj1337sub1 *subObj) {
- _field3EF0 = subObj;
+void Scene1337::discardCard(Card *card) {
+ _actionCard1 = card;
- _item1.setAction(&_action5);
+ _actionItem.setAction(&_action5);
}
void Scene1337::subC4CD2() {
if (R2_GLOBALS._v57709 > 0) {
subD1917();
- subD1940(false);
+ subD1940(false); // _v5780C--
}
}
void Scene1337::subC4CEC() {
- if (R2_GLOBALS._v57709 != 0)
- return;
-
- subD18F5();
- subD1940(1);
+ if (R2_GLOBALS._v57709 == 0) {
+ subD18F5();
+ subD1940(true); // _v5780C++
+ }
}
-void Scene1337::subC51A0(unkObj1337sub1 *subObj1, unkObj1337sub1 *subObj2) {
- _field3EF0 = subObj1;
- _field3EF4 = subObj2;
+void Scene1337::subC51A0(Card *subObj1, Card *subObj2) {
+ _actionCard1 = subObj1;
+ _actionCard2 = subObj2;
- _item1.setAction(&_action13);
+ _actionItem.setAction(&_action13);
}
void Scene1337::displayDialog(int dialogNumb) {
@@ -5348,8 +5174,8 @@ void Scene1337::displayDialog(int dialogNumb) {
void Scene1337::subPostInit() {
R2_GLOBALS._v57709 = 0;
R2_GLOBALS._v5780C = 0;
- subD183F(1, 0);
- subD1940(true);
+ updateCursorId(1, false);
+ subD1940(true); // _v5780C++
subD18F5();
// loadScene(1330);
@@ -5357,237 +5183,244 @@ void Scene1337::subPostInit() {
R2_GLOBALS._scenePalette.addRotation(224, 235, 1);
- _field3E28[0] = 1;
- _field3E28[1] = 1;
- _field3E28[2] = 1;
- _field3E28[3] = 1;
- _field3E28[4] = 1;
- _field3E28[5] = 1;
- _field3E28[6] = 1;
- _field3E28[7] = 1;
- _field3E28[8] = 26;
- _field3E28[9] = 2;
- _field3E28[10] = 2;
- _field3E28[11] = 2;
- _field3E28[12] = 2;
- _field3E28[13] = 2;
- _field3E28[14] = 26;
- _field3E28[15] = 3;
- _field3E28[16] = 3;
- _field3E28[17] = 3;
- _field3E28[18] = 3;
- _field3E28[19] = 3;
- _field3E28[20] = 28;
- _field3E28[21] = 4;
- _field3E28[22] = 4;
- _field3E28[23] = 4;
- _field3E28[24] = 4;
- _field3E28[25] = 4;
- _field3E28[26] = 28;
- _field3E28[27] = 5;
- _field3E28[28] = 5;
- _field3E28[29] = 5;
- _field3E28[30] = 5;
- _field3E28[31] = 5;
- _field3E28[32] = 30;
- _field3E28[33] = 6;
- _field3E28[34] = 6;
- _field3E28[35] = 6;
- _field3E28[36] = 6;
- _field3E28[37] = 6;
- _field3E28[38] = 30;
- _field3E28[39] = 7;
- _field3E28[40] = 7;
- _field3E28[41] = 7;
- _field3E28[42] = 7;
- _field3E28[43] = 7;
- _field3E28[44] = 32;
- _field3E28[45] = 8;
- _field3E28[46] = 8;
- _field3E28[47] = 8;
- _field3E28[48] = 8;
- _field3E28[49] = 8;
- _field3E28[50] = 32;
- _field3E28[51] = 9;
- _field3E28[52] = 9;
- _field3E28[53] = 9;
- _field3E28[54] = 9;
- _field3E28[55] = 9;
- _field3E28[56] = 10;
- _field3E28[57] = 11;
- _field3E28[58] = 12;
- _field3E28[59] = 13;
- _field3E28[60] = 13;
- _field3E28[61] = 14;
- _field3E28[62] = 15;
- _field3E28[63] = 16;
- _field3E28[64] = 17;
- _field3E28[65] = 18;
- _field3E28[66] = 19;
- _field3E28[67] = 20;
- _field3E28[68] = 21;
- _field3E28[69] = 26;
- _field3E28[70] = 28;
- _field3E28[71] = 24;
- _field3E28[72] = 25;
- _field3E28[73] = 25;
- _field3E28[74] = 25;
- _field3E28[75] = 25;
- _field3E28[76] = 26;
- _field3E28[77] = 26;
- _field3E28[78] = 26;
- _field3E28[79] = 27;
- _field3E28[80] = 27;
- _field3E28[81] = 28;
- _field3E28[82] = 28;
- _field3E28[83] = 28;
- _field3E28[84] = 29;
- _field3E28[85] = 29;
- _field3E28[86] = 29;
- _field3E28[87] = 30;
- _field3E28[88] = 30;
- _field3E28[89] = 30;
- _field3E28[90] = 30;
- _field3E28[91] = 32;
- _field3E28[92] = 1;
- _field3E28[93] = 32;
- _field3E28[94] = 32;
- _field3E28[95] = 32;
- _field3E28[96] = 1;
- _field3E28[97] = 1;
- _field3E28[98] = 1;
- _field3E28[99] = 0;
-
- _field3E24 = 98;
- _field3E26 = 98;
-
- _item7._field34 = 0;
- _item7._field36 = Common::Point(128, 95);
-
- _item8._field34 = 0;
- _item8._field36 = Common::Point(162, 95);
-
- _item6._field34 = 0;
-
- _item2._object1.postInit();
- _item2._object1.setVisage(1332);
- _item2._object1.setStrip(5);
- _item2._object1.setFrame(1);
- _item2._object1._moveDiff = Common::Point(10, 10);
- _item2._object1.fixPriority(400);
- _item2._object1.setPosition(Common::Point(128, 95), 0);
- _item2._object1.animate(ANIM_MODE_2, NULL);
- _item2._object1.hide();
-
- _object1.postInit();
- _object1.setVisage(1334);
- _object1.setStrip(1);
- _object1.setFrame(1);
- _object1._numFrames = 12;
- _object1.fixPriority(500);
- _object1.setPosition(Common::Point(174, 107), 0);
- _object1.animate(ANIM_MODE_2, NULL);
- _object1.hide();
-
- _field4244 = 1;
- _field4246 = 0;
- _field4248 = 0;
- _field424A = -1;
-
- _background1.setup2(9531, 1, 1, 249, 168, 155, 0);
+ _availableCardsPile[0] = 1;
+ _availableCardsPile[1] = 1;
+ _availableCardsPile[2] = 1;
+ _availableCardsPile[3] = 1;
+ _availableCardsPile[4] = 1;
+ _availableCardsPile[5] = 1;
+ _availableCardsPile[6] = 1;
+ _availableCardsPile[7] = 1;
+ _availableCardsPile[8] = 26;
+ _availableCardsPile[9] = 2;
+ _availableCardsPile[10] = 2;
+ _availableCardsPile[11] = 2;
+ _availableCardsPile[12] = 2;
+ _availableCardsPile[13] = 2;
+ _availableCardsPile[14] = 26;
+ _availableCardsPile[15] = 3;
+ _availableCardsPile[16] = 3;
+ _availableCardsPile[17] = 3;
+ _availableCardsPile[18] = 3;
+ _availableCardsPile[19] = 3;
+ _availableCardsPile[20] = 28;
+ _availableCardsPile[21] = 4;
+ _availableCardsPile[22] = 4;
+ _availableCardsPile[23] = 4;
+ _availableCardsPile[24] = 4;
+ _availableCardsPile[25] = 4;
+ _availableCardsPile[26] = 28;
+ _availableCardsPile[27] = 5;
+ _availableCardsPile[28] = 5;
+ _availableCardsPile[29] = 5;
+ _availableCardsPile[30] = 5;
+ _availableCardsPile[31] = 5;
+ _availableCardsPile[32] = 30;
+ _availableCardsPile[33] = 6;
+ _availableCardsPile[34] = 6;
+ _availableCardsPile[35] = 6;
+ _availableCardsPile[36] = 6;
+ _availableCardsPile[37] = 6;
+ _availableCardsPile[38] = 30;
+ _availableCardsPile[39] = 7;
+ _availableCardsPile[40] = 7;
+ _availableCardsPile[41] = 7;
+ _availableCardsPile[42] = 7;
+ _availableCardsPile[43] = 7;
+ _availableCardsPile[44] = 32;
+ _availableCardsPile[45] = 8;
+ _availableCardsPile[46] = 8;
+ _availableCardsPile[47] = 8;
+ _availableCardsPile[48] = 8;
+ _availableCardsPile[49] = 8;
+ _availableCardsPile[50] = 32;
+ _availableCardsPile[51] = 9;
+ _availableCardsPile[52] = 9;
+ _availableCardsPile[53] = 9;
+ _availableCardsPile[54] = 9;
+ _availableCardsPile[55] = 9;
+ _availableCardsPile[56] = 10;
+ _availableCardsPile[57] = 11;
+ _availableCardsPile[58] = 12;
+ _availableCardsPile[59] = 13;
+ _availableCardsPile[60] = 13;
+ _availableCardsPile[61] = 14;
+ _availableCardsPile[62] = 15;
+ _availableCardsPile[63] = 16;
+ _availableCardsPile[64] = 17;
+ _availableCardsPile[65] = 18;
+ _availableCardsPile[66] = 19;
+ _availableCardsPile[67] = 20;
+ _availableCardsPile[68] = 21;
+ _availableCardsPile[69] = 26;
+ _availableCardsPile[70] = 28;
+ _availableCardsPile[71] = 24;
+ _availableCardsPile[72] = 25;
+ _availableCardsPile[73] = 25;
+ _availableCardsPile[74] = 25;
+ _availableCardsPile[75] = 25;
+ _availableCardsPile[76] = 26;
+ _availableCardsPile[77] = 26;
+ _availableCardsPile[78] = 26;
+ _availableCardsPile[79] = 27;
+ _availableCardsPile[80] = 27;
+ _availableCardsPile[81] = 28;
+ _availableCardsPile[82] = 28;
+ _availableCardsPile[83] = 28;
+ _availableCardsPile[84] = 29;
+ _availableCardsPile[85] = 29;
+ _availableCardsPile[86] = 29;
+ _availableCardsPile[87] = 30;
+ _availableCardsPile[88] = 30;
+ _availableCardsPile[89] = 30;
+ _availableCardsPile[90] = 30;
+ _availableCardsPile[91] = 32;
+ _availableCardsPile[92] = 1;
+ _availableCardsPile[93] = 32;
+ _availableCardsPile[94] = 32;
+ _availableCardsPile[95] = 32;
+ _availableCardsPile[96] = 1;
+ _availableCardsPile[97] = 1;
+ _availableCardsPile[98] = 1;
+ _availableCardsPile[99] = 0;
+
+ _cardsAvailableNumb = 98;
+ _currentDiscardIndex = 98; // CHECKME: Would make more sense at pos 99
+
+ _discardPile._cardId = 0;
+ _discardPile._stationPos = Common::Point(128, 95);
+
+ _stockCard._cardId = 0;
+ _stockCard._stationPos = Common::Point(162, 95);
+
+ _selectedCard._cardId = 0;
+
+ _animatedCard._card.postInit();
+ _animatedCard._card.setVisage(1332);
+ _animatedCard._card.setStrip(5);
+ _animatedCard._card.setFrame(1);
+ _animatedCard._card._moveDiff = Common::Point(10, 10);
+ _animatedCard._card.fixPriority(400);
+ _animatedCard._card.setPosition(Common::Point(128, 95), 0);
+ _animatedCard._card.animate(ANIM_MODE_2, NULL);
+ _animatedCard._card.hide();
+
+ _currentPlayerArrow.postInit();
+ _currentPlayerArrow.setVisage(1334);
+ _currentPlayerArrow.setStrip(1);
+ _currentPlayerArrow.setFrame(1);
+ _currentPlayerArrow._numFrames = 12;
+ _currentPlayerArrow.fixPriority(500);
+ _currentPlayerArrow.setPosition(Common::Point(174, 107), 0);
+ _currentPlayerArrow.animate(ANIM_MODE_2, NULL);
+ _currentPlayerArrow.hide();
+
+ _showPlayerTurn = true;
+ _displayHelpFl = false;
+ _winnerId = -1;
+
+ _helpIcon.postInit();
+ _helpIcon.setup(9531, 1, 1);
+ _helpIcon.setPosition(Common::Point(249, 168));
+ _helpIcon.setPriority(155);
+ _helpIcon._effect = EFFECT_NONE;
+ _helpIcon.show();
_autoplay = false;
- _field424C = 0;
- _field424E = 0;
+ _instructionsDisplayedFl = false;
+ _instructionsWaitCount = 0;
}
void Scene1337::suggestInstructions() {
if (R2_GLOBALS._v57709 > 0)
subD1917();
+
if (MessageDialog::show(NEED_INSTRUCTIONS, NO_MSG, YES_MSG) == 0) {
if (R2_GLOBALS._v57709 == 0)
subD18F5();
- subCCF26();
+ dealCards();
} else {
if (R2_GLOBALS._v57709 == 0)
subD18F5();
- subCB59B();
+ displayInstructions();
}
}
-void Scene1337::subCB59B() {
- _item1.setAction(&_action1);
+void Scene1337::displayInstructions() {
+ _actionItem.setAction(&_action1);
}
void Scene1337::shuffleCards() {
R2_GLOBALS._sceneObjects->draw();
+ // Remove holes in card pile
for (int i = 0; i <= 98; i++) {
- if (_field3E28[i] == 0) {
+ if (_availableCardsPile[i] == 0) {
for (int j = i + 1; j <= 98; j ++) {
- if (_field3E28[j] != 0) {
- _field3E28[i] = _field3E28[j];
- _field3E28[j] = 0;
+ if (_availableCardsPile[j] != 0) {
+ _availableCardsPile[i] = _availableCardsPile[j];
+ _availableCardsPile[j] = 0;
break;
}
}
}
}
+ // Compute the number of available cards
for (int i = 0; i <= 99; i ++) {
- if (_field3E28[i] == 0) {
- _field3E24 = i - 1;
- _field3E26 = 98;
+ if (_availableCardsPile[i] == 0) {
+ // CHECKME: This will fail if i == 0, which shouldn't happen
+ // as we don't shuffle cards when no card is available.
+ _cardsAvailableNumb = i - 1;
+ _currentDiscardIndex = 98; // CHECKME: Would make more sense at pos 99
break;
}
}
- // tmpVal is never modified in the original. It looks weird but it works: at the end, the cards are suffled!
- int tmpVal = 0;
- int randIndx;
- int swap;
for (int i = 0; i < 2000; i ++) {
- randIndx = R2_GLOBALS._randomSource.getRandomNumber(_field3E24);
- swap = _field3E28[tmpVal];
- _field3E28[tmpVal] = _field3E28[randIndx];
- _field3E28[randIndx] = swap;
+ int randIndx = R2_GLOBALS._randomSource.getRandomNumber(_cardsAvailableNumb);
+ int swap = _availableCardsPile[0];
+ _availableCardsPile[0] = _availableCardsPile[randIndx];
+ _availableCardsPile[randIndx] = swap;
}
- _field423C = 0;
- _item2._object1.setAction(&_action2);
+ _shuffleEndedFl = false;
+
+ // Shuffle cards
+ _animatedCard._card.setAction(&_action2);
- while(_field423C == 0) {
+ while(!_shuffleEndedFl && !g_vm->shouldQuit()) {
+ g_globals->_sceneObjects->recurse(SceneHandler::dispatchObject);
g_globals->_scenePalette.signalListeners();
R2_GLOBALS._sceneObjects->draw();
- warning("TODO: recurse on draw() and on signalListeners()?");
g_globals->_events.delay(g_globals->_sceneHandler->_delayTicks);
-
- // Hack to avoid eternal loop
- // To be removed when the recurse is working properly
- _field423C = 1;
}
}
-void Scene1337::subCCF26() {
- _item2._object1._moveDiff = Common::Point(30, 30);
+void Scene1337::dealCards() {
+ _animatedCard._card._moveDiff = Common::Point(30, 30);
shuffleCards();
- _item1.setAction(&_action3);
+
+ // Deal cards
+ _actionItem.setAction(&_action3);
}
-void Scene1337::subCD193() {
- warning("STUBBED: subCD193()");
+
+void Scene1337::showOptionsDialog() {
+ // Display menu with "Auto Play", "New Game", "Quit" and "Continue"
+ OptionsDialog::show();
}
-void Scene1337::subCDB90(int arg1, Common::Point pt) {
+void Scene1337::handleClick(int arg1, Common::Point pt) {
bool found = false;
int curReg = R2_GLOBALS._sceneRegions.indexOf(g_globals->_events._mousePos);
if (arg1 == 3) {
int i;
for (i = 0; i <= 7; i++) {
- if ( (subC2BF8(&_arrunkObj1337[2]._arr2[i], pt))
- || (subC2BF8(&_arrunkObj1337[0]._arr2[i], pt))
- || (subC2BF8(&_arrunkObj1337[1]._arr2[i], pt))
- || (subC2BF8(&_arrunkObj1337[3]._arr2[i], pt)) ) {
+ if ( _gameBoardSide[2]._outpostStation[i].isIn(pt)
+ || _gameBoardSide[0]._outpostStation[i].isIn(pt)
+ || _gameBoardSide[1]._outpostStation[i].isIn(pt)
+ || _gameBoardSide[3]._outpostStation[i].isIn(pt) ) {
found = true;
break;
}
@@ -5596,124 +5429,114 @@ void Scene1337::subCDB90(int arg1, Common::Point pt) {
if (found) {
switch (curReg) {
case 5:
- if (_arrunkObj1337[2]._arr2[i]._field34 != 0)
- displayDialog(_arrunkObj1337[2]._arr2[i]._field34);
+ if (_gameBoardSide[2]._outpostStation[i]._cardId != 0)
+ displayDialog(_gameBoardSide[2]._outpostStation[i]._cardId);
else
actionDisplay(1330, 20, 159, 10, 1, 200, 0, 7, 0, 154, 154);
break;
case 10:
- if (_arrunkObj1337[3]._arr2[i]._field34 != 0)
- displayDialog(_arrunkObj1337[3]._arr2[i]._field34);
+ if (_gameBoardSide[3]._outpostStation[i]._cardId != 0)
+ displayDialog(_gameBoardSide[3]._outpostStation[i]._cardId);
else
actionDisplay(1330, 22, 159, 10, 1, 200, 0, 7, 0, 154, 154);
break;
case 15:
- if (_arrunkObj1337[0]._arr2[i]._field34 != 0)
- displayDialog(_arrunkObj1337[0]._arr2[i]._field34);
+ if (_gameBoardSide[0]._outpostStation[i]._cardId != 0)
+ displayDialog(_gameBoardSide[0]._outpostStation[i]._cardId);
else
actionDisplay(1330, 21, 159, 10, 1, 200, 0, 7, 0, 154, 154);
break;
case 20:
- if (_arrunkObj1337[1]._arr2[i]._field34 != 0)
- displayDialog(_arrunkObj1337[1]._arr2[i]._field34);
+ if (_gameBoardSide[1]._outpostStation[i]._cardId != 0)
+ displayDialog(_gameBoardSide[1]._outpostStation[i]._cardId);
else
actionDisplay(1330, 23, 159, 10, 1, 200, 0, 7, 0, 154, 154);
break;
default:
break;
}
- } else {
- if ( (subC2BF8(&_arrunkObj1337[2]._arr3[0], pt))
- || (subC2BF8(&_arrunkObj1337[0]._arr3[0], pt))
- || (subC2BF8(&_arrunkObj1337[1]._arr3[0], pt))
- || (subC2BF8(&_arrunkObj1337[3]._arr3[0], pt)) ) {
- found = true;
+ } else if ( _gameBoardSide[2]._delayCard.isIn(pt)
+ || _gameBoardSide[0]._delayCard.isIn(pt)
+ || _gameBoardSide[1]._delayCard.isIn(pt)
+ || _gameBoardSide[3]._delayCard.isIn(pt) ) {
+ switch (curReg) {
+ case 5:
+ if (_gameBoardSide[2]._delayCard._cardId != 0)
+ displayDialog(_gameBoardSide[2]._delayCard._cardId);
+ else
+ actionDisplay(1330, 10, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ break;
+ case 10:
+ if (_gameBoardSide[3]._delayCard._cardId != 0)
+ displayDialog(_gameBoardSide[3]._delayCard._cardId);
+ else
+ actionDisplay(1330, 16, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ break;
+ case 15:
+ if (_gameBoardSide[0]._delayCard._cardId != 0)
+ displayDialog(_gameBoardSide[0]._delayCard._cardId);
+ else
+ actionDisplay(1330, 13, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ break;
+ case 20:
+ if (_gameBoardSide[1]._delayCard._cardId != 0)
+ displayDialog(_gameBoardSide[1]._delayCard._cardId);
+ else
+ actionDisplay(1330, 18, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ break;
+ default:
+ break;
}
-
- if (found) {
- switch (curReg) {
- case 5:
- if (_arrunkObj1337[2]._arr3[0]._field34 != 0)
- displayDialog(_arrunkObj1337[2]._arr3[0]._field34);
- else
- actionDisplay(1330, 10, 159, 10, 1, 200, 0, 7, 0, 154, 154);
- break;
- case 10:
- if (_arrunkObj1337[3]._arr3[0]._field34 != 0)
- displayDialog(_arrunkObj1337[3]._arr3[0]._field34);
- else
- actionDisplay(1330, 16, 159, 10, 1, 200, 0, 7, 0, 154, 154);
- break;
- case 15:
- if (_arrunkObj1337[0]._arr3[0]._field34 != 0)
- displayDialog(_arrunkObj1337[3]._arr3[0]._field34);
- else
- actionDisplay(1330, 13, 159, 10, 1, 200, 0, 7, 0, 154, 154);
- break;
- case 20:
- if (_arrunkObj1337[1]._arr3[0]._field34 != 0)
- displayDialog(_arrunkObj1337[1]._arr3[0]._field34);
- else
- actionDisplay(1330, 18, 159, 10, 1, 200, 0, 7, 0, 154, 154);
- break;
- default:
- break;
- }
- } else {
- if (subC2BF8(&_item7, pt)) {
- if (_item7._field34 != 0)
- displayDialog(_item7._field34);
- else
- actionDisplay(1330, 7, 159, 10, 1, 200, 0, 7, 0, 154, 154);
- } else if (_background1._bounds.contains(pt)) {
- actionDisplay(1330, 43, 159, 10, 1, 200, 0, 7, 0, 154, 154);
- } else if (subC2BF8(&_item8, pt)) {
- actionDisplay(1330, 4, 159, 10, 1, 200, 0, 7, 0, 154, 154);
- } else if ( (subC2BF8(&_arrunkObj1337[2]._arr4[0], pt))
- || (subC2BF8(&_arrunkObj1337[3]._arr4[0], pt))
- || (subC2BF8(&_arrunkObj1337[0]._arr4[0], pt))
- || (subC2BF8(&_arrunkObj1337[1]._arr4[0], pt)) ) {
- actionDisplay(1330, 32, 159, 10, 1, 200, 0, 7, 0, 154, 154);
- } else {
- if (subC2BF8(&_arrunkObj1337[2]._arr1[0], pt))
- displayDialog(_arrunkObj1337[2]._arr1[0]._field34);
- else if (subC2BF8(&_arrunkObj1337[2]._arr1[1], pt))
- displayDialog(_arrunkObj1337[2]._arr1[1]._field34);
- else if (subC2BF8(&_arrunkObj1337[2]._arr1[2], pt))
- displayDialog(_arrunkObj1337[2]._arr1[2]._field34);
- else if (subC2BF8(&_arrunkObj1337[2]._arr1[3], pt))
- displayDialog(_arrunkObj1337[2]._arr1[3]._field34);
- else if ((curReg >= 6) && (curReg <= 9))
- actionDisplay(1330, 29, 159, 10, 1, 200, 0, 7, 0, 154, 154);
- else if ((curReg >= 11) && (curReg <= 14))
- actionDisplay(1330, 31, 159, 10, 1, 200, 0, 7, 0, 154, 154);
- else if ((curReg >= 16) && (curReg <= 19))
- actionDisplay(1330, 30, 159, 10, 1, 200, 0, 7, 0, 154, 154);
- else {
- switch (curReg) {
- case 0:
- actionDisplay(1330, 2, 159, 134, 1, 200, 0, 7, 0, 105, 105);
- break;
- case 5:
- actionDisplay(1330, 25, 159, 10, 1, 200, 0, 7, 0, 154, 154);
- break;
- case 10:
- actionDisplay(1330, 27, 159, 10, 1, 200, 0, 7, 0, 154, 154);
- break;
- case 15:
- actionDisplay(1330, 26, 159, 10, 1, 200, 0, 7, 0, 154, 154);
- break;
- case 20:
- actionDisplay(1330, 28, 159, 10, 1, 200, 0, 7, 0, 154, 154);
- break;
- case 21:
- actionDisplay(1330, 24, 159, 10, 1, 200, 0, 7, 0, 154, 154);
- break;
- default:
- break;
- }
- }
- }
+ } else if (_discardPile.isIn(pt)) {
+ if (_discardPile._cardId != 0)
+ displayDialog(_discardPile._cardId);
+ else
+ actionDisplay(1330, 7, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ } else if (_helpIcon._bounds.contains(pt))
+ actionDisplay(1330, 43, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ else if (_stockCard.isIn(pt))
+ actionDisplay(1330, 4, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ else if ( (_gameBoardSide[2]._emptyStationPos.isIn(pt))
+ || (_gameBoardSide[3]._emptyStationPos.isIn(pt))
+ || (_gameBoardSide[0]._emptyStationPos.isIn(pt))
+ || (_gameBoardSide[1]._emptyStationPos.isIn(pt)) )
+ actionDisplay(1330, 32, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ else if (_gameBoardSide[2]._handCard[0].isIn(pt))
+ displayDialog(_gameBoardSide[2]._handCard[0]._cardId);
+ else if (_gameBoardSide[2]._handCard[1].isIn(pt))
+ displayDialog(_gameBoardSide[2]._handCard[1]._cardId);
+ else if (_gameBoardSide[2]._handCard[2].isIn(pt))
+ displayDialog(_gameBoardSide[2]._handCard[2]._cardId);
+ else if (_gameBoardSide[2]._handCard[3].isIn(pt))
+ displayDialog(_gameBoardSide[2]._handCard[3]._cardId);
+ else if ((curReg >= 6) && (curReg <= 9))
+ actionDisplay(1330, 29, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ else if ((curReg >= 11) && (curReg <= 14))
+ actionDisplay(1330, 31, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ else if ((curReg >= 16) && (curReg <= 19))
+ actionDisplay(1330, 30, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ else {
+ switch (curReg) {
+ case 0:
+ actionDisplay(1330, 2, 159, 134, 1, 200, 0, 7, 0, 105, 105);
+ break;
+ case 5:
+ actionDisplay(1330, 25, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ break;
+ case 10:
+ actionDisplay(1330, 27, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ break;
+ case 15:
+ actionDisplay(1330, 26, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ break;
+ case 20:
+ actionDisplay(1330, 28, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ break;
+ case 21:
+ actionDisplay(1330, 24, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ break;
+ default:
+ break;
}
}
}
@@ -5722,8 +5545,8 @@ void Scene1337::subCDB90(int arg1, Common::Point pt) {
return;
for (int i = 0; i <= 7; i++) {
- if (subC2BF8(&_arrunkObj1337[2]._arr2[i], pt)) {
- switch (_arrunkObj1337[2]._arr2[i]._field34) {
+ if (_gameBoardSide[2]._outpostStation[i].isIn(pt)) {
+ switch (_gameBoardSide[2]._outpostStation[i]._cardId) {
case 0:
actionDisplay(1330, 11, 159, 10, 1, 200, 0, 7, 0, 154, 154);
break;
@@ -5734,10 +5557,10 @@ void Scene1337::subCDB90(int arg1, Common::Point pt) {
actionDisplay(1330, 34, 159, 10, 1, 200, 0, 7, 0, 154, 154);
break;
}
- found = true;
- break;
- } else if (subC2BF8(&_arrunkObj1337[0]._arr2[i], pt)) {
- switch (_arrunkObj1337[0]._arr2[i]._field34) {
+ return;
+ }
+ if (_gameBoardSide[0]._outpostStation[i].isIn(pt)) {
+ switch (_gameBoardSide[0]._outpostStation[i]._cardId) {
case 0:
actionDisplay(1330, 11, 159, 10, 1, 200, 0, 7, 0, 154, 154);
break;
@@ -5745,10 +5568,10 @@ void Scene1337::subCDB90(int arg1, Common::Point pt) {
actionDisplay(1330, 1, 159, 10, 1, 200, 0, 7, 0, 154, 154);
break;
}
- found = true;
- break;
- } else if (subC2BF8(&_arrunkObj1337[1]._arr2[i], pt)) {
- switch (_arrunkObj1337[1]._arr2[i]._field34) {
+ return;
+ }
+ if (_gameBoardSide[1]._outpostStation[i].isIn(pt)) {
+ switch (_gameBoardSide[1]._outpostStation[i]._cardId) {
case 0:
actionDisplay(1330, 146, 300, 99, 1, 136, 0, 7, 0, 117, 117);
break;
@@ -5756,10 +5579,10 @@ void Scene1337::subCDB90(int arg1, Common::Point pt) {
actionDisplay(1330, 144, 300, 99, 1, 136, 0, 7, 0, 117, 117);
break;
}
- found = true;
- break;
- } else if (subC2BF8(&_arrunkObj1337[3]._arr2[i], pt)) {
- switch (_arrunkObj1337[3]._arr2[i]._field34) {
+ return;
+ }
+ if (_gameBoardSide[3]._outpostStation[i].isIn(pt)) {
+ switch (_gameBoardSide[3]._outpostStation[i]._cardId) {
case 0:
actionDisplay(1330, 147, 20, 99, 1, 136, 0, 7, 0, 172, 172);
break;
@@ -5767,73 +5590,64 @@ void Scene1337::subCDB90(int arg1, Common::Point pt) {
actionDisplay(1330, 145, 20, 99, 1, 136, 0, 7, 0, 172, 172);
break;
}
- found = true;
- break;
+ return;
}
}
- if (subC2BF8(&_arrunkObj1337[2]._arr3[0], pt)) {
- if (_arrunkObj1337[0]._arr3[0]._field34 != 0) {
+ if (_gameBoardSide[2]._delayCard.isIn(pt)) {
+ // The original uses _gameBoardSide[0], which is obviously a bug.
+ if (_gameBoardSide[2]._delayCard._cardId != 0)
actionDisplay(1330, 39, 159, 10, 1, 200, 0, 7, 0, 154, 154);
- } else {
+ else
actionDisplay(1330, 11, 159, 10, 1, 200, 0, 7, 0, 154, 154);
- }
- found = true;
- }
- if (subC2BF8(&_arrunkObj1337[3]._arr3[0], pt)) {
- if (_arrunkObj1337[3]._arr3[0]._field34 != 0) {
+ return;
+ }
+ if (_gameBoardSide[3]._delayCard.isIn(pt)) {
+ if (_gameBoardSide[3]._delayCard._cardId != 0)
actionDisplay(1330, 145, 20, 99, 1, 136, 0, 7, 0, 172, 172);
- } else {
+ else
actionDisplay(1330, 147, 20, 99, 1, 136, 0, 7, 0, 172, 172);
- }
- found = true;
- }
- if (subC2BF8(&_arrunkObj1337[1]._arr3[0], pt)) {
- if (_arrunkObj1337[1]._arr3[0]._field34 != 0) {
+ return;
+ }
+ if (_gameBoardSide[1]._delayCard.isIn(pt)) {
+ if (_gameBoardSide[1]._delayCard._cardId != 0)
actionDisplay(1330, 144, 300, 99, 1, 136, 0, 7, 0, 117, 117);
- } else {
+ else
actionDisplay(1330, 146, 300, 99, 1, 136, 0, 7, 0, 117, 117);
- }
- found = true;
- }
- if (subC2BF8(&_arrunkObj1337[0]._arr3[0], pt)) {
- if (_arrunkObj1337[0]._arr3[0]._field34 != 0) {
+ return;
+ }
+ if (_gameBoardSide[0]._delayCard.isIn(pt)) {
+ if (_gameBoardSide[0]._delayCard._cardId != 0)
actionDisplay(1330, 1, 159, 10, 1, 200, 0, 7, 0, 154, 154);
- } else {
+ else
actionDisplay(1330, 11, 159, 10, 1, 200, 0, 7, 0, 154, 154);
- }
- found = true;
- }
- if (subC2BF8(&_arrunkObj1337[3]._arr4[0], pt)) {
+ return;
+ }
+ if (_gameBoardSide[3]._emptyStationPos.isIn(pt)) {
actionDisplay(1330, 147, 20, 99, 1, 136, 0, 7, 0, 172, 172);
- found = true;
+ return;
}
-
- if (subC2BF8(&_arrunkObj1337[1]._arr4[0], pt)) {
+ if (_gameBoardSide[1]._emptyStationPos.isIn(pt)) {
actionDisplay(1330, 146, 300, 99, 1, 136, 0, 7, 0, 117, 117);
- found = true;
+ return;
}
-
- if (subC2BF8(&_arrunkObj1337[0]._arr4[0], pt)) {
+ if (_gameBoardSide[0]._emptyStationPos.isIn(pt)) {
actionDisplay(1330, 11, 159, 10, 1, 200, 0, 7, 0, 154, 154);
- found = true;
- }
-
- if (found)
return;
+ }
- if (_background1._bounds.contains(pt)) {
- subCD193();
+ if (_helpIcon._bounds.contains(pt)) {
+ showOptionsDialog();
return;
}
- if (subC2BF8(&_item7, pt))
+ if (_discardPile.isIn(pt))
actionDisplay(1330, 9, 159, 10, 1, 200, 0, 7, 0, 154, 154);
- else if (subC2BF8(&_item8, pt))
+ else if (_stockCard.isIn(pt))
actionDisplay(1330, 5, 159, 10, 1, 200, 0, 7, 0, 154, 154);
else {
switch (curReg) {
@@ -5880,1064 +5694,1156 @@ void Scene1337::subCDB90(int arg1, Common::Point pt) {
}
}
-void Scene1337::subCF31D() {
- int tmpVal = 1;
- bool found;
- int count;
-
- if (this->_arrunkObj1337[1]._arr3[0]._field34 != 0) {
- switch (_arrunkObj1337[1]._arr3[0]._field34) {
+void Scene1337::handlePlayer0() {
+ if (_gameBoardSide[0]._delayCard._cardId != 0) {
+ switch (_gameBoardSide[0]._delayCard._cardId) {
case 10:
- // No break on purpose
+ //No break on purpose
case 12:
- // No break on purpose
+ //No break on purpose
case 15:
- // No break on purpose
+ //No break on purpose
case 17:
- // No break on purpose
+ //No break on purpose
case 18:
- // No break on purpose
+ //No break on purpose
case 19:
- // No break on purpose
+ //No break on purpose
case 20:
- // No break on purpose
+ //No break on purpose
case 21:
- tmpVal = 0;
- subC4A39(&_arrunkObj1337[1]._arr3[0]);
+ discardCard(&_gameBoardSide[0]._delayCard);
break;
default:
- found = false;
- int i;
- for (i = 0; i <= 3; i++) {
- if (subC3386(_arrunkObj1337[1]._arr3[0]._field34, _arrunkObj1337[1]._arr1[i]._field34)) {
- found = true;
- break;
+ for (int i = 0; i <= 3; i++) {
+ if (checkAntiDelayCard(_gameBoardSide[0]._delayCard._cardId, _gameBoardSide[0]._handCard[i]._cardId)) {
+ playAntiDelayCard(&_gameBoardSide[0]._handCard[i], &_gameBoardSide[0]._delayCard);
+ return;
}
}
- if (found) {
- tmpVal = 0;
- subC34A1(&_arrunkObj1337[1]._arr1[i], &_arrunkObj1337[1]._arr3[0]);
- }
+ break;
}
}
- if (tmpVal != 1)
- return;
-
- found = false;
for (int i = 0; i <= 3; i++) {
- int tmpIndx = subC26CB(1, i);
- if (tmpIndx == -1)
- break;
+ int tmpVal = getStationId(0, i);
- tmpVal = 0;
- for (int j = 0; j <= 7; j++) {
- if (_arrunkObj1337[1]._arr2[j]._field34 == _arrunkObj1337[1]._arr1[tmpIndx]._field34) {
- tmpVal = 1;
- break;
+ if (tmpVal != -1) {
+ bool stationAlreadyPresentFl = false;
+ for (int j = 0; j <= 7; j++) {
+ if (_gameBoardSide[0]._outpostStation[j]._cardId == _gameBoardSide[0]._handCard[tmpVal]._cardId) {
+ stationAlreadyPresentFl = true;
+ break;
+ }
}
- }
-
- if (tmpVal == 0)
- break;
- for (int j = 0; j <= 7; j++) {
- if (_arrunkObj1337[1]._arr2[j]._field34 == 1) {
- if (!subC2687(_arrunkObj1337[1]._arr3[0]._field34)) {
- count = 0;
- for (int k = 0; k <= 7; k++) {
- if ((_arrunkObj1337[1]._arr2[k]._field34 > 1) && (_arrunkObj1337[1]._arr2[k]._field34 <= 9))
- ++count;
- }
+ if (!stationAlreadyPresentFl) {
+ for (int j = 0; j <= 7; j++) {
+ if ((_gameBoardSide[0]._outpostStation[j]._cardId == 1) && !isStopConstructionCard(_gameBoardSide[0]._delayCard._cardId)) {
+ int stationCount = 0;
+ for (int k = 0; k <= 7; k++) {
+ if ((_gameBoardSide[0]._outpostStation[k]._cardId > 1) && (_gameBoardSide[0]._outpostStation[k]._cardId <= 9)) {
+ ++stationCount;
+ }
+ }
- if (count == 7)
- _field424A = 1;
+ if (stationCount == 7)
+ _winnerId = 0;
- subC33C0(&_arrunkObj1337[1]._arr1[tmpIndx], &_arrunkObj1337[1]._arr2[j]);
- found = true;
- break;
+ playStationCard(&_gameBoardSide[0]._handCard[tmpVal], &_gameBoardSide[0]._outpostStation[j]);
+ return;
+ }
}
}
}
}
- if (found)
- return;
+ int tmpVal = findPlatformCardInHand(0);
- tmpVal = subC2719(1);
if (tmpVal != -1) {
for (int i = 0; i <= 7; i++) {
- if ((_arrunkObj1337[1]._arr2[i]._field34 == 0) && (!subC2687(_arrunkObj1337[1]._arr3[0]._field34))) {
- subC340B(&_arrunkObj1337[1]._arr1[tmpVal], &_arrunkObj1337[1]._arr2[i]);
- found = true;
- break;
- }
+ if ((_gameBoardSide[0]._outpostStation[i]._cardId == 0) && !isStopConstructionCard(_gameBoardSide[0]._delayCard._cardId)) {
+ playPlatformCard(&_gameBoardSide[0]._handCard[tmpVal], &_gameBoardSide[0]._outpostStation[i]);
+ return;
+ }
}
}
- if (found)
- return;
-
- tmpVal = subC274D(1);
- int tmpVal2 = subC331B(1);
-
- if ((tmpVal != -1) && ( tmpVal2 != -1)) {
- subC358E(&_arrunkObj1337[1]._arr1[tmpVal], tmpVal2);
- found = true;
- }
-
- if (found)
- return;
-
- tmpVal = subC2781(1);
- if (tmpVal != -1) {
- count = -1;
- int rndVal = R2_GLOBALS._randomSource.getRandomNumber(3);
- for (int i = 0; i <= 3; i++) {
- if (rndVal != 1) {
- if ( (_arrunkObj1337[rndVal]._arr1[0]._field34 != 0)
- || (_arrunkObj1337[rndVal]._arr1[1]._field34 != 0)
- || (_arrunkObj1337[rndVal]._arr1[2]._field34 != 0)
- || (_arrunkObj1337[rndVal]._arr1[3]._field34 == 0)) {
- count = rndVal;
- break;
- }
-
- rndVal--;
- if (rndVal < 0)
- rndVal = 3;
+ int card13Id = findCard13InHand(0);
+ if (card13Id != -1) {
+ for (int i = 0; i <= 7; i++) {
+ if (_gameBoardSide[2]._outpostStation[i]._cardId != 0) {
+ playCounterTrickCard(&_gameBoardSide[0]._handCard[card13Id], 2);
+ return;
}
}
+ }
- if (count != -1) {
- subC318B(1, &_arrunkObj1337[1]._arr1[tmpVal], count);
- found = true;
+ int thieftId = checkThieftCard(0);
+ if (thieftId != -1) {
+ if ( (_gameBoardSide[2]._handCard[0]._cardId != 0)
+ || (_gameBoardSide[2]._handCard[1]._cardId != 0)
+ || (_gameBoardSide[2]._handCard[2]._cardId != 0)
+ || (_gameBoardSide[2]._handCard[3]._cardId != 0) ) {
+ playThieftCard(0, &_gameBoardSide[0]._handCard[thieftId], 2);
+ return;
}
}
- if (found)
- return;
+ for (int i = 0; i <= 3; i++) {
+ if ((isDelayCard(_gameBoardSide[0]._handCard[i]._cardId) != -1)
+ && (_gameBoardSide[2]._delayCard._cardId == 0)
+ && isAttackPossible(2, _gameBoardSide[0]._handCard[i]._cardId)) {
+ playDelayCard(&_gameBoardSide[0]._handCard[i], &_gameBoardSide[2]._delayCard);
+ return;
+ }
+ }
- count = -1;
- int i;
- for (i = 0; i <= 3; i++) {
- tmpVal = subC27B5(_arrunkObj1337[1]._arr1[i]._field34);
- if (tmpVal != -1) {
- int rndVal = R2_GLOBALS._randomSource.getRandomNumber(3);
+ for (int i = 0; i <= 3; i++) {
+ if ((getStationCardId(_gameBoardSide[0]._handCard[i]._cardId) != -1)
+ && (_gameBoardSide[2]._delayCard._cardId == 0)
+ && isAttackPossible(2, _gameBoardSide[0]._handCard[i]._cardId)) {
+ playDelayCard(&_gameBoardSide[0]._handCard[i], &_gameBoardSide[2]._delayCard);
+ return;
+ }
+ }
- for (int j = 0; j <= 3; j++) {
- if (tmpVal != 1) {
- for (int k = 0; k <= 7; k++) {
- // 'k' is not used in that loop.
- // It looks suspicious.
- if ((_arrunkObj1337[tmpVal]._arr3[0]._field34 == 0) && (subC32B1(tmpVal, _arrunkObj1337[1]._arr1[i]._field34))) {
- count = tmpVal;
- break;
- }
- }
- }
+ card13Id = findCard13InHand(0);
+ int victimPlayerId = getPlayerWithOutpost(0);
- if (count != -1) {
- found = true;
- break;
- } else {
- rndVal--;
- if (rndVal < 0)
- rndVal = 3;
- }
- }
+ if ((card13Id != -1) && (victimPlayerId != -1)) {
+ playCounterTrickCard(&_gameBoardSide[0]._handCard[card13Id], victimPlayerId);
+ return;
+ }
- if (found)
- break;
+ thieftId = checkThieftCard(0);
+ if (thieftId != -1) {
+ if ( (_gameBoardSide[1]._handCard[0]._cardId != 0)
+ || (_gameBoardSide[1]._handCard[1]._cardId != 0)
+ || (_gameBoardSide[1]._handCard[2]._cardId != 0)
+ || (_gameBoardSide[1]._handCard[3]._cardId != 0) ) {
+ playThieftCard(0, &_gameBoardSide[0]._handCard[thieftId], 1);
+ return;
}
}
- if (found) {
- if (count == -1)
- return;
+ for (int i = 0; i <= 3; i++) {
+ if (getStationCardId(_gameBoardSide[0]._handCard[i]._cardId) != -1) {
+ if ((_gameBoardSide[1]._delayCard._cardId == 0) && isAttackPossible(1, _gameBoardSide[0]._handCard[i]._cardId)) {
+ playDelayCard(&_gameBoardSide[0]._handCard[i], &_gameBoardSide[1]._delayCard);
+ return;
+ }
- subC3456(&_arrunkObj1337[1]._arr1[i], &_arrunkObj1337[count]._arr3[0]);
- } else {
- int j;
- for (j = 0; j <= 3; j++) {
- if (subC27F9(_arrunkObj1337[1]._arr1[j]._field34) != -1) {
- count = -1;
- int rndVal = R2_GLOBALS._randomSource.getRandomNumber(3);
- for (int l = 0; l <= 3; l++) {
- if (rndVal != 1) {
- for (int m = 0; m <= 7; m++) {
- // 'm' is not used in that loop. It looks suspicious.
- if ((_arrunkObj1337[rndVal]._arr3[0]._field34 == 0) && (_arrunkObj1337[1]._arr1[j]._field34 == 1)) {
- count = rndVal;
- break;
- }
- }
- }
- if (count != -1) {
- found = true;
- break;
- } else {
- rndVal--;
- if (rndVal < 0)
- rndVal = 3;
- }
- }
- if (found)
- break;
+ if ((_gameBoardSide[3]._delayCard._cardId == 0) && isAttackPossible(3, _gameBoardSide[0]._handCard[i]._cardId)) {
+ playDelayCard(&_gameBoardSide[0]._handCard[i], &_gameBoardSide[3]._delayCard);
+ return;
}
}
+ }
- if (found) {
- if (count == -1)
+ for (int i = 0; i <= 3; i++) {
+ tmpVal = isDelayCard(_gameBoardSide[0]._handCard[i]._cardId);
+ if (tmpVal != -1) {
+ if ((_gameBoardSide[1]._delayCard._cardId == 0) && isAttackPossible(1, _gameBoardSide[0]._handCard[i]._cardId)) {
+ playDelayCard(&_gameBoardSide[0]._handCard[i], &_gameBoardSide[1]._delayCard);
return;
+ }
- subC3456(&_arrunkObj1337[1]._arr1[j], &_arrunkObj1337[count]._arr3[0]);
- } else {
- subC2835(1);
+ if ((_gameBoardSide[3]._delayCard._cardId == 0) && isAttackPossible(3, _gameBoardSide[0]._handCard[i]._cardId)) {
+ playDelayCard(&_gameBoardSide[0]._handCard[i], &_gameBoardSide[3]._delayCard);
+ return;
+ }
}
}
+ handlePlayer01Discard(0);
}
-void Scene1337::subCF979() {
- bool found = true;
-
- if (_arrunkObj1337[0]._arr3[0]._field34 != 0) {
- switch (_arrunkObj1337[0]._arr3[0]._field34) {
+void Scene1337::handlePlayer1() {
+ if (this->_gameBoardSide[1]._delayCard._cardId != 0) {
+ switch (_gameBoardSide[1]._delayCard._cardId) {
case 10:
- //No break on purpose
+ // No break on purpose
case 12:
- //No break on purpose
+ // No break on purpose
case 15:
- //No break on purpose
+ // No break on purpose
case 17:
- //No break on purpose
+ // No break on purpose
case 18:
- //No break on purpose
+ // No break on purpose
case 19:
- //No break on purpose
+ // No break on purpose
case 20:
- //No break on purpose
+ // No break on purpose
case 21:
- subC4A39(&_arrunkObj1337[0]._arr3[0]);
- found = false;
- break;
+ discardCard(&_gameBoardSide[1]._delayCard);
+ return;
default:
- int i;
- found = false;
-
- for (i = 0; i <= 3; i++) {
- if (subC3386(_arrunkObj1337[0]._arr3[0]._field34, _arrunkObj1337[0]._arr1[i]._field34)) {
- found = true;
- break;
+ for (int i = 0; i <= 3; i++) {
+ if (checkAntiDelayCard(_gameBoardSide[1]._delayCard._cardId, _gameBoardSide[1]._handCard[i]._cardId)) {
+ playAntiDelayCard(&_gameBoardSide[1]._handCard[i], &_gameBoardSide[1]._delayCard);
+ return;
}
}
-
- if (found) {
- found = false;
- subC34A1(&_arrunkObj1337[0]._arr1[i], &_arrunkObj1337[0]._arr3[0]);
- }
break;
}
}
- if (found)
- return;
-
- int tmpVal;
- found = false;
for (int i = 0; i <= 3; i++) {
- tmpVal = subC26CB(0, i);
-
- if (tmpVal != -1) {
- bool flag = false;
- for (int j = 0; j <= 7; j++) {
- if (_arrunkObj1337[0]._arr2[j]._field34 == _arrunkObj1337[0]._arr1[tmpVal]._field34) {
- flag = true;
- break;
- }
- }
-
- if (!flag) {
- for (int j = 0; j <= 7; j++) {
- if ((_arrunkObj1337[0]._arr2[j]._field34 == 1) && (!subC2687(_arrunkObj1337[0]._arr3[0]._field34))) {
- int count = 0;
- for (int k = 0; k <= 7; k++) {
- if ((_arrunkObj1337[0]._arr2[k]._field34 > 1) && (_arrunkObj1337[0]._arr2[k]._field34 <= 9)) {
- ++count;
- }
- }
-
- if (count == 7)
- _field424A = 0;
+ int tmpIndx = getStationId(1, i);
+ if (tmpIndx == -1)
+ break;
- subC33C0(&_arrunkObj1337[0]._arr1[tmpVal], &_arrunkObj1337[0]._arr2[j]);
- found = true;
- }
- }
+ int tmpVal = 0;
+ for (int j = 0; j <= 7; j++) {
+ if (_gameBoardSide[1]._outpostStation[j]._cardId == _gameBoardSide[1]._handCard[tmpIndx]._cardId) {
+ tmpVal = 1;
+ break;
}
}
- if (found)
+ if (tmpVal == 0)
break;
- }
- if (found)
- return;
+ for (int j = 0; j <= 7; j++) {
+ if ((_gameBoardSide[1]._outpostStation[j]._cardId == 1) && !isStopConstructionCard(_gameBoardSide[1]._delayCard._cardId)) {
+ int stationCount = 0;
+ for (int k = 0; k <= 7; k++) {
+ if ((_gameBoardSide[1]._outpostStation[k]._cardId > 1) && (_gameBoardSide[1]._outpostStation[k]._cardId <= 9))
+ ++stationCount;
+ }
- found = false;
- tmpVal = subC2719(0);
+ if (stationCount == 7)
+ _winnerId = 1;
- if (tmpVal != -1) {
- for (int i = 0; i <= 7; i++) {
- if ((_arrunkObj1337[0]._arr2[i]._field34 == 0) && (!subC2687(_arrunkObj1337[0]._arr3[0]._field34))) {
- subC340B(&_arrunkObj1337[0]._arr1[tmpVal], &_arrunkObj1337[0]._arr2[i]);
- found = true;
- break;
+ playStationCard(&_gameBoardSide[1]._handCard[tmpIndx], &_gameBoardSide[1]._outpostStation[j]);
+ return;
}
}
}
- if (found)
- return;
-
- tmpVal = subC274D(0);
- if (tmpVal != -1) {
+ int normalCardId = findPlatformCardInHand(1);
+ if (normalCardId != -1) {
for (int i = 0; i <= 7; i++) {
- if (_arrunkObj1337[2]._arr2[i]._field34 != 0) {
- subC358E(&_arrunkObj1337[0]._arr1[tmpVal], 2);
- found = true;
- break;
+ if ((_gameBoardSide[1]._outpostStation[i]._cardId == 0) && !isStopConstructionCard(_gameBoardSide[1]._delayCard._cardId)) {
+ playPlatformCard(&_gameBoardSide[1]._handCard[normalCardId], &_gameBoardSide[1]._outpostStation[i]);
+ return;
}
}
}
- if (found)
- return;
-
- tmpVal = subC2781(0);
- if (tmpVal != -1) {
- if ( (_arrunkObj1337[2]._arr1[0]._field34 != 0)
- || (_arrunkObj1337[2]._arr1[1]._field34 != 0)
- || (_arrunkObj1337[2]._arr1[2]._field34 != 0)
- || (_arrunkObj1337[2]._arr1[3]._field34 != 0) ) {
- subC318B(0, &_arrunkObj1337[0]._arr1[tmpVal], 2);
- found = true;
- }
- }
+ int card13Id = findCard13InHand(1);
+ int tmpVal2 = getPlayerWithOutpost(1);
- if (found)
+ if ((card13Id != -1) && (tmpVal2 != -1)) {
+ playCounterTrickCard(&_gameBoardSide[1]._handCard[card13Id], tmpVal2);
return;
+ }
- for (int i = 0; i <= 3; i++) {
- if (subC27B5(_arrunkObj1337[0]._arr1[i]._field34) != -1) {
- // The variable 'j' is not used in the inner code of the loop. It's suspect
- for (int j = 0; j <= 7; j++) {
- if ((_arrunkObj1337[2]._arr3[0]._field34 == 0) && (subC32B1(2, _arrunkObj1337[0]._arr1[i]._field34))) {
- subC3456(&_arrunkObj1337[0]._arr1[i], &_arrunkObj1337[2]._arr3[0]);
- found = true;
- break;
+ int thieftId = checkThieftCard(1);
+ if (thieftId != -1) {
+ int playerIdFound = -1;
+ int rndVal = R2_GLOBALS._randomSource.getRandomNumber(3);
+ for (int i = 0; i <= 3; i++) {
+ if (rndVal != 1) {
+ if ( (_gameBoardSide[rndVal]._handCard[0]._cardId != 0)
+ || (_gameBoardSide[rndVal]._handCard[1]._cardId != 0)
+ || (_gameBoardSide[rndVal]._handCard[2]._cardId != 0)
+ || (_gameBoardSide[rndVal]._handCard[3]._cardId == 0)) {
+ playerIdFound = rndVal;
+ break;
}
}
+ // The original was only updating in the rndVal block,
+ // which was a bug as the checks were stopping at this point
+ rndVal--;
+ if (rndVal < 0)
+ rndVal = 3;
+ }
- if (found)
- break;
+ if (playerIdFound != -1) {
+ playThieftCard(1, &_gameBoardSide[1]._handCard[thieftId], playerIdFound);
+ return;
}
}
- if (found)
- return;
+ int count = -1;
+ int i;
+ for (i = 0; i <= 3; i++) {
+ int tmpVal = isDelayCard(_gameBoardSide[1]._handCard[i]._cardId);
+ if (tmpVal != -1) {
+ int rndVal = R2_GLOBALS._randomSource.getRandomNumber(3);
- for (int i = 0; i <= 3; i++) {
- if (subC27F9(_arrunkObj1337[0]._arr1[i]._field34) != -1) {
- // The variable 'j' is not used in the inner code of the loop. It's suspect
- for (int j = 0; j <= 7; j++) {
- if ((_arrunkObj1337[2]._arr3[0]._field34 == 0) && (subC32B1(2, _arrunkObj1337[0]._arr1[i]._field34))) {
- subC3456(&_arrunkObj1337[0]._arr1[i], &_arrunkObj1337[2]._arr3[0]);
- found = true;
+ for (int j = 0; j <= 3; j++) {
+ //CHECKME: tmpVal or rndVal?
+ if (tmpVal != 1) {
+ if ((_gameBoardSide[tmpVal]._delayCard._cardId == 0) && isAttackPossible(tmpVal, _gameBoardSide[1]._handCard[i]._cardId))
+ count = tmpVal;
}
- }
- if (found)
- break;
+ if (count != -1) {
+ playDelayCard(&_gameBoardSide[1]._handCard[i], &_gameBoardSide[count]._delayCard);
+ return;
+ } else {
+ rndVal--;
+ if (rndVal < 0)
+ rndVal = 3;
+ }
+ }
}
}
- if (found)
- return;
-
- tmpVal = subC274D(0);
- int tmpVal2 = subC331B(0);
-
- if ((tmpVal != -1) && (tmpVal2 != -1)) {
- subC358E(&_arrunkObj1337[0]._arr1[tmpVal], tmpVal2);
- found = true;
+ int j;
+ for (j = 0; j <= 3; j++) {
+ if (getStationCardId(_gameBoardSide[1]._handCard[j]._cardId) != -1) {
+ count = -1;
+ int rndVal = R2_GLOBALS._randomSource.getRandomNumber(3);
+ for (int l = 0; l <= 3; l++) {
+ if (rndVal != 1) {
+ if ((_gameBoardSide[rndVal]._delayCard._cardId == 0) && (_gameBoardSide[1]._handCard[j]._cardId == 1))
+ count = rndVal;
+ }
+ if (count != -1) {
+ playDelayCard(&_gameBoardSide[1]._handCard[j], &_gameBoardSide[count]._delayCard);
+ return;
+ } else {
+ rndVal--;
+ if (rndVal < 0)
+ rndVal = 3;
+ }
+ }
+ }
}
- if (found)
- return;
+ handlePlayer01Discard(1);
+}
- tmpVal = subC2781(0);
- if (tmpVal != -1) {
- if ( (_arrunkObj1337[1]._arr1[0]._field34 != 0)
- || (_arrunkObj1337[1]._arr1[1]._field34 != 0)
- || (_arrunkObj1337[1]._arr1[2]._field34 != 0)
- || (_arrunkObj1337[1]._arr1[3]._field34 != 0) ) {
- subC318B(0, &_arrunkObj1337[0]._arr1[tmpVal], 1);
- found = true;
+void Scene1337::handlePlayer3() {
+ if (_gameBoardSide[3]._delayCard._cardId != 0) {
+ switch (_gameBoardSide[3]._delayCard._cardId) {
+ case 10:
+ // No break on purpose
+ case 12:
+ // No break on purpose
+ case 15:
+ // No break on purpose
+ case 17:
+ // No break on purpose
+ case 18:
+ // No break on purpose
+ case 19:
+ // No break on purpose
+ case 20:
+ // No break on purpose
+ case 21:
+ discardCard(&_gameBoardSide[3]._delayCard);
+ return;
+ default:
+ for (int i = 0; i <= 3; i++) {
+ if (checkAntiDelayCard(_gameBoardSide[3]._delayCard._cardId, _gameBoardSide[3]._handCard[i]._cardId)) {
+ playAntiDelayCard(&_gameBoardSide[3]._handCard[i], &_gameBoardSide[3]._delayCard);
+ return;
+ }
+ }
+ break;
}
}
- if (found)
- return;
+ int randIndx = R2_GLOBALS._randomSource.getRandomNumber(3);
- for (int i = 0; i <= 3; i++) {
- tmpVal = subC27F9(_arrunkObj1337[0]._arr1[i]._field34);
- if (tmpVal != -1) {
- // The variable 'j' is not used in the inner code of the loop. It's suspect.
- for (int j = 0; j <= 7; j++) {
- if ((_arrunkObj1337[1]._arr3[0]._field34 == 0) && (subC32B1(1, _arrunkObj1337[0]._arr1[i]._field34))) {
- subC3456(&_arrunkObj1337[0]._arr1[i], &_arrunkObj1337[1]._arr3[0]);
- found = true;
- }
+ if (_gameBoardSide[3]._handCard[randIndx]._cardId == 1) {
+ for (int i = 0; i <= 7; i++) {
+ if ((_gameBoardSide[3]._outpostStation[i]._cardId == 0) && !isStopConstructionCard(_gameBoardSide[3]._delayCard._cardId)) {
+ playPlatformCard(&_gameBoardSide[3]._handCard[randIndx], &_gameBoardSide[3]._outpostStation[i]);
+ return;
}
+ }
+ } else if (_gameBoardSide[3]._handCard[randIndx]._cardId <= 9) {
+ for (int i = 0; i <= 7; i++) {
+ if (_gameBoardSide[3]._outpostStation[i]._cardId == _gameBoardSide[3]._handCard[randIndx]._cardId) {
+ discardCard(&_gameBoardSide[3]._handCard[randIndx]);
+ return;
+ }
+ }
- if (!found) {
- // The variable 'j' is not used in the inner code of the loop. It's suspect.
+ for (int i = 0; i <= 7; i++) {
+ if ((_gameBoardSide[3]._outpostStation[i]._cardId == 1) && !isStopConstructionCard(_gameBoardSide[3]._delayCard._cardId)) {
+ int stationCount = 0;
for (int j = 0; j <= 7; j++) {
- if ((_arrunkObj1337[3]._arr3[0]._field34 == 0) && (subC32B1(3, _arrunkObj1337[0]._arr1[i]._field34))) {
- subC3456(&_arrunkObj1337[0]._arr1[i], &_arrunkObj1337[3]._arr3[0]);
- found = true;
- }
+ if ((_gameBoardSide[3]._outpostStation[j]._cardId > 1) && (_gameBoardSide[3]._outpostStation[j]._cardId <= 9))
+ ++stationCount;
}
- }
- if (found)
- break;
+ if (stationCount == 7)
+ _winnerId = 3;
+
+ playStationCard(&_gameBoardSide[3]._handCard[randIndx], &_gameBoardSide[3]._outpostStation[i]);
+ return;
+ }
}
- }
+ } else if (_gameBoardSide[3]._handCard[randIndx]._cardId == 13) {
+ int victimId = getPlayerWithOutpost(3);
- if (found)
- return;
+ if (victimId != -1) {
+ playCounterTrickCard(&_gameBoardSide[3]._handCard[randIndx], victimId);
+ return;
+ }
+ } else if (_gameBoardSide[3]._handCard[randIndx]._cardId == 25) {
+ int victimId = -1;
+ int tmpRandIndx = R2_GLOBALS._randomSource.getRandomNumber(3);
- for (int i = 0; i <= 3; i++) {
- tmpVal = subC27B5(_arrunkObj1337[0]._arr1[i]._field34);
- if (tmpVal != -1) {
- // The variable 'j' is not used in the inner code of the loop. It's suspect.
- for (int j = 0; j <= 7; j++) {
- if ((_arrunkObj1337[1]._arr3[0]._field34 == 0) && (subC32B1(1, _arrunkObj1337[0]._arr1[i]._field34))) {
- subC3456(&_arrunkObj1337[0]._arr1[i], &_arrunkObj1337[1]._arr3[0]);
- found = true;
- }
+ for (int i = 0; i <= 3; i++) {
+ if ( (tmpRandIndx != 3)
+ && ( (_gameBoardSide[tmpRandIndx]._handCard[0]._cardId != 0)
+ || (_gameBoardSide[tmpRandIndx]._handCard[1]._cardId != 0)
+ || (_gameBoardSide[tmpRandIndx]._handCard[2]._cardId != 0)
+ || (_gameBoardSide[tmpRandIndx]._handCard[3]._cardId != 0) )) {
+ victimId = tmpRandIndx;
+ break;
}
- if (!found) {
- // The variable 'j' is not used in the inner code of the loop. It's suspect.
- for (int j = 0; j <= 7; j++) {
- if ((_arrunkObj1337[3]._arr3[0]._field34 == 0) && (subC32B1(3, _arrunkObj1337[0]._arr1[i]._field34))) {
- subC3456(&_arrunkObj1337[0]._arr1[i], &_arrunkObj1337[3]._arr3[0]);
- found = true;
- }
+ ++tmpRandIndx;
+ if (tmpRandIndx > 3)
+ tmpRandIndx = 0;
+ }
+
+ if (victimId != -1) {
+ playThieftCard(3, &_gameBoardSide[3]._handCard[randIndx], victimId);
+ return;
+ }
+ } else {
+ switch (_gameBoardSide[3]._handCard[randIndx]._cardId) {
+ case 10:
+ // No break on purpose
+ case 11:
+ // No break on purpose
+ case 12:
+ // No break on purpose
+ case 14:
+ // No break on purpose
+ case 15:
+ // No break on purpose
+ case 16:
+ // No break on purpose
+ case 17:
+ // No break on purpose
+ case 18:
+ // No break on purpose
+ case 19:
+ // No break on purpose
+ case 20:
+ // No break on purpose
+ case 21:
+ // No break on purpose
+ case 24: {
+ int victimId = -1;
+ int tmpRandIndx = R2_GLOBALS._randomSource.getRandomNumber(3);
+
+ for (int i = 0; i <= 3; i++) {
+ if (tmpRandIndx != 3) {
+ if ((_gameBoardSide[tmpRandIndx]._delayCard._cardId == 0)
+ && isAttackPossible(tmpRandIndx, _gameBoardSide[3]._handCard[randIndx]._cardId))
+ victimId = tmpRandIndx;
}
+
+ ++tmpRandIndx;
+ if (tmpRandIndx > 3)
+ tmpRandIndx = 0;
+
+ if (victimId != -1)
+ break;
}
- if (found)
- break;
+ if (victimId != -1) {
+ // Useless second identical check skipped
+ playDelayCard(&_gameBoardSide[3]._handCard[randIndx], &_gameBoardSide[victimId]._delayCard);
+ return;
+ }
+ }
+ default:
+ break;
}
}
- if (found)
- return;
-
- subC2835(0);
-}
-
-void Scene1337::subD026D() {
- subD02CA();
+ discardCard(&_gameBoardSide[3]._handCard[randIndx]);
}
-void Scene1337::subD0281() {
- if (subC27F9(this->_arrunkObj1337[2]._arr3[0]._field34) == -1)
- _unkFctPtr412 = &Scene1337::subD026D;
+void Scene1337::handleAutoplayPlayer2() {
+ if (getStationCardId(this->_gameBoardSide[2]._delayCard._cardId) == -1)
+ _delayedFunction = &Scene1337::handlePlayer2;
else
- subC4A39(&_arrunkObj1337[2]._arr3[0]);
+ discardCard(&_gameBoardSide[2]._delayCard);
}
-void Scene1337::subD02CA() {
- _item6._field36 = g_globals->_events._mousePos;
+void Scene1337::handlePlayer2() {
+ _selectedCard._stationPos = g_globals->_events._mousePos;
if (R2_GLOBALS._v57810 == 200) {
- int di;
- for (di = 0; di < 4; di++) {
- if ((subC2BF8(&_arrunkObj1337[2]._arr1[di], _item6._field36) != 0) && (_arrunkObj1337[2]._arr1[di]._field34 != 0)) {
- _item6._field34 = _arrunkObj1337[2]._arr1[di]._field34;
- _item6._field36 = _arrunkObj1337[2]._arr1[di]._field36;
- // _item6._actorName = _arrunkObj1337[2]._arr1[di]._actorName;
- _item6._fieldE = _arrunkObj1337[2]._arr1[di]._fieldE;
- _item6._field10 = _arrunkObj1337[2]._arr1[di]._field10;
- warning("_item6._field12 = _arrunkObj1337[2]._arr1[di]._field12;");
- warning("_item6._field14 = _arrunkObj1337[2]._arr1[di]._field14;");
- warning("_item6._field16 = _arrunkObj1337[2]._arr1[di]._field16;");
- _item6._sceneRegionId = _arrunkObj1337[2]._arr1[di]._sceneRegionId;
- _item6._position = _arrunkObj1337[2]._arr1[di]._position;
- _item6._yDiff = _arrunkObj1337[2]._arr1[di]._yDiff;
- _item6._bounds = _arrunkObj1337[2]._arr1[di]._bounds;
- _item6._resNum = _arrunkObj1337[2]._arr1[di]._resNum;
- _item6._lookLineNum = _arrunkObj1337[2]._arr1[di]._lookLineNum;
- _item6._talkLineNum = _arrunkObj1337[2]._arr1[di]._talkLineNum;
- _item6._useLineNum = _arrunkObj1337[2]._arr1[di]._useLineNum;
- _item6._action = _arrunkObj1337[2]._arr1[di]._action;
- warning("_item6._field0 = _arrunkObj1337[2]._arr1[di]._field0;");
- _item6._object1._updateStartFrame = _arrunkObj1337[2]._arr1[di]._object1._updateStartFrame;
- _item6._object1._walkStartFrame = _arrunkObj1337[2]._arr1[di]._object1._walkStartFrame;
+ // Hand
+ int i;
+ for (i = 0; i < 4; i++) {
+ if ((_gameBoardSide[2]._handCard[i].isIn(_selectedCard._stationPos)) && (_gameBoardSide[2]._handCard[i]._cardId != 0)) {
+ Card *handcard = &_gameBoardSide[2]._handCard[i];
+ _selectedCard._cardId = handcard->_cardId;
+ _selectedCard._stationPos = handcard->_stationPos;
+ //warning("_selectedCard._actorName = handcard->_actorName;");
+ //warning("_selectedCard._fieldE = handcard->_fieldE;");
+ //warning("_selectedCard._field10 = handcard->_field10;");
+ //warning("_selectedCard._field12 = handcard->_field12;");
+ //warning("_selectedCard._field14 = handcard->_field14;");
+ //warning("_selectedCard._field16 = handcard->_field16;");
+ _selectedCard._sceneRegionId = handcard->_sceneRegionId;
+ _selectedCard._position = handcard->_position;
+ _selectedCard._yDiff = handcard->_yDiff;
+ _selectedCard._bounds = handcard->_bounds;
+ _selectedCard._resNum = handcard->_resNum;
+ _selectedCard._lookLineNum = handcard->_lookLineNum;
+ _selectedCard._talkLineNum = handcard->_talkLineNum;
+ _selectedCard._useLineNum = handcard->_useLineNum;
+ _selectedCard._action = handcard->_action;
+ //warning("_selectedCard._field0 = handcard->_field0;");
+ _selectedCard._card._updateStartFrame = handcard->_card._updateStartFrame;
+ _selectedCard._card._walkStartFrame = handcard->_card._walkStartFrame;
// _field2E is named _field3C in R2R
- _item6._object1._field2E = _arrunkObj1337[2]._arr1[di]._object1._field2E;
- _item6._object1._percent = _arrunkObj1337[2]._arr1[di]._object1._percent;
- _item6._object1._priority = _arrunkObj1337[2]._arr1[di]._object1._priority;
- _item6._object1._angle = _arrunkObj1337[2]._arr1[di]._object1._angle;
- _item6._object1._flags = _arrunkObj1337[2]._arr1[di]._object1._flags;
- _item6._object1._xe = _arrunkObj1337[2]._arr1[di]._object1._xe;
- _item6._object1._xs = _arrunkObj1337[2]._arr1[di]._object1._xs;
- _item6._object1._paneRects[0] = _arrunkObj1337[2]._arr1[di]._object1._paneRects[0];
- _item6._object1._paneRects[1] = _arrunkObj1337[2]._arr1[di]._object1._paneRects[1];
- _item6._object1._visage = _arrunkObj1337[2]._arr1[di]._object1._visage;
- _item6._object1._objectWrapper = _arrunkObj1337[2]._arr1[di]._object1._objectWrapper;
- _item6._object1._strip = _arrunkObj1337[2]._arr1[di]._object1._strip;
- _item6._object1._animateMode = _arrunkObj1337[2]._arr1[di]._object1._animateMode;
- _item6._object1._frame = _arrunkObj1337[2]._arr1[di]._object1._frame;
- _item6._object1._endFrame = _arrunkObj1337[2]._arr1[di]._object1._endFrame;
+ _selectedCard._card._oldPosition = handcard->_card._oldPosition;
+ _selectedCard._card._percent = handcard->_card._percent;
+ _selectedCard._card._priority = handcard->_card._priority;
+ _selectedCard._card._angle = handcard->_card._angle;
+ _selectedCard._card._flags = handcard->_card._flags;
+ _selectedCard._card._xe = handcard->_card._xe;
+ _selectedCard._card._xs = handcard->_card._xs;
+ _selectedCard._card._paneRects[0] = handcard->_card._paneRects[0];
+ _selectedCard._card._paneRects[1] = handcard->_card._paneRects[1];
+ _selectedCard._card._visage = handcard->_card._visage;
+ _selectedCard._card._objectWrapper = handcard->_card._objectWrapper;
+ _selectedCard._card._strip = handcard->_card._strip;
+ _selectedCard._card._animateMode = handcard->_card._animateMode;
+ _selectedCard._card._frame = handcard->_card._frame;
+ _selectedCard._card._endFrame = handcard->_card._endFrame;
// _field68 is named _field76 in R2R
- _item6._object1._field68 = _arrunkObj1337[2]._arr1[di]._object1._field68;
- _item6._object1._frameChange = _arrunkObj1337[2]._arr1[di]._object1._frameChange;
- _item6._object1._numFrames = _arrunkObj1337[2]._arr1[di]._object1._numFrames;
- _item6._object1._regionIndex = _arrunkObj1337[2]._arr1[di]._object1._regionIndex;
- _item6._object1._mover = _arrunkObj1337[2]._arr1[di]._object1._mover;
- _item6._object1._moveDiff = _arrunkObj1337[2]._arr1[di]._object1._moveDiff;
- _item6._object1._moveRate = _arrunkObj1337[2]._arr1[di]._object1._moveRate;
- _item6._object1._field8A = _arrunkObj1337[2]._arr1[di]._object1._field8A;
- _item6._object1._endAction = _arrunkObj1337[2]._arr1[di]._object1._endAction;
- _item6._object1._regionBitList = _arrunkObj1337[2]._arr1[di]._object1._regionBitList;
- // _item6._object1._actorName = _arrunkObj1337[2]._arr1[di]._object1._actorName;
- _item6._object1._fieldE = _arrunkObj1337[2]._arr1[di]._object1._fieldE;
- _item6._object1._field10 = _arrunkObj1337[2]._arr1[di]._object1._field10;
- warning("_item6._object1._field12 = _arrunkObj1337[2]._arr1[di]._object1._field12;");
- warning("_item6._object1._field14 = _arrunkObj1337[2]._arr1[di]._object1._field14;");
- warning("_item6._object1._field16 = _arrunkObj1337[2]._arr1[di]._object1._field16;");
- _item6._object1 = _arrunkObj1337[2]._arr1[di]._object1;
- }
- }
-
- if (di == 4) {
- subCDB90(1, _item6._field36);
- subD0281();
+ _selectedCard._card._loopCount = handcard->_card._loopCount;
+ _selectedCard._card._frameChange = handcard->_card._frameChange;
+ _selectedCard._card._numFrames = handcard->_card._numFrames;
+ _selectedCard._card._regionIndex = handcard->_card._regionIndex;
+ _selectedCard._card._mover = handcard->_card._mover;
+ _selectedCard._card._moveDiff = handcard->_card._moveDiff;
+ _selectedCard._card._moveRate = handcard->_card._moveRate;
+ _selectedCard._card._actorDestPos = handcard->_card._actorDestPos;
+ _selectedCard._card._endAction = handcard->_card._endAction;
+ _selectedCard._card._regionBitList = handcard->_card._regionBitList;
+ // _selectedCard._object1._actorName = handcard->_object1._actorName;
+ //warning("_selectedCard._card._fieldE = handcard->_card._fieldE;");
+ //warning("_selectedCard._card._field10 = handcard->_card._field10;");
+ //warning("_selectedCard._card._field12 = handcard->_card._field12;");
+ //warning("_selectedCard._card._field14 = handcard->_card._field14;");
+ //warning("_selectedCard._card._field16 = handcard->_card._field16;");
+
+ _gameBoardSide[2]._handCard[i]._cardId = 0;
+ _gameBoardSide[2]._handCard[i]._card.remove();
+ break;
+ }
+ }
+
+ if (i == 4) {
+ handleClick(1, _selectedCard._stationPos);
+ handleAutoplayPlayer2();
return;
+ } else {
+ setCursorData(1332, _selectedCard._card._strip, _selectedCard._card._frame);
+ R2_GLOBALS._sceneObjects->draw();
}
} else if (R2_GLOBALS._v57810 == 300) {
- subCDB90(3, _item6._field36);
- subD0281();
+ // Eye
+ handleClick(3, _selectedCard._stationPos);
+ handleAutoplayPlayer2();
return;
} else {
- subD1A48(R2_GLOBALS._v57810);
- subD0281();
+ // The original code is calling a function full of dead code.
+ // Only this message remains after a cleanup.
+ MessageDialog::show(WRONG_ANSWER_MSG, OK_BTN_STRING);
+ //
+ handleAutoplayPlayer2();
return;
}
- // That continues the block when R2_GLOBALS._v57810 == 200 and di != 4
- subD18B5(1332, _item6._object1._strip, _item6._object1._frame);
- R2_GLOBALS._sceneObjects->draw();
Event event;
- bool found = false;
- bool found_di;
+ bool found;
for (;;) {
if ( ((g_globals->_events.getEvent(event, EVENT_BUTTON_DOWN)) && (event.btnState == BTNSHIFT_RIGHT))
|| (g_globals->_events.getEvent(event, EVENT_KEYPRESS)) ){
- _item6._field36 = g_globals->_events._mousePos;
- found_di = false;
+ _selectedCard._stationPos = g_globals->_events._mousePos;
+ found = false;
for (int i = 0; i <= 3; i ++) {
- if (subC2BF8(&_arrunkObj1337[2]._arr1[i], Common::Point(_item6._field36.x + 12, _item6._field36.y + 12)) != 0) {
- if (_arrunkObj1337[2]._arr1[i]._field34 == 0) {
- _arrunkObj1337[2]._arr1[i]._field34 = _item6._field34;
- _arrunkObj1337[2]._arr1[i]._object1.postInit();
- _arrunkObj1337[2]._arr1[i]._object1.hide();
- _arrunkObj1337[2]._arr1[i]._object1.setVisage(1332);
- _arrunkObj1337[2]._arr1[i]._object1.setPosition(_arrunkObj1337[2]._arr1[i]._field36, 0);
- _arrunkObj1337[2]._arr1[i]._object1.fixPriority(170);
- setAnimationInfo(&_arrunkObj1337[2]._arr1[i]);
- subD18B5(5, 1, 4);
- found = true;
- _field423E--;
- _field4244 = 0;
- subC20F9();
+ if (_gameBoardSide[2]._handCard[i].isIn(Common::Point(_selectedCard._stationPos.x + 12, _selectedCard._stationPos.y + 12))) {
+ if (_gameBoardSide[2]._handCard[i]._cardId == 0) {
+ _gameBoardSide[2]._handCard[i]._cardId = _selectedCard._cardId;
+ _gameBoardSide[2]._handCard[i]._card.postInit();
+ _gameBoardSide[2]._handCard[i]._card.hide();
+ _gameBoardSide[2]._handCard[i]._card.setVisage(1332);
+ _gameBoardSide[2]._handCard[i]._card.setPosition(_gameBoardSide[2]._handCard[i]._stationPos, 0);
+ _gameBoardSide[2]._handCard[i]._card.fixPriority(170);
+ setAnimationInfo(&_gameBoardSide[2]._handCard[i]);
+ setCursorData(5, 1, 4);
+ _currentPlayerNumb--;
+ _showPlayerTurn = false;
+ handleNextTurn();
+ return;
} else {
actionDisplay(1330, 127, 159, 10, 1, 200, 0, 7, 0, 154, 154);
- found_di = true;
+ found = true;
}
break;
}
}
- if ((!found) && (!found_di)) {
- if (subC2BF8(&_item7, Common::Point(_item6._field36.x + 12, _item6._field36.y + 12)) != 0) {
- subC4A39(&_item6);
- } else if (!found) {
- bool foundVar4;
+ if (!found) {
+ if (_discardPile.isIn(Common::Point(_selectedCard._stationPos.x + 12, _selectedCard._stationPos.y + 12))) {
+ discardCard(&_selectedCard);
+ return;
+ } else if (_selectedCard._cardId == 1) {
+ bool isInCardFl = false;
int i;
- if (_item6._field34 == 1) {
- foundVar4 = false;
- for (i = 0; i <= 7; i++) {
- if (subC2BF8(&_arrunkObj1337[2]._arr2[i], Common::Point(_item6._field36.x + 12, _item6._field36.y + 12)) != 0) {
- foundVar4 = true;
- break;
- }
+ for (i = 0; i <= 7; i++) {
+ if (_gameBoardSide[2]._outpostStation[i].isIn(Common::Point(_selectedCard._stationPos.x + 12, _selectedCard._stationPos.y + 12))) {
+ isInCardFl = true;
+ break;
}
+ }
- if ((foundVar4) && (_arrunkObj1337[2]._arr2[i]._field34 == 0)) {
- if (subC27B5(_arrunkObj1337[2]._arr3[0]._field34) != -1) {
- actionDisplay(1330, 55, 159, 10, 1, 200, 0, 7, 0, 154, 154);
- } else {
- subC340B(&_item6, &_arrunkObj1337[2]._arr2[i]);
- return;
- }
+ if ((isInCardFl) && (_gameBoardSide[2]._outpostStation[i]._cardId == 0)) {
+ if (isDelayCard(_gameBoardSide[2]._delayCard._cardId) != -1) {
+ actionDisplay(1330, 55, 159, 10, 1, 200, 0, 7, 0, 154, 154);
} else {
- actionDisplay(1330, 56, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ playPlatformCard(&_selectedCard, &_gameBoardSide[2]._outpostStation[i]);
+ return;
+ }
+ } else {
+ actionDisplay(1330, 56, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ }
+ } else if (_selectedCard._cardId <= 9) {
+ bool isInCardFl = false;
+ int i;
+ for (i = 0; i <= 7; i++) {
+ if (_gameBoardSide[2]._outpostStation[i].isIn(Common::Point(_selectedCard._stationPos.x + 12, _selectedCard._stationPos.y + 12))) {
+ isInCardFl = true;
+ break;
}
- } else if (_item6._field34 <= 9) {
- foundVar4 = false;
- for (i = 0; i <= 7; i++) {
- if (subC2BF8(&_arrunkObj1337[2]._arr2[i], Common::Point(_item6._field36.x + 12, _item6._field36.y + 12)) != 0) {
- foundVar4 = true;
+ }
+ if ((isInCardFl) && (_gameBoardSide[2]._outpostStation[i]._cardId == 1)) {
+ isInCardFl = false;
+ for (int j = 0; j <= 7; j++) {
+ if (_selectedCard._cardId == _gameBoardSide[2]._outpostStation[j]._cardId) {
+ isInCardFl = true;
break;
}
}
- if ((foundVar4) && (_arrunkObj1337[2]._arr2[i]._field34 == 1)) {
- foundVar4 = false;
- int j;
- for (j = 0; j <= 7; j++) {
- if (_item6._field34 == _arrunkObj1337[2]._arr2[j]._field34) {
- foundVar4 = true;
- break;
- }
+ if (isInCardFl) {
+ // This station is already in place
+ actionDisplay(1330, 34, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ } else if (isDelayCard(_gameBoardSide[2]._delayCard._cardId) != -1) {
+ // You must eliminate your delay before you can play a station
+ actionDisplay(1330, 35, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ } else {
+ int stationCount = 0;
+ for (int k = 0; k <= 7; k++) {
+ if ((_gameBoardSide[2]._outpostStation[k]._cardId > 1) && (_gameBoardSide[2]._outpostStation[k]._cardId <= 9))
+ ++stationCount;
}
- if (foundVar4) {
- actionDisplay(1330, 34, 159, 10, 1, 200, 0, 7, 0, 154, 154);
- } else if (subC27B5(_arrunkObj1337[2]._arr3[0]._field34) != -1) {
- actionDisplay(1330, 35, 159, 10, 1, 200, 0, 7, 0, 154, 154);
- } else {
- if (j == 7)
- _field424A = 2;
- subC33C0(&_item6, &_arrunkObj1337[2]._arr2[i]);
- return;
+ if (stationCount == 7)
+ _winnerId = 2;
+
+ playStationCard(&_selectedCard, &_gameBoardSide[2]._outpostStation[i]);
+ return;
+ }
+ } else {
+ actionDisplay(1330, 37, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ }
+ } else if ((_selectedCard._cardId == 26) || (_selectedCard._cardId == 30) ||(_selectedCard._cardId == 32) || (_selectedCard._cardId == 28)) {
+ // Check anti-delay card
+ if (_gameBoardSide[2]._delayCard.isIn(Common::Point(_selectedCard._stationPos.x + 12, _selectedCard._stationPos.y + 12))) {
+ actionDisplay(1330, 42, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ } else if (checkAntiDelayCard(_gameBoardSide[2]._delayCard._cardId, _selectedCard._cardId)) {
+ playAntiDelayCard(&_selectedCard, &_gameBoardSide[2]._delayCard);
+ return;
+ } else {
+ if (_gameBoardSide[2]._delayCard._cardId != 0) {
+ switch (_gameBoardSide[2]._delayCard._cardId) {
+ case 11:
+ actionDisplay(1330, 68, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ break;
+ case 14:
+ actionDisplay(1330, 80, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ break;
+ case 16:
+ actionDisplay(1330, 84, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ break;
+ case 24:
+ actionDisplay(1330, 96, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ break;
+ default:
+ break;
}
} else {
- actionDisplay(1330, 37, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ actionDisplay(1330, 41, 159, 10, 1, 200, 0, 7, 0, 154, 154);
}
- } else {
- if ((_item6._field34 == 26) || (_item6._field34 == 30) ||(_item6._field34 == 32) || (_item6._field34 == 28)) {
- if (subC2BF8(&_arrunkObj1337[2]._arr3[0], Common::Point(_item6._field36.x + 12, _item6._field36.y + 12)) != 0) {
- actionDisplay(1330, 42, 159, 10, 1, 200, 0, 7, 0, 154, 154);
- } else if (!subC3386(_arrunkObj1337[2]._arr3[0]._field34, _item6._field34)) {
- if (_arrunkObj1337[2]._arr3[0]._field34 != 0) {
- switch (_arrunkObj1337[2]._arr3[0]._field34) {
- case 11:
- actionDisplay(1330, 68, 159, 10, 1, 200, 0, 7, 0, 154, 154);
- break;
- case 14:
- actionDisplay(1330, 80, 159, 10, 1, 200, 0, 7, 0, 154, 154);
- break;
- case 16:
- actionDisplay(1330, 84, 159, 10, 1, 200, 0, 7, 0, 154, 154);
- break;
- case 24:
- actionDisplay(1330, 96, 159, 10, 1, 200, 0, 7, 0, 154, 154);
- break;
- default:
- break;
- }
- } else {
- actionDisplay(1330, 41, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ }
+ } else if ((getStationCardId(_selectedCard._cardId) == -1) && (isDelayCard(_selectedCard._cardId) == -1)) {
+ if (_selectedCard._cardId == 13) {
+ if (_gameBoardSide[0]._emptyStationPos.isIn(Common::Point(_selectedCard._stationPos.x + 12, _selectedCard._stationPos.y + 12))) {
+ for (int k = 0; k <= 7; k++) {
+ if (_gameBoardSide[0]._outpostStation[k]._cardId != 0) {
+ playCounterTrickCard(&_selectedCard, 0);
+ return;
+ }
+ }
+ actionDisplay(1330, 74, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ } else if (_gameBoardSide[3]._emptyStationPos.isIn(Common::Point(_selectedCard._stationPos.x + 12, _selectedCard._stationPos.y + 12))) {
+ for (int k = 0; k <= 7; k++) {
+ if (_gameBoardSide[3]._outpostStation[k]._cardId != 0) {
+ playCounterTrickCard(&_selectedCard, 3);
+ return;
}
- } else {
- subC34A1(&_item6, &_arrunkObj1337[2]._arr3[0]);
- return;
}
+ actionDisplay(1330, 74, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ } else if (_gameBoardSide[1]._emptyStationPos.isIn(Common::Point(_selectedCard._stationPos.x + 12, _selectedCard._stationPos.y + 12))) {
+ for (int k = 0; k <= 7; k++) {
+ if (_gameBoardSide[1]._outpostStation[k]._cardId == 0) {
+ playCounterTrickCard(&_selectedCard, 1);
+ return;
+ }
+ }
+ actionDisplay(1330, 74, 159, 10, 1, 200, 0, 7, 0, 154, 154);
} else {
- if ((subC27F9(_item6._field34) == -1) && (subC27B5(_item6._field34) == -1)) {
- if (_item6._field34 == 13) {
- if (subC2BF8(&_arrunkObj1337[0]._arr4[0], Common::Point(_item6._field36.x + 12, _item6._field36.y + 12)) != 0) {
- for (int k = 0; k <= 7; k++) {
- if (_arrunkObj1337[0]._arr2[k]._field34 != 0) {
- found = true;
- subC358E(&_item6, 0);
- }
- }
-
- if (!found)
- actionDisplay(1330, 74, 159, 10, 1, 200, 0, 7, 0, 154, 154);
- } else if (subC2BF8(&_arrunkObj1337[3]._arr4[0], Common::Point(_item6._field36.x + 12, _item6._field36.y + 12)) != 0) {
- for (int k = 0; k <= 7; k++) {
- if (_arrunkObj1337[3]._arr2[k]._field34 != 0) {
- found = true;
- subC358E(&_item6, 3);
- }
- }
- if (!found)
- actionDisplay(1330, 74, 159, 10, 1, 200, 0, 7, 0, 154, 154);
- } else if (subC2BF8(&_arrunkObj1337[1]._arr4[0], Common::Point(_item6._field36.x + 12, _item6._field36.y + 12)) != 0) {
- for (int k = 0; k <= 7; k++) {
- if (_arrunkObj1337[1]._arr2[k]._field34 == 0) {
- found = true;
- subC358E(&_item6, 1);
- }
- }
- if (!found)
- actionDisplay(1330, 74, 159, 10, 1, 200, 0, 7, 0, 154, 154);
- } else {
- actionDisplay(1330, 128, 159, 10, 1, 200, 0, 7, 0, 154, 154);
- }
- } else if (_item6._field34 == 25) {
+ actionDisplay(1330, 128, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ }
+ } else if (_selectedCard._cardId == 25) {
+ if (_gameBoardSide[0]._emptyStationPos.isIn(Common::Point(_selectedCard._stationPos.x + 12, _selectedCard._stationPos.y + 12))) {
+ if ( (_gameBoardSide[0]._handCard[0]._cardId != 0)
+ || (_gameBoardSide[0]._handCard[1]._cardId != 0)
+ || (_gameBoardSide[0]._handCard[2]._cardId != 0)
+ || (_gameBoardSide[0]._handCard[3]._cardId != 0) ) {
int k;
- if (subC2BF8(&_arrunkObj1337[0]._arr4[0], Common::Point(_item6._field36.x + 12, _item6._field36.y + 12)) != 0) {
- if ( (_arrunkObj1337[0]._arr1[0]._field34 != 0)
- || (_arrunkObj1337[0]._arr1[1]._field34 != 0)
- || (_arrunkObj1337[0]._arr1[2]._field34 != 0)
- || (_arrunkObj1337[0]._arr1[3]._field34 != 0) ) {
- for (k = 0; k <= 3; k++){
- if (_arrunkObj1337[2]._arr1[k]._field34 == 0)
- break;
- }
- subC318B(2, &_arrunkObj1337[2]._arr1[k], 0);
- return;
- } else {
- actionDisplay(1330, 99, 159, 10, 1, 200, 0, 7, 0, 154, 154);
- }
- } else if (subC2BF8(&_arrunkObj1337[1]._arr4[0], Common::Point(_item6._field36.x + 12, _item6._field36.y + 12)) != 0) {
- if ( (_arrunkObj1337[1]._arr1[0]._field34 != 0)
- || (_arrunkObj1337[1]._arr1[1]._field34 != 0)
- || (_arrunkObj1337[1]._arr1[2]._field34 != 0)
- || (_arrunkObj1337[1]._arr1[3]._field34 != 0) ) {
- for (k = 0; k <= 3; k++){
- if (_arrunkObj1337[2]._arr1[k]._field34 == 0)
- break;
- }
- subC318B(2, &_arrunkObj1337[2]._arr1[k], 1);
- return;
- } else {
- actionDisplay(1330, 99, 159, 10, 1, 200, 0, 7, 0, 154, 154);
- }
- }
-
- if (subC2BF8(&_arrunkObj1337[3]._arr4[0], Common::Point(_item6._field36.x + 12, _item6._field36.y + 12)) != 0) {
- if ( (_arrunkObj1337[3]._arr1[0]._field34 != 0)
- || (_arrunkObj1337[3]._arr1[1]._field34 != 0)
- || (_arrunkObj1337[3]._arr1[2]._field34 != 0)
- || (_arrunkObj1337[3]._arr1[3]._field34 != 0) ) {
- for (k = 0; k <= 3; k++){
- if (_arrunkObj1337[2]._arr1[k]._field34 == 0)
- break;
- }
- subC318B(2, &_arrunkObj1337[2]._arr1[k], 3);
- return;
- } else {
- actionDisplay(1330, 99, 159, 10, 1, 200, 0, 7, 0, 154, 154);
- }
- } else {
- actionDisplay(1330, 129, 159, 10, 1, 200, 0, 7, 0, 154, 154);
- }
- } else if (_item6._field34 == 29) {
- actionDisplay(1330, 136, 159, 10, 1, 200, 0, 7, 0, 154, 154);
- } else if (_item6._field34 == 27) {
- actionDisplay(1330, 137, 159, 10, 1, 200, 0, 7, 0, 154, 154);
- }
- } else {
- if (subC2BF8(&_arrunkObj1337[0]._arr3[0], Common::Point(_item6._field36.x + 12, _item6._field36.y + 12)) != 0) {
- if (_arrunkObj1337[0]._arr3[0]._field34 != 0) {
- actionDisplay(1330, 15, 159, 10, 1, 200, 0, 7, 0, 154, 154);
- } else if (!subC32B1(0, _item6._field34)) {
- switch (_item6._field34) {
- case 10:
- actionDisplay(1330, 66, 159, 10, 1, 200, 0, 7, 0, 154, 154);
- break;
- case 12:
- actionDisplay(1330, 70, 159, 10, 1, 200, 0, 7, 0, 154, 154);
- break;
- case 15:
- actionDisplay(1330, 82, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ for (k = 0; k <= 3; k++){
+ if (_gameBoardSide[2]._handCard[k]._cardId == 0)
break;
- case 17:
- actionDisplay(1330, 86, 159, 10, 1, 200, 0, 7, 0, 154, 154);
- break;
- case 18:
- actionDisplay(1330, 88, 159, 10, 1, 200, 0, 7, 0, 154, 154);
- break;
- case 19:
- actionDisplay(1330, 90, 159, 10, 1, 200, 0, 7, 0, 154, 154);
- break;
- case 20:
- actionDisplay(1330, 92, 159, 10, 1, 200, 0, 7, 0, 154, 154);
- break;
- case 21:
- actionDisplay(1330, 94, 159, 10, 1, 200, 0, 7, 0, 154, 154);
- break;
- default:
- break;
- }
- } else {
- subC3456(&_item6, &_arrunkObj1337[0]._arr3[0]);
- found = true;
}
- } else if (subC2BF8(&_arrunkObj1337[3]._arr3[0], Common::Point(_item6._field36.x + 12, _item6._field36.y + 12)) != 0) {
- if (_arrunkObj1337[3]._arr3[0]._field34 != 0) {
- actionDisplay(1330, 17, 159, 10, 1, 200, 0, 7, 0, 154, 154);
- } else if (!subC32B1(3, _item6._field34)) {
- switch (_item6._field34) {
- case 10:
- actionDisplay(1330, 66, 159, 10, 1, 200, 0, 7, 0, 154, 154);
- break;
- case 12:
- actionDisplay(1330, 70, 159, 10, 1, 200, 0, 7, 0, 154, 154);
- break;
- case 15:
- actionDisplay(1330, 82, 159, 10, 1, 200, 0, 7, 0, 154, 154);
- break;
- case 17:
- actionDisplay(1330, 86, 159, 10, 1, 200, 0, 7, 0, 154, 154);
- break;
- case 18:
- actionDisplay(1330, 88, 159, 10, 1, 200, 0, 7, 0, 154, 154);
- break;
- case 19:
- actionDisplay(1330, 90, 159, 10, 1, 200, 0, 7, 0, 154, 154);
- break;
- case 20:
- actionDisplay(1330, 92, 159, 10, 1, 200, 0, 7, 0, 154, 154);
- break;
- case 21:
- actionDisplay(1330, 94, 159, 10, 1, 200, 0, 7, 0, 154, 154);
- break;
- default:
+ playThieftCard(2, &_gameBoardSide[2]._handCard[k], 0);
+ return;
+ } else {
+ actionDisplay(1330, 99, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ }
+ } else if (_gameBoardSide[1]._emptyStationPos.isIn(Common::Point(_selectedCard._stationPos.x + 12, _selectedCard._stationPos.y + 12))) {
+ if ( (_gameBoardSide[1]._handCard[0]._cardId != 0)
+ || (_gameBoardSide[1]._handCard[1]._cardId != 0)
+ || (_gameBoardSide[1]._handCard[2]._cardId != 0)
+ || (_gameBoardSide[1]._handCard[3]._cardId != 0) ) {
+ int k;
+ for (k = 0; k <= 3; k++){
+ if (_gameBoardSide[2]._handCard[k]._cardId == 0)
break;
- }
- } else {
- subC3456(&_item6, &_arrunkObj1337[3]._arr3[0]);
- found = true;
}
- } else if (subC2BF8(&_arrunkObj1337[1]._arr3[0], Common::Point(_item6._field36.x + 12, _item6._field36.y + 12)) != 0) {
- if (_arrunkObj1337[1]._arr3[0]._field34 != 0) {
- actionDisplay(1330, 19, 159, 10, 1, 200, 0, 7, 0, 154, 154);
- } else if (!subC32B1(1, _item6._field34)) {
- switch (_item6._field34) {
- case 10:
- actionDisplay(1330, 66, 159, 10, 1, 200, 0, 7, 0, 154, 154);
- break;
- case 12:
- actionDisplay(1330, 70, 159, 10, 1, 200, 0, 7, 0, 154, 154);
- break;
- case 15:
- actionDisplay(1330, 82, 159, 10, 1, 200, 0, 7, 0, 154, 154);
- break;
- case 17:
- actionDisplay(1330, 86, 159, 10, 1, 200, 0, 7, 0, 154, 154);
- break;
- case 18:
- actionDisplay(1330, 88, 159, 10, 1, 200, 0, 7, 0, 154, 154);
- break;
- case 19:
- actionDisplay(1330, 90, 159, 10, 1, 200, 0, 7, 0, 154, 154);
- break;
- case 20:
- actionDisplay(1330, 92, 159, 10, 1, 200, 0, 7, 0, 154, 154);
- break;
- case 21:
- actionDisplay(1330, 94, 159, 10, 1, 200, 0, 7, 0, 154, 154);
- break;
- default:
+ playThieftCard(2, &_gameBoardSide[2]._handCard[k], 1);
+ return;
+ } else {
+ actionDisplay(1330, 99, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ }
+ }
+
+ if (_gameBoardSide[3]._emptyStationPos.isIn(Common::Point(_selectedCard._stationPos.x + 12, _selectedCard._stationPos.y + 12))) {
+ if ( (_gameBoardSide[3]._handCard[0]._cardId != 0)
+ || (_gameBoardSide[3]._handCard[1]._cardId != 0)
+ || (_gameBoardSide[3]._handCard[2]._cardId != 0)
+ || (_gameBoardSide[3]._handCard[3]._cardId != 0) ) {
+ int k;
+ for (k = 0; k <= 3; k++){
+ if (_gameBoardSide[2]._handCard[k]._cardId == 0)
break;
- }
- } else {
- subC3456(&_item6, &_arrunkObj1337[1]._arr3[0]);
- found = true;
}
- } else {
- actionDisplay(1330, 38, 159, 10, 1, 200, 0, 7, 0, 154, 154);
- }
+ playThieftCard(2, &_gameBoardSide[2]._handCard[k], 3);
+ return;
+ } else {
+ actionDisplay(1330, 99, 159, 10, 1, 200, 0, 7, 0, 154, 154);
}
+ } else {
+ actionDisplay(1330, 129, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ }
+ } else if (_selectedCard._cardId == 29) {
+ // Interceptor cards are used to prevent collision
+ actionDisplay(1330, 136, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ } else if (_selectedCard._cardId == 27) {
+ actionDisplay(1330, 137, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ }
+ } else if (_gameBoardSide[0]._delayCard.isIn(Common::Point(_selectedCard._stationPos.x + 12, _selectedCard._stationPos.y + 12))) {
+ if (_gameBoardSide[0]._delayCard._cardId != 0) {
+ actionDisplay(1330, 15, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ } else if (!isAttackPossible(0, _selectedCard._cardId)) {
+ switch (_selectedCard._cardId) {
+ case 10:
+ actionDisplay(1330, 66, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ break;
+ case 12:
+ actionDisplay(1330, 70, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ break;
+ case 15:
+ actionDisplay(1330, 82, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ break;
+ case 17:
+ actionDisplay(1330, 86, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ break;
+ case 18:
+ actionDisplay(1330, 88, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ break;
+ case 19:
+ actionDisplay(1330, 90, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ break;
+ case 20:
+ actionDisplay(1330, 92, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ break;
+ case 21:
+ actionDisplay(1330, 94, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ break;
+ default:
+ break;
+ }
+ } else {
+ playDelayCard(&_selectedCard, &_gameBoardSide[0]._delayCard);
+ return;
+ }
+ } else if (_gameBoardSide[3]._delayCard.isIn(Common::Point(_selectedCard._stationPos.x + 12, _selectedCard._stationPos.y + 12))) {
+ if (_gameBoardSide[3]._delayCard._cardId != 0) {
+ actionDisplay(1330, 17, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ } else if (!isAttackPossible(3, _selectedCard._cardId)) {
+ switch (_selectedCard._cardId) {
+ case 10:
+ actionDisplay(1330, 66, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ break;
+ case 12:
+ actionDisplay(1330, 70, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ break;
+ case 15:
+ actionDisplay(1330, 82, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ break;
+ case 17:
+ actionDisplay(1330, 86, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ break;
+ case 18:
+ actionDisplay(1330, 88, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ break;
+ case 19:
+ actionDisplay(1330, 90, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ break;
+ case 20:
+ actionDisplay(1330, 92, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ break;
+ case 21:
+ actionDisplay(1330, 94, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ break;
+ default:
+ break;
+ }
+ } else {
+ playDelayCard(&_selectedCard, &_gameBoardSide[3]._delayCard);
+ return;
+ }
+ } else if (_gameBoardSide[1]._delayCard.isIn(Common::Point(_selectedCard._stationPos.x + 12, _selectedCard._stationPos.y + 12))) {
+ if (_gameBoardSide[1]._delayCard._cardId != 0) {
+ actionDisplay(1330, 19, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ } else if (!isAttackPossible(1, _selectedCard._cardId)) {
+ switch (_selectedCard._cardId) {
+ case 10:
+ actionDisplay(1330, 66, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ break;
+ case 12:
+ actionDisplay(1330, 70, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ break;
+ case 15:
+ actionDisplay(1330, 82, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ break;
+ case 17:
+ actionDisplay(1330, 86, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ break;
+ case 18:
+ actionDisplay(1330, 88, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ break;
+ case 19:
+ actionDisplay(1330, 90, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ break;
+ case 20:
+ actionDisplay(1330, 92, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ break;
+ case 21:
+ actionDisplay(1330, 94, 159, 10, 1, 200, 0, 7, 0, 154, 154);
+ break;
+ default:
+ break;
}
+ } else {
+ playDelayCard(&_selectedCard, &_gameBoardSide[1]._delayCard);
+ return;
}
+ } else {
+ actionDisplay(1330, 38, 159, 10, 1, 200, 0, 7, 0, 154, 154);
}
}
-
- if (found)
- return;
} else {
g_globals->_scenePalette.signalListeners();
R2_GLOBALS._sceneObjects->draw();
g_globals->_events.delay(g_globals->_sceneHandler->_delayTicks);
}
+
+ g_globals->_sceneObjects->recurse(SceneHandler::dispatchObject);
}
}
-void Scene1337::subD183F(int arg1, int arg2) {
+void Scene1337::updateCursorId(int cursorId, bool updateFl) {
if ((R2_GLOBALS._v57709 != 0) || (R2_GLOBALS._v5780C != 0))
return;
- R2_GLOBALS._v5780E = arg1 + arg2;
+ R2_GLOBALS._mouseCursorId = cursorId;
- if (arg2 != 0) {
- if (R2_GLOBALS._v5780E < 1)
- R2_GLOBALS._v5780E = 2;
+ if (updateFl) {
+ R2_GLOBALS._mouseCursorId++;
- if (R2_GLOBALS._v5780E > 2)
- R2_GLOBALS._v5780E = 1;
+ if (R2_GLOBALS._mouseCursorId < 1)
+ R2_GLOBALS._mouseCursorId = 2;
+
+ if (R2_GLOBALS._mouseCursorId > 2)
+ R2_GLOBALS._mouseCursorId = 1;
}
- if (R2_GLOBALS._v5780E == 1) {
+ // The original was using an intermediate function to call setCursorData.
+ // It has been removed to improve readability
+ if (R2_GLOBALS._mouseCursorId == 1) {
R2_GLOBALS._v57810 = 200;
- subD195F(1, 4);
- } else if (R2_GLOBALS._v5780E == 2) {
+ setCursorData(5, 1, 4);
+ } else if (R2_GLOBALS._mouseCursorId == 2) {
R2_GLOBALS._v57810 = 300;
- subD195F(1, 5);
+ setCursorData(5, 1, 5);
} else {
R2_GLOBALS._v57810 = 0;
- subD195F(0, 0);
+ setCursorData(5, 0, 0);
}
}
-void Scene1337::subD18B5(int resNum, int rlbNum, int arg3) {
- warning("STUBBED lvl3 Scene1337::subD18B5()");
+void Scene1337::setCursorData(int resNum, int rlbNum, int frameNum) {
+ _cursorCurRes = resNum;
+ _cursorCurStrip = rlbNum;
+ _cursorCurFrame = frameNum;
+
+ if (!frameNum) {
+ // Should be a hardcoded cursor displaying only a dot.
+ // FIXME: Use another cursor when possible
+ R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
+ } else {
+ // TODO: The original was using some ressource caching, which was useless and complex
+ // and which has been removed. This cursor behavior clearly made intensive use of this caching...
+ // We now have to find a way to cache these cursor pointers and avoid loading them multiple times per seconds
+ uint size;
+ byte *cursor = g_resourceManager->getSubResource(resNum, rlbNum, frameNum, &size);
+ // Decode the cursor
+ GfxSurface s = surfaceFromRes(cursor);
+
+ Graphics::Surface surface = s.lockSurface();
+ const byte *cursorData = (const byte *)surface.getPixels();
+ CursorMan.replaceCursor(cursorData, surface.w, surface.h, s._centroid.x, s._centroid.y, s._transColor);
+ s.unlockSurface();
+
+ DEALLOCATE(cursor);
+ }
}
-int Scene1337::subD18F5() {
+void Scene1337::subD18F5() {
if (R2_GLOBALS._v57709 == 0)
- // The cursor looks... very dummy
- // To be checked
- warning("TODO: CursorManager.setData(R2_GLOBALS.off_57705)");
+ R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
++R2_GLOBALS._v57709;
-
- return R2_GLOBALS._v57709;
}
-int Scene1337::subD1917() {
+void Scene1337::subD1917() {
if (R2_GLOBALS._v57709 != 0) {
R2_GLOBALS._v57709--;
- if (R2_GLOBALS._v57709 != 0)
- warning("FIXME: subD195F(_width, _data);");
+ if (R2_GLOBALS._v57709 != 0) {
+ // The original was using an intermediate function to call setCursorData.
+ // It has been removed to improve readability
+ setCursorData(5, _cursorCurStrip, _cursorCurFrame);
+ }
}
-
- return R2_GLOBALS._v57709;
}
-int Scene1337::subD1940(bool flag) {
+void Scene1337::subD1940(bool flag) {
if (flag)
++R2_GLOBALS._v5780C;
else if (R2_GLOBALS._v5780C != 0)
--R2_GLOBALS._v5780C;
-
- return R2_GLOBALS._v5780C;
-}
-
-void Scene1337::subD195F(int arg1, int arg2) {
- subD18B5(5, arg1, arg2);
}
void Scene1337::subD1975(int arg1, int arg2) {
warning("STUBBED lvl2 Scene1337::subD1975()");
}
-void Scene1337::subD1A48(int arg1) {
- int tmpVal = -1;
+void Scene1337::OptionsDialog::show() {
+ OptionsDialog *dlg = new OptionsDialog();
+ dlg->draw();
- switch (arg1) {
- case 200:
- tmpVal = 141;
- break;
- case 300:
- tmpVal = 142;
- break;
- default:
- MessageDialog::show(WRONG_ANSWER_MSG, OK_BTN_STRING);
- break;
- }
+ // Show the dialog
+ GfxButton *btn = dlg->execute(NULL);
- if (tmpVal == -1)
- return;
+ // Figure out the new selected character
+ if (btn == &dlg->_quitGame)
+ R2_GLOBALS._sceneManager.changeScene(125);
+ else if (btn == &dlg->_restartGame)
+ R2_GLOBALS._sceneManager.changeScene(1330);
+
+ // Remove the dialog
+ dlg->remove();
+ delete dlg;
+}
+
+Scene1337::OptionsDialog::OptionsDialog() {
+ // Set the elements text
+ Scene1337 *scene = (Scene1337 *)R2_GLOBALS._sceneManager._scene;
+ _autoplay.setText(scene->_autoplay ? AUTO_PLAY_ON : AUTO_PLAY_OFF);
+ _restartGame.setText(START_NEW_CARD_GAME);
+ _quitGame.setText(QUIT_CARD_GAME);
+ _continueGame.setText(CONTINUE_CARD_GAME);
+
+ // Set position of the elements
+ _autoplay._bounds.moveTo(5, 2);
+ _restartGame._bounds.moveTo(5, _autoplay._bounds.bottom + 2);
+ _quitGame._bounds.moveTo(5, _restartGame._bounds.bottom + 2);
+ _continueGame._bounds.moveTo(5, _quitGame._bounds.bottom + 2);
+
+ // Add the items to the dialog
+ addElements(&_autoplay, &_restartGame, &_quitGame, &_continueGame, NULL);
+
+ // Set the dialog size and position
+ frame();
+ _bounds.collapse(-6, -6);
+ setCenter(160, 100);
+}
+
+GfxButton *Scene1337::OptionsDialog::execute(GfxButton *defaultButton) {
+ _gfxManager.activate();
+
+ // Event loop
+ GfxButton *selectedButton = NULL;
+
+ bool breakFlag = false;
+ while (!g_vm->shouldQuit() && !breakFlag) {
+ Event event;
+ while (g_globals->_events.getEvent(event) && !breakFlag) {
+ // Adjust mouse positions to be relative within the dialog
+ event.mousePos.x -= _gfxManager._bounds.left;
+ event.mousePos.y -= _gfxManager._bounds.top;
+
+ for (GfxElementList::iterator i = _elements.begin(); i != _elements.end(); ++i) {
+ if ((*i)->process(event))
+ selectedButton = static_cast<GfxButton *>(*i);
+ }
+
+ if (selectedButton == &_autoplay) {
+ // Toggle Autoplay
+ selectedButton = NULL;
+ Scene1337 *scene = (Scene1337 *)R2_GLOBALS._sceneManager._scene;
+ scene->_autoplay = !scene->_autoplay;
+
+ _autoplay.setText(scene->_autoplay ? AUTO_PLAY_ON : AUTO_PLAY_OFF);
+ _autoplay.draw();
+ } else if (selectedButton) {
+ breakFlag = true;
+ break;
+ } else if (!event.handled) {
+ if ((event.eventType == EVENT_KEYPRESS) && (event.kbd.keycode == Common::KEYCODE_ESCAPE)) {
+ selectedButton = NULL;
+ breakFlag = true;
+ break;
+ }
+ }
+ }
+
+ g_system->delayMillis(10);
+ GLOBALS._screenSurface.updateScreen();
+ }
- actionDisplay(1330, tmpVal, -1, -1, 1, 220, 1, 5, 0, 105, 0);
+ _gfxManager.deactivate();
+ return selectedButton;
}
/*--------------------------------------------------------------------------
* Scene 1500 - Cutscene: Ship landing
*
*--------------------------------------------------------------------------*/
+
void Scene1500::postInit(SceneObjectList *OwnerList) {
loadScene(1500);
R2_GLOBALS._uiElements._active = false;
- R2_GLOBALS._v5589E.top = 0;
- R2_GLOBALS._v5589E.bottom = 200;
setZoomPercents(170, 13, 240, 100);
SceneExt::postInit();
+ R2_GLOBALS._interfaceY = SCREEN_HEIGHT;
+
scalePalette(65, 65, 65);
R2_GLOBALS._player.postInit();
R2_GLOBALS._player.hide();
R2_GLOBALS._player.disableControl();
- _actor2.postInit();
- _actor2.setup(1401, 1, 1);
- _actor2._effect = 5;
- _actor2.fixPriority(10);
- _actor2._field9C = _field312;
+ _starshipShadow.postInit();
+ _starshipShadow.setup(1401, 1, 1);
+ _starshipShadow._effect = EFFECT_SHADOW_MAP;
+ _starshipShadow.fixPriority(10);
+ _starshipShadow._shadowMap = _shadowPaletteMap;
- _actor1.postInit();
- _actor1.setup(1400, 1, 1);
- _actor1._moveDiff = Common::Point(1, 1);
- _actor1._linkedActor = &_actor2;
+ _starship.postInit();
+ _starship.setup(1400, 1, 1);
+ _starship._moveDiff = Common::Point(1, 1);
+ _starship._linkedActor = &_starshipShadow;
if (R2_GLOBALS._sceneManager._previousScene != 1010) {
- _actor4.postInit();
- _actor4.setup(1401, 2, 1);
- _actor4._effect = 5;
- _actor4.fixPriority(10);
- _actor4._field9C = _field312;
+ _smallShipShadow.postInit();
+ _smallShipShadow.setup(1401, 2, 1);
+ _smallShipShadow._effect = EFFECT_SHADOW_MAP;
+ _smallShipShadow.fixPriority(10);
+ _smallShipShadow._shadowMap = _shadowPaletteMap;
- _actor3.postInit();
- _actor3._moveRate = 30;
- _actor3._moveDiff = Common::Point(1, 1);
- _actor3._linkedActor = &_actor4;
+ _smallShip.postInit();
+ _smallShip._moveRate = 30;
+ _smallShip._moveDiff = Common::Point(1, 1);
+ _smallShip._linkedActor = &_smallShipShadow;
}
if (R2_GLOBALS._sceneManager._previousScene == 300) {
- _actor1.setPosition(Common::Point(189, 139), 5);
+ _starship.setPosition(Common::Point(189, 139), 5);
- _actor3.setup(1400, 1, 2);
- _actor3.setPosition(Common::Point(148, 108), 0);
+ _smallShip.setup(1400, 1, 2);
+ _smallShip.setPosition(Common::Point(148, 108), 0);
_sceneMode = 20;
R2_GLOBALS._sound1.play(110);
} else if (R2_GLOBALS._sceneManager._previousScene == 1550) {
- _actor1.setPosition(Common::Point(189, 139), 5);
+ _starship.setPosition(Common::Point(189, 139), 5);
- _actor3.setup(1400, 2, 1);
- _actor3.changeZoom(-1);
- _actor3.setPosition(Common::Point(298, 258), 5);
+ _smallShip.setup(1400, 2, 1);
+ _smallShip.changeZoom(-1);
+ _smallShip.setPosition(Common::Point(298, 258), 5);
_sceneMode = 10;
R2_GLOBALS._sound1.play(106);
} else {
- _actor1.setPosition(Common::Point(289, 239), -30);
+ _starship.setPosition(Common::Point(289, 239), -30);
_sceneMode = 0;
R2_GLOBALS._sound1.play(102);
}
+
signal();
}
void Scene1500::remove() {
- R2_GLOBALS._v5589E.top = 3;
- R2_GLOBALS._v5589E.bottom = 168;
R2_GLOBALS._uiElements._active = true;
+ R2_GLOBALS._uiElements._visible = true;
SceneExt::remove();
}
@@ -6949,8 +6855,8 @@ void Scene1500::signal() {
setAction(&_sequenceManager, this, 1, &R2_GLOBALS._player, NULL);
// No break on purpose
case 1:
- if (_actor1._yDiff < 50) {
- _actor1.setPosition(Common::Point(289, 239), _actor1._yDiff + 1);
+ if (_starship._yDiff < 50) {
+ _starship.setPosition(Common::Point(289, 239), _starship._yDiff + 1);
_sceneMode = 1;
}
setAction(&_sequenceManager, this, 1, &R2_GLOBALS._player, NULL);
@@ -6958,12 +6864,12 @@ void Scene1500::signal() {
case 2: {
Common::Point pt(189, 139);
NpcMover *mover = new NpcMover();
- _actor1.addMover(mover, &pt, this);
+ _starship.addMover(mover, &pt, this);
}
break;
case 3:
- if (_actor1._yDiff > 5) {
- _actor1.setPosition(Common::Point(189, 139), _actor1._yDiff - 1);
+ if (_starship._yDiff > 5) {
+ _starship.setPosition(Common::Point(189, 139), _starship._yDiff - 1);
_sceneMode = 3;
}
setAction(&_sequenceManager, this, 1, &R2_GLOBALS._player, NULL);
@@ -6982,7 +6888,7 @@ void Scene1500::signal() {
case 11: {
Common::Point pt(148, 108);
NpcMover *mover = new NpcMover();
- _actor3.addMover(mover, &pt, this);
+ _smallShip.addMover(mover, &pt, this);
}
break;
case 12:
@@ -6991,13 +6897,13 @@ void Scene1500::signal() {
case 21: {
Common::Point pt(-2, -42);
NpcMover *mover = new NpcMover();
- _actor3.addMover(mover, &pt, NULL);
+ _smallShip.addMover(mover, &pt, NULL);
signal();
}
break;
case 22:
- if (_actor1._yDiff < 50) {
- _actor1.setPosition(Common::Point(189, 139), _actor1._yDiff + 1);
+ if (_starship._yDiff < 50) {
+ _starship.setPosition(Common::Point(189, 139), _starship._yDiff + 1);
_sceneMode = 22;
}
setAction(&_sequenceManager, this, 1, &R2_GLOBALS._player, NULL);
@@ -7005,7 +6911,7 @@ void Scene1500::signal() {
case 23: {
Common::Point pt(-13, -61);
NpcMover *mover = new NpcMover();
- _actor1.addMover(mover, &pt, this);
+ _starship.addMover(mover, &pt, this);
}
break;
case 24:
@@ -7018,9 +6924,9 @@ void Scene1500::signal() {
void Scene1500::dispatch() {
if (_sceneMode > 10) {
- float yDiff = sqrt((float) (_actor3._position.x * _actor3._position.x) + (_actor3._position.y * _actor3._position.y));
+ float yDiff = sqrt((float) (_smallShip._position.x * _smallShip._position.x) + (_smallShip._position.y * _smallShip._position.y));
if (yDiff > 6)
- _actor3.setPosition(_actor3._position, (int) yDiff);
+ _smallShip.setPosition(_smallShip._position, (int) yDiff);
}
Scene::dispatch();
@@ -7030,6 +6936,7 @@ void Scene1500::dispatch() {
* Scene 1525 - Cutscene - Ship
*
*--------------------------------------------------------------------------*/
+
void Scene1525::postInit(SceneObjectList *OwnerList) {
loadScene(1525);
R2_GLOBALS._uiElements._active = false;
@@ -7069,9 +6976,10 @@ void Scene1525::signal() {
}
/*--------------------------------------------------------------------------
- * Scene 1530 - Cutscene - Elevator
+ * Scene 1530 - Cutscene - Crashing on Rimwall
*
*--------------------------------------------------------------------------*/
+
void Scene1530::postInit(SceneObjectList *OwnerList) {
if (R2_GLOBALS._sceneManager._previousScene == 1000)
loadScene(1650);
@@ -7082,6 +6990,7 @@ void Scene1530::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._uiElements._active = false;
SceneExt::postInit();
+ R2_GLOBALS._interfaceY = SCREEN_HEIGHT;
_stripManager.addSpeaker(&_quinnSpeaker);
_stripManager.addSpeaker(&_seekerSpeaker);
@@ -7105,15 +7014,15 @@ void Scene1530::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player._moveRate = 30;
R2_GLOBALS._player._moveDiff = Common::Point(4, 1);
- _actor2.postInit();
- _actor2.setup(1516, 7, 1);
- _actor2.setPosition(Common::Point(121, 41));
- _actor2.animate(ANIM_MODE_2, NULL);
+ _leftReactor.postInit();
+ _leftReactor.setup(1516, 7, 1);
+ _leftReactor.setPosition(Common::Point(121, 41));
+ _leftReactor.animate(ANIM_MODE_2, NULL);
- _actor3.postInit();
- _actor3.setup(1516, 8, 1);
- _actor3.setPosition(Common::Point(107, 116));
- _actor3.animate(ANIM_MODE_2, NULL);
+ _rightReactor.postInit();
+ _rightReactor.setup(1516, 8, 1);
+ _rightReactor.setPosition(Common::Point(107, 116));
+ _rightReactor.animate(ANIM_MODE_2, NULL);
R2_GLOBALS._player.disableControl();
Common::Point pt(480, 75);
@@ -7123,14 +7032,14 @@ void Scene1530::postInit(SceneObjectList *OwnerList) {
_sceneMode = 1;
} else {
- _actor1.postInit();
- _actor1._effect = 1;
+ _seeker.postInit();
+ _seeker._effect = EFFECT_SHADED;
R2_GLOBALS._player.postInit();
R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
R2_GLOBALS._player.disableControl();
- setAction(&_sequenceManager, this, 1530, &R2_GLOBALS._player, &_actor1, NULL);
+ setAction(&_sequenceManager, this, 1530, &R2_GLOBALS._player, &_seeker, NULL);
_sceneMode = 2;
}
@@ -7163,8 +7072,8 @@ void Scene1530::dispatch() {
int16 x = R2_GLOBALS._player._position.x;
int16 y = R2_GLOBALS._player._position.y;
- _actor2.setPosition(Common::Point(x - 39, y - 85));
- _actor3.setPosition(Common::Point(x - 53, y - 9));
+ _leftReactor.setPosition(Common::Point(x - 39, y - 85));
+ _rightReactor.setPosition(Common::Point(x - 53, y - 9));
Scene::dispatch();
}
@@ -7175,13 +7084,12 @@ void Scene1530::dispatch() {
*--------------------------------------------------------------------------*/
Scene1550::Junk::Junk() {
- _fieldA4 = _junkNumber = 0;
+ _junkNumber = 0;
}
void Scene1550::Junk::synchronize(Serializer &s) {
SceneActor::synchronize(s);
- s.syncAsSint16LE(_fieldA4);
s.syncAsSint16LE(_junkNumber);
}
@@ -7204,13 +7112,13 @@ bool Scene1550::Junk::startAction(CursorType action, Event &event) {
if (_visage == 1561) {
switch (_frame) {
case 2:
- SceneItem::display(1550, 23, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ SceneItem::display(1550, 23, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, LIST_END);
break;
case 3:
- SceneItem::display(1550, 26, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ SceneItem::display(1550, 26, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, LIST_END);
break;
case 4:
- SceneItem::display(1550, 35, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ SceneItem::display(1550, 35, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, LIST_END);
break;
default:
break;
@@ -7218,13 +7126,13 @@ bool Scene1550::Junk::startAction(CursorType action, Event &event) {
} else {
switch ((((_strip - 1) * 5) + _frame) % 3) {
case 0:
- SceneItem::display(1550, 62, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ SceneItem::display(1550, 62, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, LIST_END);
break;
case 1:
- SceneItem::display(1550, 53, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ SceneItem::display(1550, 53, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, LIST_END);
break;
case 2:
- SceneItem::display(1550, 76, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ SceneItem::display(1550, 76, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, LIST_END);
break;
default:
break;
@@ -7254,7 +7162,7 @@ bool Scene1550::ShipComponent::startAction(CursorType action, Event &event) {
switch (action) {
case CURSOR_USE:
if (_componentId == 8) {
- scene->_field412 = 1;
+ scene->_dontExit = true;
R2_GLOBALS._player.disableControl();
if (R2_GLOBALS._player._characterIndex == R2_QUINN)
scene->_sceneMode = 1576;
@@ -7268,101 +7176,101 @@ bool Scene1550::ShipComponent::startAction(CursorType action, Event &event) {
break;
case CURSOR_LOOK:
if (_componentId == 8)
- SceneItem::display(1550, 75, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ SceneItem::display(1550, 75, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, LIST_END);
else if (_frame == 1)
- SceneItem::display(1550, 70, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ SceneItem::display(1550, 70, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, LIST_END);
else
- SceneItem::display(1550, 71, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ SceneItem::display(1550, 71, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, LIST_END);
return true;
break;
case R2_FUEL_CELL:
- scene->_field412 = 1;
+ scene->_dontExit = true;
if (_componentId == 6) {
R2_GLOBALS._player.disableControl();
- scene->_landingStrut.postInit();
+ scene->_wreckage2.postInit();
if (R2_GLOBALS._player._characterIndex == R2_QUINN)
scene->_sceneMode = 1574;
else
scene->_sceneMode = 1582;
- scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player, &scene->_shipComponents[5], &scene->_landingStrut, NULL);
+ scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player, &scene->_shipComponents[5], &scene->_wreckage2, NULL);
return true;
}
return SceneActor::startAction(action, event);
break;
case R2_GYROSCOPE:
- scene->_field412 = 1;
+ scene->_dontExit = true;
if (_componentId == 3) {
R2_GLOBALS._player.disableControl();
- scene->_landingStrut.postInit();
+ scene->_wreckage2.postInit();
if (R2_GLOBALS._player._characterIndex == R2_QUINN)
scene->_sceneMode = 1571;
else
scene->_sceneMode = 1581;
- scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player, &scene->_shipComponents[2], &scene->_landingStrut, NULL);
+ scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player, &scene->_shipComponents[2], &scene->_wreckage2, NULL);
return true;
}
return SceneActor::startAction(action, event);
break;
case R2_GUIDANCE_MODULE:
- scene->_field412 = 1;
+ scene->_dontExit = true;
if (_componentId == 1) {
R2_GLOBALS._player.disableControl();
- scene->_landingStrut.postInit();
+ scene->_wreckage2.postInit();
if (R2_GLOBALS._player._characterIndex == R2_QUINN)
scene->_sceneMode = 1569;
else
scene->_sceneMode = 1579;
- scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player, &scene->_shipComponents[0], &scene->_landingStrut, NULL);
+ scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player, &scene->_shipComponents[0], &scene->_wreckage2, NULL);
return true;
}
return SceneActor::startAction(action, event);
break;
case R2_THRUSTER_VALVE:
- scene->_field412 = 1;
+ scene->_dontExit = true;
if (_componentId == 4) {
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 1572;
- scene->_landingStrut.postInit();
- scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player, &scene->_shipComponents[3], &scene->_landingStrut, NULL);
+ scene->_wreckage2.postInit();
+ scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player, &scene->_shipComponents[3], &scene->_wreckage2, NULL);
return true;
}
return SceneActor::startAction(action, event);
break;
case R2_RADAR_MECHANISM:
- scene->_field412 = 1;
+ scene->_dontExit = true;
if (_componentId == 2) {
R2_GLOBALS._player.disableControl();
- scene->_landingStrut.postInit();
+ scene->_wreckage2.postInit();
if (R2_GLOBALS._player._characterIndex == R2_QUINN)
scene->_sceneMode = 1570;
else
scene->_sceneMode = 1580;
- scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player, &scene->_shipComponents[1], &scene->_landingStrut, NULL);
+ scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player, &scene->_shipComponents[1], &scene->_wreckage2, NULL);
return true;
}
return SceneActor::startAction(action, event);
break;
case R2_IGNITOR:
- scene->_field412 = 1;
+ scene->_dontExit = true;
if (_componentId == 5) {
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 1573;
- scene->_landingStrut.postInit();
- scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player, &scene->_shipComponents[4], &scene->_landingStrut, NULL);
+ scene->_wreckage2.postInit();
+ scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player, &scene->_shipComponents[4], &scene->_wreckage2, NULL);
return true;
}
return SceneActor::startAction(action, event);
break;
case R2_BATTERY:
- scene->_field412 = 1;
+ scene->_dontExit = true;
if (_componentId == 7) {
R2_GLOBALS._player.disableControl();
- scene->_landingStrut.postInit();
+ scene->_wreckage2.postInit();
if (R2_GLOBALS._player._characterIndex == R2_QUINN)
scene->_sceneMode = 1575;
else
scene->_sceneMode = 1583;
- scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player, &scene->_shipComponents[6], &scene->_landingStrut, NULL);
+ scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player, &scene->_shipComponents[6], &scene->_wreckage2, NULL);
return true;
}
return SceneActor::startAction(action, event);
@@ -7432,45 +7340,48 @@ void Scene1550::ShipComponent::setupShipComponent(int componentId) {
setDetails(1550, 70, -1, -1, 2, (SceneItem *)NULL);
}
-Scene1550::UnkObj15503::UnkObj15503() {
- _fieldA4 = 0;
+Scene1550::DishControlsWindow::DishControl::DishControl() {
+ _controlId = 0;
}
-void Scene1550::UnkObj15503::synchronize(Serializer &s) {
+void Scene1550::DishControlsWindow::DishControl::synchronize(Serializer &s) {
SceneActor::synchronize(s);
- s.syncAsSint16LE(_fieldA4);
+ s.syncAsSint16LE(_controlId);
}
-bool Scene1550::UnkObj15503::startAction(CursorType action, Event &event) {
- Scene1550 *scene = (Scene1550 *)R2_GLOBALS._sceneManager._scene;
-
+bool Scene1550::DishControlsWindow::DishControl::startAction(CursorType action, Event &event) {
if (action != CURSOR_USE)
return SceneActor::startAction(action, event);
- switch (_fieldA4) {
+
+ Scene1550 *scene = (Scene1550 *)R2_GLOBALS._sceneManager._scene;
+
+ switch (_controlId) {
case 1:
- if (scene->_actor13._frame == 5) {
+ // Button control
+ if (scene->_dish._frame == 5) {
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 25;
- if (scene->_actor4._frame == 1) {
- scene->setAction(&scene->_sequenceManager1, scene, 1560, &scene->_actor4, NULL);
+ if (scene->_walkway._frame == 1) {
+ scene->setAction(&scene->_sequenceManager1, scene, 1560, &scene->_walkway, NULL);
R2_GLOBALS.setFlag(20);
setFrame(2);
} else {
- scene->setAction(&scene->_sequenceManager1, scene, 1561, &scene->_actor4, NULL);
+ scene->setAction(&scene->_sequenceManager1, scene, 1561, &scene->_walkway, NULL);
R2_GLOBALS.clearFlag(20);
setFrame(1);
}
- scene->_unkArea1.remove();
+ scene->_dishControlsWindow.remove();
}
break;
case 2:
+ // Lever control
R2_GLOBALS._player.disableControl();
- if (scene->_actor13._frame == 1) {
+ if (scene->_dish._frame == 1) {
scene->_sceneMode = 23;
scene->setAction(&scene->_sequenceManager1, scene, 1560, this, NULL);
} else {
- if (scene->_actor4._frame == 1)
+ if (scene->_walkway._frame == 1)
scene->_sceneMode = 24;
else
scene->_sceneMode = 22;
@@ -7483,22 +7394,19 @@ bool Scene1550::UnkObj15503::startAction(CursorType action, Event &event) {
return true;
}
-void Scene1550::UnkArea1550::remove() {
+void Scene1550::DishControlsWindow::remove() {
Scene1550 *scene = (Scene1550 *)R2_GLOBALS._sceneManager._scene;
- _unkObj155031.remove();
- _unkObj155032.remove();
- // sub201EA is a common part with UnkArea1200
- R2_GLOBALS._sceneItems.remove((SceneItem *)this);
- _areaActor.remove();
- SceneArea::remove();
- R2_GLOBALS._insetUp--;
- //
+ _button.remove();
+ _lever.remove();
+
+ ModalWindow::remove();
+
if ((scene->_sceneMode >= 20) && (scene->_sceneMode <= 29))
return;
R2_GLOBALS._player.disableControl();
- if (scene->_actor4._frame == 1) {
+ if (scene->_walkway._frame == 1) {
scene->_sceneMode = 1559;
scene->setAction(&scene->_sequenceManager1, scene, 1559, &R2_GLOBALS._player, NULL);
} else {
@@ -7507,91 +7415,40 @@ void Scene1550::UnkArea1550::remove() {
}
}
-void Scene1550::UnkArea1550::process(Event &event) {
-// This is a copy of Scene1200::LaserPanel::process
- if (_field20 != R2_GLOBALS._insetUp)
- return;
-
- CursorType cursor = R2_GLOBALS._events.getCursor();
-
- if (_areaActor._bounds.contains(event.mousePos.x + g_globals->gfxManager()._bounds.left , event.mousePos.y)) {
- if (cursor == _cursorNum) {
- R2_GLOBALS._events.setCursor(_savedCursorNum);
- }
- } else if (event.mousePos.y < 168) {
- if (cursor != _cursorNum) {
- _savedCursorNum = cursor;
- R2_GLOBALS._events.setCursor(CURSOR_INVALID);
- }
- if (event.eventType == EVENT_BUTTON_DOWN) {
- event.handled = true;
- R2_GLOBALS._events.setCursor(_savedCursorNum);
- remove();
- }
- }
-}
+void Scene1550::DishControlsWindow::setup2(int visage, int stripFrameNum, int frameNum,
+ int posX, int posY) {
+ // Call inherited setup
+ ModalWindow::setup2(visage, stripFrameNum, frameNum, posX, posY);
-void Scene1550::UnkArea1550::proc12(int visage, int stripFrameNum, int frameNum, int posX, int posY) {
- // UnkArea1200::proc12();
+ // Further setup
Scene1550 *scene = (Scene1550 *)R2_GLOBALS._sceneManager._scene;
-
- _areaActor.postInit();
- _areaActor.setup(visage, stripFrameNum, frameNum);
- _areaActor.setPosition(Common::Point(posX, posY));
- _areaActor.fixPriority(250);
- _cursorNum = CURSOR_INVALID;
- scene->_sceneAreas.push_front(this);
- ++R2_GLOBALS._insetUp;
- _field20 = R2_GLOBALS._insetUp;
- //
-
- proc13(1550, 67, -1, -1);
- _unkObj155031.postInit();
- _unkObj155031._fieldA4 = 1;
- if (scene->_actor4._frame == 1)
- _unkObj155031.setup(1559, 3, 1);
+ setup3(1550, 67, -1, -1);
+ _button.postInit();
+ _button._controlId = 1;
+ if (scene->_walkway._frame == 1)
+ _button.setup(1559, 3, 1);
else
- _unkObj155031.setup(1559, 3, 2);
- _unkObj155031.setPosition(Common::Point(142, 79));
- _unkObj155031.fixPriority(251);
- _unkObj155031.setDetails(1550, 68, -1, -1, 2, (SceneItem *) NULL);
-
- _unkObj155032.postInit();
- _unkObj155032._numFrames = 5;
- _unkObj155032._fieldA4 = 2;
- if (scene->_actor13._frame == 1)
- _unkObj155032.setup(1559, 2, 1);
- else
- _unkObj155032.setup(1559, 2, 2);
- _unkObj155032.setPosition(Common::Point(156, 103));
- _unkObj155032.fixPriority(251);
- _unkObj155032.setDetails(1550, 69, -1, -1, 2, (SceneItem *) NULL);
-}
+ _button.setup(1559, 3, 2);
+ _button.setPosition(Common::Point(142, 79));
+ _button.fixPriority(251);
+ _button.setDetails(1550, 68, -1, -1, 2, (SceneItem *) NULL);
-void Scene1550::UnkArea1550::proc13(int resNum, int lookLineNum, int talkLineNum, int useLineNum) {
- // Copy of Scene1200::LaserPanel::proc13
- _areaActor.setDetails(resNum, lookLineNum, talkLineNum, useLineNum, 2, (SceneItem *) NULL);
+ _lever.postInit();
+ _lever._numFrames = 5;
+ _lever._controlId = 2;
+ if (scene->_dish._frame == 1)
+ _lever.setup(1559, 2, 1);
+ else
+ _lever.setup(1559, 2, 2);
+ _lever.setPosition(Common::Point(156, 103));
+ _lever.fixPriority(251);
+ _lever.setDetails(1550, 69, -1, -1, 2, (SceneItem *) NULL);
}
bool Scene1550::WorkingShip::startAction(CursorType action, Event &event) {
return SceneHotspot::startAction(action, event);
}
-bool Scene1550::Hotspot3::startAction(CursorType action, Event &event) {
- // Arrays related to this scene are all hacky in the origina: they are based on the impossibility to use Miranda
- assert ((R2_GLOBALS._player._characterIndex == R2_QUINN) || (R2_GLOBALS._player._characterIndex == R2_SEEKER));
- // The original contains a debug message when CURSOR_TALK is used.
- // This part is totally useless, we could remove it (and the entire function as well)
- if (action == CURSOR_TALK)
- warning("Location: %d/%d - %d",
- R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].x,
- R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].y,
- scene1550AreaMap[(R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].y * 30)] +
- R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].x);
-
- return SceneHotspot::startAction(action, event);
-}
-
bool Scene1550::Wreckage::startAction(CursorType action, Event &event) {
return SceneActor::startAction(action, event);
}
@@ -7607,23 +7464,23 @@ bool Scene1550::Companion::startAction(CursorType action, Event &event) {
return true;
}
-bool Scene1550::Actor8::startAction(CursorType action, Event &event) {
+bool Scene1550::AirBag::startAction(CursorType action, Event &event) {
if (action != CURSOR_USE)
return SceneActor::startAction(action, event);
R2_GLOBALS._player.disableControl();
Scene1550 *scene = (Scene1550 *)R2_GLOBALS._sceneManager._scene;
- scene->_field412 = 1;
+ scene->_dontExit = true;
if (R2_GLOBALS._player._characterIndex == R2_QUINN)
scene->_sceneMode = 1552;
else
scene->_sceneMode = 1588;
- scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player, &scene->_actor8, NULL);
+ scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player, &scene->_airbag, NULL);
return true;
}
-bool Scene1550::Actor9::startAction(CursorType action, Event &event) {
+bool Scene1550::Joystick::startAction(CursorType action, Event &event) {
Scene1550 *scene = (Scene1550 *)R2_GLOBALS._sceneManager._scene;
switch (action) {
@@ -7638,7 +7495,7 @@ bool Scene1550::Actor9::startAction(CursorType action, Event &event) {
return true;
break;
case CURSOR_LOOK:
- SceneItem::display(1550, 41, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ SceneItem::display(1550, 41, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, LIST_END);
return true;
break;
default:
@@ -7646,7 +7503,7 @@ bool Scene1550::Actor9::startAction(CursorType action, Event &event) {
}
}
-bool Scene1550::Actor10::startAction(CursorType action, Event &event) {
+bool Scene1550::Gyroscope::startAction(CursorType action, Event &event) {
if (action != CURSOR_USE)
return SceneActor::startAction(action, event);
@@ -7657,27 +7514,29 @@ bool Scene1550::Actor10::startAction(CursorType action, Event &event) {
else
scene->_sceneMode = 1589;
- scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player, &scene->_actor10, NULL);
+ scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player,
+ &scene->_gyroscope, NULL);
return true;
}
-bool Scene1550::Actor11::startAction(CursorType action, Event &event) {
+bool Scene1550::DiagnosticsDisplay::startAction(CursorType action, Event &event) {
if (action != CURSOR_USE)
return SceneActor::startAction(action, event);
Scene1550 *scene = (Scene1550 *)R2_GLOBALS._sceneManager._scene;
R2_GLOBALS._player.disableControl();
- scene->_field412 = 1;
+ scene->_dontExit = true;
if (R2_GLOBALS._player._characterIndex == R2_QUINN)
scene->_sceneMode = 1586;
else
scene->_sceneMode = 1587;
- scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player, &scene->_actor11, NULL);
+ scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player,
+ &scene->_diagnosticsDisplay, NULL);
return true;
}
-bool Scene1550::Actor12::startAction(CursorType action, Event &event) {
+bool Scene1550::DishTower::startAction(CursorType action, Event &event) {
if (action != CURSOR_USE)
return SceneActor::startAction(action, event);
@@ -7689,10 +7548,10 @@ bool Scene1550::Actor12::startAction(CursorType action, Event &event) {
scene->setAction(&scene->_sequenceManager1, scene, 1585, &R2_GLOBALS._player, NULL);
} else {
R2_GLOBALS._player.disableControl();
- switch(scene->_field415) {
+ switch(scene->_dishMode) {
case 0:
- scene->_actor13.fixPriority(168);
- scene->_actor4.fixPriority(125);
+ scene->_dish.fixPriority(168);
+ scene->_walkway.fixPriority(125);
scene->_sceneMode = 1558;
scene->setAction(&scene->_sequenceManager1, scene, 1558, &R2_GLOBALS._player, NULL);
break;
@@ -7700,9 +7559,9 @@ bool Scene1550::Actor12::startAction(CursorType action, Event &event) {
return SceneActor::startAction(action, event);
break;
case 2:
- scene->_field415 = 1;
+ scene->_dishMode = 1;
scene->_sceneMode = 1563;
- scene->setAction(&scene->_sequenceManager1, scene, 1563, &R2_GLOBALS._player, &scene->_actor4, NULL);
+ scene->setAction(&scene->_sequenceManager1, scene, 1563, &R2_GLOBALS._player, &scene->_walkway, NULL);
break;
default:
break;
@@ -7712,12 +7571,12 @@ bool Scene1550::Actor12::startAction(CursorType action, Event &event) {
}
-bool Scene1550::Actor13::startAction(CursorType action, Event &event) {
+bool Scene1550::Dish::startAction(CursorType action, Event &event) {
Scene1550 *scene = (Scene1550 *)R2_GLOBALS._sceneManager._scene;
switch (action) {
case CURSOR_USE:
- if (scene->_field415 != 2)
+ if (scene->_dishMode != 2)
return SceneActor::startAction(action, event);
if (R2_INVENTORY.getObjectScene(R2_BATTERY) == 1550) {
@@ -7725,17 +7584,17 @@ bool Scene1550::Actor13::startAction(CursorType action, Event &event) {
scene->_sceneMode = 1564;
scene->setAction(&scene->_sequenceManager1, scene, 1564, &R2_GLOBALS._player, NULL);
} else
- SceneItem::display(1550, 64, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ SceneItem::display(1550, 64, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, LIST_END);
return true;
break;
case CURSOR_LOOK:
- if (scene->_field415 != 2)
+ if (scene->_dishMode != 2)
return SceneActor::startAction(action, event);
if (R2_INVENTORY.getObjectScene(R2_BATTERY) == 1550) {
- SceneItem::display(1550, 74, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ SceneItem::display(1550, 74, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, LIST_END);
} else
- SceneItem::display(1550, 64, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ SceneItem::display(1550, 64, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, LIST_END);
return true;
break;
default:
@@ -7744,26 +7603,28 @@ bool Scene1550::Actor13::startAction(CursorType action, Event &event) {
}
}
+/*--------------------------------------------------------------------------*/
+
Scene1550::Scene1550() {
- _field412 = 0;
- _field414 = 0;
- _field415 = 0;
- _field417 = 0;
- _field419 = 0;
+ _dontExit = false;
+ _wallType = 0;
+ _dishMode = 0;
+ _sceneResourceId = 0;
+ _walkRegionsId = 0;
}
void Scene1550::synchronize(Serializer &s) {
SceneExt::synchronize(s);
- s.syncAsSint16LE(_field412);
- s.syncAsByte(_field414);
- s.syncAsSint16LE(_field415);
- s.syncAsSint16LE(_field417);
- s.syncAsSint16LE(_field419);
+ s.syncAsSint16LE(_dontExit);
+ s.syncAsByte(_wallType);
+ s.syncAsSint16LE(_dishMode);
+ s.syncAsSint16LE(_sceneResourceId);
+ s.syncAsSint16LE(_walkRegionsId);
}
void Scene1550::postInit(SceneObjectList *OwnerList) {
- if ((R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].x == 9) &&
+ if ((R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].x == 9) &&
(R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].y == 11))
// Exiting the intact spaceship
loadScene(1234);
@@ -7774,8 +7635,8 @@ void Scene1550::postInit(SceneObjectList *OwnerList) {
scalePalette(65, 65, 65);
setZoomPercents(30, 75, 170, 100);
- _field417 = 1550;
- _field419 = 0;
+ _sceneResourceId = 1550;
+ _walkRegionsId = 0;
if (R2_GLOBALS._sceneManager._previousScene == -1)
R2_GLOBALS.setFlag(16);
@@ -7791,7 +7652,7 @@ void Scene1550::postInit(SceneObjectList *OwnerList) {
_stripManager.addSpeaker(&_seekerSpeaker);
R2_GLOBALS._player.postInit();
- R2_GLOBALS._player._effect = 6;
+ R2_GLOBALS._player._effect = EFFECT_SHADED2;
if (R2_GLOBALS._player._characterIndex == R2_QUINN)
R2_GLOBALS._player.setup(1500, 3, 1);
@@ -7800,7 +7661,7 @@ void Scene1550::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player._moveDiff = Common::Point(5, 3);
- if ((R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].x == 9) &&
+ if ((R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].x == 9) &&
(R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].y == 11))
R2_GLOBALS._player.setPosition(Common::Point(157, 135));
else
@@ -7809,13 +7670,13 @@ void Scene1550::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
R2_GLOBALS._player.disableControl();
- _field414 = 0;
+ _wallType = 0;
_companion.changeZoom(-1);
R2_GLOBALS._player.changeZoom(-1);
switch (R2_GLOBALS._sceneManager._previousScene) {
case 1530:
- R2_GLOBALS._v565AE = 0;
+ R2_GLOBALS._stripModifier = 0;
// No break on purpose
case 300:
// No break on purpose
@@ -7830,9 +7691,9 @@ void Scene1550::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player.disableControl();
R2_GLOBALS._player.animate(ANIM_MODE_NONE, NULL);
- _field412 = 1;
+ _dontExit = true;
- _landingStrut.postInit();
+ _wreckage2.postInit();
_shipComponents[7].setupShipComponent(8);
_shipComponents[7].hide();
if (R2_GLOBALS._player._characterIndex == R2_QUINN)
@@ -7840,7 +7701,7 @@ void Scene1550::postInit(SceneObjectList *OwnerList) {
else
_sceneMode = 1578;
- setAction(&_sequenceManager1, this, _sceneMode, &R2_GLOBALS._player, &_landingStrut, &_shipComponents[7], NULL);
+ setAction(&_sequenceManager1, this, _sceneMode, &R2_GLOBALS._player, &_wreckage2, &_shipComponents[7], NULL);
R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] = 1550;
} else {
R2_GLOBALS._player.enableControl();
@@ -7852,9 +7713,9 @@ void Scene1550::postInit(SceneObjectList *OwnerList) {
enterArea();
- _shipHull.setDetails(16, 1550, 10, -1, -1);
- _item2.setDetails(24, 1550, 10, -1, -1);
- _item3.setDetails(Rect(0, 0, 320, 200), 1550, 0, 1, -1, 1, NULL);
+ _intactHull1.setDetails(16, 1550, 10, -1, -1);
+ _intactHull2.setDetails(24, 1550, 10, -1, -1);
+ _background.setDetails(Rect(0, 0, 320, 200), 1550, 0, 1, -1, 1, NULL);
if ((R2_GLOBALS._sceneManager._previousScene == 1500) && (R2_GLOBALS.getFlag(16))) {
_sceneMode = 70;
@@ -7869,8 +7730,8 @@ void Scene1550::postInit(SceneObjectList *OwnerList) {
_companion.changeZoom(77);
_companion.setDetails(1550, -1, -1, -1, 2, (SceneItem *) NULL);
- assert(_field419 >= 1550);
- R2_GLOBALS._walkRegions.disableRegion(k5A750[_field419 - 1550]);
+ assert(_walkRegionsId >= 1550);
+ R2_GLOBALS._walkRegions.disableRegion(k5A750[_walkRegionsId - 1550]);
setAction(&_sequenceManager1, this, 1590, &_companion, NULL);
} else if ((_sceneMode != 1577) && (_sceneMode != 1578))
@@ -7886,8 +7747,7 @@ void Scene1550::signal() {
case 5:
// No break on purpose
case 7:
- _field412 = 0;
- R2_GLOBALS._v56AAB = 0;
+ _dontExit = false;
R2_GLOBALS._player.enableControl(CURSOR_WALK);
break;
case 20:
@@ -7897,27 +7757,28 @@ void Scene1550::signal() {
case 25:
// No break on purpose
case 1563:
+ // Show the communication dish controls window
R2_GLOBALS.clearFlag(20);
- _unkArea1.proc12(1559, 1, 1, 160, 125);
+ _dishControlsWindow.setup2(1559, 1, 1, 160, 125);
R2_GLOBALS._player.enableControl();
_sceneMode = 0;
break;
case 22:
- _unkArea1.remove();
+ _dishControlsWindow.remove();
_sceneMode = 24;
- setAction(&_sequenceManager1, this, 1561, &_actor4, NULL);
+ setAction(&_sequenceManager1, this, 1561, &_walkway, NULL);
R2_GLOBALS.clearFlag(20);
break;
case 23:
- _unkArea1.remove();
+ _dishControlsWindow.remove();
_sceneMode = 20;
- setAction(&_sequenceManager1, this, 1566, &_actor13, &_actor5, NULL);
- R2_GLOBALS.setFlag(21);
+ setAction(&_sequenceManager1, this, 1566, &_dish, &_dishTowerShadow, NULL);
+ R2_GLOBALS.setFlag(19);
break;
case 24:
- _unkArea1.remove();
+ _dishControlsWindow.remove();
_sceneMode = 21;
- setAction(&_sequenceManager1, this, 1567, &_actor13, &_actor5, NULL);
+ setAction(&_sequenceManager1, this, 1567, &_dish, &_dishTowerShadow, NULL);
R2_GLOBALS.clearFlag(19);
break;
case 30:
@@ -7990,7 +7851,7 @@ void Scene1550::signal() {
R2_GLOBALS._player.enableControl();
break;
case 50:
- warning("STUB: sub_1D227()");
+ // Removed (useless ?) call to sub_1D227
++_sceneMode;
setAction(&_sequenceManager1, this, 1591, &R2_GLOBALS._player, NULL);
if (g_globals->_sceneObjects->contains(&_companion))
@@ -8013,18 +7874,20 @@ void Scene1550::signal() {
_companion.changeZoom(-1);
_sceneMode = 1592;
if (R2_GLOBALS._player._characterIndex == R2_QUINN)
- setAction(&_sequenceManager1, this, 1592, &R2_GLOBALS._player, &_companion, &_junk[0], &_actor9, NULL);
+ setAction(&_sequenceManager1, this, 1592, &R2_GLOBALS._player, &_companion,
+ &_junk[0], &_joystick, NULL);
else
- setAction(&_sequenceManager1, this, 1593, &R2_GLOBALS._player, &_companion, &_junk[0], &_actor9, NULL);
+ setAction(&_sequenceManager1, this, 1593, &R2_GLOBALS._player, &_companion,
+ &_junk[0], &_joystick, NULL);
break;
case 61:
R2_GLOBALS._player.enableControl(CURSOR_USE);
R2_GLOBALS._player._canWalk = false;
- _field415 = 2;
+ _dishMode = 2;
break;
case 62:
R2_GLOBALS._player.enableControl(CURSOR_TALK);
- if (_field415 == 2) {
+ if (_dishMode == 2) {
R2_GLOBALS._player.enableControl(CURSOR_USE);
R2_GLOBALS._player._canWalk = false;
}
@@ -8041,33 +7904,33 @@ void Scene1550::signal() {
_sceneMode = 60;
R2_GLOBALS._player.disableControl();
R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
- if (R2_GLOBALS._v565AE >= 3) {
+ if (R2_GLOBALS._stripModifier >= 3) {
if (R2_GLOBALS._player._characterIndex == R2_QUINN)
_stripManager.start(572, this);
else
_stripManager.start(573, this);
} else {
- ++R2_GLOBALS._v565AE;
+ ++R2_GLOBALS._stripModifier;
if (R2_GLOBALS._player._characterIndex == R2_QUINN)
- _stripManager.start(499 + R2_GLOBALS._v565AE, this);
+ _stripManager.start(499 + R2_GLOBALS._stripModifier, this);
else
- _stripManager.start(502 + R2_GLOBALS._v565AE, this);
+ _stripManager.start(502 + R2_GLOBALS._stripModifier, this);
}
} else {
_sceneMode = 60;
R2_GLOBALS._player.disableControl();
R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
- if (R2_GLOBALS._v565AE >= 4) {
+ if (R2_GLOBALS._stripModifier >= 4) {
if (R2_GLOBALS._player._characterIndex == R2_QUINN)
_stripManager.start(572, this);
else
_stripManager.start(573, this);
} else {
- ++R2_GLOBALS._v565AE;
+ ++R2_GLOBALS._stripModifier;
if (R2_GLOBALS._player._characterIndex == R2_QUINN)
- _stripManager.start(563 + R2_GLOBALS._v565AE, this);
+ _stripManager.start(563 + R2_GLOBALS._stripModifier, this);
else
- _stripManager.start(567 + R2_GLOBALS._v565AE, this);
+ _stripManager.start(567 + R2_GLOBALS._stripModifier, this);
}
}
break;
@@ -8078,8 +7941,8 @@ void Scene1550::signal() {
// No break on purpose
case 1588:
R2_INVENTORY.setObjectScene(R2_AIRBAG, R2_GLOBALS._player._characterIndex);
- _actor8.remove();
- _field412 = 0;
+ _airbag.remove();
+ _dontExit = false;
R2_GLOBALS._player.enableControl();
break;
case 1553:
@@ -8087,33 +7950,33 @@ void Scene1550::signal() {
break;
case 1554:
R2_GLOBALS._player.enableControl();
- _field412 = 0;
+ _dontExit = false;
break;
case 1555:
// No break on purpose
case 1589:
R2_INVENTORY.setObjectScene(R2_GYROSCOPE, R2_GLOBALS._player._characterIndex);
- _actor10.remove();
+ _gyroscope.remove();
R2_GLOBALS._player.enableControl();
break;
case 1558:
- _actor13.fixPriority(124);
- _field415 = 1;
- _unkArea1.proc12(1559, 1, 1, 160, 125);
+ _dish.fixPriority(124);
+ _dishMode = 1;
+ _dishControlsWindow.setup2(1559, 1, 1, 160, 125);
R2_GLOBALS._player.enableControl();
break;
case 1559:
- _actor13.fixPriority(168);
- _actor4.fixPriority(169);
+ _dish.fixPriority(168);
+ _walkway.fixPriority(169);
R2_GLOBALS._player.fixPriority(-1);
R2_GLOBALS._player.changeZoom(-1);
- _field415 = 0;
+ _dishMode = 0;
R2_GLOBALS._player.enableControl();
break;
case 1562:
R2_GLOBALS._player.enableControl();
R2_GLOBALS._player._canWalk = false;
- _field415 = 2;
+ _dishMode = 2;
break;
case 1564:
R2_INVENTORY.setObjectScene(R2_BATTERY, 1);
@@ -8127,52 +7990,52 @@ void Scene1550::signal() {
case 1569:
// No break on purpose
case 1579:
- _field412 = 0;
- _landingStrut.remove();
+ _dontExit = false;
+ _wreckage2.remove();
R2_INVENTORY.setObjectScene(R2_GUIDANCE_MODULE, 0);
R2_GLOBALS._player.enableControl();
break;
case 1570:
// No break on purpose
case 1580:
- _field412 = 0;
- _landingStrut.remove();
+ _dontExit = false;
+ _wreckage2.remove();
R2_INVENTORY.setObjectScene(R2_RADAR_MECHANISM, 0);
R2_GLOBALS._player.enableControl();
break;
case 1571:
// No break on purpose
case 1581:
- _field412 = 0;
- _landingStrut.remove();
+ _dontExit = false;
+ _wreckage2.remove();
R2_INVENTORY.setObjectScene(R2_GYROSCOPE, 0);
R2_GLOBALS._player.enableControl();
break;
case 1572:
- _field412 = 0;
- _landingStrut.remove();
+ _dontExit = false;
+ _wreckage2.remove();
R2_INVENTORY.setObjectScene(R2_THRUSTER_VALVE, 0);
R2_GLOBALS._player.enableControl();
break;
case 1573:
- _field412 = 0;
- _landingStrut.remove();
+ _dontExit = false;
+ _wreckage2.remove();
R2_INVENTORY.setObjectScene(R2_IGNITOR, 0);
R2_GLOBALS._player.enableControl();
break;
case 1574:
// No break on purpose
case 1582:
- _field412 = 0;
- _landingStrut.remove();
+ _dontExit = false;
+ _wreckage2.remove();
R2_INVENTORY.setObjectScene(R2_FUEL_CELL, 0);
R2_GLOBALS._player.enableControl();
break;
case 1575:
// No break on purpose
case 1583:
- _field412 = 0;
- _landingStrut.remove();
+ _dontExit = false;
+ _wreckage2.remove();
R2_INVENTORY.setObjectScene(R2_BATTERY, 0);
R2_GLOBALS._player.enableControl();
break;
@@ -8186,32 +8049,32 @@ void Scene1550::signal() {
// No break on purpose
case 1578:
_sceneMode = 0;
- _landingStrut.remove();
- _field412 = 0;
+ _wreckage2.remove();
+ _dontExit = false;
R2_GLOBALS._player.fixPriority(-1);
R2_GLOBALS._player.enableControl();
break;
case 1585:
- SceneItem::display(1550, 66, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ SceneItem::display(1550, 66, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, LIST_END);
R2_GLOBALS._player.enableControl();
break;
case 1586:
// No break on purpose
case 1587:
R2_INVENTORY.setObjectScene(R2_DIAGNOSTICS_DISPLAY, R2_GLOBALS._player._characterIndex);
- _landingStrut.remove();
- _field412 = 0;
+ _diagnosticsDisplay.remove();
+ _dontExit = false;
R2_GLOBALS._player.enableControl();
break;
case 1592:
- _actor9.remove();
+ _joystick.remove();
R2_INVENTORY.setObjectScene(R2_JOYSTICK, 1);
if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
R2_GLOBALS._s1550PlayerArea[R2_SEEKER] = R2_GLOBALS._s1550PlayerArea[R2_QUINN];
} else {
R2_GLOBALS._s1550PlayerArea[R2_QUINN] = R2_GLOBALS._s1550PlayerArea[R2_SEEKER];
}
- R2_GLOBALS._player.enableControl();
+ R2_GLOBALS._player.enableControl(CURSOR_WALK);
break;
default:
_sceneMode = 62;
@@ -8224,14 +8087,14 @@ void Scene1550::process(Event &event) {
if ((!R2_GLOBALS._player._canWalk) && (R2_GLOBALS._events.getCursor() == R2_NEGATOR_GUN) && (event.eventType == EVENT_BUTTON_DOWN) && (this->_screenNumber == 1234)) {
int curReg = R2_GLOBALS._sceneRegions.indexOf(event.mousePos);
if (curReg == 0)
- _field412 = 1;
+ _dontExit = true;
else if (((R2_GLOBALS._player._position.y < 90) && (event.mousePos.y > 90)) || ((R2_GLOBALS._player._position.y > 90) && (event.mousePos.y < 90)))
- _field412 = 1;
+ _dontExit = true;
else
- _field412 = 0;
+ _dontExit = false;
if ((curReg == 13) || (curReg == 14))
- _field412 = 0;
+ _dontExit = false;
}
Scene::process(event);
@@ -8245,20 +8108,23 @@ void Scene1550::dispatch() {
if ((R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].x == 15) && (R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].y == 16)) {
R2_GLOBALS._player._shade = 0;
- // Original game contains a switch based on an uninitialized variable.
- // Until we understand what should really happen there, this code is unused on purpose
+
+ // NOTE: Original game contains a switch based on an uninitialized variable.
+ // We're leaving this code here, but ifdef'ed out, in case we can ever figure out
+ // what the original programmers intended the value to come from
+#if 0
int missingVariable = 0;
switch (missingVariable) {
case 144:
// No break on purpose
case 146:
- _actor13._frame = 5;
+ _dish._frame = 5;
R2_GLOBALS._player._shade = 3;
break;
case 148:
// No break on purpose
case 149:
- _actor13._frame = 1;
+ _dish._frame = 1;
// No break on purpose
case 147:
// No break on purpose
@@ -8268,9 +8134,10 @@ void Scene1550::dispatch() {
default:
break;
}
+#endif
}
- if (_field412 != 0)
+ if (_dontExit)
return;
switch (R2_GLOBALS._player.getRegionIndex() - 11) {
@@ -8280,7 +8147,7 @@ void Scene1550::dispatch() {
// Exiting the top of the screen
R2_GLOBALS._player.disableControl();
_sceneMode = 1;
- _field412 = 1;
+ _dontExit = true;
--R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].y;
enterArea();
@@ -8304,7 +8171,7 @@ void Scene1550::dispatch() {
// Exiting the bottom of the screen
R2_GLOBALS._player.disableControl();
_sceneMode = 3;
- _field412 = 1;
+ _dontExit = true;
++R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].y;
enterArea();
@@ -8328,7 +8195,7 @@ void Scene1550::dispatch() {
// Exiting the right of the screen
R2_GLOBALS._player.disableControl();
_sceneMode = 5;
- _field412 = 1;
+ _dontExit = true;
++R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].x;
enterArea();
@@ -8356,7 +8223,7 @@ void Scene1550::dispatch() {
// Exiting to the left of the screen
R2_GLOBALS._player.disableControl();
_sceneMode = 7;
- _field412 = 1;
+ _dontExit = true;
--R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].x;
enterArea();
@@ -8397,11 +8264,11 @@ void Scene1550::saveCharacter(int characterIndex) {
SceneExt::saveCharacter(characterIndex);
}
-void Scene1550::SceneActor1550::subA4D14(int frameNumber, int strip) {
+void Scene1550::Wall::setupWall(int frameNumber, int strip) {
Scene1550 *scene = (Scene1550 *)R2_GLOBALS._sceneManager._scene;
postInit();
- if (scene->_field414 == 2)
+ if (scene->_wallType == 2)
setup(1551, strip, frameNumber);
else
setup(1554, strip, frameNumber);
@@ -8512,7 +8379,7 @@ void Scene1550::SceneActor1550::subA4D14(int frameNumber, int strip) {
switch (frameNumber) {
case 2:
fixPriority(2);
- if (scene->_field414 == 2)
+ if (scene->_wallType == 2)
setup(1553, 2, 1);
else
setup(1556, 2, 1);
@@ -8537,7 +8404,7 @@ void Scene1550::SceneActor1550::subA4D14(int frameNumber, int strip) {
case 4:
if (frameNumber == 2) {
fixPriority(250);
- if (scene->_field414 == 2)
+ if (scene->_wallType == 2)
setup(1553, 1, 1);
else
setup(1556, 1, 1);
@@ -8582,17 +8449,14 @@ void Scene1550::SceneActor1550::subA4D14(int frameNumber, int strip) {
}
void Scene1550::enterArea() {
- Rect tmpRect;
- _field419 = 0;
- _field415 = 0;
-
- tmpRect = R2_GLOBALS._v5589E;
+ _walkRegionsId = 0;
+ _dishMode = 0;
- _actor14.remove();
+ _wallCorner1.remove();
_westWall.remove();
_northWall.remove();
_southWall.remove();
- _actor16.remove();
+ _wallCorner2.remove();
_eastWall.remove();
for (int i = 0; i < 8; ++i)
@@ -8603,21 +8467,21 @@ void Scene1550::enterArea() {
for (int i = 0; i < 8; ++i)
_shipComponents[i].remove();
- _actor8.remove();
- _actor9.remove();
- _actor10.remove();
- _actor3.remove();
- _actor11.remove();
+ _airbag.remove();
+ _joystick.remove();
+ _gyroscope.remove();
+ _wreckage4.remove();
+ _diagnosticsDisplay.remove();
if ((_sceneMode != 1577) && (_sceneMode != 1578))
- _landingStrut.remove();
+ _wreckage2.remove();
- _actor2.remove();
+ _wreckage3.remove();
_companion.remove();
- _actor13.remove();
- _actor5.remove();
- _actor12.remove();
- _actor4.remove();
+ _dish.remove();
+ _dishTowerShadow.remove();
+ _dishTower.remove();
+ _walkway.remove();
// Set up of special walk regions for certain areas
switch (R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].y) {
@@ -8625,11 +8489,11 @@ void Scene1550::enterArea() {
switch (R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].x) {
case 3:
R2_GLOBALS._walkRegions.load(1554);
- _field419 = 1554;
+ _walkRegionsId = 1554;
break;
case 4:
R2_GLOBALS._walkRegions.load(1553);
- _field419 = 1553;
+ _walkRegionsId = 1553;
break;
default:
break;
@@ -8641,7 +8505,7 @@ void Scene1550::enterArea() {
if ((R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].x == 23) || (R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].x)) {
if (!R2_GLOBALS.getFlag(16)) {
R2_GLOBALS._walkRegions.load(1559);
- _field419 = 1559;
+ _walkRegionsId = 1559;
}
}
break;
@@ -8649,11 +8513,11 @@ void Scene1550::enterArea() {
switch (R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].x) {
case 10:
R2_GLOBALS._walkRegions.load(1555);
- _field419 = 1555;
+ _walkRegionsId = 1555;
break;
case 11:
R2_GLOBALS._walkRegions.load(1556);
- _field419 = 1556;
+ _walkRegionsId = 1556;
break;
default:
break;
@@ -8663,11 +8527,11 @@ void Scene1550::enterArea() {
switch (R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].x) {
case 24:
R2_GLOBALS._walkRegions.load(1558);
- _field419 = 1558;
+ _walkRegionsId = 1558;
break;
case 25:
R2_GLOBALS._walkRegions.load(1557);
- _field419 = 1557;
+ _walkRegionsId = 1557;
break;
default:
break;
@@ -8677,15 +8541,15 @@ void Scene1550::enterArea() {
switch (R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].x) {
case 2:
R2_GLOBALS._walkRegions.load(1552);
- _field419 = 1552;
+ _walkRegionsId = 1552;
break;
case 3:
R2_GLOBALS._walkRegions.load(1551);
- _field419 = 1551;
+ _walkRegionsId = 1551;
break;
case 15:
R2_GLOBALS._walkRegions.load(1575);
- _field419 = 1575;
+ _walkRegionsId = 1575;
default:
break;
}
@@ -8696,13 +8560,15 @@ void Scene1550::enterArea() {
int varA = 0;
+ // This section handles checks if the ARM spacecraft have not yet seized
+ // control of Lance of Truth.
if (!R2_GLOBALS.getFlag(16)) {
switch (R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].y - 2) {
case 0:
switch (R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].x - 22) {
case 0:
varA = 1553;
- _northWall.subA4D14(6, 0);
+ _northWall.setupWall(6, 0);
break;
case 1:
// No break on purpose
@@ -8715,7 +8581,7 @@ void Scene1550::enterArea() {
break;
case 5:
varA = 1553;
- _northWall.subA4D14(6, 0);
+ _northWall.setupWall(6, 0);
break;
default:
break;
@@ -8727,11 +8593,11 @@ void Scene1550::enterArea() {
switch (R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].x - 21) {
case 0:
varA = 1550;
- _northWall.subA4D14(9, 0);
+ _northWall.setupWall(9, 0);
break;
case 1:
varA = 1552;
- _northWall.subA4D14(10, 0);
+ _northWall.setupWall(10, 0);
break;
case 2:
// No break on purpose
@@ -8744,11 +8610,11 @@ void Scene1550::enterArea() {
break;
case 6:
varA = 1552;
- _northWall.subA4D14(7, 0);
+ _northWall.setupWall(7, 0);
break;
case 7:
varA = 1550;
- _northWall.subA4D14(8, 0);
+ _northWall.setupWall(8, 0);
break;
default:
break;
@@ -8758,11 +8624,11 @@ void Scene1550::enterArea() {
switch (R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].x - 21) {
case 0:
varA = 1550;
- _northWall.subA4D14(4, 0);
+ _northWall.setupWall(4, 0);
break;
case 1:
varA = 1550;
- _northWall.subA4D14(3, 0);
+ _northWall.setupWall(3, 0);
break;
case 2:
// No break on purpose
@@ -8775,11 +8641,11 @@ void Scene1550::enterArea() {
break;
case 6:
varA = 1550;
- _northWall.subA4D14(2, 0);
+ _northWall.setupWall(2, 0);
break;
case 7:
varA = 1550;
- _northWall.subA4D14(1, 0);
+ _northWall.setupWall(1, 0);
break;
default:
break;
@@ -8788,41 +8654,44 @@ void Scene1550::enterArea() {
default:
break;
}
- if ((R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].y > 0) && (R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].x <= 29) && (R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].x >= 20) && (R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].y > 7)) {
+ if ((R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].y > 0) &&
+ (R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].x <= 29) &&
+ ((R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].x < 20) ||
+ (R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].y > 7))) {
+ // In an area where the cutscene can be triggered, so start it
R2_GLOBALS.setFlag(16);
R2_GLOBALS._sceneManager.changeScene(1500);
}
}
- if ((R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].x == 9) &&
+ if ((R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].x == 9) &&
(R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].y == 11)) {
if (_screenNumber != 1234) {
R2_GLOBALS._sceneManager._fadeMode = FADEMODE_IMMEDIATE;
loadScene(1234);
R2_GLOBALS._sceneManager._hasPalette = false;
- _field414 = 0;
- }
- } else {
- if (_screenNumber == 1234) {
- R2_GLOBALS._sceneManager._fadeMode = FADEMODE_IMMEDIATE;
- loadScene(1550);
- R2_GLOBALS._sceneManager._hasPalette = false;
+ _wallType = 0;
}
+ } else if (_screenNumber == 1234) {
+ R2_GLOBALS._sceneManager._fadeMode = FADEMODE_IMMEDIATE;
+ loadScene(1550);
+ R2_GLOBALS._sceneManager._hasPalette = false;
}
- if (R2_GLOBALS._sceneManager._sceneNumber == 1234)
- _field419 = 1576;
+ if (_screenNumber == 1234)
+ _walkRegionsId = 1576;
- if (_field414 == 0) {
- _field414 = 1;
+ if (_wallType == 0) {
+ _wallType = 1;
} else {
- if (_field414 == 2) {
- _field414 = 3;
+ if (_wallType == 2) {
+ _wallType = 3;
} else {
- _field414 = 2;
+ _wallType = 2;
}
if (R2_GLOBALS._sceneManager._sceneNumber == 1550){
+#if 0
warning("Mouse_hideIfNeeded()");
warning("gfx_set_pane_p");
for (int i = 3; i != 168; ++i) {
@@ -8830,12 +8699,13 @@ void Scene1550::enterArea() {
warning("missing for loop, to be implemented");
warning("gfx_draw_slice");
}
- warning("Missing sub2957D()");
+ warning("gfx_flip_screen()");
warning("gfx_set_pane_p()");
+#endif
R2_GLOBALS._sceneManager._fadeMode = FADEMODE_IMMEDIATE;
if (varA == 0) {
- if (_field417 != 1550) {
+ if (_sceneResourceId != 1550) {
g_globals->_scenePalette.loadPalette(1550);
R2_GLOBALS._sceneManager._hasPalette = true;
}
@@ -8845,142 +8715,142 @@ void Scene1550::enterArea() {
}
if (R2_GLOBALS._sceneManager._hasPalette)
- _field417 = varA;
+ _sceneResourceId = varA;
- warning("sub_2C429()");
+// warning("sub_2C429()");
}
}
// Scene setup dependent on the type of cell specified in the scene map
- switch (scene1550AreaMap[(R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].y * 30) +
+ switch (scene1550AreaMap[(R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].y * 30) +
R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].x]) {
case 0:
// Standard cell
- if (_field419 == 0) {
+ if (_walkRegionsId == 0) {
R2_GLOBALS._walkRegions.load(1550);
- _field419 = 1550;
+ _walkRegionsId = 1550;
}
break;
case 1:
// North end of the spaceport
- if (_field419 == 0) {
+ if (_walkRegionsId == 0) {
R2_GLOBALS._walkRegions.load(1560);
- _field419 = 1560;
+ _walkRegionsId = 1560;
}
- _actor14.subA4D14(2, 1);
- _northWall.subA4D14(1, 3);
- _actor16.subA4D14(2, 5);
+ _wallCorner1.setupWall(2, 1);
+ _northWall.setupWall(1, 3);
+ _wallCorner2.setupWall(2, 5);
break;
case 2:
R2_GLOBALS._walkRegions.load(1561);
- _field419 = 1561;
- _actor14.subA4D14(2, 1);
- _westWall.subA4D14(2, 2);
- _northWall.subA4D14(1, 3);
- _actor16.subA4D14(2, 5);
+ _walkRegionsId = 1561;
+ _wallCorner1.setupWall(2, 1);
+ _westWall.setupWall(2, 2);
+ _northWall.setupWall(1, 3);
+ _wallCorner2.setupWall(2, 5);
break;
case 3:
R2_GLOBALS._walkRegions.load(1562);
- _field419 = 1562;
- _actor14.subA4D14(2, 1);
- _northWall.subA4D14(1, 3);
- _actor16.subA4D14(2, 5);
- _eastWall.subA4D14(2, 6);
+ _walkRegionsId = 1562;
+ _wallCorner1.setupWall(2, 1);
+ _northWall.setupWall(1, 3);
+ _wallCorner2.setupWall(2, 5);
+ _eastWall.setupWall(2, 6);
break;
case 4:
R2_GLOBALS._walkRegions.load(1563);
- _field419 = 1563;
- _northWall.subA4D14(2, 3);
+ _walkRegionsId = 1563;
+ _northWall.setupWall(2, 3);
break;
case 5:
R2_GLOBALS._walkRegions.load(1564);
- _field419 = 1564;
- _southWall.subA4D14(2, 4);
+ _walkRegionsId = 1564;
+ _southWall.setupWall(2, 4);
break;
case 6:
R2_GLOBALS._walkRegions.load(1565);
- _field419 = 1565;
- _actor14.subA4D14(1, 1);
- _westWall.subA4D14(1, 2);
- _northWall.subA4D14(3, 3);
+ _walkRegionsId = 1565;
+ _wallCorner1.setupWall(1, 1);
+ _westWall.setupWall(1, 2);
+ _northWall.setupWall(3, 3);
break;
case 7:
R2_GLOBALS._walkRegions.load(1566);
- _field419 = 1566;
- _actor14.subA4D14(1, 1);
- _westWall.subA4D14(1, 2);
- _northWall.subA4D14(2, 4);
+ _walkRegionsId = 1566;
+ _wallCorner1.setupWall(1, 1);
+ _westWall.setupWall(1, 2);
+ _northWall.setupWall(2, 4);
break;
case 8:
R2_GLOBALS._walkRegions.load(1567);
- _field419 = 1567;
- _westWall.subA4D14(5, 2);
+ _walkRegionsId = 1567;
+ _westWall.setupWall(5, 2);
break;
case 9:
R2_GLOBALS._walkRegions.load(1568);
- _field419 = 1568;
- _westWall.subA4D14(4, 2);
+ _walkRegionsId = 1568;
+ _westWall.setupWall(4, 2);
break;
case 10:
R2_GLOBALS._walkRegions.load(1569);
- _field419 = 1569;
- _actor14.subA4D14(3, 1);
+ _walkRegionsId = 1569;
+ _wallCorner1.setupWall(3, 1);
break;
case 11:
R2_GLOBALS._walkRegions.load(1570);
- _field419 = 1570;
- _actor14.subA4D14(1, 1);
- _westWall.subA4D14(1, 2);
+ _walkRegionsId = 1570;
+ _wallCorner1.setupWall(1, 1);
+ _westWall.setupWall(1, 2);
break;
case 12:
R2_GLOBALS._walkRegions.load(1571);
- _field419 = 1571;
- _actor16.subA4D14(1, 5);
- _eastWall.subA4D14(1, 6);
+ _walkRegionsId = 1571;
+ _wallCorner2.setupWall(1, 5);
+ _eastWall.setupWall(1, 6);
break;
case 13:
R2_GLOBALS._walkRegions.load(1572);
- _field419 = 1572;
- _actor14.subA4D14(1, 1);
- _westWall.subA4D14(1, 2);
- _southWall.subA4D14(1, 4);
+ _walkRegionsId = 1572;
+ _wallCorner1.setupWall(1, 1);
+ _westWall.setupWall(1, 2);
+ _southWall.setupWall(1, 4);
break;
case 14:
R2_GLOBALS._walkRegions.load(1573);
- _field419 = 1573;
- _southWall.subA4D14(1, 4);
- _actor16.subA4D14(1, 5);
- _eastWall.subA4D14(1, 6);
+ _walkRegionsId = 1573;
+ _southWall.setupWall(1, 4);
+ _wallCorner2.setupWall(1, 5);
+ _eastWall.setupWall(1, 6);
break;
case 15:
// South wall
R2_GLOBALS._walkRegions.load(1574);
- _field419 = 1574;
- _southWall.subA4D14(1, 4);
+ _walkRegionsId = 1574;
+ _southWall.setupWall(1, 4);
break;
case 16:
R2_GLOBALS._walkRegions.load(1570);
- _field419 = 1570;
- _actor14.subA4D14(2, 1);
- _westWall.subA4D14(2, 2);
+ _walkRegionsId = 1570;
+ _wallCorner1.setupWall(2, 1);
+ _westWall.setupWall(2, 2);
break;
case 17:
R2_GLOBALS._walkRegions.load(1570);
- _field419 = 1570;
- _actor14.subA4D14(2, 1);
- _westWall.subA4D14(3, 2);
+ _walkRegionsId = 1570;
+ _wallCorner1.setupWall(2, 1);
+ _westWall.setupWall(3, 2);
break;
case 18:
R2_GLOBALS._walkRegions.load(1571);
- _field419 = 1571;
- _actor16.subA4D14(2, 5);
- _eastWall.subA4D14(2, 6);
+ _walkRegionsId = 1571;
+ _wallCorner2.setupWall(2, 5);
+ _eastWall.setupWall(2, 6);
break;
case 19:
R2_GLOBALS._walkRegions.load(1571);
- _field419 = 1571;
- _actor16.subA4D14(2, 5);
- _eastWall.subA4D14(3, 6);
+ _walkRegionsId = 1571;
+ _wallCorner2.setupWall(2, 5);
+ _eastWall.setupWall(3, 6);
break;
default:
break;
@@ -8989,14 +8859,14 @@ void Scene1550::enterArea() {
int di = 0;
int tmpIdx = 0;
for (int i = 0; i < 127 * 4; i += 4) {
- if ((R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].x == R2_GLOBALS._scene1550JunkLocations[i]) &&
- (R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].y == R2_GLOBALS._scene1550JunkLocations[i + 1]) &&
+ if ((R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].x == R2_GLOBALS._scene1550JunkLocations[i]) &&
+ (R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].y == R2_GLOBALS._scene1550JunkLocations[i + 1]) &&
(R2_GLOBALS._scene1550JunkLocations[i + 2] != 0)) {
tmpIdx = R2_GLOBALS._scene1550JunkLocations[i + 3];
_junk[di].postInit();
- _junk[di]._effect = 6;
+ _junk[di]._effect = EFFECT_SHADED2;
_junk[di]._shade = 0;
- _junk[di]._fieldA4 = tmpIdx;
+ //_junk[di]._junkState = tmpIdx;
_junk[di]._junkNumber = i;
_junk[di].setDetails(1550, 62, -1, 63, 2, (SceneItem *) NULL);
if (R2_GLOBALS._scene1550JunkLocations[i + 2] == 41) {
@@ -9010,11 +8880,11 @@ void Scene1550::enterArea() {
R2_GLOBALS._walkRegions.disableRegion(scene1550JunkRegions[7]);
if (R2_INVENTORY.getObjectScene(R2_JOYSTICK) == 1550) {
- _actor9.postInit();
- _actor9.setup(1562, 3, 1);
- _actor9.setPosition(Common::Point(150, 70));
- _actor9.fixPriority(10);
- _actor9.setDetails(1550, 41, -1, 42, 2, (SceneItem *) NULL);
+ _joystick.postInit();
+ _joystick.setup(1562, 3, 1);
+ _joystick.setPosition(Common::Point(150, 70));
+ _joystick.fixPriority(10);
+ _joystick.setDetails(1550, 41, -1, 42, 2, (SceneItem *) NULL);
}
} else {
if (R2_GLOBALS._scene1550JunkLocations[i + 2] > 40) {
@@ -9024,7 +8894,7 @@ void Scene1550::enterArea() {
_junk[di].changeZoom(-1);
_junk[di].setup(1552, ((R2_GLOBALS._scene1550JunkLocations[i + 2] - 1) / 5) + 1, ((R2_GLOBALS._scene1550JunkLocations[i + 2] - 1) % 5) + 1);
}
- _junk[di].setPosition(Common::Point(k5A72E[tmpIdx], k5A73F[tmpIdx]));
+ _junk[di].setPosition(Common::Point(scene1550JunkX[tmpIdx], scene1550JunkY[tmpIdx]));
if (scene1550JunkRegions[tmpIdx] != 0)
R2_GLOBALS._walkRegions.disableRegion(scene1550JunkRegions[tmpIdx]);
di++;
@@ -9032,195 +8902,195 @@ void Scene1550::enterArea() {
}
}
- for (int i = 0; i < 15 * 3; i++) {
- if ((R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].x == k5A79B[i])
- && (R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].y == k5A79B[i + 1])) {
- tmpIdx = k5A79B[i + 2];
- switch (tmpIdx - 1) {
- case 0:
+ // Loop for detecting and setting up certain special areas within the map
+ for (int i = 0; i < 15 * 3; i += 3) {
+ if ((R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].x == scene1550SpecialAreas[i])
+ && (R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].y == scene1550SpecialAreas[i + 1])) {
+ int areaType = scene1550SpecialAreas[i + 2];
+ switch (areaType) {
+ case 1:
if (!R2_GLOBALS.getFlag(16)) {
- _landingStrut.postInit();
+ _wreckage2.postInit();
if (R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].y == 3)
- _landingStrut.setup(1555, 2, 1);
+ _wreckage2.setup(1555, 2, 1);
else
- _landingStrut.setup(1555, 1, 1);
- _landingStrut.setPosition(Common::Point(150, 100));
- _landingStrut.fixPriority(92);
- _landingStrut.setDetails(1550, 73, -1, -1, 2, (SceneItem *) NULL);
+ _wreckage2.setup(1555, 1, 1);
+ _wreckage2.setPosition(Common::Point(150, 100));
+ _wreckage2.fixPriority(92);
+ _wreckage2.setDetails(1550, 73, -1, -1, 2, (SceneItem *) NULL);
}
break;
- case 1:
- _actor13.postInit();
- warning("_actor13._actorName = \"dish\";");
+ case 2:
+ _dish.postInit();
if (R2_GLOBALS.getFlag(19))
- _actor13.setup(1556, 3, 5);
+ _dish.setup(1556, 3, 5);
else
- _actor13.setup(1556, 3, 1);
- _actor13.changeZoom(95);
- _actor13.setPosition(Common::Point(165, 83));
- _actor13.fixPriority(168);
- _actor13.setDetails(1550, 17, -1, 19, 2, (SceneItem *) NULL);
-
- _actor12.postInit();
- _actor12.setup(1556, 4, 1);
- _actor12.setPosition(Common::Point(191, 123));
- _actor12.changeZoom(95);
- _actor12.setDetails(1550, 65, -1, 66, 2, (SceneItem *) NULL);
-
- _actor5.postInit();
- _actor5._numFrames = 5;
+ _dish.setup(1556, 3, 1);
+ _dish.changeZoom(95);
+ _dish.setPosition(Common::Point(165, 83));
+ _dish.fixPriority(168);
+ _dish.setDetails(1550, 17, -1, 19, 2, (SceneItem *) NULL);
+
+ _dishTower.postInit();
+ _dishTower.setup(1556, 4, 1);
+ _dishTower.setPosition(Common::Point(191, 123));
+ _dishTower.changeZoom(95);
+ _dishTower.setDetails(1550, 65, -1, 66, 2, (SceneItem *) NULL);
+
+ _dishTowerShadow.postInit();
+ _dishTowerShadow._numFrames = 5;
if (R2_GLOBALS.getFlag(19))
- _actor5.setup(1556, 8, 5);
+ _dishTowerShadow.setup(1556, 8, 5);
else
- _actor5.setup(1556, 8, 1);
+ _dishTowerShadow.setup(1556, 8, 1);
- _actor5.setPosition(Common::Point(156, 151));
- _actor5.fixPriority(10);
+ _dishTowerShadow.setPosition(Common::Point(156, 151));
+ _dishTowerShadow.fixPriority(10);
- _actor4.postInit();
+ _walkway.postInit();
if (R2_GLOBALS.getFlag(20))
- _actor4.setup(1558, 3, 10);
+ _walkway.setup(1558, 3, 10);
else
- _actor4.setup(1558, 3, 1);
+ _walkway.setup(1558, 3, 1);
- _actor4.setPosition(Common::Point(172, 48));
- _actor4.fixPriority(169);
+ _walkway.setPosition(Common::Point(172, 48));
+ _walkway.fixPriority(169);
R2_GLOBALS._walkRegions.disableRegion(scene1550JunkRegions[15]);
break;
- case 2:
+ case 3:
_wreckage.postInit();
_wreckage.setup(1550, 1, 1);
_wreckage.setPosition(Common::Point(259, 55));
_wreckage.fixPriority(133);
_wreckage.setDetails(1550, 9, -1, -1, 2, (SceneItem *) NULL);
- _landingStrut.postInit();
- _landingStrut.setup(1550, 1, 2);
- _landingStrut.setPosition(Common::Point(259, 133));
- _landingStrut.fixPriority(105);
- _landingStrut.setDetails(1550, 9, -1, -1, 2, (SceneItem *) NULL);
+ _wreckage2.postInit();
+ _wreckage2.setup(1550, 1, 2);
+ _wreckage2.setPosition(Common::Point(259, 133));
+ _wreckage2.fixPriority(105);
+ _wreckage2.setDetails(1550, 9, -1, -1, 2, (SceneItem *) NULL);
if (R2_INVENTORY.getObjectScene(R2_GYROSCOPE) == 1550) {
- _actor10.postInit();
- _actor10.setup(1550, 7, 2);
- _actor10.setPosition(Common::Point(227, 30));
- _actor10.fixPriority(130);
- _actor10.setDetails(1550, 29, -1, 63, 2, (SceneItem *) NULL);
+ _gyroscope.postInit();
+ _gyroscope.setup(1550, 7, 2);
+ _gyroscope.setPosition(Common::Point(227, 30));
+ _gyroscope.fixPriority(130);
+ _gyroscope.setDetails(1550, 29, -1, 63, 2, (SceneItem *) NULL);
}
break;
- case 3:
+ case 4:
_wreckage.postInit();
_wreckage.setup(1550, 1, 4);
_wreckage.setPosition(Common::Point(76, 131));
_wreckage.fixPriority(10);
_wreckage.setDetails(1550, 9, -1, -1, 2, (SceneItem *) NULL);
- _landingStrut.postInit();
- _landingStrut.setup(1550, 1, 3);
- _landingStrut.setPosition(Common::Point(76, 64));
- _landingStrut.setDetails(1550, 9, -1, -1, 2, (SceneItem *) NULL);
+ _wreckage2.postInit();
+ _wreckage2.setup(1550, 1, 3);
+ _wreckage2.setPosition(Common::Point(76, 64));
+ _wreckage2.setDetails(1550, 9, -1, -1, 2, (SceneItem *) NULL);
if (R2_INVENTORY.getObjectScene(R2_DIAGNOSTICS_DISPLAY) == 1550) {
- _actor11.postInit();
- _actor11.setup(1504, 4, 1);
- _actor11.setPosition(Common::Point(49, 35));
- _actor11.animate(ANIM_MODE_2, NULL);
- _actor11._numFrames = 4;
- _actor11.fixPriority(65);
- _actor11.setDetails(1550, 14, 15, 63, 2, (SceneItem *) NULL);
+ _diagnosticsDisplay.postInit();
+ _diagnosticsDisplay.setup(1504, 4, 1);
+ _diagnosticsDisplay.setPosition(Common::Point(49, 35));
+ _diagnosticsDisplay.animate(ANIM_MODE_2, NULL);
+ _diagnosticsDisplay._numFrames = 4;
+ _diagnosticsDisplay.fixPriority(65);
+ _diagnosticsDisplay.setDetails(1550, 14, 15, 63, 2, (SceneItem *) NULL);
}
if (R2_INVENTORY.getObjectScene(R2_AIRBAG) == 1550) {
- _actor8.postInit();
- _actor8.setup(1550, 7, 1);
- _actor8.setPosition(Common::Point(45, 44));
- _actor8.fixPriority(150);
- _actor8.setDetails(1550, 44, -1, 63, 2, (SceneItem *) NULL);
+ _airbag.postInit();
+ _airbag.setup(1550, 7, 1);
+ _airbag.setPosition(Common::Point(45, 44));
+ _airbag.fixPriority(150);
+ _airbag.setDetails(1550, 44, -1, 63, 2, (SceneItem *) NULL);
}
break;
- case 4:
+ case 5:
_wreckage.postInit();
_wreckage.setup(1550, 2, 4);
_wreckage.setPosition(Common::Point(243, 131));
_wreckage.fixPriority(10);
_wreckage.setDetails(1550, 9, -1, -1, 2, (SceneItem *) NULL);
- _landingStrut.postInit();
- _landingStrut.setup(1550, 2, 3);
- _landingStrut.setPosition(Common::Point(243, 64));
- _landingStrut.setDetails(1550, 9, -1, -1, 2, (SceneItem *) NULL);
+ _wreckage2.postInit();
+ _wreckage2.setup(1550, 2, 3);
+ _wreckage2.setPosition(Common::Point(243, 64));
+ _wreckage2.setDetails(1550, 9, -1, -1, 2, (SceneItem *) NULL);
break;
- case 5:
+ case 6:
_wreckage.postInit();
_wreckage.setup(1550, 2, 1);
_wreckage.setPosition(Common::Point(60, 55));
_wreckage.fixPriority(133);
_wreckage.setDetails(1550, 9, -1, -1, 2, (SceneItem *) NULL);
- _landingStrut.postInit();
- _landingStrut.setup(1550, 2, 2);
- _landingStrut.setPosition(Common::Point(60, 133));
- _landingStrut.fixPriority(106);
- _landingStrut.setDetails(1550, 9, -1, -1, 2, (SceneItem *) NULL);
+ _wreckage2.postInit();
+ _wreckage2.setup(1550, 2, 2);
+ _wreckage2.setPosition(Common::Point(60, 133));
+ _wreckage2.fixPriority(106);
+ _wreckage2.setDetails(1550, 9, -1, -1, 2, (SceneItem *) NULL);
break;
- case 6:
+ case 7:
_wreckage.postInit();
_wreckage.setup(1550, 3, 1);
_wreckage.setPosition(Common::Point(281, 132));
_wreckage.setDetails(1550, 56, -1, -1, 2, (SceneItem *) NULL);
break;
- case 7:
+ case 8:
_wreckage.postInit();
_wreckage.setup(1550, 3, 2);
_wreckage.setPosition(Common::Point(57, 96));
_wreckage.fixPriority(70);
_wreckage.setDetails(1550, 56, -1, -1, 2, (SceneItem *) NULL);
- _landingStrut.postInit();
- _landingStrut.setup(1550, 3, 3);
- _landingStrut.setPosition(Common::Point(145, 88));
- _landingStrut.fixPriority(55);
- _landingStrut.setDetails(1550, 56, -1, -1, 2, (SceneItem *) NULL);
-
- _actor2.postInit();
- _actor2.setup(1550, 3, 4);
- _actor2.setPosition(Common::Point(64, 137));
- _actor2.fixPriority(115);
- _actor2.setDetails(1550, 56, -1, -1, 2, (SceneItem *) NULL);
-
- _actor3.postInit();
- _actor3.setup(1550, 5, 1);
- _actor3.setPosition(Common::Point(60, 90));
- _actor3.fixPriority(45);
+ _wreckage2.postInit();
+ _wreckage2.setup(1550, 3, 3);
+ _wreckage2.setPosition(Common::Point(145, 88));
+ _wreckage2.fixPriority(55);
+ _wreckage2.setDetails(1550, 56, -1, -1, 2, (SceneItem *) NULL);
+
+ _wreckage3.postInit();
+ _wreckage3.setup(1550, 3, 4);
+ _wreckage3.setPosition(Common::Point(64, 137));
+ _wreckage3.fixPriority(115);
+ _wreckage3.setDetails(1550, 56, -1, -1, 2, (SceneItem *) NULL);
+
+ _wreckage4.postInit();
+ _wreckage4.setup(1550, 5, 1);
+ _wreckage4.setPosition(Common::Point(60, 90));
+ _wreckage4.fixPriority(45);
break;
- case 8:
+ case 9:
_wreckage.postInit();
_wreckage.setup(1550, 4, 2);
_wreckage.setPosition(Common::Point(262, 96));
_wreckage.fixPriority(70);
_wreckage.setDetails(1550, 56, -1, -1, 2, (SceneItem *) NULL);
- _landingStrut.postInit();
- _landingStrut.setup(1550, 4, 3);
- _landingStrut.setPosition(Common::Point(174, 88));
- _landingStrut.fixPriority(55);
- _landingStrut.setDetails(1550, 56, -1, -1, 2, (SceneItem *) NULL);
-
- _actor2.postInit();
- _actor2.setup(1550, 4, 4);
- _actor2.setPosition(Common::Point(255, 137));
- _actor2.fixPriority(115);
- _actor2.setDetails(1550, 56, -1, -1, 2, (SceneItem *) NULL);
-
- _actor3.postInit();
- _actor3.setup(1550, 6, 1);
- _actor3.setPosition(Common::Point(259, 90));
- _actor3.fixPriority(45);
+ _wreckage2.postInit();
+ _wreckage2.setup(1550, 4, 3);
+ _wreckage2.setPosition(Common::Point(174, 88));
+ _wreckage2.fixPriority(55);
+ _wreckage2.setDetails(1550, 56, -1, -1, 2, (SceneItem *) NULL);
+
+ _wreckage3.postInit();
+ _wreckage3.setup(1550, 4, 4);
+ _wreckage3.setPosition(Common::Point(255, 137));
+ _wreckage3.fixPriority(115);
+ _wreckage3.setDetails(1550, 56, -1, -1, 2, (SceneItem *) NULL);
+
+ _wreckage4.postInit();
+ _wreckage4.setup(1550, 6, 1);
+ _wreckage4.setPosition(Common::Point(259, 90));
+ _wreckage4.fixPriority(45);
break;
- case 9:
+ case 10:
_wreckage.postInit();
_wreckage.setup(1550, 4, 1);
_wreckage.setPosition(Common::Point(38, 132));
_wreckage.setDetails(1550, 56, -1, -1, 2, (SceneItem *) NULL);
break;
- case 11:
+ case 12:
// Intact ship
_shipComponents[7].setupShipComponent(8);
_shipComponents[0].setupShipComponent(1);
@@ -9230,6 +9100,7 @@ void Scene1550::enterArea() {
_shipComponents[4].setupShipComponent(5);
_shipComponents[5].setupShipComponent(6);
_shipComponents[6].setupShipComponent(7);
+ break;
default:
break;
}
@@ -9238,12 +9109,12 @@ void Scene1550::enterArea() {
if (R2_GLOBALS._s1550PlayerArea[R2_QUINN] == R2_GLOBALS._s1550PlayerArea[R2_SEEKER]) {
_companion.postInit();
- _companion._effect = 7;
+ _companion._effect = EFFECT_SHADED2;
_companion.changeZoom(-1);
- assert((_field419 >= 1550) && (_field419 <= 2008));
- R2_GLOBALS._walkRegions.disableRegion(k5A750[_field419 - 1550]);
- _companion.setPosition(Common::Point(k5A72E[k5A76D[_field419 - 1550]], k5A73F[k5A76D[_field419 - 1550]] + 8));
+ assert((_walkRegionsId >= 1550) && (_walkRegionsId <= 2008));
+ R2_GLOBALS._walkRegions.disableRegion(k5A750[_walkRegionsId - 1550]);
+ _companion.setPosition(Common::Point(scene1550JunkX[k5A76D[_walkRegionsId - 1550]], scene1550JunkY[k5A76D[_walkRegionsId - 1550]] + 8));
if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
if (R2_GLOBALS._player._characterScene[R2_SEEKER] == 1580) {
_companion.setup(1516, 3, 17);
@@ -9272,177 +9143,206 @@ void Scene1550::enterArea() {
}
/*--------------------------------------------------------------------------
- * Scene 1575 -
+ * Scene 1575 - Spaceport - unused ship scene
*
*--------------------------------------------------------------------------*/
-Scene1575::Scene1575() {
- _field412 = 0;
- _field414 = 0;
- _field416 = 0;
- _field418 = 0;
- _field41A = 0;
-}
-void Scene1575::synchronize(Serializer &s) {
- SceneExt::synchronize(s);
-
- s.syncAsSint16LE(_field412);
- s.syncAsSint16LE(_field414);
- s.syncAsSint16LE(_field416);
- s.syncAsSint16LE(_field418);
- s.syncAsSint16LE(_field41A);
-}
-
-Scene1575::Hotspot1::Hotspot1() {
- _field34 = 0;
- _field36 = 0;
+Scene1575::Button::Button() {
+ _buttonId = 0;
+ _pressed = false;
}
-void Scene1575::Hotspot1::synchronize(Serializer &s) {
+void Scene1575::Button::synchronize(Serializer &s) {
NamedHotspot::synchronize(s);
- s.syncAsSint16LE(_field34);
- s.syncAsSint16LE(_field36);
+ s.syncAsSint16LE(_buttonId);
+ s.syncAsSint16LE(_pressed);
}
-void Scene1575::Hotspot1::process(Event &event) {
- if ((event.eventType != EVENT_BUTTON_DOWN) || (R2_GLOBALS._events.getCursor() != R2_STEPPING_DISKS) || (!_bounds.contains(event.mousePos))) {
- if (_field36 == 0)
- return;
- if ((_field34 == 1) || (event.eventType == EVENT_BUTTON_UP) || (!_bounds.contains(event.mousePos))) {
- _field36 = 0;
- return;
- }
- }
- _field36 = 1;
+void Scene1575::Button::process(Event &event) {
Scene1575 *scene = (Scene1575 *)R2_GLOBALS._sceneManager._scene;
+ bool isInBounds = _bounds.contains(event.mousePos);
+ CursorType cursor = R2_GLOBALS._events.getCursor();
- event.handled = true;
- if (R2_GLOBALS.getFlag(18) && (_field34 > 1) && (_field34 < 6)) {
- warning("sub1A03B(\"Better not move the laser while it\'s firing!\", 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);");
- return;
- }
- int di = scene->_actor1._position.x;
+ if ((event.eventType == EVENT_BUTTON_DOWN && cursor == CURSOR_USE && isInBounds) ||
+ (_pressed && _buttonId != 1 && event.eventType == EVENT_BUTTON_UP && isInBounds)) {
+ // Button pressed
+ _pressed = true;
+ Common::Point pos = scene->_actor1._position;
+ event.handled = true;
- switch (_field34 - 1) {
- case 0:
- if (R2_GLOBALS.getFlag(18)) {
- scene->_actor14.hide();
- scene->_actor15.hide();
- R2_GLOBALS.clearFlag(18);
- } else if ((scene->_actor12._position.x == 85) && (scene->_actor12._position.y == 123)) {
- scene->_actor14.show();
- scene->_actor15.show();
- R2_GLOBALS.setFlag(18);
+ if (!R2_GLOBALS.getFlag(18) || _buttonId <= 1 || _buttonId >= 6) {
+ switch (_buttonId) {
+ case 1:
+ if (R2_GLOBALS.getFlag(18)) {
+ scene->_actor14.hide();
+ scene->_actor15.hide();
+ R2_GLOBALS.clearFlag(18);
+ } else if ((scene->_actor12._position.x == 85) && (scene->_actor12._position.y == 123)) {
+ scene->_actor14.show();
+ scene->_actor15.show();
+ R2_GLOBALS.setFlag(18);
+ } else {
+ SceneItem::display("That's probably not a good thing, ya know!");
+ }
+ break;
+ case 2:
+ if (scene->_field41A < 780) {
+ if (pos.x > 54)
+ pos.x -= 65;
+ pos.x += 2;
+ scene->_field41A += 2;
+
+ for (int i = 0; i < 17; i++)
+ scene->_arrActor[i].setPosition(Common::Point(scene->_arrActor[i]._position.x + 2, scene->_arrActor[i]._position.y));
+
+ scene->_actor13.setPosition(Common::Point(scene->_actor13._position.x + 2, scene->_actor13._position.y));
+ scene->_actor12.setPosition(Common::Point(scene->_actor12._position.x + 2, scene->_actor12._position.y));
+ scene->_actor1.setPosition(Common::Point(pos.x, pos.y));
+ scene->_actor2.setPosition(Common::Point(pos.x + 65, pos.y));
+ scene->_actor3.setPosition(Common::Point(pos.x + 130, pos.y));
+ }
+ break;
+ case 3:
+ if (scene->_field41A > 0) {
+ if (pos.x < -8)
+ pos.x += 65;
+
+ pos.x -= 2;
+ scene->_field41A -= 2;
+ for (int i = 0; i < 17; i++)
+ scene->_arrActor[i].setPosition(Common::Point(scene->_arrActor[i]._position.x - 2, scene->_arrActor[i]._position.y));
+
+ scene->_actor13.setPosition(Common::Point(scene->_actor13._position.x - 2, scene->_actor13._position.y));
+ scene->_actor12.setPosition(Common::Point(scene->_actor12._position.x - 2, scene->_actor12._position.y));
+ scene->_actor1.setPosition(Common::Point(pos.x, pos.y));
+ scene->_actor2.setPosition(Common::Point(pos.x + 65, pos.y));
+ scene->_actor3.setPosition(Common::Point(pos.x + 130, pos.y));
+ }
+ break;
+ case 4: {
+ if (pos.y < 176) {
+ ++pos.y;
+ for (int i = 0; i < 17; ++i)
+ scene->_arrActor[i].setPosition(Common::Point(scene->_arrActor[i]._position.x, scene->_arrActor[i]._position.y + 1));
+
+ scene->_actor13.setPosition(Common::Point(scene->_actor13._position.x, scene->_actor13._position.y + 1));
+ scene->_actor12.setPosition(Common::Point(scene->_actor12._position.x, scene->_actor12._position.y + 1));
+ scene->_actor1.setPosition(Common::Point(pos.x, pos.y));
+ scene->_actor2.setPosition(Common::Point(pos.x + 65, pos.y));
+ scene->_actor3.setPosition(Common::Point(pos.x + 130, pos.y));
+ }
+ }
+ break;
+ case 5: {
+ if (pos.y > 145) {
+ --pos.y;
+ for (int i = 0; i < 17; ++i)
+ scene->_arrActor[i].setPosition(Common::Point(scene->_arrActor[i]._position.x, scene->_arrActor[i]._position.y - 1));
+
+ scene->_actor13.setPosition(Common::Point(scene->_actor13._position.x, scene->_actor13._position.y - 1));
+ scene->_actor12.setPosition(Common::Point(scene->_actor12._position.x, scene->_actor12._position.y - 1));
+ scene->_actor1.setPosition(Common::Point(pos.x, pos.y));
+ scene->_actor2.setPosition(Common::Point(pos.x + 65, pos.y));
+ scene->_actor3.setPosition(Common::Point(pos.x + 130, pos.y));
+ }
+ }
+ break;
+ case 6:
+ R2_GLOBALS._sceneManager.changeScene(1550);
+ break;
+ default:
+ break;
+ }
+
+ int j = 0;
+ for (int i = 0; i < 17; i++) {
+ if (scene->_arrActor[i]._bounds.contains(85, 116))
+ j = i;
+ }
+
+ if (scene->_actor13._bounds.contains(85, 116))
+ j = 18;
+
+ if (scene->_actor12._bounds.contains(85, 116))
+ j = 19;
+
+ if (j)
+ scene->_actor11.show();
+ else
+ scene->_actor11.hide();
} else {
- warning("sub1A03B(\"That\'s probably not a good thing, ya know!\", 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);");
+ SceneItem::display("Better not move the laser while it's firing!");
}
- break;
- case 1:
- if (scene->_field41A < 780) {
- if (di > 54)
- di -= 65;
- di += 2;
- scene->_field41A += 2;
+ } else {
+ _pressed = false;
+ }
+}
- for (int i = 0; i < 17; i++)
- scene->_arrActor[i].setPosition(Common::Point(scene->_arrActor[i]._position.x + 2, scene->_arrActor[i]._position.y));
+bool Scene1575::Button::startAction(CursorType action, Event &event) {
+ if (action == CURSOR_USE)
+ return false;
+ return SceneHotspot::startAction(action, event);
+}
- scene->_actor13.setPosition(Common::Point(scene->_actor13._position.x + 2, scene->_actor13._position.y));
- scene->_actor12.setPosition(Common::Point(scene->_actor12._position.x + 2, scene->_actor12._position.y));
- scene->_actor1.setPosition(Common::Point(di, scene->_actor1._position.y));
- scene->_actor2.setPosition(Common::Point(di + 65, scene->_actor1._position.y));
- scene->_actor3.setPosition(Common::Point(di + 130, scene->_actor1._position.y));
- }
+void Scene1575::Button::initButton(int buttonId) {
+ _buttonId = buttonId;
+ _pressed = false;
+ EventHandler::postInit();
+
+ switch (_buttonId) {
+ case 1:
+ setDetails(Rect(53, 165, 117, 190), -1, -1, -1, 2, 1, NULL);
break;
case 2:
- if (scene->_field41A > 0) {
- if (di < -8)
- di += 65;
-
- di -= 2;
- scene->_field41A -= 2;
- for (int i = 0; i < 17; i++)
- scene->_arrActor[i].setPosition(Common::Point(scene->_arrActor[i]._position.x - 2, scene->_arrActor[i]._position.y));
-
- scene->_actor13.setPosition(Common::Point(scene->_actor13._position.x - 2, scene->_actor13._position.y));
- scene->_actor12.setPosition(Common::Point(scene->_actor12._position.x - 2, scene->_actor12._position.y));
- scene->_actor1.setPosition(Common::Point(di, scene->_actor1._position.y));
- scene->_actor2.setPosition(Common::Point(di + 65, scene->_actor1._position.y));
- scene->_actor3.setPosition(Common::Point(di + 130, scene->_actor1._position.y));
- }
+ setDetails(Rect(151, 142, 189, 161), -1, -1, -1, 2, 1, NULL);
break;
- case 3: {
- int tmpPosY = scene->_actor1._position.y;
- if (tmpPosY < 176) {
- ++tmpPosY;
- for (int i = 0; i < 17; ++i)
- scene->_arrActor[i].setPosition(Common::Point(scene->_arrActor[i]._position.x, scene->_arrActor[i]._position.y + 1));
-
- scene->_actor13.setPosition(Common::Point(scene->_actor13._position.x, scene->_actor13._position.y + 1));
- scene->_actor12.setPosition(Common::Point(scene->_actor12._position.x, scene->_actor12._position.y + 1));
- scene->_actor1.setPosition(Common::Point(di, scene->_actor1._position.y));
- scene->_actor2.setPosition(Common::Point(di + 65, scene->_actor1._position.y));
- scene->_actor3.setPosition(Common::Point(di + 130, scene->_actor1._position.y));
- }
- }
+ case 3:
+ setDetails(Rect(225, 142, 263, 161), -1, -1, -1, 2, 1, NULL);
break;
- case 4: {
- int tmpPosY = scene->_actor1._position.y;
- if (tmpPosY > 145) {
- tmpPosY--;
- for (int i = 0; i < 17; ++i)
- scene->_arrActor[i].setPosition(Common::Point(scene->_arrActor[i]._position.x, scene->_arrActor[i]._position.y - 1));
-
- scene->_actor13.setPosition(Common::Point(scene->_actor13._position.x, scene->_actor13._position.y - 1));
- scene->_actor12.setPosition(Common::Point(scene->_actor12._position.x, scene->_actor12._position.y - 1));
- scene->_actor1.setPosition(Common::Point(di, scene->_actor1._position.y));
- scene->_actor2.setPosition(Common::Point(di + 65, scene->_actor1._position.y));
- scene->_actor3.setPosition(Common::Point(di + 130, scene->_actor1._position.y));
- }
- }
+ case 4:
+ setDetails(Rect(188, 122, 226, 140), -1, -1, -1, 2, 1, NULL);
break;
case 5:
- R2_GLOBALS._sceneManager.changeScene(1550);
+ setDetails(Rect(188, 162, 226, 180), -1, -1, -1, 2, 1, NULL);
+ break;
+ case 6:
+ setDetails(Rect(269, 169, 301, 185), -1, -1, -1, 2, 1, NULL);
break;
default:
break;
}
+}
- int j = 0;
- for (int i = 0; i < 17; i++) {
- if (scene->_arrActor[i]._bounds.contains(85, 116))
- j = i;
- }
-
- if (scene->_actor13._bounds.contains(85, 116))
- j = 18;
-
- if (scene->_actor12._bounds.contains(85, 116))
- j = 19;
+/*--------------------------------------------------------------------------*/
- if (j)
- scene->_actor11.show();
- else
- scene->_actor11.hide();
+Scene1575::Scene1575() {
+ _field412 = 0;
+ _field414 = 390;
+ _field416 = 0;
+ _field418 = 0;
+ _field41A = 0;
}
-bool Scene1575::Hotspot1::startAction(CursorType action, Event &event) {
- if (action == CURSOR_USE)
- return false;
- return SceneHotspot::startAction(action, event);
+void Scene1575::synchronize(Serializer &s) {
+ SceneExt::synchronize(s);
+
+ s.syncAsSint16LE(_field412);
+ s.syncAsSint16LE(_field414);
+ s.syncAsSint16LE(_field416);
+ s.syncAsSint16LE(_field418);
+ s.syncAsSint16LE(_field41A);
}
-void Scene1575::Hotspot1::subA910D(int indx) {
- warning("STUB: Scene1575:Hotspot1::subA910D(%d)", indx);
+double hypotenuse(double v1, double v2) {
+ return sqrt(v1 * v1 + v2 * v2);
}
void Scene1575::postInit(SceneObjectList *OwnerList) {
loadScene(1575);
R2_GLOBALS._uiElements._active = false;
- R2_GLOBALS._v5589E = Rect(0, 0, 320, 200);
SceneExt::postInit();
- _field414 = 390;
+ R2_GLOBALS._interfaceY = SCREEN_HEIGHT;
_actor1.postInit();
_actor1.setup(1575, 1, 1);
@@ -9461,8 +9361,17 @@ void Scene1575::postInit(SceneObjectList *OwnerList) {
for (int i = 0; i < 17; i++) {
_arrActor[i].postInit();
- _arrActor[i].setup(1575, 2, k5A7F6[(3 * i) + 2]);
- warning("TODO: immense pile of floating operations");
+ _arrActor[i].setup(1575, 2, k5A7F6[3 * i + 2]);
+
+ double v1 = hypotenuse(2.0, 3 - k5A7F6[3 * i]);
+ v1 += hypotenuse(2.0, 3 - k5A7F6[3 * i + 1]);
+ int yp = (int)(sqrt(v1) * 75.0 / 17.0 - 161.0);
+
+ int angle = R2_GLOBALS._gfxManagerInstance.getAngle(
+ Common::Point(3, 16), Common::Point(k5A7F6[3 * i], k5A7F6[3 * i + 1]));
+ int xp = angle * 78 / 9 - 319;
+
+ _arrActor[i].setPosition(Common::Point(xp, yp));
_arrActor[i].fixPriority(6);
}
@@ -9494,12 +9403,13 @@ void Scene1575::postInit(SceneObjectList *OwnerList) {
_actor10.setup(1575, 3, 2);
_actor10.setPosition(Common::Point(287, 91));
- _item1.subA910D(1);
- _item1.subA910D(2);
- _item1.subA910D(3);
- _item1.subA910D(4);
- _item1.subA910D(5);
- _item1.subA910D(6);
+ // Initialize buttons
+ _button1.initButton(1);
+ _button2.initButton(2);
+ _button3.initButton(3);
+ _button4.initButton(4);
+ _button5.initButton(5);
+ _button6.initButton(6);
_actor11.postInit();
_actor11.setup(1575, 4, 2);
@@ -9527,6 +9437,7 @@ void Scene1575::postInit(SceneObjectList *OwnerList) {
_actor13.postInit();
_actor13.setup(1575, 2, 4);
+ // TODO
warning("TODO: another immense pile of floating operations");
_actor12.postInit();
@@ -9552,8 +9463,6 @@ void Scene1575::postInit(SceneObjectList *OwnerList) {
void Scene1575::remove() {
SceneExt::remove();
- R2_GLOBALS._v5589E.top = 3;
- R2_GLOBALS._v5589E.bottom = 168;
R2_GLOBALS._uiElements._active = true;
}
@@ -9565,7 +9474,6 @@ void Scene1575::process(Event &event) {
Scene::process(event);
g_globals->_sceneObjects->recurse(SceneHandler::dispatchObject);
- warning("TODO: check Scene1575::process");
}
void Scene1575::dispatch() {
@@ -9655,26 +9563,24 @@ void Scene1575::dispatch() {
* Scene 1580 - Inside wreck
*
*--------------------------------------------------------------------------*/
+
Scene1580::Scene1580() {
- _field412 = 0;
}
void Scene1580::synchronize(Serializer &s) {
SceneExt::synchronize(s);
-
- s.syncAsSint16LE(_field412);
}
-bool Scene1580::Hotspot1::startAction(CursorType action, Event &event) {
- Scene1580 *scene = (Scene1580 *)R2_GLOBALS._sceneManager._scene;
-
+bool Scene1580::JoystickPlug::startAction(CursorType action, Event &event) {
if (action == R2_JOYSTICK) {
+ Scene1580 *scene = (Scene1580 *)R2_GLOBALS._sceneManager._scene;
+
R2_INVENTORY.setObjectScene(R2_JOYSTICK, 1580);
- R2_GLOBALS._sceneItems.remove(&scene->_item1);
- scene->_actor2.postInit();
- scene->_actor2.setup(1580, 1, 4);
- scene->_actor2.setPosition(Common::Point(159, 163));
- scene->_actor2.setDetails(1550, 78, -1, -1, 2, (SceneItem *) NULL);
+ R2_GLOBALS._sceneItems.remove(&scene->_joystickPlug);
+ scene->_joystick.postInit();
+ scene->_joystick.setup(1580, 1, 4);
+ scene->_joystick.setPosition(Common::Point(159, 163));
+ scene->_joystick.setDetails(1550, 78, -1, -1, 2, (SceneItem *) NULL);
scene->_arrActor[5].remove();
@@ -9684,29 +9590,29 @@ bool Scene1580::Hotspot1::startAction(CursorType action, Event &event) {
return SceneHotspot::startAction(action, event);
}
-bool Scene1580::Hotspot2::startAction(CursorType action, Event &event) {
- Scene1580 *scene = (Scene1580 *)R2_GLOBALS._sceneManager._scene;
-
+bool Scene1580::ScreenSlot::startAction(CursorType action, Event &event) {
if (action == R2_DIAGNOSTICS_DISPLAY) {
+ Scene1580 *scene = (Scene1580 *)R2_GLOBALS._sceneManager._scene;
+
R2_INVENTORY.setObjectScene(R2_DIAGNOSTICS_DISPLAY, 1580);
R2_GLOBALS._player.disableControl();
- R2_GLOBALS._sceneItems.remove(&scene->_item2);
+ R2_GLOBALS._sceneItems.remove(&scene->_screenSlot);
- scene->_actor3.postInit();
- scene->_actor3.setup(1580, 1, 1);
- scene->_actor3.setPosition(Common::Point(124, 108));
- scene->_actor3.fixPriority(10);
+ scene->_screen.postInit();
+ scene->_screen.setup(1580, 1, 1);
+ scene->_screen.setPosition(Common::Point(124, 108));
+ scene->_screen.fixPriority(10);
if (R2_INVENTORY.getObjectScene(R2_JOYSTICK) == 1580)
- scene->_actor3.setDetails(1550, 14, -1, -1, 5, &scene->_actor2);
+ scene->_screen.setDetails(1550, 14, -1, -1, 5, &scene->_joystick);
else
- scene->_actor3.setDetails(1550, 14, -1, -1, 2, (SceneItem *)NULL);
+ scene->_screen.setDetails(1550, 14, -1, -1, 2, (SceneItem *)NULL);
- scene->_actor1.postInit();
- scene->_actor1.setup(1580, 3, 1);
- scene->_actor1.setPosition(Common::Point(124, 109));
- scene->_actor1.fixPriority(20);
- scene->_field412 = 1;
+ scene->_screenDisplay.postInit();
+ scene->_screenDisplay.setup(1580, 3, 1);
+ scene->_screenDisplay.setPosition(Common::Point(124, 109));
+ scene->_screenDisplay.fixPriority(20);
+ //scene->_field412 = 1;
scene->_sceneMode = 10;
scene->setAction(&scene->_sequenceManager, scene, 1, &R2_GLOBALS._player, NULL);
@@ -9716,7 +9622,7 @@ bool Scene1580::Hotspot2::startAction(CursorType action, Event &event) {
return SceneHotspot::startAction(action, event);
}
-bool Scene1580::Actor2::startAction(CursorType action, Event &event) {
+bool Scene1580::Joystick::startAction(CursorType action, Event &event) {
if ( (action == CURSOR_USE) && (R2_INVENTORY.getObjectScene(R2_DIAGNOSTICS_DISPLAY) == 1580)
&& (R2_INVENTORY.getObjectScene(R2_FUEL_CELL) == 0) && (R2_INVENTORY.getObjectScene(R2_GUIDANCE_MODULE) == 0)
&& (R2_INVENTORY.getObjectScene(R2_RADAR_MECHANISM) == 0) && (R2_INVENTORY.getObjectScene(R2_GYROSCOPE) == 0)
@@ -9736,13 +9642,13 @@ bool Scene1580::Actor2::startAction(CursorType action, Event &event) {
return SceneActor::startAction(action, event);
}
-bool Scene1580::Actor3::startAction(CursorType action, Event &event) {
+bool Scene1580::Screen::startAction(CursorType action, Event &event) {
if ((action == CURSOR_USE) && (R2_INVENTORY.getObjectScene(R2_BROKEN_DISPLAY) == 1580)) {
Scene1580 *scene = (Scene1580 *)R2_GLOBALS._sceneManager._scene;
R2_INVENTORY.setObjectScene(R2_BROKEN_DISPLAY, R2_GLOBALS._player._characterIndex);
- scene->_item2.setDetails(Rect(69, 29, 177, 108), 1550, 82, -1, -1, 2, NULL);
- scene->_actor1.remove();
+ scene->_screenSlot.setDetails(Rect(69, 29, 177, 108), 1550, 82, -1, -1, 2, NULL);
+ scene->_screenDisplay.remove();
remove();
return true;
}
@@ -9750,21 +9656,21 @@ bool Scene1580::Actor3::startAction(CursorType action, Event &event) {
return SceneActor::startAction(action, event);
}
-bool Scene1580::Actor4::startAction(CursorType action, Event &event) {
+bool Scene1580::StorageCompartment::startAction(CursorType action, Event &event) {
if (action != CURSOR_USE)
return SceneActor::startAction(action, event);
Scene1580 *scene = (Scene1580 *)R2_GLOBALS._sceneManager._scene;
R2_GLOBALS._player.disableControl();
- R2_GLOBALS._sceneItems.remove(&scene->_actor4);
+ R2_GLOBALS._sceneItems.remove(&scene->_storageCompartment);
scene->_sceneMode = 0;
animate(ANIM_MODE_5, scene);
return true;
}
-bool Scene1580::Actor5::startAction(CursorType action, Event &event) {
+bool Scene1580::HatchButton::startAction(CursorType action, Event &event) {
if (action != CURSOR_USE)
return SceneActor::startAction(action, event);
@@ -9778,7 +9684,7 @@ bool Scene1580::Actor5::startAction(CursorType action, Event &event) {
return true;
}
-bool Scene1580::Actor6::startAction(CursorType action, Event &event) {
+bool Scene1580::ThrusterValve::startAction(CursorType action, Event &event) {
Scene1580 *scene = (Scene1580 *)R2_GLOBALS._sceneManager._scene;
switch (action) {
@@ -9810,7 +9716,7 @@ bool Scene1580::Actor6::startAction(CursorType action, Event &event) {
return SceneActor::startAction(action, event);
}
-bool Scene1580::Actor7::startAction(CursorType action, Event &event) {
+bool Scene1580::Ignitor::startAction(CursorType action, Event &event) {
Scene1580 *scene = (Scene1580 *)R2_GLOBALS._sceneManager._scene;
switch (action) {
@@ -9846,7 +9752,6 @@ void Scene1580::postInit(SceneObjectList *OwnerList) {
loadScene(1580);
R2_GLOBALS._sceneManager._fadeMode = FADEMODE_GRADUAL;
SceneExt::postInit();
- _field412 = 0;
_stripManager.setColors(60, 255);
_stripManager.setFontNumber(3);
@@ -9857,89 +9762,89 @@ void Scene1580::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player.disableControl();
if (R2_INVENTORY.getObjectScene(R2_JOYSTICK) == 1580) {
- _actor2.postInit();
- _actor2.setup(1580, 1, 4);
- _actor2.setPosition(Common::Point(159, 163));
- _actor2.setDetails(1550, 78, -1, -1, 1, (SceneItem *) NULL);
+ _joystick.postInit();
+ _joystick.setup(1580, 1, 4);
+ _joystick.setPosition(Common::Point(159, 163));
+ _joystick.setDetails(1550, 78, -1, -1, 1, (SceneItem *) NULL);
} else {
- _item1.setDetails(Rect(141, 148, 179, 167), 1550, 79, -1, -1, 1, NULL);
+ _joystickPlug.setDetails(Rect(141, 148, 179, 167), 1550, 79, -1, -1, 1, NULL);
}
if (R2_INVENTORY.getObjectScene(R2_BROKEN_DISPLAY) == 1580) {
- _actor3.postInit();
- _actor3.setup(1580, 1, 1);
- _actor3.setPosition(Common::Point(124, 108));
- _actor3.fixPriority(10);
- _actor3.setDetails(1550, 13, -1, -1, 1, (SceneItem *) NULL);
-
- _actor1.postInit();
- _actor1.setup(1580, 1, 3);
- _actor1.setPosition(Common::Point(124, 96));
- _actor1.fixPriority(20);
+ _screen.postInit();
+ _screen.setup(1580, 1, 1);
+ _screen.setPosition(Common::Point(124, 108));
+ _screen.fixPriority(10);
+ _screen.setDetails(1550, 13, -1, -1, 1, (SceneItem *) NULL);
+
+ _screenDisplay.postInit();
+ _screenDisplay.setup(1580, 1, 3);
+ _screenDisplay.setPosition(Common::Point(124, 96));
+ _screenDisplay.fixPriority(20);
} else if (R2_INVENTORY.getObjectScene(R2_DIAGNOSTICS_DISPLAY) == 1580) {
- _actor3.postInit();
- _actor3.setup(1580, 1, 1);
- _actor3.setPosition(Common::Point(124, 108));
- _actor3.fixPriority(10);
- _actor3.setDetails(1550, 14, -1, -1, 1, (SceneItem *) NULL);
+ _screen.postInit();
+ _screen.setup(1580, 1, 1);
+ _screen.setPosition(Common::Point(124, 108));
+ _screen.fixPriority(10);
+ _screen.setDetails(1550, 14, -1, -1, 1, (SceneItem *) NULL);
- _actor1.postInit();
- _actor1.setup(1580, 3, 1);
- _actor1.setPosition(Common::Point(124, 109));
- _actor1.fixPriority(20);
+ _screenDisplay.postInit();
+ _screenDisplay.setup(1580, 3, 1);
+ _screenDisplay.setPosition(Common::Point(124, 109));
+ _screenDisplay.fixPriority(20);
_sceneMode = 10;
} else {
- _item2.setDetails(Rect(69, 29, 177, 108), 1550, 82, -1, -1, 1, NULL);
+ _screenSlot.setDetails(Rect(69, 29, 177, 108), 1550, 82, -1, -1, 1, NULL);
}
- _actor4.postInit();
+ _storageCompartment.postInit();
if (R2_GLOBALS.getFlag(58) == 0) {
- _actor4.setup(1580, 5, 1);
- _actor4.setDetails(1550, 80, -1, -1, 1, (SceneItem *) NULL);
+ _storageCompartment.setup(1580, 5, 1);
+ _storageCompartment.setDetails(1550, 80, -1, -1, 1, (SceneItem *) NULL);
} else {
- _actor4.setup(1580, 5, 6);
+ _storageCompartment.setup(1580, 5, 6);
}
- _actor4.setPosition(Common::Point(216, 108));
- _actor4.fixPriority(100);
+ _storageCompartment.setPosition(Common::Point(216, 108));
+ _storageCompartment.fixPriority(100);
+
+ _hatchButton.postInit();
+ _hatchButton.setup(1580, 4, 1);
+ _hatchButton.setPosition(Common::Point(291, 147));
+ _hatchButton.fixPriority(100);
+ _hatchButton.setDetails(1550, 81, -1, -1, 1, (SceneItem *) NULL);
- _actor5.postInit();
- _actor5.setup(1580, 4, 1);
- _actor5.setPosition(Common::Point(291, 147));
- _actor5.fixPriority(100);
- _actor5.setDetails(1550, 81, -1, -1, 1, (SceneItem *) NULL);
-
if (R2_INVENTORY.getObjectScene(R2_THRUSTER_VALVE) == 1580) {
- _actor6.postInit();
- _actor6.setup(1580, 6, 2);
- _actor6.setPosition(Common::Point(222, 108));
- _actor6.fixPriority(50);
- _actor6.setDetails(1550, 32, -1, 34, 1, (SceneItem *) NULL);
+ _thrusterValve.postInit();
+ _thrusterValve.setup(1580, 6, 2);
+ _thrusterValve.setPosition(Common::Point(222, 108));
+ _thrusterValve.fixPriority(50);
+ _thrusterValve.setDetails(1550, 32, -1, 34, 1, (SceneItem *) NULL);
}
if (R2_INVENTORY.getObjectScene(R2_IGNITOR) == 1580) {
- _actor7.postInit();
- _actor7.setup(1580, 6, 1);
- _actor7.setPosition(Common::Point(195, 108));
- _actor7.fixPriority(50);
- _actor7.setDetails(1550, 38, -1, 34, 1, (SceneItem *) NULL);
+ _ignitor.postInit();
+ _ignitor.setup(1580, 6, 1);
+ _ignitor.setPosition(Common::Point(195, 108));
+ _ignitor.fixPriority(50);
+ _ignitor.setDetails(1550, 38, -1, 34, 1, (SceneItem *) NULL);
}
R2_GLOBALS._player.postInit();
R2_GLOBALS._player.hide();
setAction(&_sequenceManager, this, 1, &R2_GLOBALS._player, NULL);
- _item3.setDetails(Rect(0, 0, 320, 200), 1550, 50, -1, -1, 1, NULL);
+ _background.setDetails(Rect(0, 0, 320, 200), 1550, 50, -1, -1, 1, NULL);
}
void Scene1580::signal() {
switch (_sceneMode++) {
case 10:
- _actor1.animate(ANIM_MODE_5, this);
+ _screenDisplay.animate(ANIM_MODE_5, this);
break;
case 11:
- _actor1.setup(1580, 1, 2);
- _actor1.setPosition(Common::Point(124, 94));
+ _screenDisplay.setup(1580, 1, 2);
+ _screenDisplay.setPosition(Common::Point(124, 94));
if (R2_INVENTORY.getObjectScene(R2_GYROSCOPE) != 0) {
_arrActor[0].postInit();
@@ -10018,19 +9923,16 @@ bool Scene1625::Wire::startAction(CursorType action, Event &event) {
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 1631;
- scene->_actor3.postInit();
- scene->setAction(&scene->_sequenceManager, scene, 1631, &scene->_actor3, &scene->_wire, NULL);
+ scene->_mirandaMouth.postInit();
+ scene->setAction(&scene->_sequenceManager, scene, 1631, &scene->_mirandaMouth, &scene->_wire, NULL);
return true;
}
Scene1625::Scene1625() {
- _field412 = 0;
}
void Scene1625::synchronize(Serializer &s) {
SceneExt::synchronize(s);
-
- s.syncAsSint16LE(_field412);
}
void Scene1625::postInit(SceneObjectList *OwnerList) {
@@ -10050,10 +9952,10 @@ void Scene1625::postInit(SceneObjectList *OwnerList) {
_wire.setPosition(Common::Point(206, 133));
_wire.setDetails(1625, 0, -1, -1, 1, (SceneItem *) NULL);
- _actor5.postInit();
- _actor5.setup(1625, 8, 1);
- _actor5.setPosition(Common::Point(190, 131));
- _actor5.setDetails(1625, 6, -1, 2, 1, (SceneItem *) NULL);
+ _wristRestraints.postInit();
+ _wristRestraints.setup(1625, 8, 1);
+ _wristRestraints.setPosition(Common::Point(190, 131));
+ _wristRestraints.setDetails(1625, 6, -1, 2, 1, (SceneItem *) NULL);
if (R2_GLOBALS._player._oldCharacterScene[R2_MIRANDA] == 1625) {
if (!R2_GLOBALS.getFlag(83)) {
@@ -10065,18 +9967,18 @@ void Scene1625::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player.enableControl();
R2_GLOBALS._player._canWalk = false;
} else {
- _actor1.postInit();
- _actor1.fixPriority(10);
+ _teal.postInit();
+ _teal.fixPriority(10);
- _actor6.postInit();
+ _tealRightArm.postInit();
R2_GLOBALS._player.disableControl();
_sceneMode = 1625;
- setAction(&_sequenceManager, this, 1625, &_actor1, &_actor6, NULL);
+ setAction(&_sequenceManager, this, 1625, &_teal, &_tealRightArm, NULL);
}
R2_GLOBALS._sound1.play(245);
- _item1.setDetails(Rect(0, 0, 320, 200), 1625, 12, -1, -1, 1, NULL);
+ _background.setDetails(Rect(0, 0, 320, 200), 1625, 12, -1, -1, 1, NULL);
R2_GLOBALS._player._oldCharacterScene[R2_MIRANDA] = 1625;
R2_GLOBALS._player._characterScene[R2_MIRANDA] = 1625;
}
@@ -10111,11 +10013,11 @@ void Scene1625::signal() {
switch (_stripManager._exitMode) {
case 1:
_sceneMode = 1627;
- setAction(&_sequenceManager, this, 1627, &_actor3, &_glass, NULL);
+ setAction(&_sequenceManager, this, 1627, &_mirandaMouth, &_glass, NULL);
break;
case 2:
_sceneMode = 1629;
- setAction(&_sequenceManager, this, 1629, &_tealHead, &_actor5, NULL);
+ setAction(&_sequenceManager, this, 1629, &_tealHead, &_wristRestraints, NULL);
break;
case 4:
R2_GLOBALS._player._oldCharacterScene[R2_MIRANDA] = 3150;
@@ -10126,7 +10028,7 @@ void Scene1625::signal() {
case 5:
_sceneMode = 1628;
_tealHead.remove();
- setAction(&_sequenceManager, this, 1628, &_actor3, &_glass, NULL);
+ setAction(&_sequenceManager, this, 1628, &_mirandaMouth, &_glass, NULL);
break;
case 6:
_glass.postInit();
@@ -10140,24 +10042,24 @@ void Scene1625::signal() {
break;
case 8:
_sceneMode = 1635;
- setAction(&_sequenceManager, this, 1635, &_actor3, &_actor5, NULL);
+ setAction(&_sequenceManager, this, 1635, &_mirandaMouth, &_wristRestraints, NULL);
break;
case 9:
_glass.postInit();
_glass.setDetails(1625, -1, -1, -1, 2, (SceneItem *) NULL);
_sceneMode = 1634;
- setAction(&_sequenceManager, this, 1634, &_actor3, &_actor5, NULL);
+ setAction(&_sequenceManager, this, 1634, &_mirandaMouth, &_wristRestraints, NULL);
break;
case 3:
// No break on purpose
default:
_sceneMode = 1630;
_tealHead.remove();
- setAction(&_sequenceManager, this, 1630, &_actor1, &_actor6, NULL);
+ setAction(&_sequenceManager, this, 1630, &_teal, &_tealRightArm, NULL);
break;
}
- _field412 = _stripManager._field2E8;
- _stripManager._field2E8 = 0;
+ //_field412 = _stripManager._field2E8;
+ _stripManager._currObj44Id = 0;
break;
case 1625:
_tealHead.postInit();
@@ -10172,18 +10074,18 @@ void Scene1625::signal() {
_tealHead.setPosition(Common::Point(68, 68));
_tealHead.show();
- _actor3.postInit();
- _actor3.setup(1627, 3, 1);
- _actor3.setPosition(Common::Point(196, 65));
+ _mirandaMouth.postInit();
+ _mirandaMouth.setup(1627, 3, 1);
+ _mirandaMouth.setPosition(Common::Point(196, 65));
_sceneMode = 99;
R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
_stripManager.start(832, this);
break;
case 1627:
- _actor3.setup(1627, 3, 1);
- _actor3.setPosition(Common::Point(196, 65));
- _actor3.show();
+ _mirandaMouth.setup(1627, 3, 1);
+ _mirandaMouth.setPosition(Common::Point(196, 65));
+ _mirandaMouth.show();
_sceneMode = 99;
R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
@@ -10195,9 +10097,9 @@ void Scene1625::signal() {
_tealHead.setup(1627, 1, 1);
_tealHead.setPosition(Common::Point(68, 68));
- _actor3.setup(1627, 3, 1);
- _actor3.setPosition(Common::Point(196, 65));
- _actor3.show();
+ _mirandaMouth.setup(1627, 3, 1);
+ _mirandaMouth.setPosition(Common::Point(196, 65));
+ _mirandaMouth.show();
_sceneMode = 99;
R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
@@ -10217,21 +10119,21 @@ void Scene1625::signal() {
R2_GLOBALS._player._canWalk = true;
break;
case 1631:
- _actor3.setup(1627, 3, 1);
- _actor3.setPosition(Common::Point(196, 65));
- _actor3.show();
+ _mirandaMouth.setup(1627, 3, 1);
+ _mirandaMouth.setPosition(Common::Point(196, 65));
+ _mirandaMouth.show();
_wire.remove();
- _actor1.postInit();
- _actor1.fixPriority(10);
+ _teal.postInit();
+ _teal.fixPriority(10);
- _actor6.postInit();
+ _tealRightArm.postInit();
R2_INVENTORY.setObjectScene(R2_SUPERCONDUCTOR_WIRE, 3);
_sceneMode = 14;
- setAction(&_sequenceManager, this, 1625, &_actor1, &_actor6, NULL);
+ setAction(&_sequenceManager, this, 1625, &_teal, &_tealRightArm, NULL);
break;
case 1632:
_tealHead.setup(1627, 1, 1);
@@ -10254,9 +10156,9 @@ void Scene1625::signal() {
_stripManager.start(836, this);
break;
case 1635:
- _actor3.setup(1627, 3, 1);
- _actor3.setPosition(Common::Point(196, 65));
- _actor3.show();
+ _mirandaMouth.setup(1627, 3, 1);
+ _mirandaMouth.setPosition(Common::Point(196, 65));
+ _mirandaMouth.show();
_sceneMode = 99;
R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
@@ -10280,21 +10182,13 @@ void Scene1625::process(Event &event) {
*--------------------------------------------------------------------------*/
Scene1700::Scene1700() {
- _field77A = 0;
- _field77C = 0;
+ _walkFlag = 0;
}
void Scene1700::synchronize(Serializer &s) {
SceneExt::synchronize(s);
- s.syncAsSint16LE(_field77A);
- s.syncAsSint16LE(_field77C);
-}
-
-bool Scene1700::Item2::startAction(CursorType action, Event &event) {
- // The original contains a debug trace. It's currently skipped.
- // TODO: either add the debug trace, or remove this function and associated class
- return SceneHotspot::startAction(action, event);
+ s.syncAsSint16LE(_walkFlag);
}
bool Scene1700::RimTransport::startAction(CursorType action, Event &event) {
@@ -10304,7 +10198,6 @@ bool Scene1700::RimTransport::startAction(CursorType action, Event &event) {
Scene1700 *scene = (Scene1700 *)R2_GLOBALS._sceneManager._scene;
R2_GLOBALS._player.disableControl();
- R2_GLOBALS._v558B6.set(80, 0, 240, 200);
scene->_sceneMode = 4;
Common::Point pt(271, 90);
@@ -10314,7 +10207,7 @@ bool Scene1700::RimTransport::startAction(CursorType action, Event &event) {
return true;
}
-bool Scene1700::Actor12::startAction(CursorType action, Event &event) {
+bool Scene1700::Companion::startAction(CursorType action, Event &event) {
if (action != CURSOR_TALK)
return SceneActor::startAction(action, event);
@@ -10372,23 +10265,14 @@ void Scene1700::enterArea() {
_westPlatform.remove();
_rimTransportDoor.remove();
_rimTransport.remove();
-
+
if (_sceneMode != 40) {
_ledgeHopper.remove();
- _actor10.remove();
+ _hatch.remove();
}
- warning("tmpRect = _v5589E;");
- warning("Mouse_hideIfNeeded");
- warning("set_pane_p(_paneNumber);");
- warning("Big loop calling gfx_draw_slice_p");
-
- if (_field77A == 0)
- _field77A = 1;
- else
- _field77A = 0;
-
- warning("set_pane_p(_paneNumber);");
+ // The original had manual code here to redraw the background manually when
+ // changing areas within the scene. Which seems to be totally redundant.
if (_sceneMode != 40 && R2_GLOBALS._rimLocation == 0) {
// Crashed ledge hopper
@@ -10444,7 +10328,7 @@ void Scene1700::enterArea() {
// Rim transport vechile located
R2_GLOBALS._rimTransportLocation = R2_GLOBALS._rimLocation;
if (!R2_GLOBALS.getFlag(15))
- _field77C = 1;
+ _walkFlag = true;
_rimTransport.postInit();
_rimTransport.setup(1700, 3, 1);
@@ -10484,44 +10368,44 @@ void Scene1700::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player._moveDiff = Common::Point(3, 1);
}
- _actor12.postInit();
- _actor12.animate(ANIM_MODE_1, NULL);
- _actor12.setObjectWrapper(new SceneObjectWrapper());
+ _companion.postInit();
+ _companion.animate(ANIM_MODE_1, NULL);
+ _companion.setObjectWrapper(new SceneObjectWrapper());
if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
- _actor12.setVisage(1506);
- _actor12._moveDiff = Common::Point(3, 1);
- _actor12.setDetails(9002, 1, -1, -1, 1, (SceneItem *) NULL);
+ _companion.setVisage(1506);
+ _companion._moveDiff = Common::Point(3, 1);
+ _companion.setDetails(9002, 1, -1, -1, 1, (SceneItem *) NULL);
} else {
- _actor12.setVisage(1501);
- _actor12._moveDiff = Common::Point(2, 1);
- _actor12.setDetails(9001, 1, -1, -1, 1, (SceneItem *) NULL);
+ _companion.setVisage(1501);
+ _companion._moveDiff = Common::Point(2, 1);
+ _companion.setDetails(9001, 1, -1, -1, 1, (SceneItem *) NULL);
}
R2_GLOBALS._sound1.play(134);
- _actor1.postInit();
- _actor1.fixPriority(10);
+ _playerShadow.postInit();
+ _playerShadow.fixPriority(10);
if (R2_GLOBALS._player._characterIndex == R2_QUINN)
- _actor1.setVisage(1112);
+ _playerShadow.setVisage(1112);
else
- _actor1.setVisage(1111);
+ _playerShadow.setVisage(1111);
- _actor1._effect = 5;
- _actor1._field9C = _field312;
- R2_GLOBALS._player._linkedActor = &_actor1;
+ _playerShadow._effect = EFFECT_SHADOW_MAP;
+ _playerShadow._shadowMap = _shadowPaletteMap;
+ R2_GLOBALS._player._linkedActor = &_playerShadow;
- _actor2.postInit();
- _actor2.fixPriority(10);
+ _companionShadow.postInit();
+ _companionShadow.fixPriority(10);
if (R2_GLOBALS._player._characterIndex == R2_QUINN)
- _actor2.setVisage(1111);
+ _companionShadow.setVisage(1111);
else
- _actor2.setVisage(1112);
+ _companionShadow.setVisage(1112);
- _actor2._effect = 5;
- _actor2._field9C = _field312;
- _actor12._linkedActor = &_actor2;
+ _companionShadow._effect = EFFECT_SHADOW_MAP;
+ _companionShadow._shadowMap = _shadowPaletteMap;
+ _companion._linkedActor = &_companionShadow;
R2_GLOBALS._sound1.play(134);
@@ -10530,60 +10414,59 @@ void Scene1700::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player._characterIndex = R2_QUINN;
R2_GLOBALS._player.disableControl();
R2_GLOBALS._player.hide();
- _actor12.hide();
+ _companion.hide();
- _actor10.postInit();
- warning("_actor10._actorName = \"hatch\";");
- _actor10.hide();
+ _hatch.postInit();
+ _hatch.hide();
_ledgeHopper.postInit();
_ledgeHopper.setup(1701, 1, 1);
_ledgeHopper.setPosition(Common::Point(220, 137));
_ledgeHopper.setDetails(1700, 6, -1, -1, 1, (SceneItem *) NULL);
- _actor1.hide();
- _actor2.hide();
+ _playerShadow.hide();
+ _companionShadow.hide();
R2_GLOBALS._events.setCursor(CURSOR_WALK);
_stripManager.start(539, this);
_sceneMode = 40;
break;
case 1750: {
R2_GLOBALS._player.setPosition(Common::Point(282, 121));
- _actor12.setPosition(Common::Point(282, 139));
+ _companion.setPosition(Common::Point(282, 139));
_sceneMode = 8;
Common::Point pt(262, 101);
NpcMover *mover = new NpcMover();
R2_GLOBALS._player.addMover(mover, &pt, this);
Common::Point pt2(262, 119);
NpcMover *mover2 = new NpcMover();
- _actor12.addMover(mover2, &pt2, this);
+ _companion.addMover(mover2, &pt2, this);
}
break;
case 1800: {
R2_GLOBALS._player.disableControl();
R2_GLOBALS._player.setPosition(Common::Point(0, 86));
- _actor12.setPosition(Common::Point(0, 64));
+ _companion.setPosition(Common::Point(0, 64));
_sceneMode = 7;
R2_GLOBALS._player.setObjectWrapper(NULL);
R2_GLOBALS._player._strip = 1;
Common::Point pt(64, 86);
NpcMover *mover = new NpcMover();
R2_GLOBALS._player.addMover(mover, &pt, this);
- _actor12.setObjectWrapper(NULL);
- _actor12._strip = 1;
+ _companion.setObjectWrapper(NULL);
+ _companion._strip = 1;
Common::Point pt2(77, 64);
NpcMover *mover2 = new NpcMover();
- _actor12.addMover(mover2, &pt2, NULL);
+ _companion.addMover(mover2, &pt2, NULL);
}
break;
default:
if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
R2_GLOBALS._player.setPosition(Common::Point(109, 160));
- _actor12.setPosition(Common::Point(156, 160));
+ _companion.setPosition(Common::Point(156, 160));
R2_GLOBALS._walkRegions.disableRegion(15);
} else {
R2_GLOBALS._player.setPosition(Common::Point(156, 160));
- _actor12.setPosition(Common::Point(109, 160));
+ _companion.setPosition(Common::Point(109, 160));
R2_GLOBALS._walkRegions.disableRegion(17);
}
_sceneMode = 50;
@@ -10595,10 +10478,10 @@ void Scene1700::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player._oldCharacterScene[R2_QUINN] = 1700;
R2_GLOBALS._player._oldCharacterScene[R2_SEEKER] = 1700;
- R2_GLOBALS._v558B6.set(20, 0, 320, 200);
enterArea();
- _item1.setDetails(1, 1700, 3, -1, -1);
- _item2.setDetails(Rect(0, 0, 480, 200), 1700, 0, -1, -1, 1, NULL);
+
+ _surface.setDetails(1, 1700, 3, -1, -1);
+ _background.setDetails(Rect(0, 0, 480, 200), 1700, 0, -1, -1, 1, NULL);
}
void Scene1700::remove() {
@@ -10619,16 +10502,16 @@ void Scene1700::signal() {
R2_GLOBALS._player.addMover(mover, &pt, this);
if (R2_GLOBALS._player._position.x < 132) {
- _actor12.setPosition(Common::Point(156, 170));
+ _companion.setPosition(Common::Point(156, 170));
Common::Point pt2(156, 160);
NpcMover *mover2 = new NpcMover();
- _actor12.addMover(mover2, &pt2, NULL);
+ _companion.addMover(mover2, &pt2, NULL);
R2_GLOBALS._walkRegions.disableRegion(15);
} else {
- _actor12.setPosition(Common::Point(109, 170));
+ _companion.setPosition(Common::Point(109, 170));
Common::Point pt3(109, 160);
NpcMover *mover3 = new NpcMover();
- _actor12.addMover(mover3, &pt3, NULL);
+ _companion.addMover(mover3, &pt3, NULL);
R2_GLOBALS._walkRegions.disableRegion(17);
}
}
@@ -10644,26 +10527,26 @@ void Scene1700::signal() {
R2_GLOBALS._player.addMover(mover, &pt, this);
if (R2_GLOBALS._player._position.x >= 171) {
- _actor12.setPosition(Common::Point(155, 0));
+ _companion.setPosition(Common::Point(155, 0));
Common::Point pt2(155, 10);
NpcMover *mover2 = new NpcMover();
- _actor12.addMover(mover2, &pt2, NULL);
+ _companion.addMover(mover2, &pt2, NULL);
R2_GLOBALS._walkRegions.disableRegion(15);
} else {
- _actor12.setPosition(Common::Point(188, 0));
+ _companion.setPosition(Common::Point(188, 0));
Common::Point pt3(188, 10);
NpcMover *mover3 = new NpcMover();
- _actor12.addMover(mover3, &pt3, NULL);
+ _companion.addMover(mover3, &pt3, NULL);
R2_GLOBALS._walkRegions.disableRegion(17);
}
}
break;
case 3:
- if (_field77C == 0) {
+ if (!_walkFlag) {
R2_GLOBALS._player.enableControl(CURSOR_WALK);
} else {
R2_GLOBALS.setFlag(15);
- _field77C = 0;
+ _walkFlag = false;
_sceneMode = 31;
R2_GLOBALS._events.setCursor(CURSOR_WALK);
if (R2_GLOBALS._player._characterIndex == R2_QUINN)
@@ -10676,7 +10559,7 @@ void Scene1700::signal() {
_sceneMode = 5;
Common::Point pt(271, 90);
PlayerMover *mover = new PlayerMover();
- _actor12.addMover(mover, &pt, NULL);
+ _companion.addMover(mover, &pt, NULL);
if (R2_GLOBALS._player._characterIndex == R2_QUINN)
setAction(&_sequenceManager, this, 1700, &R2_GLOBALS._player, &_rimTransportDoor, NULL);
else
@@ -10692,14 +10575,14 @@ void Scene1700::signal() {
case 7:
R2_GLOBALS._player.setObjectWrapper(new SceneObjectWrapper());
R2_GLOBALS._player._strip = 1;
- _actor12.setObjectWrapper(new SceneObjectWrapper());
- _actor12._strip = 1;
+ _companion.setObjectWrapper(new SceneObjectWrapper());
+ _companion._strip = 1;
R2_GLOBALS._player.enableControl(CURSOR_WALK);
R2_GLOBALS._walkRegions.disableRegion(14);
break;
case 8:
R2_GLOBALS._player._strip = 2;
- _actor12._strip = 1;
+ _companion._strip = 1;
R2_GLOBALS._player.enableControl(CURSOR_WALK);
R2_GLOBALS._walkRegions.disableRegion(12);
break;
@@ -10713,13 +10596,13 @@ void Scene1700::signal() {
_stripManager.start(541, this);
break;
case 31:
- R2_GLOBALS._v56AAB = 0;
R2_GLOBALS._player.enableControl(CURSOR_TALK);
break;
case 40:
R2_GLOBALS._player.disableControl();
_sceneMode = 1704;
- setAction(&_sequenceManager, this, 1704, &R2_GLOBALS._player, &_actor12, &_actor10, &_ledgeHopper, &_actor1, &_actor2, NULL);
+ setAction(&_sequenceManager, this, 1704, &R2_GLOBALS._player, &_companion,
+ &_hatch, &_ledgeHopper, &_playerShadow, &_companionShadow, NULL);
break;
case 50:
if (R2_GLOBALS._player._characterIndex == R2_QUINN)
@@ -10847,13 +10730,8 @@ void Scene1750::SpeedSlider::calculateSlider() {
scene->_speed = scene->_direction * tmpVar2;
}
-void Scene1750::SpeedSlider::remove() {
- // Function kept to match IDA. Could be removed.
- SceneActor::remove();
-}
-
void Scene1750::SpeedSlider::process(Event &event) {
- if ((event.eventType == EVENT_BUTTON_DOWN) && (R2_GLOBALS._events.getCursor() == CURSOR_USE) &&
+ if ((event.eventType == EVENT_BUTTON_DOWN) && (R2_GLOBALS._events.getCursor() == CURSOR_USE) &&
(_bounds.contains(event.mousePos))) {
_mouseDown = true;
event.eventType = EVENT_NONE;
@@ -10890,12 +10768,14 @@ bool Scene1750::SpeedSlider::startAction(CursorType action, Event &event) {
Scene1750::Scene1750() {
_direction = 0;
- _field413 = 0;
+ _speedCurrent = 0;
_speed = 0;
- _field417 = 0;
- _field419 = 0;
- _field41B = 0;
- _field41D = 0;
+ _speedDelta = 0;
+ _rotationSegment = 0;
+ _rotationSegCurrent = 0;
+ _newRotation = 0;
+
+ _rotation = nullptr;
}
void Scene1750::synchronize(Serializer &s) {
@@ -10903,20 +10783,21 @@ void Scene1750::synchronize(Serializer &s) {
SYNC_POINTER(_rotation);
s.syncAsSint16LE(_direction);
- s.syncAsSint16LE(_field413);
+ s.syncAsSint16LE(_speedCurrent);
s.syncAsSint16LE(_speed);
- s.syncAsSint16LE(_field417);
- s.syncAsSint16LE(_field419);
- s.syncAsSint16LE(_field41B);
- s.syncAsSint16LE(_field41D);
+ s.syncAsSint16LE(_speedDelta);
+ s.syncAsSint16LE(_rotationSegment);
+ s.syncAsSint16LE(_rotationSegCurrent);
+ s.syncAsSint16LE(_newRotation);
}
void Scene1750::postInit(SceneObjectList *OwnerList) {
loadScene(1750);
R2_GLOBALS._sound1.play(115);
R2_GLOBALS._uiElements._active = false;
- R2_GLOBALS._v5589E.set(0, 0, 320, 200);
+
SceneExt::postInit();
+ R2_GLOBALS._interfaceY = SCREEN_HEIGHT;
R2_GLOBALS._player._characterScene[R2_QUINN] = 1750;
R2_GLOBALS._player._characterScene[R2_SEEKER] = 1750;
@@ -10966,28 +10847,28 @@ void Scene1750::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player.hide();
R2_GLOBALS._player.enableControl();
- _actor3.postInit();
- _actor3.setup(1750, 3, 1);
- _actor3.setPosition(Common::Point(49, 185));
- _actor3.fixPriority(7);
- _actor3.setDetails(1750, 30, -1, -1, 1, (SceneItem *) NULL);
+ _radarSweep.postInit();
+ _radarSweep.setup(1750, 3, 1);
+ _radarSweep.setPosition(Common::Point(49, 185));
+ _radarSweep.fixPriority(7);
+ _radarSweep.setDetails(1750, 30, -1, -1, 1, (SceneItem *) NULL);
- _actor1.postInit();
- _actor1.setup(1750, 2, 1);
- _actor1.setPosition(Common::Point(35, ((_rotation->_currIndex - 218) % 4) + ((R2_GLOBALS._rimLocation % 800) * 4) - 1440));
- _actor1.fixPriority(8);
+ _scannerIcon.postInit();
+ _scannerIcon.setup(1750, 2, 1);
+ _scannerIcon.setPosition(Common::Point(35, ((_rotation->_currIndex - 218) % 4) + ((R2_GLOBALS._rimLocation % 800) * 4) - 1440));
+ _scannerIcon.fixPriority(8);
- _actor2.postInit();
- _actor2.setup(1750, 1, 4);
+ _redLights.postInit();
+ _redLights.setup(1750, 1, 4);
- int tmpVar = abs(_actor1._position.y - 158) / 100;
+ int tmpVar = ABS(_scannerIcon._position.y - 158) / 100;
if (tmpVar >= 8)
- _actor2.hide();
- else if (_actor1._position.y <= 158)
- _actor2.setPosition(Common::Point(137, (tmpVar * 7) + 122));
+ _redLights.hide();
+ else if (_scannerIcon._position.y <= 158)
+ _redLights.setPosition(Common::Point(137, (tmpVar * 7) + 122));
else
- _actor2.setPosition(Common::Point(148, (tmpVar * 7) + 122));
+ _redLights.setPosition(Common::Point(148, (tmpVar * 7) + 122));
_speedSlider.setupSlider(1, 286, 143, 41, 15);
_speedSlider.setDetails(1750, 24, 1, -1, 1, (SceneItem *) NULL);
@@ -11012,12 +10893,12 @@ void Scene1750::postInit(SceneObjectList *OwnerList) {
_exitButton.setDetails(1750, 27, 1, -1, 1, (SceneItem *) NULL);
_direction = 1; // Forward by default
- _field417 = 0;
- _field413 = 0;
+ _speedDelta = 0;
+ _speedCurrent = 0;
_speed = 0;
- _field419 = ((_rotation->_currIndex - 218) / 4) % 4;
+ _rotationSegment = ((_rotation->_currIndex - 218) / 4) % 4;
- _redLights.setDetails(Rect(129, 112, 155, 175), 1750, 21, -1, -1, 1, NULL);
+ _redLightsDescr.setDetails(Rect(129, 112, 155, 175), 1750, 21, -1, -1, 1, NULL);
_greenLights.setDetails(Rect(93, 122, 126, 172), 1750, 15, -1, -1, 1, NULL);
_frontView.setDetails(Rect(3, 3, 157, 99), 1750, 9, -1, -1, 1, NULL);
_rearView.setDetails(Rect(162, 3, 316, 99), 1750, 12, -1, -1, 1, NULL);
@@ -11035,8 +10916,6 @@ void Scene1750::remove() {
SceneExt::remove();
R2_GLOBALS._sound1.fadeOut2(NULL);
- R2_GLOBALS._v5589E.top = 3;
- R2_GLOBALS._v5589E.bottom = 168;
R2_GLOBALS._uiElements._active = true;
}
@@ -11052,71 +10931,73 @@ void Scene1750::process(Event &event) {
void Scene1750::dispatch() {
if (_rotation) {
- if (!_field417 && (_speed != _field413)) {
- if (_field413 >= _speed)
- --_field413;
+ if (!_speedDelta && (_speed != _speedCurrent)) {
+ if (_speedCurrent >= _speed)
+ --_speedCurrent;
else
- ++_field413;
+ ++_speedCurrent;
- _field417 = 21 - ABS(_field413);
+ _speedDelta = 21 - ABS(_speedCurrent);
}
- if (_field417 == 1) {
- if (_field413 == 0) {
- _actor3.show();
+ if (_speedDelta == 1) {
+ if (_speedCurrent == 0) {
+ _radarSweep.show();
_rotation->_idxChange = 0;
} else {
if (_rotation->_idxChange == 0)
- _actor3.hide();
+ _radarSweep.hide();
- if (_field413 < -12) {
- _rotation->setDelay(15 - ABS(_field413));
+ if (_speedCurrent < -12) {
+ _rotation->setDelay(15 - ABS(_speedCurrent));
_rotation->_idxChange = -2;
- } else if (_field413 < 0) {
- _rotation->setDelay(10 - ABS(_field413));
+ } else if (_speedCurrent < 0) {
+ _rotation->setDelay(10 - ABS(_speedCurrent));
_rotation->_idxChange = -1;
- } else if (_field413 < 11) {
- _rotation->setDelay(10 - _field413);
+ } else if (_speedCurrent < 11) {
+ _rotation->setDelay(10 - _speedCurrent);
_rotation->_idxChange = 1;
} else {
- _rotation->setDelay(15 - _field413);
+ _rotation->setDelay(15 - _speedCurrent);
_rotation->_idxChange = 2;
}
- }
+ }
}
- if (_field417)
- --_field417;
+ if (_speedDelta)
+ --_speedDelta;
- _field41B = _field419;
- _field419 = ((_rotation->_currIndex - 218) / 4) / 4;
+ _rotationSegCurrent = _rotationSegment;
+ _rotationSegment = ((_rotation->_currIndex - 218) / 4) % 4;
- if ((_field41B + 1) == _field419 || (_field41B - 3) == _field419) {
+ if ((_rotationSegCurrent + 1) == _rotationSegment || (_rotationSegCurrent - 3) == _rotationSegment) {
if (R2_GLOBALS._rimLocation < 2400) {
++R2_GLOBALS._rimLocation;
}
}
- if ((_field41B - 1) == _field419 || (_field41B + 3) == _field419) {
+ if ((_rotationSegCurrent - 1) == _rotationSegment || (_rotationSegCurrent + 3) == _rotationSegment) {
if (R2_GLOBALS._rimLocation > -2400) {
--R2_GLOBALS._rimLocation;
}
}
- if (_rotation->_currIndex != _field41D) {
- _field41D = _rotation->_currIndex;
- _actor1.setPosition(Common::Point(35, ((_rotation->_currIndex - 218) % 4) +
+ if (_rotation->_currIndex != _newRotation) {
+ // Handle setting the position of the lift icon in the scanner display
+ _newRotation = _rotation->_currIndex;
+ _scannerIcon.setPosition(Common::Point(35, ((_rotation->_currIndex - 218) % 4) +
((R2_GLOBALS._rimLocation % 800) * 4) - 1440));
}
}
- int v = ABS(_actor1._position.y - 158) / 100;
+ int v = ABS(_scannerIcon._position.y - 158) / 100;
if (v < 8) {
- _actor2.show();
- _actor2.setPosition(Common::Point((_actor1._position.y <= 158) ? 137 : 148,
+ // Show how close the user is to the lift on the second column of lights
+ _redLights.show();
+ _redLights.setPosition(Common::Point((_scannerIcon._position.y <= 158) ? 137 : 148,
v * 7 + 122));
} else {
- _actor2.hide();
+ _redLights.hide();
}
}
@@ -11212,8 +11093,11 @@ bool Scene1800::Doors::startAction(CursorType action, Event &event) {
R2_GLOBALS.setFlag(14);
}
} else {
+ // Seeker failing to force open doors
scene->_sceneMode = 1813;
- scene->setAction(&scene->_sequenceManager, scene, 1813, &R2_GLOBALS._player, NULL);
+ // Original was using 1813 in setAction too, but it somewhat broken.
+ // Seeker goes 2 pixels to high, hiding behind the door
+ scene->setAction(&scene->_sequenceManager, scene, 1808, &R2_GLOBALS._player, &scene->_doors, NULL);
}
} else if (R2_GLOBALS.getFlag(14)) {
return SceneActor::startAction(action, event);
@@ -11259,30 +11143,28 @@ bool Scene1800::PassengerDoor::startAction(CursorType action, Event &event) {
}
}
}
+ } else if (scene->_leftStaircase._frame == 1) {
+ return SceneActor::startAction(action, event);
} else {
- if (scene->_leftStaircase._frame == 1) {
- return SceneActor::startAction(action, event);
+ R2_GLOBALS.clearFlag(29);
+ R2_GLOBALS._player.disableControl();
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
+ if (R2_GLOBALS.getFlag(14)) {
+ scene->_sceneMode = 2;
+ scene->setAction(&scene->_sequenceManager, scene, 1809, &scene->_companion, &scene->_doors, NULL);
+ R2_GLOBALS.clearFlag(14);
+ } else {
+ scene->_sceneMode = 1806;
+ scene->setAction(&scene->_sequenceManager, scene, 1806, &R2_GLOBALS._player, &scene->_companion, &scene->_rightDoor, NULL);
+ }
} else {
- R2_GLOBALS.clearFlag(29);
- R2_GLOBALS._player.disableControl();
- if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
- if (R2_GLOBALS.getFlag(14)) {
- scene->_sceneMode = 2;
- scene->setAction(&scene->_sequenceManager, scene, 1809, &scene->_companion, &scene->_doors, NULL);
- R2_GLOBALS.clearFlag(14);
- } else {
- scene->_sceneMode = 1806;
- scene->setAction(&scene->_sequenceManager, scene, 1806, &R2_GLOBALS._player, &scene->_companion, &scene->_rightDoor, NULL);
- }
+ if (R2_GLOBALS.getFlag(14)) {
+ scene->_sceneMode = 2;
+ scene->setAction(&scene->_sequenceManager, scene, 1809, &R2_GLOBALS._player, &scene->_doors, NULL);
+ R2_GLOBALS.clearFlag(14);
} else {
- if (R2_GLOBALS.getFlag(14)) {
- scene->_sceneMode = 2;
- scene->setAction(&scene->_sequenceManager, scene, 1809, &R2_GLOBALS._player, &scene->_doors, NULL);
- R2_GLOBALS.clearFlag(14);
- } else {
- scene->_sceneMode = 1807;
- scene->setAction(&scene->_sequenceManager, scene, 1807, &R2_GLOBALS._player, &scene->_companion, &scene->_rightDoor, NULL);
- }
+ scene->_sceneMode = 1807;
+ scene->setAction(&scene->_sequenceManager, scene, 1807, &R2_GLOBALS._player, &scene->_companion, &scene->_rightDoor, NULL);
}
}
}
@@ -11290,7 +11172,7 @@ bool Scene1800::PassengerDoor::startAction(CursorType action, Event &event) {
return true;
}
-void Scene1800::Exit1::changeScene() {
+void Scene1800::SouthExit::changeScene() {
Scene1800 *scene = (Scene1800 *)R2_GLOBALS._sceneManager._scene;
_enabled = false;
@@ -11329,7 +11211,7 @@ void Scene1800::postInit(SceneObjectList *OwnerList) {
_locationMode = 0;
scalePalette(65, 65, 65);
- _exit1.setDetails(Rect(0, 160, 319, 168), EXITCURSOR_S, 1800);
+ _southExit.setDetails(Rect(0, 160, 319, 168), EXITCURSOR_S, 1800);
_background.setDetails(Rect(0, 0, 320, 200), -1, -1, -1, -1, 1, NULL);
_lever.postInit();
@@ -11439,50 +11321,48 @@ void Scene1800::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._walkRegions.disableRegion(10);
R2_GLOBALS._walkRegions.disableRegion(11);
}
+ } else if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
+ R2_GLOBALS._player.setPosition(Common::Point(140, 160));
+ _companion.setPosition(Common::Point(180, 160));
} else {
- if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
- R2_GLOBALS._player.setPosition(Common::Point(140, 160));
- _companion.setPosition(Common::Point(180, 160));
- } else {
- R2_GLOBALS._player.setPosition(Common::Point(180, 160));
- _companion.setPosition(Common::Point(140, 160));
- }
+ R2_GLOBALS._player.setPosition(Common::Point(180, 160));
+ _companion.setPosition(Common::Point(140, 160));
}
- _actor1.postInit();
- _actor1.fixPriority(10);
+ _playerShadow.postInit();
+ _playerShadow.fixPriority(10);
if (R2_GLOBALS._player._characterIndex == R2_QUINN)
- _actor1.setVisage(1111);
+ _playerShadow.setVisage(1111);
else
- _actor1.setVisage(1110);
+ _playerShadow.setVisage(1110);
- _actor1._effect = 5;
- _actor1._field9C = _field312;
+ _playerShadow._effect = EFFECT_SHADOW_MAP;
+ _playerShadow._shadowMap = _shadowPaletteMap;
- R2_GLOBALS._player._linkedActor = &_actor1;
+ R2_GLOBALS._player._linkedActor = &_playerShadow;
- _actor3.postInit();
- _actor3.fixPriority(10);
+ _companionShadow.postInit();
+ _companionShadow.fixPriority(10);
if (R2_GLOBALS._player._characterIndex == R2_QUINN)
- _actor3.setVisage(1110);
+ _companionShadow.setVisage(1110);
else
- _actor3.setVisage(1111);
+ _companionShadow.setVisage(1111);
- _actor3._effect = 5;
- _actor3._field9C = _field312;
+ _companionShadow._effect = EFFECT_SHADOW_MAP;
+ _companionShadow._shadowMap = _shadowPaletteMap;
- _companion._linkedActor = &_actor3;
+ _companion._linkedActor = &_companionShadow;
R2_GLOBALS._player._characterScene[R2_QUINN] = 1800;
R2_GLOBALS._player._characterScene[R2_SEEKER] = 1800;
- _item2.setDetails(Rect(128, 95, 190, 135), 1800, 10, -1, -1, 1, NULL);
- _item1.setDetails(Rect(95, 3, 223, 135), 1800, 0, -1, -1, 1, NULL);
+ _elevatorContents.setDetails(Rect(128, 95, 190, 135), 1800, 10, -1, -1, 1, NULL);
+ _elevator.setDetails(Rect(95, 3, 223, 135), 1800, 0, -1, -1, 1, NULL);
// Original was calling _item3.setDetails(Rect(1800, 11, 24, 23), 25, -1, -1, -1, 1, NULL);
// This is *wrong*. The following statement is a wild guess based on good common sense
- _item3.setDetails(11, 1800, 23, 24, 25);
- _item4.setDetails(Rect(0, 0, 320, 200), 1800, 17, -1, 19, 1, NULL);
+ _surface.setDetails(11, 1800, 23, 24, 25);
+ _secBackground.setDetails(Rect(0, 0, 320, 200), 1800, 17, -1, 19, 1, NULL);
R2_GLOBALS._player.disableControl();
if (R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] == 1800) {
@@ -11501,23 +11381,19 @@ void Scene1800::postInit(SceneObjectList *OwnerList) {
_sceneMode = 1815;
setAction(&_sequenceManager, this, 1815, &R2_GLOBALS._player, &_companion, &_leftDoor, NULL);
}
+ } else if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
+ _sceneMode = 1816;
+ setAction(&_sequenceManager, this, 1816, &R2_GLOBALS._player, &_companion, &_rightDoor, NULL);
} else {
- if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
- _sceneMode = 1816;
- setAction(&_sequenceManager, this, 1816, &R2_GLOBALS._player, &_companion, &_rightDoor, NULL);
- } else {
- _sceneMode = 1817;
- setAction(&_sequenceManager, this, 1817, &R2_GLOBALS._player, &_companion, &_rightDoor, NULL);
- }
+ _sceneMode = 1817;
+ setAction(&_sequenceManager, this, 1817, &R2_GLOBALS._player, &_companion, &_rightDoor, NULL);
}
+ } else if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
+ _sceneMode = 1800;
+ setAction(&_sequenceManager, this, 1800, &R2_GLOBALS._player, &_companion, NULL);
} else {
- if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
- _sceneMode = 1800;
- setAction(&_sequenceManager, this, 1800, &R2_GLOBALS._player, &_companion, NULL);
- } else {
- _sceneMode = 1801;
- setAction(&_sequenceManager, this, 1801, &R2_GLOBALS._player, &_companion, NULL);
- }
+ _sceneMode = 1801;
+ setAction(&_sequenceManager, this, 1801, &R2_GLOBALS._player, &_companion, NULL);
}
R2_GLOBALS._player._oldCharacterScene[R2_QUINN] = 1800;
@@ -11564,7 +11440,7 @@ void Scene1800::signal() {
_sceneMode = 14;
R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
R2_GLOBALS._player.setup(1801, 7, 1);
- R2_GLOBALS._player.animate(ANIM_MODE_8, NULL);
+ R2_GLOBALS._player.animate(ANIM_MODE_8, 0, NULL);
_stripManager.start(550, this);
break;
case 14:
@@ -11578,6 +11454,29 @@ void Scene1800::signal() {
R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
R2_GLOBALS._player.enableControl(CURSOR_USE);
break;
+ // Cases 23 and 24 have been added to fix missing hardcoded logic in the original,
+ // when Seeker tries to open the door
+ case 23:
+ _sceneMode = 24;
+ R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
+ R2_GLOBALS._player.setup(1801, 5, 1);
+ R2_GLOBALS._player.animate(ANIM_MODE_8, 0, NULL);
+ _stripManager.start(550, this);
+ break;
+ case 24:
+ R2_GLOBALS._player.disableControl();
+ R2_GLOBALS._player.setup(1507, 4, 1);
+ R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
+ R2_GLOBALS._player.enableControl(CURSOR_USE);
+
+ _doors.setup(1801, 3, 1);
+ _doors.setPosition(Common::Point(160, 139));
+ _doors.setDetails(1800, 6, -1, -1, 1, (SceneItem *) NULL);
+ _doors.show();
+
+ R2_GLOBALS._player._position.y += 2;
+ R2_GLOBALS._player.show();
+ break;
case 1800:
R2_GLOBALS._walkRegions.disableRegion(8);
if (R2_GLOBALS.getFlag(63))
@@ -11592,16 +11491,7 @@ void Scene1800::signal() {
R2_GLOBALS._walkRegions.disableRegion(10);
R2_GLOBALS._walkRegions.disableRegion(11);
R2_GLOBALS.setFlag(63);
-
- // The following check is completely dumb.
- // Either an original bug, or dead code.
- if (R2_GLOBALS.getFlag(63)) {
- R2_GLOBALS._player.enableControl(CURSOR_WALK);
- } else {
- _sceneMode = 10;
- R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
- _stripManager.start(545, this);
- }
+ R2_GLOBALS._player.enableControl(CURSOR_WALK);
break;
case 1802:
R2_GLOBALS.clearFlag(14);
@@ -11626,6 +11516,11 @@ void Scene1800::signal() {
_sceneMode = 13;
R2_GLOBALS._player.animate(ANIM_MODE_5, this);
break;
+ // Case 1813 has been added to fix Seeker missing animation in the original game
+ case 1813:
+ _sceneMode = 23;
+ R2_GLOBALS._player.animate(ANIM_MODE_5, this);
+ break;
case 1814:
// No break on purpose
case 1815:
@@ -11671,7 +11566,7 @@ bool Scene1850::Button::startAction(CursorType action, Event &event) {
else
scene->setAction(&scene->_sequenceManager1, scene, 1852, &R2_GLOBALS._player, NULL);
} else if (R2_GLOBALS.getFlag(30)) {
- scene->_field41E = 1;
+ scene->_seqNumber = 1;
scene->_sceneMode = 1860;
if (R2_GLOBALS.getFlag(32))
@@ -11713,9 +11608,9 @@ bool Scene1850::Robot::startAction(CursorType action, Event &event) {
break;
case CURSOR_LOOK:
if (R2_GLOBALS.getFlag(34))
- SceneItem::display(1850, 2, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ SceneItem::display(1850, 2, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, LIST_END);
else
- SceneItem::display(1850, 1, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ SceneItem::display(1850, 1, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, LIST_END);
return true;
break;
@@ -11735,12 +11630,14 @@ bool Scene1850::Robot::startAction(CursorType action, Event &event) {
} else if (R2_GLOBALS.getFlag(30)) {
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 1875;
- scene->_actor2.postInit();
+ scene->_airbag.postInit();
if (R2_GLOBALS.getFlag(32))
- scene->setAction(&scene->_sequenceManager1, scene, 1876, &R2_GLOBALS._player, &scene->_actor2, NULL);
+ scene->setAction(&scene->_sequenceManager1, scene, 1876,
+ &R2_GLOBALS._player, &scene->_airbag, NULL);
else
- scene->setAction(&scene->_sequenceManager1, scene, 1875, &R2_GLOBALS._player, &scene->_actor2, NULL);
+ scene->setAction(&scene->_sequenceManager1, scene, 1875,
+ &R2_GLOBALS._player, &scene->_airbag, NULL);
return true;
} else if (R2_GLOBALS.getFlag(70)) {
@@ -11762,7 +11659,8 @@ bool Scene1850::Robot::startAction(CursorType action, Event &event) {
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 1878;
- scene->setAction(&scene->_sequenceManager1, scene, 1878, &R2_GLOBALS._player, &scene->_robot, &scene->_actor2, NULL);
+ scene->setAction(&scene->_sequenceManager1, scene, 1878, &R2_GLOBALS._player,
+ &scene->_robot, &scene->_airbag, NULL);
}
return true;
@@ -11773,20 +11671,20 @@ bool Scene1850::Robot::startAction(CursorType action, Event &event) {
}
}
-bool Scene1850::Actor6::startAction(CursorType action, Event &event) {
+bool Scene1850::Door::startAction(CursorType action, Event &event) {
if (action != CURSOR_USE)
return SceneHotspot::startAction(action, event);
- Scene1850 *scene = (Scene1850 *)R2_GLOBALS._sceneManager._scene;
-
if (R2_GLOBALS.getFlag(32)) {
- SceneItem::display(3240, 4, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ SceneItem::display(3240, 4, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, LIST_END);
return true;
}
+ Scene1850 *scene = (Scene1850 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.disableControl();
- if (scene->_field412 == 1851)
- R2_GLOBALS._player._effect = 1;
+ if (scene->_sceneMode == 1851)
+ R2_GLOBALS._player._effect = EFFECT_SHADED;
if (_position.x >= 160)
R2_GLOBALS.setFlag(29);
@@ -11795,9 +11693,9 @@ bool Scene1850::Actor6::startAction(CursorType action, Event &event) {
if ((R2_GLOBALS._player._characterIndex == R2_SEEKER) && (R2_GLOBALS.getFlag(30))) {
if (_position.x >= 160)
- scene->_field41E = 3;
+ scene->_seqNumber = 3;
else
- scene->_field41E = 2;
+ scene->_seqNumber = 2;
scene->_sceneMode = 1860;
@@ -11839,23 +11737,23 @@ bool Scene1850::DisplayScreen::startAction(CursorType action, Event &event) {
/*------------------------------------------------------------------------*/
Scene1850::Scene1850() {
- _field412 = 0;
- _field414 = 0;
- _field416 = 0;
- _field418 = 0;
- _field41E = 0;
+ _sceneMode = 0;
+ _shadeCountdown = 0;
+ _shadeDirection = 0;
+ _shadeChanging = false;
+ _seqNumber = 0;
}
void Scene1850::synchronize(Serializer &s) {
SceneExt::synchronize(s);
- s.syncAsSint16LE(_field412);
- s.syncAsSint16LE(_field414);
- s.syncAsSint16LE(_field416);
- s.syncAsSint16LE(_field418);
- s.syncAsSint16LE(_field41E);
- s.syncAsSint16LE(_field41A.x);
- s.syncAsSint16LE(_field41A.y);
+ s.syncAsSint16LE(_sceneMode);
+ s.syncAsSint16LE(_shadeCountdown);
+ s.syncAsSint16LE(_shadeDirection);
+ s.syncAsSint16LE(_shadeChanging);
+ s.syncAsSint16LE(_seqNumber);
+ s.syncAsSint16LE(_playerDest.x);
+ s.syncAsSint16LE(_playerDest.y);
}
void Scene1850::postInit(SceneObjectList *OwnerList) {
@@ -11867,10 +11765,10 @@ void Scene1850::postInit(SceneObjectList *OwnerList) {
_palette1.loadPalette(0);
if (R2_GLOBALS.getFlag(31)) {
- _field412 = 1850;
+ _sceneMode = 1850;
g_globals->_scenePalette.loadPalette(1850);
} else {
- _field412 = 1851;
+ _sceneMode = 1851;
g_globals->_scenePalette.loadPalette(1851);
}
@@ -11882,9 +11780,9 @@ void Scene1850::postInit(SceneObjectList *OwnerList) {
_stripManager.addSpeaker(&_quinnSpeaker);
_stripManager.addSpeaker(&_seekerSpeaker);
- _field418 = 0;
- _field41E = 0;
- _field41A = Common::Point(0, 0);
+ _shadeChanging = false;
+ _seqNumber = 0;
+ _playerDest = Common::Point(0, 0);
R2_GLOBALS._player._characterScene[R2_QUINN] = 1850;
R2_GLOBALS._player._characterScene[R2_SEEKER] = 1850;
@@ -11934,8 +11832,8 @@ void Scene1850::postInit(SceneObjectList *OwnerList) {
}
if (R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] == 1850) {
- R2_GLOBALS._player._effect = 6;
- _companion._effect = 6;
+ R2_GLOBALS._player._effect = EFFECT_SHADED2;
+ _companion._effect = EFFECT_SHADED2;
if (R2_GLOBALS.getFlag(31)) {
R2_GLOBALS._player._shade = 0;
_companion._shade = 0;
@@ -11945,21 +11843,21 @@ void Scene1850::postInit(SceneObjectList *OwnerList) {
}
if (R2_INVENTORY.getObjectScene(R2_AIRBAG) == 1850) {
- _actor2.postInit();
+ _airbag.postInit();
if (R2_GLOBALS.getFlag(34)) {
- _actor2.setup(1851, 4, 2);
- _actor2.fixPriority(114);
+ _airbag.setup(1851, 4, 2);
+ _airbag.fixPriority(114);
} else {
- _actor2.setup(1851, 4, 1);
+ _airbag.setup(1851, 4, 1);
}
- _actor2.setPosition(Common::Point(179, 113));
+ _airbag.setPosition(Common::Point(179, 113));
if ((_robot._strip == 1) && (_robot._frame == 3)){
- _actor2.hide();
+ _airbag.hide();
}
- _actor2.setDetails(1850, 6, -1, -1, 1, (SceneItem *) NULL);
+ _airbag.setDetails(1850, 6, -1, -1, 1, (SceneItem *) NULL);
}
if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
@@ -11967,89 +11865,61 @@ void Scene1850::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player.setVisage(1511);
_companion.setVisage(1508);
- _actor3.postInit();
- _actor3.setup(1853, 3, 1);
- _actor3.setPosition(Common::Point(122, 113));
- _actor3.fixPriority(114);
- _actor3._effect = 6;
-
- // Totally useless test
- if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
- _actor3.setDetails(1850, 28, -1, -1, 2, (SceneItem *) NULL);
- } else {
- // And the associated dead code
- _actor3.setDetails(1850, 30, -1, -1, 2, (SceneItem *) NULL);
- }
+ _screen.postInit();
+ _screen.setup(1853, 3, 1);
+ _screen.setPosition(Common::Point(122, 113));
+ _screen.fixPriority(114);
+ _screen._effect = EFFECT_SHADED2;
+ _screen.setDetails(1850, 28, -1, -1, 2, (SceneItem *) NULL);
- _actor4.postInit();
- _actor4.setup(1853, 3, 2);
- _actor4.setPosition(Common::Point(139, 111));
- _actor4.fixPriority(114);
- _actor4._effect = 6;
-
- // Still totally useless test
- if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
- _actor4.setDetails(1850, 29, -1, -1, 2, (SceneItem *) NULL);
- } else {
- // Another piece of dead code
- _actor4.setDetails(1850, 28, -1, -1, 2, (SceneItem *) NULL);
- }
+ _helmet.postInit();
+ _helmet.setup(1853, 3, 2);
+ _helmet.setPosition(Common::Point(139, 111));
+ _helmet.fixPriority(114);
+ _helmet._effect = EFFECT_SHADED2;
+ _helmet.setDetails(1850, 29, -1, -1, 2, (SceneItem *) NULL);
if (R2_GLOBALS.getFlag(31)) {
- _actor3._shade = 0;
- _actor4._shade = 0;
+ _screen._shade = 0;
+ _helmet._shade = 0;
} else {
- _actor3._shade = 6;
- _actor4._shade = 6;
+ _screen._shade = 6;
+ _helmet._shade = 6;
}
} else {
R2_GLOBALS._player.setVisage(1500);
_companion.setVisage(1505);
}
- } else { // Not Quinn
- if (R2_GLOBALS.getFlag(32)) {
- R2_GLOBALS._player.setVisage(1508);
- _companion.setVisage(1511);
-
- _actor3.postInit();
- _actor3.setup(1853, 3, 1);
- _actor3.setPosition(Common::Point(122, 113));
- _actor3.fixPriority(114);
- _actor3._effect = 6;
-
- // Totally useless test
- if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
- // Dead code
- _actor3.setDetails(1850, 28, -1, -1, 2, (SceneItem *) NULL);
- } else {
- _actor3.setDetails(1850, 30, -1, -1, 2, (SceneItem *) NULL);
- }
-
- _actor4.postInit();
- _actor4.setup(1853, 3, 2);
- _actor4.setPosition(Common::Point(139, 111));
- _actor4.fixPriority(114);
- _actor4._effect = 6;
-
- // Again, useless test
- if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
- // and dead code
- _actor4.setDetails(1850, 29, -1, -1, 1, (SceneItem *) NULL);
- } else {
- _actor4.setDetails(1850, 28, -1, -1, 1, (SceneItem *) NULL);
- }
-
- if (R2_GLOBALS.getFlag(31)) {
- _actor3._shade = 0;
- _actor4._shade = 0;
- } else {
- _actor3._shade = 6;
- _actor4._shade = 6;
- }
+ } else if (R2_GLOBALS.getFlag(32)) {
+ // Not Quinn, flag 32
+ R2_GLOBALS._player.setVisage(1508);
+ _companion.setVisage(1511);
+
+ _screen.postInit();
+ _screen.setup(1853, 3, 1);
+ _screen.setPosition(Common::Point(122, 113));
+ _screen.fixPriority(114);
+ _screen._effect = EFFECT_SHADED2;
+ _screen.setDetails(1850, 30, -1, -1, 2, (SceneItem *) NULL);
+
+ _helmet.postInit();
+ _helmet.setup(1853, 3, 2);
+ _helmet.setPosition(Common::Point(139, 111));
+ _helmet.fixPriority(114);
+ _helmet._effect = EFFECT_SHADED2;
+ _helmet.setDetails(1850, 28, -1, -1, 1, (SceneItem *) NULL);
+
+ if (R2_GLOBALS.getFlag(31)) {
+ _screen._shade = 0;
+ _helmet._shade = 0;
} else {
- R2_GLOBALS._player.setVisage(1505);
- _companion.setVisage(1500);
+ _screen._shade = 6;
+ _helmet._shade = 6;
}
+ } else {
+ // Not Quinn, nor flag 32
+ R2_GLOBALS._player.setVisage(1505);
+ _companion.setVisage(1500);
}
R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
@@ -12087,8 +11957,8 @@ void Scene1850::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player.enableControl();
} else { // R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] != 1850
- R2_GLOBALS._player._effect = 1;
- _companion._effect = 1;
+ R2_GLOBALS._player._effect = EFFECT_SHADED;
+ _companion._effect = EFFECT_SHADED;
R2_GLOBALS._player.disableControl();
_sceneMode = 10;
if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
@@ -12154,10 +12024,10 @@ void Scene1850::remove() {
void Scene1850::signal() {
switch (_sceneMode) {
case 10:
- R2_GLOBALS._player._effect = 6;
+ R2_GLOBALS._player._effect = EFFECT_SHADED2;
R2_GLOBALS._player._shade = 6;
- _companion._effect = 6;
+ _companion._effect = EFFECT_SHADED2;
_companion._shade = 6;
R2_GLOBALS._walkRegions.disableRegion(5);
@@ -12180,7 +12050,8 @@ void Scene1850::signal() {
break;
case 16:
_sceneMode = 1870;
- setAction(&_sequenceManager1, this, 1870, &R2_GLOBALS._player, &_companion, &_actor3, &_actor4, NULL);
+ setAction(&_sequenceManager1, this, 1870, &R2_GLOBALS._player, &_companion,
+ &_screen, &_helmet, NULL);
break;
case 20:
R2_GLOBALS._player.enableControl(CURSOR_TALK);
@@ -12188,7 +12059,8 @@ void Scene1850::signal() {
case 21:
R2_GLOBALS._player.disableControl();
_sceneMode = 1877;
- setAction(&_sequenceManager1, this, 1877, &R2_GLOBALS._player, &_companion, &_robot, NULL);
+ setAction(&_sequenceManager1, this, 1877, &R2_GLOBALS._player, &_companion,
+ &_robot, NULL);
break;
case 30:
R2_GLOBALS._player.disableControl();
@@ -12198,17 +12070,17 @@ void Scene1850::signal() {
case 1852:
// No break on purpose:
case 1853:
- if (_field412 == 1851) {
+ if (_sceneMode == 1851) { // At this point, SceneMode can't be equal to 1851 => dead code
R2_GLOBALS.setFlag(31);
_palette1.loadPalette(1850);
- _field412 = 1850;
+ _sceneMode = 1850;
} else {
R2_GLOBALS.clearFlag(31);
_palette1.loadPalette(1851);
- _field412 = 1851;
+ _sceneMode = 1851;
}
- _field418 = 1;
+ _shadeChanging = true;
if (R2_GLOBALS.getFlag(30)) {
_displayScreen.setAction(&_sequenceManager2, NULL, 1867, &_displayScreen, NULL);
} else if (R2_GLOBALS.getFlag(34)) {
@@ -12224,12 +12096,13 @@ void Scene1850::signal() {
R2_GLOBALS.setFlag(34);
R2_GLOBALS._walkRegions.disableRegion(2);
- _actor2.postInit();
- _actor2.setDetails(1850, 6, -1, -1, 5, &_robot);
+ _airbag.postInit();
+ _airbag.setDetails(1850, 6, -1, -1, 5, &_robot);
_sceneMode = 1879;
- _displayScreen.setAction(&_sequenceManager2, this, 1879, &_robot, &_displayScreen, &_actor2, NULL);
+ _displayScreen.setAction(&_sequenceManager2, this, 1879, &_robot,
+ &_displayScreen, &_airbag, NULL);
} else {
_displayScreen.setAction(&_sequenceManager2, NULL, 1867, &_displayScreen, NULL);
}
@@ -12239,12 +12112,12 @@ void Scene1850::signal() {
else
R2_GLOBALS._scenePalette.addFader(_palette1._palette, 256, 5, this);
- if (_field412 == 1851)
- _field416 = -20;
+ if (_sceneMode == 1851)
+ _shadeDirection = -20;
else
- _field416 = 20;
+ _shadeDirection = 20;
- _field414 = 20;
+ _shadeCountdown = 20;
if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
if (_sceneMode == 1879)
@@ -12290,16 +12163,16 @@ void Scene1850::signal() {
_stripManager.start(575, this);
break;
case 1860:
- if (_field41A.x != 0) {
+ if (_playerDest.x != 0) {
R2_GLOBALS._player.enableControl();
PlayerMover *mover = new PlayerMover();
- R2_GLOBALS._player.addMover(mover, &_field41A, this);
+ R2_GLOBALS._player.addMover(mover, &_playerDest, this);
- _field41A = Common::Point(0, 0);
+ _playerDest = Common::Point(0, 0);
}
- switch (_field41E) {
+ switch (_seqNumber) {
case 1:
_sceneMode = 1853;
if (R2_GLOBALS.getFlag(32)) {
@@ -12320,7 +12193,7 @@ void Scene1850::signal() {
break;
}
- _field41E = 0;
+ _seqNumber = 0;
break;
case 1870:
R2_GLOBALS._walkRegions.disableRegion(5);
@@ -12335,36 +12208,36 @@ void Scene1850::signal() {
_stripManager.start(561, this);
break;
case 1877:
- _actor3.postInit();
- _actor3._effect = 6;
+ _screen.postInit();
+ _screen._effect = EFFECT_SHADED2;
if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
- _actor3.setDetails(1850, 28, -1, -1, 2, (SceneItem *)NULL);
+ _screen.setDetails(1850, 28, -1, -1, 2, (SceneItem *)NULL);
} else {
- _actor3.setDetails(1850, 30, -1, -1, 2, (SceneItem *)NULL);
+ _screen.setDetails(1850, 30, -1, -1, 2, (SceneItem *)NULL);
}
- _actor4.postInit();
- _actor4._effect = 6;
+ _helmet.postInit();
+ _helmet._effect = EFFECT_SHADED2;
if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
- _actor4.setDetails(1850, 29, -1, -1, 2, (SceneItem *)NULL);
+ _helmet.setDetails(1850, 29, -1, -1, 2, (SceneItem *)NULL);
} else {
- _actor4.setDetails(1850, 28, -1, -1, 2, (SceneItem *)NULL);
+ _helmet.setDetails(1850, 28, -1, -1, 2, (SceneItem *)NULL);
}
if (R2_GLOBALS.getFlag(31)) {
- _actor3._shade = 0;
- _actor4._shade = 0;
+ _screen._shade = 0;
+ _helmet._shade = 0;
} else {
- _actor3._shade = 6;
- _actor4._shade = 6;
+ _screen._shade = 6;
+ _helmet._shade = 6;
}
R2_GLOBALS.clearFlag(30);
_sceneMode = 15;
- setAction(&_sequenceManager1, this, 1869, &R2_GLOBALS._player, &_actor3, NULL);
- _companion.setAction(&_sequenceManager2, this, 1868, &_companion, &_actor4, NULL);
+ setAction(&_sequenceManager1, this, 1869, &R2_GLOBALS._player, &_screen, NULL);
+ _companion.setAction(&_sequenceManager2, this, 1868, &_companion, &_helmet, NULL);
break;
case 1878:
R2_INVENTORY.setObjectScene(R2_REBREATHER_TANK, 1850);
@@ -12390,8 +12263,8 @@ void Scene1850::signal() {
void Scene1850::process(Event &event) {
if ( (event.eventType == EVENT_BUTTON_DOWN) && (R2_GLOBALS._events.getCursor() == CURSOR_WALK)
- && (R2_GLOBALS._player._characterIndex == R2_SEEKER) && (R2_GLOBALS.getFlag(30))) {
- _field41A = event.mousePos;
+ && (R2_GLOBALS._player._characterIndex == R2_SEEKER) && (R2_GLOBALS.getFlag(30))) {
+ _playerDest = event.mousePos;
R2_GLOBALS._player.disableControl();
_sceneMode = 1860;
if (R2_GLOBALS.getFlag(32)) {
@@ -12399,7 +12272,7 @@ void Scene1850::process(Event &event) {
} else {
setAction(&_sequenceManager1, this, 1859, &R2_GLOBALS._player, &_robot, NULL);
}
- R2_GLOBALS.clearFlag(32);
+ R2_GLOBALS.clearFlag(30);
event.handled = true;
}
@@ -12407,35 +12280,35 @@ void Scene1850::process(Event &event) {
}
void Scene1850::dispatch() {
- if (_field418 != 0) {
- _field414--;
- if (_field414 == 0)
- _field418 = 0;
+ if (_shadeChanging) {
+ _shadeCountdown--;
+ if (_shadeCountdown == 0)
+ _shadeChanging = false;
- if (_field416 >= 0) {
- R2_GLOBALS._player._shade = (_field414 * 6) / _field416;
+ if (_shadeDirection >= 0) {
+ R2_GLOBALS._player._shade = (_shadeCountdown * 6) / _shadeDirection;
} else {
- R2_GLOBALS._player._shade = ((_field414 * 6) / _field416) + 6;
+ R2_GLOBALS._player._shade = ((_shadeCountdown * 6) / _shadeDirection) + 6;
}
R2_GLOBALS._player._flags |= OBJFLAG_PANES;
_companion._shade = R2_GLOBALS._player._shade;
_companion._flags |= OBJFLAG_PANES;
- _actor3._shade = R2_GLOBALS._player._shade;
- _actor3._flags |= OBJFLAG_PANES;
+ _screen._shade = R2_GLOBALS._player._shade;
+ _screen._flags |= OBJFLAG_PANES;
- _actor4._shade = R2_GLOBALS._player._shade;
- _actor4._flags |= OBJFLAG_PANES;
+ _helmet._shade = R2_GLOBALS._player._shade;
+ _helmet._flags |= OBJFLAG_PANES;
}
if (R2_GLOBALS.getFlag(32)) {
- _actor3.setPosition(Common::Point(_displayScreen._position.x - 37, _displayScreen._position.y - 71));
- _actor4.setPosition(Common::Point(_displayScreen._position.x - 20, _displayScreen._position.y - 73));
+ _screen.setPosition(Common::Point(_displayScreen._position.x - 37, _displayScreen._position.y - 71));
+ _helmet.setPosition(Common::Point(_displayScreen._position.x - 20, _displayScreen._position.y - 73));
}
if (R2_INVENTORY.getObjectScene(R2_AIRBAG) == 1850) {
- _actor2.setPosition(Common::Point(_displayScreen._position.x + 20, _displayScreen._position.y - 71));
+ _airbag.setPosition(Common::Point(_displayScreen._position.x + 20, _displayScreen._position.y - 71));
}
Scene::dispatch();
@@ -12466,7 +12339,7 @@ void Scene1875::Button::doButtonPress() {
int newFrameNumber;
switch (_buttonId) {
case 3:
- if ((scene->_actor1._frame == 1) && (scene->_button1._strip == 2)) {
+ if ((scene->_map._frame == 1) && (scene->_button1._strip == 2)) {
R2_GLOBALS._player.disableControl();
R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
scene->_sceneMode = 10;
@@ -12474,21 +12347,21 @@ void Scene1875::Button::doButtonPress() {
} else {
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 1890;
- scene->_actor2.postInit();
- scene->setAction(&scene->_sequenceManager, scene, 1890, &scene->_actor2, NULL);
+ scene->_rimPosition.postInit();
+ scene->setAction(&scene->_sequenceManager, scene, 1890, &scene->_rimPosition, NULL);
}
break;
case 4:
- newFrameNumber = scene->_actor1._frame + 1;
+ newFrameNumber = scene->_map._frame + 1;
if (newFrameNumber > 6)
newFrameNumber = 1;
- scene->_actor1.setFrame(newFrameNumber);
+ scene->_map.setFrame(newFrameNumber);
break;
case 5:
- newFrameNumber = scene->_actor1._frame - 1;
+ newFrameNumber = scene->_map._frame - 1;
if (newFrameNumber < 1)
newFrameNumber = 6;
- scene->_actor1.setFrame(newFrameNumber);
+ scene->_map.setFrame(newFrameNumber);
break;
default:
break;
@@ -12536,7 +12409,7 @@ void Scene1875::Button::process(Event &event) {
Scene1875 *scene = (Scene1875 *)R2_GLOBALS._sceneManager._scene;
- if ((event.eventType == EVENT_BUTTON_DOWN) && (R2_GLOBALS._events.getCursor() == CURSOR_USE)
+ if ((event.eventType == EVENT_BUTTON_DOWN) && (R2_GLOBALS._events.getCursor() == CURSOR_USE)
&& (_bounds.contains(event.mousePos)) && !_buttonDown) {
setStrip(2);
switch (_buttonId) {
@@ -12581,9 +12454,9 @@ void Scene1875::postInit(SceneObjectList *OwnerList) {
_button4.initButton(4);
_button5.initButton(5);
- _actor1.postInit();
- _actor1.setup(1855, 4, 1);
- _actor1.setPosition(Common::Point(160, 116));
+ _map.postInit();
+ _map.setup(1855, 4, 1);
+ _map.setPosition(Common::Point(160, 116));
R2_GLOBALS._player.postInit();
R2_GLOBALS._player.hide();
@@ -12592,19 +12465,19 @@ void Scene1875::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._sound1.play(122);
R2_GLOBALS._player.disableControl();
_sceneMode = 11;
- _actor2.postInit();
- setAction(&_sequenceManager, this, 1892, &_actor2, NULL);
+ _rimPosition.postInit();
+ setAction(&_sequenceManager, this, 1892, &_rimPosition, NULL);
} else {
if (R2_GLOBALS._sceneManager._previousScene == 3150) {
R2_GLOBALS._sound1.play(116);
- }
+ }
R2_GLOBALS._player.enableControl();
R2_GLOBALS._player._canWalk = false;
}
- _item2.setDetails(Rect(43, 14, 275, 122), 1875, 9, 1, -1, 1, NULL);
- _item1.setDetails(Rect(0, 0, 320, 200), 1875, 3, -1, -1, 1, NULL);
+ _screen.setDetails(Rect(43, 14, 275, 122), 1875, 9, 1, -1, 1, NULL);
+ _background.setDetails(Rect(0, 0, 320, 200), 1875, 3, -1, -1, 1, NULL);
R2_GLOBALS._player._characterScene[R2_QUINN] = 1875;
R2_GLOBALS._player._characterScene[R2_SEEKER] = 1875;
@@ -12617,8 +12490,8 @@ void Scene1875::signal() {
case 10:
R2_GLOBALS._player.disableControl();
_sceneMode = 1891;
- _actor2.postInit();
- setAction(&_sequenceManager, this, 1891, &_actor2, NULL);
+ _rimPosition.postInit();
+ setAction(&_sequenceManager, this, 1891, &_rimPosition, NULL);
break;
case 11:
R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
@@ -12626,7 +12499,7 @@ void Scene1875::signal() {
_stripManager.start(577, this);
break;
case 1890:
- _actor2.remove();
+ _rimPosition.remove();
R2_GLOBALS._player.enableControl();
R2_GLOBALS._player._canWalk = false;
break;
@@ -12661,8 +12534,6 @@ void Scene1875::process(Event &event) {
*--------------------------------------------------------------------------*/
bool Scene1900::LiftDoor::startAction(CursorType action, Event &event) {
- Scene1900 *scene = (Scene1900 *)R2_GLOBALS._sceneManager._scene;
-
if (action != CURSOR_USE)
return SceneActor::startAction(action, event);
@@ -12673,6 +12544,8 @@ bool Scene1900::LiftDoor::startAction(CursorType action, Event &event) {
return true;
}
+ Scene1900 *scene = (Scene1900 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.enableControl(CURSOR_USE);
if (_position.x >= 160) {
@@ -12769,23 +12642,23 @@ void Scene1900::postInit(SceneObjectList *OwnerList) {
_rightDoor.setDetails(1900, 0, 1, -1, 1, (SceneItem *) NULL);
if (R2_GLOBALS._sceneManager._previousScene != 1875) {
- _object1.postInit();
- _object1.setup(1945, 6, 1);
- _object1.setPosition(Common::Point(96, 109));
- _object1.fixPriority(80);
+ _leftDoorFrame.postInit();
+ _leftDoorFrame.setup(1945, 6, 1);
+ _leftDoorFrame.setPosition(Common::Point(96, 109));
+ _leftDoorFrame.fixPriority(80);
- _object2.postInit();
- _object2.setup(1945, 6, 2);
- _object2.setPosition(Common::Point(223, 109));
- _object2.fixPriority(80);
+ _rightDoorFrame.postInit();
+ _rightDoorFrame.setup(1945, 6, 2);
+ _rightDoorFrame.setPosition(Common::Point(223, 109));
+ _rightDoorFrame.fixPriority(80);
}
if (R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] == 1875) {
R2_GLOBALS._player._characterIndex = R2_QUINN;
- _actor1.postInit();
+ _companion.postInit();
_sceneMode = 20;
R2_GLOBALS._player.setAction(&_sequenceManager1, NULL, 1901, &R2_GLOBALS._player, &_leftDoor, NULL);
- _actor1.setAction(&_sequenceManager2, this, 1900, &_actor1, &_rightDoor, NULL);
+ _companion.setAction(&_sequenceManager2, this, 1900, &_companion, &_rightDoor, NULL);
} else if (R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] == 1925) {
if (R2_GLOBALS.getFlag(29)) {
R2_GLOBALS.clearFlag(29);
@@ -12804,24 +12677,24 @@ void Scene1900::postInit(SceneObjectList *OwnerList) {
}
if (R2_GLOBALS._player._characterScene[R2_QUINN] == R2_GLOBALS._player._characterScene[R2_SEEKER]) {
- _actor1.postInit();
- _actor1.setPosition(Common::Point(30, 110));
+ _companion.postInit();
+ _companion.setPosition(Common::Point(30, 110));
R2_GLOBALS._walkRegions.disableRegion(1);
- _actor1.setup(2008, 3, 1);
- _actor1.setDetails(9001, 0, -1, -1, 1, (SceneItem *) NULL);
+ _companion.setup(2008, 3, 1);
+ _companion.setDetails(9001, 0, -1, -1, 1, (SceneItem *) NULL);
}
R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] = 1900;
} else {
if (R2_GLOBALS._player._characterScene[R2_QUINN] == R2_GLOBALS._player._characterScene[R2_SEEKER]) {
- _actor1.postInit();
- _actor1.setPosition(Common::Point(30, 110));
+ _companion.postInit();
+ _companion.setPosition(Common::Point(30, 110));
R2_GLOBALS._walkRegions.disableRegion(1);
if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
- _actor1.setup(20, 3, 1);
- _actor1.setDetails(9002, 1, -1, -1, 1, (SceneItem *) NULL);
+ _companion.setup(20, 3, 1);
+ _companion.setDetails(9002, 1, -1, -1, 1, (SceneItem *) NULL);
} else {
- _actor1.setup(2008, 3, 1);
- _actor1.setDetails(9001, 0, -1, -1, 1, (SceneItem *) NULL);
+ _companion.setup(2008, 3, 1);
+ _companion.setDetails(9001, 0, -1, -1, 1, (SceneItem *) NULL);
}
}
@@ -12884,7 +12757,7 @@ void Scene1900::signal() {
break;
case 22:
_sceneMode = 1910;
- _actor1.setAction(&_sequenceManager2, this, 1910, &_actor1, NULL);
+ _companion.setAction(&_sequenceManager2, this, 1910, &_companion, NULL);
break;
case 1904:
R2_GLOBALS._scene1925CurrLevel = -3;
@@ -12915,7 +12788,7 @@ void Scene1900::signal() {
*--------------------------------------------------------------------------*/
Scene1925::Scene1925() {
- _field9B8 = 0;
+ _newSceneMode = 0;
for (int i = 0; i < 5; i++)
_levelResNum[i] = 0;
}
@@ -12923,20 +12796,20 @@ Scene1925::Scene1925() {
void Scene1925::synchronize(Serializer &s) {
SceneExt::synchronize(s);
- s.syncAsSint16LE(_field9B8);
+ s.syncAsSint16LE(_newSceneMode);
for (int i = 0; i < 5; i++)
s.syncAsSint16LE(_levelResNum[i]);
}
bool Scene1925::Button::startAction(CursorType action, Event &event) {
- Scene1925 *scene = (Scene1925 *)R2_GLOBALS._sceneManager._scene;
-
if (action != CURSOR_USE)
return SceneHotspot::startAction(action, event);
if ((R2_GLOBALS._player._position.x == 110) && (R2_GLOBALS._player._position.y == 100))
return SceneHotspot::startAction(action, event);
+ Scene1925 *scene = (Scene1925 *)R2_GLOBALS._sceneManager._scene;
+
if ((R2_GLOBALS._player._position.x == 154) && (R2_GLOBALS._player._position.y == 20))
scene->_sceneMode = 1928;
else if ((R2_GLOBALS._player._position.x == 154) && (R2_GLOBALS._player._position.y == 200))
@@ -12945,7 +12818,8 @@ bool Scene1925::Button::startAction(CursorType action, Event &event) {
scene->_sceneMode = 1930;
R2_GLOBALS._player.disableControl(CURSOR_WALK);
- scene->setAction(&scene->_sequenceManager, scene, scene->_sceneMode, &R2_GLOBALS._player, &scene->_actor1, NULL);
+ scene->setAction(&scene->_sequenceManager, scene, scene->_sceneMode, &R2_GLOBALS._player,
+ &scene->_door, NULL);
return true;
}
@@ -12959,9 +12833,10 @@ bool Scene1925::Ladder::startAction(CursorType action, Event &event) {
scene->_sceneMode = 0;
if ((R2_GLOBALS._player._position.x == 110) && (R2_GLOBALS._player._position.y == 100)) {
- scene->_exit3._enabled = false;
+ scene->_westExit._enabled = false;
scene->_sceneMode = 1925;
- scene->setAction(&scene->_sequenceManager, scene, scene->_sceneMode, &R2_GLOBALS._player, &scene->_actor1, NULL);
+ scene->setAction(&scene->_sequenceManager, scene, scene->_sceneMode,
+ &R2_GLOBALS._player, &scene->_door, NULL);
return true;
}
@@ -12996,10 +12871,11 @@ void Scene1925::ExitUp::changeScene() {
scene->_sceneMode = 0;
if ((R2_GLOBALS._player._position.x == 110) && (R2_GLOBALS._player._position.y == 100)) {
- scene->_exit3._enabled = false;
- scene->_field9B8 = 1927;
+ scene->_westExit._enabled = false;
+ scene->_newSceneMode = 1927;
scene->_sceneMode = 1925;
- scene->setAction(&scene->_sequenceManager, scene, scene->_sceneMode, &R2_GLOBALS._player, &scene->_actor1, NULL);
+ scene->setAction(&scene->_sequenceManager, scene, scene->_sceneMode,
+ &R2_GLOBALS._player, &scene->_door, NULL);
return;
}
@@ -13018,7 +12894,7 @@ void Scene1925::ExitUp::changeScene() {
}
}
-void Scene1925::Exit2::changeScene() {
+void Scene1925::ExitDown::changeScene() {
Scene1925 *scene = (Scene1925 *)R2_GLOBALS._sceneManager._scene;
_moving = false;
@@ -13026,10 +12902,11 @@ void Scene1925::Exit2::changeScene() {
scene->_sceneMode = 0;
if ((R2_GLOBALS._player._position.x == 110) && (R2_GLOBALS._player._position.y == 100)) {
- scene->_exit3._enabled = false;
- scene->_field9B8 = 1926;
+ scene->_westExit._enabled = false;
+ scene->_newSceneMode = 1926;
scene->_sceneMode = 1925;
- scene->setAction(&scene->_sequenceManager, scene, scene->_sceneMode, &R2_GLOBALS._player, &scene->_actor1, NULL);
+ scene->setAction(&scene->_sequenceManager, scene, scene->_sceneMode,
+ &R2_GLOBALS._player, &scene->_door, NULL);
return;
}
@@ -13047,7 +12924,7 @@ void Scene1925::Exit2::changeScene() {
scene->setAction(&scene->_sequenceManager, scene, scene->_sceneMode, &R2_GLOBALS._player, NULL);
}
-void Scene1925::Exit3::changeScene() {
+void Scene1925::WestExit::changeScene() {
Scene1925 *scene = (Scene1925 *)R2_GLOBALS._sceneManager._scene;
_moving = false;
@@ -13056,7 +12933,7 @@ void Scene1925::Exit3::changeScene() {
scene->setAction(&scene->_sequenceManager, scene, scene->_sceneMode, &R2_GLOBALS._player, NULL);
}
-void Scene1925::Exit4::changeScene() {
+void Scene1925::EastExit::changeScene() {
Scene1925 *scene = (Scene1925 *)R2_GLOBALS._sceneManager._scene;
_moving = false;
@@ -13087,8 +12964,8 @@ void Scene1925::changeLevel(bool upFlag) {
case 3:
loadScene(_levelResNum[4]);
_button.setDetails(Rect(133, 68, 140, 77), 1925, 3, -1, 5, 2, NULL);
- _actor1.setDetails(1925, 0, 1, 2, 2, (SceneItem *) NULL);
- _actor1.show();
+ _door.setDetails(1925, 0, 1, 2, 2, (SceneItem *) NULL);
+ _door.show();
break;
case 512:
R2_GLOBALS._scene1925CurrLevel = 508;
@@ -13096,8 +12973,8 @@ void Scene1925::changeLevel(bool upFlag) {
default:
loadScene(_levelResNum[(R2_GLOBALS._scene1925CurrLevel % 4)]);
R2_GLOBALS._sceneItems.remove(&_button);
- R2_GLOBALS._sceneItems.remove(&_actor1);
- _actor1.hide();
+ R2_GLOBALS._sceneItems.remove(&_door);
+ _door.hide();
break;
}
@@ -13127,32 +13004,33 @@ void Scene1925::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player.disableControl();
R2_GLOBALS._player._characterScene[R2_SEEKER] = 1925;
R2_GLOBALS._player._characterIndex = R2_SEEKER;
+
switch (R2_GLOBALS._scene1925CurrLevel) {
case -2:
- _exit4.setDetails(Rect(203, 44, 247, 111), EXITCURSOR_E, 1925);
+ _eastExit.setDetails(Rect(203, 44, 247, 111), EXITCURSOR_E, 1925);
_ladder.setDetails(Rect(31, 3, 45, 167), 1925, 6, -1, 8, 1, NULL);
break;
case 3:
- _actor1.setDetails(1925, 0, 1, 2, 1, (SceneItem *) NULL);
+ _door.setDetails(1925, 0, 1, 2, 1, (SceneItem *) NULL);
_button.setDetails(Rect(133, 68, 140, 77), 1925, 3, -1, 5, 1, NULL);
// No break on purpose
case -3:
- _exit3.setDetails(Rect(83, 38, 128, 101), EXITCURSOR_W, 1925);
+ _westExit.setDetails(Rect(83, 38, 128, 101), EXITCURSOR_W, 1925);
// No break on purpose
default:
_exitUp.setDetails(Rect(128, 0, 186, 10), EXITCURSOR_N, 1925);
- _exit2.setDetails(Rect(128, 160, 190, 167), EXITCURSOR_S, 1925);
+ _exitDown.setDetails(Rect(128, 160, 190, 167), EXITCURSOR_S, 1925);
_ladder.setDetails(Rect(141, 11, 167, 159), 1925, 6, -1, -1, 1, NULL);
break;
}
- _actor1.postInit();
- _actor1.setup(1925, 5, 1);
- _actor1.setPosition(Common::Point(128, 35));
- _actor1.hide();
+ _door.postInit();
+ _door.setup(1925, 5, 1);
+ _door.setPosition(Common::Point(128, 35));
+ _door.hide();
if (R2_GLOBALS._scene1925CurrLevel == 3)
- _actor1.show();
+ _door.show();
R2_GLOBALS._player.enableControl(CURSOR_USE);
switch (R2_GLOBALS._scene1925CurrLevel) {
@@ -13162,7 +13040,7 @@ void Scene1925::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player.setPosition(Common::Point(224, 109));
break;
case -3:
- _actor1.hide();
+ _door.hide();
R2_GLOBALS._player.setup(20, 5, 1);
R2_GLOBALS._player.setPosition(Common::Point(110, 100));
break;
@@ -13177,9 +13055,9 @@ void Scene1925::postInit(SceneObjectList *OwnerList) {
}
R2_GLOBALS._player._canWalk = false;
- _field9B8 = 0;
+ _newSceneMode = 0;
R2_GLOBALS._sceneManager._previousScene = 1925;
- _item1.setDetails(Rect(27, 0, 292, 200), 1925, 9, -1, -1, 1, NULL);
+ _background.setDetails(Rect(27, 0, 292, 200), 1925, 9, -1, -1, 1, NULL);
}
void Scene1925::remove() {
@@ -13215,10 +13093,10 @@ void Scene1925::signal() {
changeLevel(true);
break;
case 1925:
- _exit3._enabled = false;
- if (_field9B8 != 0) {
- _sceneMode = _field9B8;
- _field9B8 = 0;
+ _westExit._enabled = false;
+ if (_newSceneMode != 0) {
+ _sceneMode = _newSceneMode;
+ _newSceneMode = 0;
setAction(&_sequenceManager, this, _sceneMode, &R2_GLOBALS._player, NULL);
}
// No break on purpose
@@ -13290,11 +13168,11 @@ bool Scene1945::Ice::startAction(CursorType action, Event &event) {
}
bool Scene1945::Ladder::startAction(CursorType action, Event &event) {
- Scene1945 *scene = (Scene1945 *)R2_GLOBALS._sceneManager._scene;
-
if (action != CURSOR_USE)
return SceneHotspot::startAction(action, event);
+ Scene1945 *scene = (Scene1945 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.disableControl(CURSOR_USE);
scene->_sceneMode = 0;
@@ -13304,7 +13182,8 @@ bool Scene1945::Ladder::startAction(CursorType action, Event &event) {
} else if ( ((R2_GLOBALS._player._position.x == 197) && (R2_GLOBALS._player._position.y == 158))
|| ((R2_GLOBALS._player._position.x == 191) && (R2_GLOBALS._player._position.y == 142)) ) {
scene->_sceneMode = 1947;
- } else if ((R2_GLOBALS._player._position.x == 221) && (R2_GLOBALS._player._position.y == 142) && (event.mousePos.y >= 30)) {
+ } else if ((R2_GLOBALS._player._position.x == 154) && (R2_GLOBALS._player._position.y == 50)
+ && (event.mousePos.y >= 30)) {
scene->_sceneMode = 1940;
} else {
R2_GLOBALS._player.enableControl(CURSOR_USE);
@@ -13413,14 +13292,14 @@ void Scene1945::postInit(SceneObjectList *OwnerList) {
else
_gunpowder.hide();
- _actor1.postInit();
- _actor1.setup(1945, 8, 1);
- _actor1.setPosition(Common::Point(253, 169));
- _actor1.fixPriority(130);
+ _coveringIce.postInit();
+ _coveringIce.setup(1945, 8, 1);
+ _coveringIce.setPosition(Common::Point(253, 169));
+ _coveringIce.fixPriority(130);
- _actor2.postInit();
- _actor2.setup(1945, 3, 1);
- _actor2.hide();
+ _alcoholLamp.postInit();
+ _alcoholLamp.setup(1945, 3, 1);
+ _alcoholLamp.hide();
} else {
_corridorExit._enabled = true;
}
@@ -13449,8 +13328,8 @@ void Scene1945::postInit(SceneObjectList *OwnerList) {
_nextSceneMode2 = 0;
_ice.setDetails(11, 1945, 3, -1, 5);
- _item1.setDetails(Rect(238, 144, 274, 167), 1945, 0, -1, 2, 1, NULL);
- _item2.setDetails(Rect(27, 3, 292, 167), 1945, 3, -1, -1, 1, NULL);
+ _hole.setDetails(Rect(238, 144, 274, 167), 1945, 0, -1, 2, 1, NULL);
+ _ice2.setDetails(Rect(27, 3, 292, 167), 1945, 3, -1, -1, 1, NULL);
}
void Scene1945::remove() {
@@ -13463,7 +13342,7 @@ void Scene1945::signal() {
case 1940:
if (_nextSceneMode1 == 1943) {
_sceneMode = _nextSceneMode1;
- setAction(&_sequenceManager1, this, _sceneMode, &R2_GLOBALS._player, &_actor2, NULL);
+ setAction(&_sequenceManager1, this, _sceneMode, &R2_GLOBALS._player, &_alcoholLamp, NULL);
} else {
_sceneMode = 1946;
setAction(&_sequenceManager1, this, _sceneMode, &R2_GLOBALS._player, NULL);
@@ -13490,7 +13369,7 @@ void Scene1945::signal() {
R2_GLOBALS._sound1.fadeOut2(NULL);
R2_INVENTORY.setObjectScene(_lampUsed, 0);
_sceneMode = 1948;
- setAction(&_sequenceManager1, this, _sceneMode, &_gunpowder, &_actor2, &_actor1, NULL);
+ setAction(&_sequenceManager1, this, _sceneMode, &_gunpowder, &_alcoholLamp, &_coveringIce, NULL);
R2_GLOBALS._player.setAction(&_sequenceManager2, NULL, 1941, &R2_GLOBALS._player, NULL);
return;
case 1944:
@@ -13505,12 +13384,13 @@ void Scene1945::signal() {
setAction(&_sequenceManager1, this, _sceneMode, &R2_GLOBALS._player, &_gunpowder, NULL);
return;
}
+ _sceneMode = 0;
break;
case 1947:
if (_nextSceneMode1 == 1943) {
_sceneMode = _nextSceneMode1;
_nextSceneMode1 = 1948;
- setAction(&_sequenceManager1, this, _sceneMode, &R2_GLOBALS._player, &_actor2, NULL);
+ setAction(&_sequenceManager1, this, _sceneMode, &R2_GLOBALS._player, &_alcoholLamp, NULL);
} else {
_sceneMode = 1941;
setAction(&_sequenceManager1, this, _sceneMode, &R2_GLOBALS._player, NULL);
@@ -13529,7 +13409,7 @@ void Scene1945::signal() {
if (_nextSceneMode2 == 1943) {
_nextSceneMode1 = _nextSceneMode2;
_nextSceneMode2 = 0;
- setAction(&_sequenceManager1, this, _sceneMode, &R2_GLOBALS._player, &_actor2, NULL);
+ setAction(&_sequenceManager1, this, _sceneMode, &R2_GLOBALS._player, &_alcoholLamp, NULL);
} else {
_nextSceneMode1 = 0;
setAction(&_sequenceManager1, this, _sceneMode, &R2_GLOBALS._player, NULL);
@@ -13549,14 +13429,12 @@ void Scene1945::signal() {
*--------------------------------------------------------------------------*/
Scene1950::KeypadWindow::KeypadWindow() {
- _field20 = 0;
_buttonIndex = 0;
}
void Scene1950::KeypadWindow::synchronize(Serializer &s) {
SceneArea::synchronize(s);
- s.syncAsByte(_field20);
s.syncAsSint16LE(_buttonIndex);
}
@@ -13589,7 +13467,7 @@ void Scene1950::KeypadWindow::KeypadButton::init(int indx) {
}
void Scene1950::KeypadWindow::KeypadButton::process(Event &event) {
- if ((event.eventType == EVENT_BUTTON_DOWN) && (R2_GLOBALS._events.getCursor() == CURSOR_USE)
+ if ((event.eventType == EVENT_BUTTON_DOWN) && (R2_GLOBALS._events.getCursor() == CURSOR_USE)
&& (_bounds.contains(event.mousePos)) && !_pressed) {
R2_GLOBALS._sound2.play(227);
if (!_toggled) {
@@ -13643,24 +13521,24 @@ void Scene1950::KeypadWindow::remove() {
}
}
-void Scene1950::KeypadWindow::proc12(int visage, int stripFrameNum, int frameNum, int posX, int posY) {
+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::proc12(visage, stripFrameNum, frameNum, posX, posY);
+ ModalWindow::setup2(visage, stripFrameNum, frameNum, posX, posY);
_object1.fixPriority(248);
scene->_eastExit._enabled = false;
- proc13(1950, 27, 28, 27);
+ setup3(1950, 27, 28, 27);
for (_buttonIndex = 0; _buttonIndex < 16; _buttonIndex++)
_buttons[_buttonIndex].init(_buttonIndex);
}
-void Scene1950::KeypadWindow::proc13(int resNum, int lookLineNum, int talkLineNum, int useLineNum) {
+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);
}
@@ -13726,11 +13604,10 @@ bool Scene1950::Gem::startAction(CursorType action, Event &event) {
/*--------------------------------------------------------------------------*/
Scene1950::Vampire::Vampire() {
- _fieldA8 = 0;
- _fieldAA = 0;
+ _deadPosition = Common::Point(0, 0);
+ _deltaX = 0;
+ _deltaY = 0;
_vampireMode = 0;
- _fieldAE = 0;
- _fieldAF = 0;
}
void Scene1950::Vampire::synchronize(Serializer &s) {
@@ -13738,11 +13615,9 @@ void Scene1950::Vampire::synchronize(Serializer &s) {
s.syncAsSint16LE(_deadPosition.x);
s.syncAsSint16LE(_deadPosition.y);
- s.syncAsSint16LE(_fieldA8);
- s.syncAsSint16LE(_fieldAA);
+ s.syncAsSint16LE(_deltaX);
+ s.syncAsSint16LE(_deltaY);
s.syncAsSint16LE(_vampireMode);
- s.syncAsByte(_fieldAE);
- s.syncAsByte(_fieldAF);
}
void Scene1950::Vampire::signal() {
@@ -13758,7 +13633,7 @@ void Scene1950::Vampire::signal() {
setStrip(1);
NpcMover *mover = new NpcMover();
- addMover(mover, &scene->_field418, scene);
+ addMover(mover, &scene->_vampireDestPos, scene);
}
break;
case 20: {
@@ -13793,7 +13668,7 @@ void Scene1950::Vampire::signal() {
R2_GLOBALS._player.enableControl();
}
break;
- case 21:
+ case 21: {
// Fatal shot
R2_GLOBALS._player.setVisage(22);
if (R2_GLOBALS._flubMazeEntryDirection == 3)
@@ -13817,23 +13692,24 @@ void Scene1950::Vampire::signal() {
R2_GLOBALS._vampireData[scene->_vampireIndex - 1]._isAlive = false;
R2_GLOBALS._vampireData[scene->_vampireIndex - 1]._shotsRequired--;
R2_GLOBALS._vampireData[scene->_vampireIndex - 1]._position = _position;
- _fieldA8 = (_position.x - R2_GLOBALS._player._position.x) / 2;
- _fieldAA = (_position.y - R2_GLOBALS._player._position.y) / 2;
+ _deltaX = (_position.x - R2_GLOBALS._player._position.x) / 2;
+ _deltaY = (_position.y - R2_GLOBALS._player._position.y) / 2;
- _fieldAE = 0;
- for (_fieldAF = 0; _fieldAF < 18; ++_fieldAF)
- if (!R2_GLOBALS._vampireData[_fieldAF]._isAlive)
- ++_fieldAE;
+ byte vampireCount = 0;
+ for (byte i = 0; i < 18; ++i) {
+ if (!R2_GLOBALS._vampireData[i]._isAlive)
+ ++vampireCount;
+ }
- if (_fieldAE == 18) {
+ if (vampireCount == 18) {
R2_GLOBALS.setFlag(36);
_vampireMode = 23;
- Common::Point pt(R2_GLOBALS._player._position.x + _fieldA8, R2_GLOBALS._player._position.y + _fieldAA);
+ 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 (_fieldAE == 1) {
+ } else if (vampireCount == 1) {
_vampireMode = 22;
- Common::Point pt(R2_GLOBALS._player._position.x + _fieldA8, R2_GLOBALS._player._position.y + _fieldAA);
+ 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 {
@@ -13845,14 +13721,15 @@ void Scene1950::Vampire::signal() {
else
scene->_westExit._enabled = true;
- scene->_field416 = 0;
+ scene->_vampireActive = false;
+ }
break;
case 22:
- SceneItem::display(1950, 18, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ 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, -999);
+ 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;
@@ -13864,7 +13741,7 @@ void Scene1950::Vampire::signal() {
bool Scene1950::Vampire::startAction(CursorType action, Event &event) {
Scene1950 *scene = (Scene1950 *)R2_GLOBALS._sceneManager._scene;
- if (!R2_GLOBALS._vampireData[scene->_vampireIndex - 1]._isAlive ||
+ if (!R2_GLOBALS._vampireData[scene->_vampireIndex - 1]._isAlive ||
(action != R2_PHOTON_STUNNER))
return SceneActor::startAction(action, event);
@@ -13909,7 +13786,7 @@ void Scene1950::UpExit::changeScene() {
R2_GLOBALS._flubMazeEntryDirection = 2;
scene->_sceneMode = 12;
- if (scene->_field412 == 0) {
+ if (!scene->_upExitStyle) {
if (R2_GLOBALS.getFlag(36))
scene->setAction(&scene->_sequenceManager, scene, 1953, &R2_GLOBALS._player, NULL);
else
@@ -13930,7 +13807,7 @@ void Scene1950::EastExit::changeScene() {
R2_GLOBALS._flubMazeEntryDirection = 3;
scene->_sceneMode = 13;
- if (scene->_field416 != 0)
+ if (scene->_vampireActive)
R2_GLOBALS._player.animate(ANIM_MODE_9);
Common::Point pt(340, 160);
@@ -13981,16 +13858,16 @@ void Scene1950::WestExit::changeScene() {
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, -999);
+ 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, -999);
+ 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->_field416 != 0)
+ if (scene->_vampireActive)
R2_GLOBALS._player.animate(ANIM_MODE_9);
scene->_sceneMode = 16;
@@ -14020,7 +13897,7 @@ void Scene1950::DoorExit::changeScene() {
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, -999);
+ 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);
@@ -14033,21 +13910,21 @@ void Scene1950::DoorExit::changeScene() {
/*--------------------------------------------------------------------------*/
Scene1950::Scene1950() {
- _field412 = 0;
- _field414 = 0;
- _field416 = 0;
- _field418 = Common::Point(0, 0);
+ _upExitStyle = false;
+ _removeFlag = false;
+ _vampireActive = false;
+ _vampireDestPos = Common::Point(0, 0);
_vampireIndex = 0;
}
void Scene1950::synchronize(Serializer &s) {
SceneExt::synchronize(s);
- s.syncAsSint16LE(_field412);
- s.syncAsSint16LE(_field414);
- s.syncAsSint16LE(_field416);
- s.syncAsSint16LE(_field418.x);
- s.syncAsSint16LE(_field418.y);
+ s.syncAsSint16LE(_upExitStyle);
+ s.syncAsSint16LE(_removeFlag);
+ s.syncAsSint16LE(_vampireActive);
+ s.syncAsSint16LE(_vampireDestPos.x);
+ s.syncAsSint16LE(_vampireDestPos.y);
s.syncAsSint16LE(_vampireIndex);
}
@@ -14076,7 +13953,7 @@ void Scene1950::initArea() {
_westExit._moving = false;
_shaftExit._moving = false;
_doorExit._moving = false;
- _field412 = 0;
+ _upExitStyle = false;
switch (R2_GLOBALS._flubMazeArea - 1) {
case 0:
@@ -14303,7 +14180,7 @@ void Scene1950::initArea() {
// No break on purpose
case 67:
loadScene(1985);
- _field412 = 1;
+ _upExitStyle = true;
break;
default:
break;
@@ -14750,7 +14627,7 @@ void Scene1950::enterArea() {
_door.remove();
_scrolls.remove();
- _field416 = 0;
+ _vampireActive = false;
_vampireIndex = 0;
// Certain areas have a vampire in them
@@ -14759,7 +14636,7 @@ void Scene1950::enterArea() {
_vampireIndex = 1;
break;
case 13:
- _vampireIndex = 2;
+ _vampireIndex = 2;
break;
case 16:
_vampireIndex = 3;
@@ -14818,7 +14695,7 @@ void Scene1950::enterArea() {
_vampire._numFrames = 6;
_vampire._moveRate = 6;
_vampire._moveDiff = Common::Point(3, 2);
- _vampire._effect = 1;
+ _vampire._effect = EFFECT_SHADED;
if (!R2_GLOBALS._vampireData[_vampireIndex - 1]._isAlive) {
// Show vampire ashes
@@ -14836,7 +14713,7 @@ void Scene1950::enterArea() {
_vampire.setPosition(Common::Point(160, 130));
_vampire.animate(ANIM_MODE_2, NULL);
_vampire.setDetails(1950, 12, -1, 14, 2, (SceneItem *) NULL);
- _field416 = 1;
+ _vampireActive = true;
}
}
if ((R2_GLOBALS._flubMazeArea == 1) && (R2_INVENTORY.getObjectScene(R2_SCRITH_KEY) != 0)) {
@@ -14866,13 +14743,13 @@ void Scene1950::enterArea() {
_cube.setPosition(Common::Point(193, 158));
_cube.setDetails(1950, 3, 4, 5, 2, (SceneItem *) NULL);
- _actor7.postInit();
- _actor7.setVisage(1970);
- _actor7.setStrip(3);
- _actor7.animate(ANIM_MODE_2, NULL);
- _actor7._numFrames = 6;
- _actor7.setPosition(Common::Point(194, 158));
- _actor7.fixPriority(159);
+ _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);
@@ -14912,27 +14789,29 @@ void Scene1950::enterArea() {
else
_scrolls.setFrame(1);
- _field414 = 1;
- } else if (_field414 != 0) {
+ _removeFlag = true;
+ } else if (_removeFlag) {
_cube.remove();
_containmentField.remove();
_gem.remove();
- _actor7.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) {
- R2_GLOBALS._v56AAB = 0;
+ 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 {
+ else
setAction(&_sequenceManager, this, 1950, &R2_GLOBALS._player, NULL);
- }
+
break;
case 1: {
_sceneMode = R2_GLOBALS._flubMazeEntryDirection;
@@ -14951,7 +14830,7 @@ void Scene1950::enterArea() {
break;
case 3:
// Entering from the left
- if (_field416 == 0) {
+ if (!_vampireActive) {
_sceneMode = R2_GLOBALS._flubMazeEntryDirection;
R2_GLOBALS._player.setPosition(Common::Point(-20, 160));
Common::Point pt(30, 160);
@@ -14960,14 +14839,13 @@ void Scene1950::enterArea() {
} else {
_sceneMode = 18;
_eastExit._enabled = false;
- _field418 = Common::Point(60, 152);
- R2_GLOBALS._v56AAB = 0;
+ _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, &_field418, this);
+ _vampire.addMover(mover, &_vampireDestPos, this);
R2_GLOBALS._player.setPosition(Common::Point(-20, 160));
Common::Point pt2(30, 160);
@@ -14977,7 +14855,7 @@ void Scene1950::enterArea() {
break;
case 4:
_sceneMode = R2_GLOBALS._flubMazeEntryDirection;
- if (_field412 == 0) {
+ if (!_upExitStyle) {
if (R2_GLOBALS.getFlag(36))
setAction(&_sequenceManager, this, 1955, &R2_GLOBALS._player, NULL);
else
@@ -14999,7 +14877,7 @@ void Scene1950::enterArea() {
break;
case 6:
// Entering from the right
- if (_field416 == 0) {
+ if (!_vampireActive) {
_sceneMode = R2_GLOBALS._flubMazeEntryDirection;
if (R2_GLOBALS._flubMazeArea == 1) {
setAction(&_sequenceManager, this, 1961, &R2_GLOBALS._player, NULL);
@@ -15012,15 +14890,14 @@ void Scene1950::enterArea() {
} else {
_sceneMode = 17;
_westExit._enabled = false;
- _field418 = Common::Point(259, 152);
+ _vampireDestPos = Common::Point(259, 152);
- R2_GLOBALS._v56AAB = 0;
R2_GLOBALS._player.enableControl(CURSOR_USE);
R2_GLOBALS._player._canWalk = false;
_vampire.setStrip(1);
NpcMover *mover = new NpcMover();
- _vampire.addMover(mover, &_field418, this);
+ _vampire.addMover(mover, &_vampireDestPos, this);
R2_GLOBALS._player.setPosition(Common::Point(340, 160));
Common::Point pt2(289, 160);
@@ -15115,9 +14992,9 @@ void Scene1950::doButtonPress(int indx) {
}
void Scene1950::postInit(SceneObjectList *OwnerList) {
- _field412 = 0;
- _field414 = 0;
- _field416 = 0;
+ _upExitStyle = false;
+ _removeFlag = false;
+ _vampireActive = false;
_vampireIndex = 0;
if (R2_GLOBALS._sceneManager._previousScene == 300)
R2_GLOBALS._flubMazeArea = 103;
@@ -15183,7 +15060,7 @@ void Scene1950::signal() {
enterArea();
break;
case 1975:
- SceneItem::display(1950, 21, SET_WIDTH, 280, SET_X, 160, SET_POS_MODE, 1,
+ 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:
@@ -15214,11 +15091,11 @@ void Scene1950::signal() {
case 17: {
_sceneMode = 13;
R2_GLOBALS._flubMazeEntryDirection = 3;
- _field416 = 0;
+ _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, NULL);
+ R2_GLOBALS._player.animate(ANIM_MODE_9);
Common::Point pt(340, 160);
NpcMover *mover = new NpcMover();
R2_GLOBALS._player.addMover(mover, &pt, this);
@@ -15230,11 +15107,11 @@ void Scene1950::signal() {
case 18: {
_sceneMode = 16;
R2_GLOBALS._flubMazeEntryDirection = 6;
- _field416 = 0;
+ _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, NULL);
+ R2_GLOBALS._player.animate(ANIM_MODE_9);
Common::Point pt(-20, 160);
NpcMover *mover = new NpcMover();
R2_GLOBALS._player.addMover(mover, &pt, this);
@@ -15254,14 +15131,12 @@ void Scene1950::signal() {
R2_GLOBALS._sceneManager.changeScene(1945);
break;
case 1958:
- SceneItem::display(1950, 24, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
- R2_GLOBALS._v56AAB = 0;
+ 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._v56AAB = 0;
R2_GLOBALS._player.enableControl(CURSOR_WALK);
_doorExit._enabled = true;
break;
@@ -15269,14 +15144,14 @@ void Scene1950::signal() {
// No break on purpose
case 1963:
R2_GLOBALS._player.enableControl();
- _KeypadWindow.proc12(1971, 1, 1, 160, 135);
+ _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, -999);
- }
+ 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:
@@ -15300,7 +15175,8 @@ void Scene1950::signal() {
R2_GLOBALS._player.setVisage(22);
R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
- Common::Point pt(218, 165);
+ // 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);
}
@@ -15316,7 +15192,6 @@ void Scene1950::signal() {
R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
break;
default:
- R2_GLOBALS._v56AAB = 0;
R2_GLOBALS._player.enableControl(CURSOR_WALK);
break;
}
diff --git a/engines/tsage/ringworld2/ringworld2_scenes1.h b/engines/tsage/ringworld2/ringworld2_scenes1.h
index 824df607b3..c809353051 100644
--- a/engines/tsage/ringworld2/ringworld2_scenes1.h
+++ b/engines/tsage/ringworld2/ringworld2_scenes1.h
@@ -94,15 +94,15 @@ public:
SpeakerQuinn1100 _quinnSpeaker;
SpeakerChief1100 _chiefSpeaker;
ScenePalette _palette1;
- NamedHotspot _item1;
- NamedHotspot _item2;
- NamedHotspot _item3;
- NamedHotspot _item4;
- NamedHotspot _item5;
- NamedHotspot _item6;
- NamedHotspot _item7;
- SceneActor _actor1;
- SceneActor _actor2;
+ NamedHotspot _background;
+ NamedHotspot _sky;
+ NamedHotspot _fuana1;
+ NamedHotspot _fauna2;
+ NamedHotspot _bouldersBlockingCave;
+ NamedHotspot _boulders;
+ NamedHotspot _trail;
+ SceneActor _ship;
+ SceneActor _cloud;
SceneActor _shipFormation;
SceneActor _shipFormationShadow;
SceneActor _shotImpact1;
@@ -111,13 +111,13 @@ public:
SceneActor _shotImpact4;
SceneActor _shotImpact5;
SceneActor _laserShot;
- SceneActor _animation;
+ SceneActor _animation; // Used for cliff collapse and ship theft
SceneActor _leftImpacts;
SceneActor _runningGuy1;
SceneActor _runningGuy2;
SceneActor _runningGuy3;
BackgroundSceneObject _rightLandslide;
- BackgroundSceneObject _object2;
+ BackgroundSceneObject _purplePlant;
Seeker _seeker;
Trooper _trooper;
Chief _chief;
@@ -183,38 +183,52 @@ public:
};
class Scene1337 : public SceneExt {
- class unkObj1337sub1: public SceneHotspot {
+ class OptionsDialog: public GfxDialog {
+ private:
+ GfxButton _autoplay;
+ GfxButton _restartGame;
+ GfxButton _quitGame;
+ GfxButton _continueGame;
+
+ OptionsDialog();
+ virtual ~OptionsDialog() {}
+ virtual GfxButton *execute(GfxButton *defaultButton);
+ public:
+ static void show();
+ };
+
+ class Card: public SceneHotspot {
public:
- SceneObject _object1;
+ SceneObject _card;
- int _field34;
- Common::Point _field36;
+ int _cardId;
+ Common::Point _stationPos;
- unkObj1337sub1();
+ Card();
void synchronize(Serializer &s);
+ bool isIn(Common::Point pt);
};
- class unkObj1337_1: public SceneHotspot {
+ class GameBoardSide: public SceneHotspot {
public:
- unkObj1337sub1 _arr1[4];
- unkObj1337sub1 _arr2[8];
- unkObj1337sub1 _arr3[1];
- unkObj1337sub1 _arr4[1];
+ Card _handCard[4];
+ Card _outpostStation[8];
+ Card _delayCard;
+ Card _emptyStationPos;
- Common::Point _fieldB94;
- Common::Point _fieldB98;
- Common::Point _fieldB9C;
- Common::Point _fieldBA0;
- int _fieldBA4;
+ Common::Point _card1Pos;
+ Common::Point _card2Pos;
+ Common::Point _card3Pos;
+ Common::Point _card4Pos;
+ int _frameNum;
- unkObj1337_1();
+ GameBoardSide();
void synchronize(Serializer &s);
};
class Action1337: public Action {
public:
- void subD18B5(int resNum, int stripNum, int frameNum);
- void skipFrames(int32 skipCount);
+ void waitFrames(int32 frameCount);
};
class Action1: public Action1337 {
@@ -270,16 +284,6 @@ class Scene1337 : public SceneExt {
void signal();
};
public:
- typedef void (Scene1337::*FunctionPtrType)();
- FunctionPtrType _unkFctPtr412;
-
- ASound _aSound1;
- ASound _aSound2;
- BackgroundSceneObject _background1;
- bool _autoplay;
- unkObj1337_1 _arrunkObj1337[4];
- SceneItem _item1;
- SceneObject _object1;
Action1 _action1;
Action2 _action2;
Action3 _action3;
@@ -293,90 +297,101 @@ public:
Action11 _action11;
Action12 _action12;
Action13 _action13;
- unkObj1337sub1 _item2;
- unkObj1337sub1 _item3;
- unkObj1337sub1 _item4;
- BackgroundSceneObject _background2;
- int _field3E24;
- int _field3E26;
- int _field3E28[100];
- unkObj1337sub1 *_field3EF0;
- unkObj1337sub1 *_field3EF4;
- unkObj1337sub1 *_field3EF8;
- unkObj1337sub1 _item5;
- unkObj1337sub1 _item6;
- unkObj1337sub1 _item7;
- unkObj1337sub1 _item8;
- int _field423C;
- int _field423E;
- int _field4240;
- int _field4242;
- int _field4244;
- int _field4246;
- int _field4248;
- int _field424A;
- int _field424C;
- int _field424E;
-
- SceneObject _arrObject1[8];
- SceneObject _arrObject2[8];
+
+ typedef void (Scene1337::*FunctionPtrType)();
+ FunctionPtrType _delayedFunction;
+
+ bool _autoplay;
+ bool _shuffleEndedFl;
+ bool _showPlayerTurn;
+ bool _displayHelpFl;
+ bool _instructionsDisplayedFl;
+
+ // Discarded cards are put in the available cards pile, with an higher index so there no conflict
+ int _currentDiscardIndex;
+ int _availableCardsPile[100];
+ int _cardsAvailableNumb;
+ int _currentPlayerNumb;
+ int _actionIdx1;
+ int _actionIdx2;
+ int _winnerId;
+ int _instructionsWaitCount;
+ int _cursorCurRes;
+ int _cursorCurStrip;
+ int _cursorCurFrame;
+
+ ASound _aSound1;
+ ASound _aSound2;
+ GameBoardSide _gameBoardSide[4];
+ SceneActor _helpIcon;
+ SceneActor _stockPile;
+ SceneItem _actionItem;
+ SceneObject _currentPlayerArrow;
+
+ Card *_actionCard1;
+ Card *_actionCard2;
+ Card *_actionCard3;
+ Card _animatedCard;
+ Card _shuffleAnimation;
+ Card _discardedPlatformCard;
+ Card _selectedCard;
+ Card _discardPile;
+ Card _stockCard;
+
+ SceneObject _upperDisplayCard[8];
+ SceneObject _lowerDisplayCard[8];
Scene1337();
virtual void synchronize(Serializer &s);
- void actionDisplay(int resNum, int lineNum, int x, int y, int arg5, int width, int textMode, int fontNum, int colFG, int colBGExt, int colFGExt);
- void setAnimationInfo(unkObj1337sub1 *subObj);
- void subC20E5();
- void subC20F9();
- void subC2586();
- bool subC264B(int arg1);
- bool subC2687(int arg1);
- int subC26CB(int arg1, int arg2);
- int subC2719(int arg1);
- int subC274D(int arg1);
- int subC2781(int arg1);
- int subC27B5(int arg1);
- int subC27F9(int arg1);
- void subC2835(int arg1);
- bool subC2BF8(unkObj1337sub1 *subObj1, Common::Point pt);
- void subC2C2F();
- void subC318B(int arg1, unkObj1337sub1 *subObj2, int arg3);
- int subC3257(int arg1);
- bool subC32B1(int arg1, int arg2);
- int subC331B(int arg1);
- bool subC3386(int arg1, int arg2);
- void subC33C0(unkObj1337sub1 *subObj1, unkObj1337sub1 *subObj2);
- void subC3456(unkObj1337sub1 *subObj1, unkObj1337sub1 *subObj2);
- void subC340B(unkObj1337sub1 *subObj1, unkObj1337sub1 *subObj2);
- void subC34A1(unkObj1337sub1 *subObj1, unkObj1337sub1 *subObj2);
- unkObj1337sub1 *subC34EC(int arg1);
- void subC358E(unkObj1337sub1 *subObj1, int arg2);
- int subC3E92(int arg1);
- void subC4A39(unkObj1337sub1 *subObj);
+ void actionDisplay(int resNum, int lineNum, int x, int y, int keepOnScreen, int width, int textMode, int fontNum, int colFG, int colBGExt, int colFGExt);
+ void setAnimationInfo(Card *card);
+ void handleNextTurn();
+ void handlePlayerTurn();
+ bool isStationCard(int cardId);
+ bool isStopConstructionCard(int cardId);
+ int getStationId(int playerId, int handCardId);
+ int findPlatformCardInHand(int playerId);
+ int findCard13InHand(int playerId);
+ int checkThieftCard(int playerId);
+ int isDelayCard(int cardId);
+ int getStationCardId(int cardId);
+ void handlePlayer01Discard(int playerId);
+ void playThieftCard(int playerId, Card *card, int victimId);
+ int getPreventionCardId(int cardId);
+ bool isAttackPossible(int victimId, int cardId);
+ int getPlayerWithOutpost(int playerId);
+ bool checkAntiDelayCard(int delayCardId, int cardId);
+ void playStationCard(Card *station, Card *platform);
+ void playDelayCard(Card *card, Card *dest);
+ void playPlatformCard(Card *card, Card *dest);
+ void playAntiDelayCard(Card *card, Card *dest);
+ Card *getStationCard(int arg1);
+ void playCounterTrickCard(Card *card, int playerId);
+ int getFreeHandCard(int playerId);
+ void discardCard(Card *card);
void subC4CD2();
void subC4CEC();
- void subC51A0(unkObj1337sub1 *subObj1, unkObj1337sub1 *subObj2);
+ void subC51A0(Card *subObj1, Card *subObj2);
void displayDialog(int dialogNumb);
void subPostInit();
- void subCB59B();
+ void displayInstructions();
void suggestInstructions();
void shuffleCards();
- void subCCF26();
- void subCD193();
- void subCDB90(int arg1, Common::Point pt);
- void subCF31D();
- void subCF979();
- void subD026D();
- void subD0281();
- void subD02CA();
- void subD183F(int arg1, int arg2);
- void subD18B5(int resNum, int rlbNum, int arg3);
- int subD18F5();
- int subD1917();
- int subD1940(bool flag);
- void subD195F(int arg1, int arg2);
+ void dealCards();
+ void showOptionsDialog();
+ void handleClick(int arg1, Common::Point pt);
+ void handlePlayer0();
+ void handlePlayer1();
+ void handlePlayer2();
+ void handlePlayer3();
+ void handleAutoplayPlayer2();
+ void updateCursorId(int arg1, bool arg2);
+ void setCursorData(int resNum, int rlbNum, int frameNum);
+ void subD18F5();
+ void subD1917();
+ void subD1940(bool flag);
void subD1975(int arg1, int arg2);
- void subD1A48(int arg1);
virtual void postInit(SceneObjectList *OwnerList = NULL);
virtual void remove();
@@ -386,10 +401,10 @@ public:
class Scene1500 : public SceneExt {
public:
- SceneActor _actor1;
- SceneActor _actor2;
- SceneActor _actor3;
- SceneActor _actor4;
+ SceneActor _starship;
+ SceneActor _starshipShadow;
+ SceneActor _smallShip;
+ SceneActor _smallShipShadow;
SequenceManager _sequenceManager;
virtual void postInit(SceneObjectList *OwnerList = NULL);
@@ -410,9 +425,9 @@ class Scene1530 : public SceneExt {
public:
SpeakerQuinn _quinnSpeaker;
SpeakerSeeker _seekerSpeaker;
- SceneActor _actor1;
- SceneActor _actor2;
- SceneActor _actor3;
+ SceneActor _seeker;
+ SceneActor _leftReactor;
+ SceneActor _rightReactor;
SequenceManager _sequenceManager;
@@ -422,14 +437,13 @@ public:
};
class Scene1550 : public SceneExt {
- class SceneActor1550 : public SceneActor {
+ class Wall : public SceneActor {
public:
- void subA4D14(int frameNumber, int strip);
+ void setupWall(int frameNumber, int strip);
};
class Junk : public SceneActor {
public:
- int _fieldA4;
int _junkNumber;
Junk();
@@ -449,27 +463,24 @@ class Scene1550 : public SceneExt {
void setupShipComponent(int componentId);
};
- class UnkObj15503 : public SceneActor {
- public:
- int _fieldA4;
-
- UnkObj15503();
- void synchronize(Serializer &s);
+ class DishControlsWindow : public ModalWindow {
+ class DishControl : public SceneActor {
+ public:
+ int _controlId;
- virtual bool startAction(CursorType action, Event &event);
- };
+ DishControl();
+ void synchronize(Serializer &s);
- class UnkArea1550 : public SceneArea {
+ virtual bool startAction(CursorType action, Event &event);
+ };
public:
byte _field20;
SceneActor _areaActor;
- UnkObj15503 _unkObj155031;
- UnkObj15503 _unkObj155032;
+ DishControl _button;
+ DishControl _lever;
virtual void remove();
- virtual void process(Event &event);
- virtual void proc12(int visage, int stripFrameNum, int frameNum, int posX, int posY);
- virtual void proc13(int resNum, int lookLineNum, int talkLineNum, int useLineNum);
+ virtual void setup2(int visage, int stripFrameNum, int frameNum, int posX, int posY);
};
class WorkingShip : public NamedHotspot {
@@ -477,11 +488,6 @@ class Scene1550 : public SceneExt {
virtual bool startAction(CursorType action, Event &event);
};
- class Hotspot3 : public NamedHotspot {
- public:
- virtual bool startAction(CursorType action, Event &event);
- };
-
class Wreckage : public SceneActor {
public:
virtual bool startAction(CursorType action, Event &event);
@@ -492,77 +498,71 @@ class Scene1550 : public SceneExt {
virtual bool startAction(CursorType action, Event &event);
};
- class Actor8 : public SceneActor {
+ class AirBag : public SceneActor {
public:
virtual bool startAction(CursorType action, Event &event);
};
- class Actor9 : public SceneActor {
+ class Joystick : public SceneActor {
public:
virtual bool startAction(CursorType action, Event &event);
};
- class Actor10 : public SceneActor {
+ class Gyroscope : public SceneActor {
public:
virtual bool startAction(CursorType action, Event &event);
};
- class Actor11 : public SceneActor {
+ class DiagnosticsDisplay : public SceneActor {
public:
virtual bool startAction(CursorType action, Event &event);
};
- class Actor12 : public SceneActor {
+ class DishTower : public SceneActor {
public:
virtual bool startAction(CursorType action, Event &event);
};
- class Actor13 : public SceneActor {
+ class Dish : public SceneActor {
public:
virtual bool startAction(CursorType action, Event &event);
};
- class Wall : public SceneActor1550 {
- // Nothing specific found in the original
- // TODO: check if it's an useless class
- };
-
public:
SpeakerQuinn _quinnSpeaker;
SpeakerSeeker _seekerSpeaker;
- WorkingShip _shipHull;
- WorkingShip _item2;
- Hotspot3 _item3;
- SceneActor _landingStrut;
- SceneActor _actor2;
- SceneActor _actor3;
- SceneActor _actor4;
- SceneActor _actor5;
+ WorkingShip _intactHull1, _intactHull2;
+ SceneHotspot _background;
+ SceneActor _wreckage2; // also used for Lance of Truth landing strut
+ SceneActor _wreckage3;
+ SceneActor _wreckage4;
+ SceneActor _walkway;
+ SceneActor _dishTowerShadow;
Wreckage _wreckage;
Companion _companion;
- Actor8 _actor8;
- Actor9 _actor9;
- Actor10 _actor10;
- Actor11 _actor11;
- Actor12 _actor12;
- Actor13 _actor13;
+ AirBag _airbag;
+ Joystick _joystick;
+ Gyroscope _gyroscope;
+ DiagnosticsDisplay _diagnosticsDisplay;
+ DishTower _dishTower;
+ Dish _dish;
Junk _junk[8];
- Wall _actor14;
+ Wall _wallCorner1;
Wall _northWall; // Is also reused for landing strip
- Wall _actor16;
+ Wall _wallCorner2;
Wall _westWall; // Is also reused for left hand space
Wall _eastWall;
Wall _southWall;
ShipComponent _shipComponents[8];
- UnkArea1550 _unkArea1;
+ DishControlsWindow _dishControlsWindow;
SequenceManager _sequenceManager1;
SequenceManager _sequenceManager2;
- int _field412;
- byte _field414;
- int _field415;
- int _field417;
- int _field419;
+ bool _dontExit;
+ int _wallType;
+ int _dishMode;
+ int _sceneResourceId;
+ int _walkRegionsId;
Scene1550();
void synchronize(Serializer &s);
@@ -576,14 +576,14 @@ public:
};
class Scene1575 : public SceneExt {
- class Hotspot1 : public NamedHotspot {
+ class Button : public NamedHotspot {
public:
- int _field34;
- int _field36;
+ int _buttonId;
+ bool _pressed;
- Hotspot1();
+ Button();
void synchronize(Serializer &s);
- void subA910D(int indx);
+ void initButton(int buttonId);
virtual void process(Event &event);
virtual bool startAction(CursorType action, Event &event);
@@ -594,12 +594,12 @@ public:
int _field416;
int _field418;
int _field41A;
- Hotspot1 _item1;
- Hotspot1 _item2;
- Hotspot1 _item3;
- Hotspot1 _item4;
- Hotspot1 _item5;
- Hotspot1 _item6;
+ Button _button1;
+ Button _button2;
+ Button _button3;
+ Button _button4;
+ Button _button5;
+ Button _button6;
SceneActor _actor1;
SceneActor _actor2;
SceneActor _actor3;
@@ -629,54 +629,53 @@ public:
};
class Scene1580 : public SceneExt {
- class Hotspot1 : public NamedHotspot {
+ class JoystickPlug : public NamedHotspot {
public:
virtual bool startAction(CursorType action, Event &event);
};
- class Hotspot2 : public NamedHotspot {
+ class ScreenSlot : public NamedHotspot {
public:
virtual bool startAction(CursorType action, Event &event);
};
- class Actor2 : public SceneActor {
+ class Joystick : public SceneActor {
public:
virtual bool startAction(CursorType action, Event &event);
};
- class Actor3 : public SceneActor {
+ class Screen : public SceneActor {
public:
virtual bool startAction(CursorType action, Event &event);
};
- class Actor4 : public SceneActor {
+ class StorageCompartment : public SceneActor {
public:
virtual bool startAction(CursorType action, Event &event);
};
- class Actor5 : public SceneActor {
+ class HatchButton : public SceneActor {
public:
virtual bool startAction(CursorType action, Event &event);
};
- class Actor6 : public SceneActor {
+ class ThrusterValve : public SceneActor {
public:
virtual bool startAction(CursorType action, Event &event);
};
- class Actor7 : public SceneActor {
+ class Ignitor : public SceneActor {
public:
virtual bool startAction(CursorType action, Event &event);
};
public:
- int _field412;
SpeakerQuinn _quinnSpeaker;
SpeakerSeeker _seekerSpeaker;
- Hotspot1 _item1;
- Hotspot2 _item2;
- NamedHotspot _item3;
- SceneActor _actor1;
+ JoystickPlug _joystickPlug;
+ ScreenSlot _screenSlot;
+ NamedHotspot _background;
+ SceneActor _screenDisplay;
SceneActor _arrActor[8];
- Actor2 _actor2;
- Actor3 _actor3;
- Actor4 _actor4;
- Actor5 _actor5;
- Actor6 _actor6;
- Actor7 _actor7;
+ Joystick _joystick;
+ Screen _screen;
+ StorageCompartment _storageCompartment;
+ HatchButton _hatchButton;
+ ThrusterValve _thrusterValve;
+ Ignitor _ignitor;
SequenceManager _sequenceManager;
Scene1580();
@@ -692,17 +691,16 @@ class Scene1625 : public SceneExt {
virtual bool startAction(CursorType action, Event &event);
};
public:
- int _field412;
SpeakerMiranda1625 _mirandaSpeaker;
SpeakerTeal1625 _tealSpeaker;
SpeakerSoldier1625 _soldierSpeaker;
- NamedHotspot _item1;
- SceneActor _actor1;
+ NamedHotspot _background;
+ SceneActor _teal;
SceneActor _tealHead;
- SceneActor _actor3;
+ SceneActor _mirandaMouth;
SceneActor _glass;
- SceneActor _actor5;
- SceneActor _actor6;
+ SceneActor _wristRestraints;
+ SceneActor _tealRightArm;
Wire _wire;
SequenceManager _sequenceManager;
@@ -716,16 +714,11 @@ public:
};
class Scene1700 : public SceneExt {
- class Item2 : public NamedHotspot {
- public:
- virtual bool startAction(CursorType action, Event &event);
- };
-
class RimTransport : public SceneActor {
public:
virtual bool startAction(CursorType action, Event &event);
};
- class Actor12 : public SceneActor {
+ class Companion : public SceneActor {
public:
virtual bool startAction(CursorType action, Event &event);
};
@@ -745,10 +738,10 @@ class Scene1700 : public SceneExt {
public:
SpeakerQuinn _quinnSpeaker;
SpeakerSeeker _seekerSpeaker;
- NamedHotspot _item1;
- Item2 _item2;
- SceneActor _actor1;
- SceneActor _actor2;
+ NamedHotspot _surface;
+ NamedHotspot _background;
+ SceneActor _playerShadow;
+ SceneActor _companionShadow;
SceneActor _slabWest;
SceneActor _slabEast;
SceneActor _slabShadowWest;
@@ -756,16 +749,15 @@ public:
SceneActor _westPlatform;
SceneActor _rimTransportDoor;
SceneActor _ledgeHopper;
- SceneActor _actor10;
+ SceneActor _hatch;
RimTransport _rimTransport;
- Actor12 _actor12;
+ Companion _companion;
NorthExit _northExit;
SouthExit _southExit;
WestExit _westExit;
SequenceManager _sequenceManager;
- int _field77A;
- int _field77C;
+ bool _walkFlag;
Scene1700();
void synchronize(Serializer &s);
@@ -791,7 +783,6 @@ class Scene1750 : public SceneExt {
void setupSlider(int incrAmount, int xp, int ys, int height, int thumbHeight);
void calculateSlider();
- virtual void remove();
virtual void process(Event &event);
virtual bool startAction(CursorType action, Event &event);
};
@@ -808,13 +799,13 @@ class Scene1750 : public SceneExt {
public:
NamedHotspot _background;
- NamedHotspot _redLights;
+ NamedHotspot _redLightsDescr;
NamedHotspot _greenLights;
NamedHotspot _frontView;
NamedHotspot _rearView;
- SceneActor _actor1;
- SceneActor _actor2;
- SceneActor _actor3;
+ SceneActor _scannerIcon;
+ SceneActor _redLights;
+ SceneActor _radarSweep;
SpeedSlider _speedSlider;
Button _forwardButton;
Button _backwardButton;
@@ -823,12 +814,12 @@ public:
PaletteRotation *_rotation;
int _direction;
- int _field413;
+ int _speedCurrent;
int _speed;
- int _field417;
- int _field419;
- int _field41B;
- int _field41D;
+ int _speedDelta;
+ int _rotationSegment;
+ int _rotationSegCurrent;
+ int _newRotation;
Scene1750();
virtual void synchronize(Serializer &s);
@@ -859,7 +850,7 @@ class Scene1800 : public SceneExt {
virtual bool startAction(CursorType action, Event &event);
};
- class Exit1 : public SceneExit {
+ class SouthExit : public SceneExit {
public:
virtual void changeScene();
};
@@ -867,21 +858,21 @@ public:
int _locationMode;
SpeakerQuinn _quinnSpeaker;
SpeakerSeeker _seekerSpeaker;
- NamedHotspot _item1;
- NamedHotspot _item2;
- NamedHotspot _item3;
- NamedHotspot _item4;
+ NamedHotspot _elevator;
+ NamedHotspot _elevatorContents;
+ NamedHotspot _surface;
+ NamedHotspot _secBackground;
Background _background;
- SceneActor _actor1;
+ SceneActor _playerShadow;
SceneActor _companion;
- SceneActor _actor3;
+ SceneActor _companionShadow;
SceneActor _leftStaircase;
SceneActor _rightStaircase;
Lever _lever;
Doors _doors;
PassengerDoor _leftDoor;
PassengerDoor _rightDoor;
- Exit1 _exit1;
+ SouthExit _southExit;
SequenceManager _sequenceManager;
Scene1800();
@@ -902,7 +893,7 @@ class Scene1850 : public SceneExt {
public:
virtual bool startAction(CursorType action, Event &event);
};
- class Actor6 : public SceneActor {
+ class Door : public SceneActor {
public:
virtual bool startAction(CursorType action, Event &event);
};
@@ -912,24 +903,24 @@ class Scene1850 : public SceneExt {
};
public:
- int _field412;
- int _field414;
- int _field416;
- int _field418;
- Common::Point _field41A;
- int _field41E;
+ int _sceneMode;
+ int _shadeCountdown;
+ int _shadeDirection;
+ bool _shadeChanging;
+ Common::Point _playerDest;
+ int _seqNumber;
ScenePalette _palette1;
SpeakerQuinn _quinnSpeaker;
SpeakerSeeker _seekerSpeaker;
NamedHotspot _background;
Button _button;
SceneActor _companion;
- SceneActor _actor2;
- SceneActor _actor3;
- SceneActor _actor4;
+ SceneActor _airbag;
+ SceneActor _screen;
+ SceneActor _helmet;
Robot _robot;
- Actor6 _leftDoor;
- Actor6 _rightDoor;
+ Door _leftDoor;
+ Door _rightDoor;
DisplayScreen _displayScreen;
SequenceManager _sequenceManager1;
SequenceManager _sequenceManager2;
@@ -961,11 +952,10 @@ class Scene1875 : public SceneExt {
public:
SpeakerQuinn _quinnSpeaker;
SpeakerSeeker _seekerSpeaker;
- NamedHotspot _item1;
- NamedHotspot _item2;
- SceneActor _actor1;
- SceneActor _actor2;
- SceneActor _actor3;
+ NamedHotspot _background;
+ NamedHotspot _screen;
+ SceneActor _map;
+ SceneActor _rimPosition;
Button _button1;
Button _button2;
Button _button3;
@@ -996,9 +986,9 @@ public:
SpeakerSeeker1900 _seekerSpeaker;
NamedHotspot _background;
NamedHotspot _elevator;
- SceneActor _actor1;
- BackgroundSceneObject _object1;
- BackgroundSceneObject _object2;
+ SceneActor _companion;
+ BackgroundSceneObject _leftDoorFrame;
+ BackgroundSceneObject _rightDoorFrame;
LiftDoor _leftDoor, _rightDoor;
WestExit _westExit;
EastExit _eastExit;
@@ -1024,30 +1014,30 @@ class Scene1925 : public SceneExt {
public:
virtual void changeScene();
};
- class Exit2 : public SceneExit {
+ class ExitDown : public SceneExit {
public:
virtual void changeScene();
};
- class Exit3 : public SceneExit {
+ class WestExit : public SceneExit {
public:
virtual void changeScene();
};
- class Exit4 : public SceneExit {
+ class EastExit : public SceneExit {
public:
virtual void changeScene();
};
public:
- NamedHotspot _item1;
+ NamedHotspot _background;
Button _button;
Ladder _ladder;
- SceneActor _actor1;
+ SceneActor _door;
ExitUp _exitUp;
- Exit2 _exit2;
- Exit3 _exit3;
- Exit4 _exit4;
+ ExitDown _exitDown;
+ WestExit _westExit;
+ EastExit _eastExit;
SequenceManager _sequenceManager;
- int _field9B8;
+ int _newSceneMode;
int _levelResNum[5];
Scene1925();
@@ -1083,12 +1073,12 @@ class Scene1945 : public SceneExt {
virtual void changeScene();
};
public:
- NamedHotspot _item1;
- NamedHotspot _item2;
+ NamedHotspot _hole;
+ NamedHotspot _ice2;
Ice _ice;
Ladder _ladder;
- SceneActor _actor1;
- SceneActor _actor2;
+ SceneActor _coveringIce;
+ SceneActor _alcoholLamp;
Gunpowder _gunpowder;
ExitUp _exitUp;
CorridorExit _corridorExit;
@@ -1128,14 +1118,13 @@ class Scene1950 : public SceneExt {
SceneActor _areaActor;
KeypadButton _buttons[16];
- byte _field20;
int _buttonIndex;
KeypadWindow();
virtual void synchronize(Serializer &s);
virtual void remove();
- virtual void proc12(int visage, int stripFrameNum, int frameNum, int posX, int posY);
- virtual void proc13(int resNum, int lookLineNum, int talkLineNum, int useLineNum);
+ 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 {
@@ -1152,10 +1141,6 @@ class Scene1950 : public SceneExt {
public:
virtual bool startAction(CursorType action, Event &event);
};
- class Actor4 : public SceneActor {
- public:
- virtual bool startAction(CursorType action, Event &event);
- };
class Gem : public SceneActor {
public:
virtual bool startAction(CursorType action, Event &event);
@@ -1163,11 +1148,9 @@ class Scene1950 : public SceneExt {
class Vampire : public SceneActor {
public:
Common::Point _deadPosition;
- int _fieldA8;
- int _fieldAA;
+ int _deltaX;
+ int _deltaY;
int _vampireMode;
- byte _fieldAE;
- byte _fieldAF;
Vampire();
void synchronize(Serializer &s);
@@ -1223,7 +1206,7 @@ public:
SceneActor _containmentField;
Gem _gem;
SceneActor _cube;
- SceneActor _actor7;
+ SceneActor _pulsingLights;
Vampire _vampire;
KeypadWindow _KeypadWindow;
NorthExit _northExit;
@@ -1236,10 +1219,10 @@ public:
DoorExit _doorExit;
SequenceManager _sequenceManager;
- int _field412;
- int _field414;
- int _field416;
- Common::Point _field418;
+ bool _upExitStyle;
+ bool _removeFlag;
+ bool _vampireActive;
+ Common::Point _vampireDestPos;
int _vampireIndex;
Scene1950();
@@ -1250,6 +1233,7 @@ public:
virtual void signal();
virtual void process(Event &event);
};
+
} // End of namespace Ringworld2
} // End of namespace TsAGE
diff --git a/engines/tsage/ringworld2/ringworld2_scenes2.cpp b/engines/tsage/ringworld2/ringworld2_scenes2.cpp
index a8e534d5cb..f928f3635c 100644
--- a/engines/tsage/ringworld2/ringworld2_scenes2.cpp
+++ b/engines/tsage/ringworld2/ringworld2_scenes2.cpp
@@ -132,25 +132,28 @@ void Scene2000::initPlayer() {
}
for (int i = 0; i < 11; i++) {
if (R2_GLOBALS._spillLocation[R2_GLOBALS._player._characterIndex] == R2_GLOBALS._spillLocation[3 + i])
- _objList1[i].show();
+ _persons[i].show();
}
- if ((R2_GLOBALS._player._characterScene[R2_QUINN] == R2_GLOBALS._player._characterScene[R2_SEEKER]) && (R2_GLOBALS._spillLocation[R2_QUINN] == R2_GLOBALS._spillLocation[R2_SEEKER])) {
- _object1.postInit();
+ if ((R2_GLOBALS._player._characterScene[R2_QUINN] == R2_GLOBALS._player._characterScene[R2_SEEKER])
+ && (R2_GLOBALS._spillLocation[R2_QUINN] == R2_GLOBALS._spillLocation[R2_SEEKER])) {
+ _companion.postInit();
if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
- _object1.setup(20, 5, 1);
- _object1.setDetails(9002, 0, 4, 3, 1, (SceneItem *)NULL);
+ // Seeker is in room with Quinn
+ _companion.setup(20, 5, 1);
+ _companion.setDetails(9002, 0, 4, 3, 1, (SceneItem *)NULL);
} else {
- _object1.setup(2008, 5, 1);
- _object1.setDetails(9001, 0, 5, 3, 1, (SceneItem *)NULL);
+ // Quinn is in room with Seeker
+ _companion.setup(2008, 5, 1);
+ _companion.setDetails(9001, 0, 5, 3, 1, (SceneItem *)NULL);
}
if (_westExit._enabled) {
if (_eastExit._enabled)
- _object1.setPosition(Common::Point(180, 128));
+ _companion.setPosition(Common::Point(180, 128));
else
- _object1.setPosition(Common::Point(75, 128));
+ _companion.setPosition(Common::Point(75, 128));
} else
- _object1.setPosition(Common::Point(300, 128));
+ _companion.setPosition(Common::Point(300, 128));
}
}
@@ -174,9 +177,9 @@ void Scene2000::initExits() {
_doorExit._moving = false;
for (int i = 0; i < 11; i++)
- _objList1[i].hide();
+ _persons[i].hide();
- _object1.remove();
+ _companion.remove();
switch (R2_GLOBALS._spillLocation[R2_GLOBALS._player._characterIndex]) {
case 3:
@@ -393,11 +396,11 @@ void Scene2000::Action1::signal() {
_actionIndex = 1;
Common::Point pt(-20, 127);
NpcMover *mover = new NpcMover();
- scene->_objList1[_state].addMover(mover, &pt, scene);
+ scene->_persons[_state].addMover(mover, &pt, scene);
break;
}
case 1:
- scene->_objList1[_state].setPosition(Common::Point(340, 127));
+ scene->_persons[_state].setPosition(Common::Point(340, 127));
--R2_GLOBALS._spillLocation[4 + _state];
_actionIndex = 0;
switch (_state - 1) {
@@ -426,9 +429,9 @@ void Scene2000::Action1::signal() {
}
if (R2_GLOBALS._spillLocation[3 + _state] == R2_GLOBALS._spillLocation[R2_GLOBALS._player._characterIndex])
- scene->_objList1[_state].show();
+ scene->_persons[_state].show();
else
- scene->_objList1[_state].hide();
+ scene->_persons[_state].hide();
signal();
break;
@@ -436,11 +439,11 @@ void Scene2000::Action1::signal() {
_actionIndex = 6;
Common::Point pt(340, 127);
NpcMover *mover = new NpcMover();
- scene->_objList1[_state].addMover(mover, &pt, this);
+ scene->_persons[_state].addMover(mover, &pt, this);
break;
}
case 6:
- scene->_objList1[_state].setPosition(Common::Point(-20, 127));
+ scene->_persons[_state].setPosition(Common::Point(-20, 127));
++R2_GLOBALS._spillLocation[3 + _state];
_actionIndex = 5;
switch (_state - 1) {
@@ -469,33 +472,33 @@ void Scene2000::Action1::signal() {
}
if (R2_GLOBALS._spillLocation[3 + _state] == R2_GLOBALS._spillLocation[R2_GLOBALS._player._characterIndex])
- scene->_objList1[_state].show();
+ scene->_persons[_state].show();
else
- scene->_objList1[_state].hide();
+ scene->_persons[_state].hide();
signal();
break;
case 10: {
Common::Point pt(290, 127);
NpcMover *mover = new NpcMover();
- scene->_objList1[_state].addMover(mover, &pt, this);
+ scene->_persons[_state].addMover(mover, &pt, this);
_actionIndex = 11;
break;
}
case 11:
if (_state == 1)
- scene->_objList1[0].setStrip(1);
+ scene->_persons[0].setStrip(1);
else if (_state == 5)
- scene->_objList1[4].setStrip(1);
+ scene->_persons[4].setStrip(1);
setDelay(600);
_actionIndex = 12;
break;
case 12:
if (_state == 1)
- scene->_objList1[0].setStrip(2);
+ scene->_persons[0].setStrip(2);
else if (_state == 5)
- scene->_objList1[4].setStrip(2);
- scene->_objList1[_state].setStrip(1);
+ scene->_persons[4].setStrip(2);
+ scene->_persons[_state].setStrip(1);
_actionIndex = 5;
signal();
break;
@@ -503,29 +506,29 @@ void Scene2000::Action1::signal() {
if ((R2_GLOBALS._spillLocation[3 + _state] == 13) || (R2_GLOBALS._spillLocation[3 + _state] == 22) || (R2_GLOBALS._spillLocation[3 + _state] == 27)) {
Common::Point pt(30, 127);
NpcMover *mover = new NpcMover();
- scene->_objList1[_state].addMover(mover, &pt, this);
+ scene->_persons[_state].addMover(mover, &pt, this);
_actionIndex = 16;
} else {
Common::Point pt(120, 127);
NpcMover *mover = new NpcMover();
- scene->_objList1[_state].addMover(mover, &pt, this);
+ scene->_persons[_state].addMover(mover, &pt, this);
_actionIndex = 16;
}
break;
case 16:
if (_state == 1)
- scene->_objList1[2].setStrip(2);
+ scene->_persons[2].setStrip(2);
else if (_state == 8)
- scene->_objList1[9].setStrip(2);
+ scene->_persons[9].setStrip(2);
setDelay(600);
_actionIndex = 17;
break;
case 17:
if (_state == 1)
- scene->_objList1[2].setStrip(1);
+ scene->_persons[2].setStrip(1);
else if (_state == 8)
- scene->_objList1[9].setStrip(1);
- scene->_objList1[_state].setStrip(2);
+ scene->_persons[9].setStrip(1);
+ scene->_persons[_state].setStrip(2);
_actionIndex = 0;
break;
case 99:
@@ -806,57 +809,57 @@ void Scene2000::postInit(SceneObjectList *OwnerList) {
_action5._state = 3;
for (int i = 0; i < 11; i++)
- _objList1[i].postInit();
+ _persons[i].postInit();
- _objList1[0].setVisage(2000);
- _objList1[0].setStrip(2);
- _objList1[0].setDetails(2001, 0, -1, -1, 1, (SceneItem *)NULL);
+ _persons[0].setVisage(2000);
+ _persons[0].setStrip(2);
+ _persons[0].setDetails(2001, 0, -1, -1, 1, (SceneItem *)NULL);
- _objList1[1].setVisage(2001);
- _objList1[1].setStrip(2);
- _objList1[1].setDetails(2001, 0, -1, -1, 1, (SceneItem *)NULL);
+ _persons[1].setVisage(2001);
+ _persons[1].setStrip(2);
+ _persons[1].setDetails(2001, 0, -1, -1, 1, (SceneItem *)NULL);
- _objList1[2].setVisage(2003);
- _objList1[2].setStrip(1);
- _objList1[2].setDetails(2001, 0, -1, -1, 1, (SceneItem *)NULL);
+ _persons[2].setVisage(2003);
+ _persons[2].setStrip(1);
+ _persons[2].setDetails(2001, 0, -1, -1, 1, (SceneItem *)NULL);
- _objList1[3].setVisage(2007);
- _objList1[3].setStrip(2);
- _objList1[3].setDetails(2001, 12, -1, -1, 1, (SceneItem *)NULL);
+ _persons[3].setVisage(2007);
+ _persons[3].setStrip(2);
+ _persons[3].setDetails(2001, 12, -1, -1, 1, (SceneItem *)NULL);
- _objList1[4].setVisage(2004);
- _objList1[4].setStrip(2);
- _objList1[4].setDetails(2001, 19, -1, -1, 1, (SceneItem *)NULL);
+ _persons[4].setVisage(2004);
+ _persons[4].setStrip(2);
+ _persons[4].setDetails(2001, 19, -1, -1, 1, (SceneItem *)NULL);
- _objList1[5].setVisage(2003);
- _objList1[5].setStrip(2);
- _objList1[5].setDetails(2001, 0, -1, -1, 1, (SceneItem *)NULL);
+ _persons[5].setVisage(2003);
+ _persons[5].setStrip(2);
+ _persons[5].setDetails(2001, 0, -1, -1, 1, (SceneItem *)NULL);
- _objList1[6].setVisage(2000);
- _objList1[6].setStrip(1);
- _objList1[6].setDetails(2001, 0, -1, -1, 1, (SceneItem *)NULL);
+ _persons[6].setVisage(2000);
+ _persons[6].setStrip(1);
+ _persons[6].setDetails(2001, 0, -1, -1, 1, (SceneItem *)NULL);
- _objList1[7].setVisage(2000);
- _objList1[7].setStrip(2);
- _objList1[7].setDetails(2001, 0, -1, -1, 1, (SceneItem *)NULL);
+ _persons[7].setVisage(2000);
+ _persons[7].setStrip(2);
+ _persons[7].setDetails(2001, 0, -1, -1, 1, (SceneItem *)NULL);
- _objList1[8].setVisage(2000);
- _objList1[8].setStrip(2);
- _objList1[8].setDetails(2001, 0, -1, -1, 1, (SceneItem *)NULL);
+ _persons[8].setVisage(2000);
+ _persons[8].setStrip(2);
+ _persons[8].setDetails(2001, 0, -1, -1, 1, (SceneItem *)NULL);
- _objList1[9].setVisage(2006);
- _objList1[9].setStrip(1);
- _objList1[9].setDetails(2001, 6, -1, -1, 1, (SceneItem *)NULL);
+ _persons[9].setVisage(2006);
+ _persons[9].setStrip(1);
+ _persons[9].setDetails(2001, 6, -1, -1, 1, (SceneItem *)NULL);
- _objList1[10].setVisage(2007);
- _objList1[10].setStrip(1);
- _objList1[10].setDetails(2001, 12, -1, -1, 1, (SceneItem *)NULL);
+ _persons[10].setVisage(2007);
+ _persons[10].setStrip(1);
+ _persons[10].setDetails(2001, 12, -1, -1, 1, (SceneItem *)NULL);
for (int i = 0; i < 11; i++) {
- _objList1[i].animate(ANIM_MODE_1, NULL);
- _objList1[i]._moveDiff.x = 3;
- _objList1[i]._moveRate = 8;
- _objList1[i].hide();
+ _persons[i].animate(ANIM_MODE_1, NULL);
+ _persons[i]._moveDiff.x = 3;
+ _persons[i]._moveRate = 8;
+ _persons[i].hide();
switch (i - 1) {
case 0:
if (R2_GLOBALS._spillLocation[3 + i] == 1)
@@ -899,28 +902,28 @@ void Scene2000::postInit(SceneObjectList *OwnerList) {
case 22:
case 27:
case 30:
- _objList1[i].setPosition(Common::Point(265, 127));
+ _persons[i].setPosition(Common::Point(265, 127));
break;
case 5:
case 12:
case 17:
case 21:
case 26:
- _objList1[i].setPosition(Common::Point(55, 127));
+ _persons[i].setPosition(Common::Point(55, 127));
break;
default:
- _objList1[i].setPosition(Common::Point(160, 127));
+ _persons[i].setPosition(Common::Point(160, 127));
break;
}
}
- _objList1[1].setAction(&_action2);
- _objList1[3].setAction(&_action5);
- _objList1[5].setAction(&_action4);
- _objList1[8].setAction(&_action1);
+ _persons[1].setAction(&_action2);
+ _persons[3].setAction(&_action5);
+ _persons[5].setAction(&_action4);
+ _persons[8].setAction(&_action1);
initPlayer();
- _item1.setDetails(Rect(0, 0, 320, 200), 2000, 0, -1, 23, 1, NULL);
+ _background.setDetails(Rect(0, 0, 320, 200), 2000, 0, -1, 23, 1, NULL);
SceneExt::postInit();
}
@@ -997,8 +1000,6 @@ void Scene2000::signal() {
g_globals->_sceneManager.changeScene(2535);
break;
default:
- if (R2_GLOBALS._v56AAB != 0)
- R2_GLOBALS._v56AAB = 0;
R2_GLOBALS._player.enableControl(CURSOR_WALK);
break;
}
@@ -1008,7 +1009,6 @@ void Scene2000::signal() {
g_globals->_sceneManager.changeScene(2350);
break;
default:
- R2_GLOBALS._v56AAB = 0;
R2_GLOBALS._player.enableControl();
break;
}
@@ -1038,20 +1038,21 @@ void Scene2000::synchronize(Serializer &s) {
* Scene 2350 - Balloon Launch Platform
*
*--------------------------------------------------------------------------*/
-bool Scene2350::Actor2::startAction(CursorType action, Event &event) {
+
+bool Scene2350::Companion::startAction(CursorType action, Event &event) {
if (action != R2_SENSOR_PROBE)
return(SceneActor::startAction(action, event));
return true;
}
-bool Scene2350::Actor3::startAction(CursorType action, Event &event) {
- Scene2350 *scene = (Scene2350 *)R2_GLOBALS._sceneManager._scene;
-
+bool Scene2350::Balloon::startAction(CursorType action, Event &event) {
if ((action == R2_REBREATHER_TANK) && (R2_GLOBALS.getFlag(74))) {
+ Scene2350 *scene = (Scene2350 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.disableControl();
- scene->_actor1.postInit();
+ scene->_person.postInit();
scene->_sceneMode = 2355;
- scene->setAction(&scene->_sequenceManager, scene, 2355, &R2_GLOBALS._player, &scene->_actor1, NULL);
+ scene->setAction(&scene->_sequenceManager, scene, 2355, &R2_GLOBALS._player, &scene->_person, NULL);
return true;
}
@@ -1060,8 +1061,9 @@ bool Scene2350::Actor3::startAction(CursorType action, Event &event) {
void Scene2350::ExitUp::changeScene() {
Scene2350 *scene = (Scene2350 *)R2_GLOBALS._sceneManager._scene;
+ _enabled = false;
- R2_GLOBALS._player.disableControl(CURSOR_CROSSHAIRS);
+ R2_GLOBALS._player.disableControl(CURSOR_WALK);
scene->_sceneMode = 12;
if (R2_GLOBALS._player._characterIndex == R2_QUINN)
scene->setAction(&scene->_sequenceManager, scene, 2350, &R2_GLOBALS._player, NULL);
@@ -1108,37 +1110,37 @@ void Scene2350::postInit(SceneObjectList *OwnerList) {
}
if (R2_GLOBALS._player._characterScene[R2_QUINN] == R2_GLOBALS._player._characterScene[R2_SEEKER]) {
- _actor2.postInit();
+ _companion.postInit();
if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
- _actor2.setup(20, 5, 1);
- _actor2.setDetails(9002, 0, 4, 3, 1, (SceneItem *)NULL);
+ _companion.setup(20, 5, 1);
+ _companion.setDetails(9002, 0, 4, 3, 1, (SceneItem *)NULL);
} else {
- _actor2.setup(2008, 5, 1);
- _actor2.setDetails(9001, 0, 5, 3, 1, (SceneItem *)NULL);
+ _companion.setup(2008, 5, 1);
+ _companion.setDetails(9001, 0, 5, 3, 1, (SceneItem *)NULL);
}
- _actor2.setPosition(Common::Point(135, 128));
+ _companion.setPosition(Common::Point(135, 128));
}
- _actor3.postInit();
- _actor4.postInit();
+ _balloon.postInit();
+ _harness.postInit();
if (R2_INVENTORY.getObjectScene(R2_REBREATHER_TANK) == 2350) {
- _actor3.hide();
- _actor4.hide();
+ _balloon.hide();
+ _harness.hide();
} else {
- _actor3.setup(2350, 0, 1);
- _actor3.setPosition(Common::Point(197, 101));
- _actor3.setDetails(2000, 12, -1, -1, 1, (SceneItem *)NULL);
- _actor3.fixPriority(10);
- _actor4.setup(2350, 1, 2);
- _actor4.setPosition(Common::Point(199, 129));
- _actor4.setDetails(2000, 12, -1, -1, 1, (SceneItem *)NULL);
- _actor4.fixPriority(10);
- }
- _item1.setDetails(Rect(0, 0, 320, 200), 2000, 9, -1, -1, 1, NULL);
+ _balloon.setup(2350, 0, 1);
+ _balloon.setPosition(Common::Point(197, 101));
+ _balloon.setDetails(2000, 12, -1, -1, 1, (SceneItem *)NULL);
+ _balloon.fixPriority(10);
+ _harness.setup(2350, 1, 2);
+ _harness.setPosition(Common::Point(199, 129));
+ _harness.setDetails(2000, 12, -1, -1, 1, (SceneItem *)NULL);
+ _harness.fixPriority(10);
+ }
+ _background.setDetails(Rect(0, 0, 320, 200), 2000, 9, -1, -1, 1, NULL);
R2_GLOBALS._player.disableControl();
if (R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] == 2000) {
- if (R2_GLOBALS._spillLocation[R2_GLOBALS._player._characterIndex] == 34) {
+ if (R2_GLOBALS._spillLocation[R2_GLOBALS._player._characterIndex] != 34) {
if (R2_GLOBALS._player._characterIndex == R2_QUINN)
_sceneMode = 2351;
else
@@ -1200,22 +1202,12 @@ void Scene2350::signal() {
}
}
-void Scene2350::process(Event &event) {
- if ((R2_GLOBALS._player._canWalk) && (event.eventType != EVENT_BUTTON_DOWN) &&
- (R2_GLOBALS._events.getCursor() == CURSOR_CROSSHAIRS)){
- Common::Point pt(event.mousePos.x, 129);
- PlayerMover *mover = new PlayerMover();
- R2_GLOBALS._player.addMover(mover, &pt);
- event.handled = true;
- }
- Scene::process(event);
-}
-
/*--------------------------------------------------------------------------
* Scene 2400 - Spill Mountains: Large empty room
*
*--------------------------------------------------------------------------*/
-void Scene2400::Exit1::changeScene() {
+
+void Scene2400::WestExit::changeScene() {
Scene2400 *scene = (Scene2400 *)R2_GLOBALS._sceneManager._scene;
R2_GLOBALS._player.disableControl();
@@ -1227,7 +1219,7 @@ void Scene2400::Exit1::changeScene() {
}
-void Scene2400::Exit2::changeScene() {
+void Scene2400::EastExit::changeScene() {
Scene2400 *scene = (Scene2400 *)R2_GLOBALS._sceneManager._scene;
R2_GLOBALS._player.disableControl();
@@ -1241,10 +1233,10 @@ void Scene2400::Exit2::changeScene() {
void Scene2400::postInit(SceneObjectList *OwnerList) {
loadScene(2400);
SceneExt::postInit();
- _exit1.setDetails(Rect(0, 125, 14, 165), EXITCURSOR_W, 2000);
- _exit1.setDest(Common::Point(14, 150));
- _exit2.setDetails(Rect(305, 125, 320, 165), EXITCURSOR_E, 2000);
- _exit2.setDest(Common::Point(315, 150));
+ _westExit.setDetails(Rect(0, 125, 14, 165), EXITCURSOR_W, 2000);
+ _westExit.setDest(Common::Point(14, 150));
+ _eastExit.setDetails(Rect(305, 125, 320, 165), EXITCURSOR_E, 2000);
+ _eastExit.setDest(Common::Point(315, 150));
R2_GLOBALS._player.postInit();
R2_GLOBALS._player.disableControl();
@@ -1279,9 +1271,9 @@ void Scene2400::signal() {
*--------------------------------------------------------------------------*/
bool Scene2425::RopeDest1::startAction(CursorType action, Event &event) {
- Scene2425 *scene = (Scene2425 *)R2_GLOBALS._sceneManager._scene;
-
if ((action == R2_CURSOR_ROPE) && (!R2_GLOBALS.getFlag(84))) {
+ Scene2425 *scene = (Scene2425 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 2426;
scene->setAction(&scene->_sequenceManager, scene, 2426, &R2_GLOBALS._player, &scene->_rope, NULL);
@@ -1296,9 +1288,9 @@ bool Scene2425::RopeDest1::startAction(CursorType action, Event &event) {
}
bool Scene2425::RopeDest2::startAction(CursorType action, Event &event) {
- Scene2425 *scene = (Scene2425 *)R2_GLOBALS._sceneManager._scene;
-
if ((action == R2_CURSOR_ROPE) && (R2_GLOBALS.getFlag(84))) {
+ Scene2425 *scene = (Scene2425 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 2427;
scene->setAction(&scene->_sequenceManager, scene, 2427, &R2_GLOBALS._player, &scene->_rope, NULL);
@@ -1313,11 +1305,11 @@ bool Scene2425::RopeDest2::startAction(CursorType action, Event &event) {
}
bool Scene2425::Crevasse::startAction(CursorType action, Event &event) {
- Scene2425 *scene = (Scene2425 *)R2_GLOBALS._sceneManager._scene;
-
if (action != R2_CURSOR_ROPE)
return NamedHotspot::startAction(action, event);
else {
+ Scene2425 *scene = (Scene2425 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.disableControl();
if (R2_GLOBALS.getFlag(84)) {
scene->_sceneMode = 20;
@@ -1331,7 +1323,7 @@ bool Scene2425::Crevasse::startAction(CursorType action, Event &event) {
}
}
-bool Scene2425::Item4::startAction(CursorType action, Event &event) {
+bool Scene2425::Background::startAction(CursorType action, Event &event) {
if (action != R2_CURSOR_ROPE)
return NamedHotspot::startAction(action, event);
else {
@@ -1365,7 +1357,7 @@ bool Scene2425::Pictographs::startAction(CursorType action, Event &event) {
}
}
-void Scene2425::Exit1::changeScene() {
+void Scene2425::SouthEastExit::changeScene() {
Scene2425 *scene = (Scene2425 *)R2_GLOBALS._sceneManager._scene;
_enabled = false;
@@ -1388,7 +1380,7 @@ void Scene2425::postInit(SceneObjectList *OwnerList) {
}
R2_GLOBALS._sound1.play(200);
- _exit1.setDetails(Rect(270, 136, 319, 168), EXITCURSOR_SE, 2000);
+ _southEastExit.setDetails(Rect(270, 136, 319, 168), EXITCURSOR_SE, 2000);
R2_GLOBALS._player.postInit();
R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
@@ -1424,8 +1416,6 @@ void Scene2425::postInit(SceneObjectList *OwnerList) {
_ropeDest1.setDetails(Rect(225, 52, 248, 65), 2425, -1, -1, -1, 1, NULL);
_ropeDest2.setDetails(Rect(292, 81, 316, 94), 2425, -1, -1, -1, 1, NULL);
-// CHECKME: SceneActor using a SceneItem function??
-// _pictographs2.setDetails(11, 2425, 3, -1, 6);
_pictographs2._sceneRegionId = 11;
_pictographs2._resNum = 2425;
_pictographs2._lookLineNum = 3;
@@ -1434,7 +1424,7 @@ void Scene2425::postInit(SceneObjectList *OwnerList) {
g_globals->_sceneItems.push_back(&_pictographs2);
_crevasse.setDetails(12, 2425, 7, -1, 9);
- _item4.setDetails(Rect(0, 0, 320, 200), 2425, 0, -1, -1, 1, NULL);
+ _background.setDetails(Rect(0, 0, 320, 200), 2425, 0, -1, -1, 1, NULL);
R2_GLOBALS._player.disableControl();
switch (R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex]) {
@@ -1493,16 +1483,16 @@ void Scene2425::signal() {
*
*--------------------------------------------------------------------------*/
-bool Scene2430::Actor1::startAction(CursorType action, Event &event) {
+bool Scene2430::Companion::startAction(CursorType action, Event &event) {
return SceneActor::startAction(action, event);
}
bool Scene2430::GunPowder::startAction(CursorType action, Event &event) {
- Scene2430 *scene = (Scene2430 *)R2_GLOBALS._sceneManager._scene;
-
if ((action != CURSOR_USE) || (R2_GLOBALS._player._characterIndex != 2))
return SceneActor::startAction(action, event);
+ Scene2430 *scene = (Scene2430 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 2430;
scene->setAction(&scene->_sequenceManager, scene, 2430, &R2_GLOBALS._player, &scene->_gunPowder, NULL);
@@ -1510,18 +1500,18 @@ bool Scene2430::GunPowder::startAction(CursorType action, Event &event) {
}
bool Scene2430::OilLamp::startAction(CursorType action, Event &event) {
- Scene2430 *scene = (Scene2430 *)R2_GLOBALS._sceneManager._scene;
-
if ((action != CURSOR_USE) || (R2_GLOBALS._player._characterIndex != 2))
return SceneActor::startAction(action, event);
+ Scene2430 *scene = (Scene2430 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 2435;
scene->setAction(&scene->_sequenceManager, scene, 2435, &R2_GLOBALS._player, &scene->_oilLamp, NULL);
return true;
}
-void Scene2430::Exit1::changeScene() {
+void Scene2430::SouthExit::changeScene() {
Scene2430 *scene = (Scene2430 *)R2_GLOBALS._sceneManager._scene;
scene->_sceneMode = 0;
@@ -1536,8 +1526,8 @@ void Scene2430::Exit1::changeScene() {
void Scene2430::postInit(SceneObjectList *OwnerList) {
loadScene(2430);
SceneExt::postInit();
- _exit1.setDetails(Rect(68, 155, 147, 168), EXITCURSOR_S, 2000);
- _exit1.setDest(Common::Point(108, 160));
+ _southExit.setDetails(Rect(68, 155, 147, 168), EXITCURSOR_S, 2000);
+ _southExit.setDest(Common::Point(108, 160));
if (R2_INVENTORY.getObjectScene(R2_GUNPOWDER) == 2430) {
_gunPowder.postInit();
@@ -1566,33 +1556,31 @@ void Scene2430::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player.setPosition(Common::Point(100, 200));
if (R2_GLOBALS._player._characterScene[R2_QUINN] == R2_GLOBALS._player._characterScene[R2_SEEKER]) {
- _actor1.postInit();
+ _companion.postInit();
if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
- _actor1.setup(20, 5, 1);
- _actor1.setDetails(9002, 0, 4, 3, 1, (SceneItem *)NULL);
+ _companion.setup(20, 5, 1);
+ _companion.setDetails(9002, 0, 4, 3, 1, (SceneItem *)NULL);
} else {
- _actor1.setup(2008, 5, 1);
- _actor1.setDetails(9001, 0, 5, 3, 1, (SceneItem *)NULL);
+ _companion.setup(2008, 5, 1);
+ _companion.setDetails(9001, 0, 5, 3, 1, (SceneItem *)NULL);
}
- _actor1.setPosition(Common::Point(189, 137));
+ _companion.setPosition(Common::Point(189, 137));
R2_GLOBALS._walkRegions.disableRegion(4);
}
- _item2.setDetails(Rect(11, 30, 37, 45), 2430, 3, -1, 5, 1, NULL);
- _item3.setDetails(Rect(9, 58, 63, 92), 2430, 6, -1, -1, 1, NULL);
- _item4.setDetails(Rect(20, 89, 127, 107), 2430, 9, -1, 11, 1, NULL);
- _item5.setDetails(Rect(49, 7, 60, 27), 2430, 12, 13, 14, 1, NULL);
- _item6.setDetails(Rect(69, 10, 95, 72), 2430, 15, -1, 14, 1, NULL);
- _item10.setDetails(Rect(198, 4, 222, 146), 2430, 30, 31, 32, 1, NULL);
- _item7.setDetails(Rect(155, 40, 304, 120), 2430, 21, -1, 23, 1, NULL);
- _item8.setDetails(Rect(249, 3, 261, 39), 2430, 24, 25, -1, 1, NULL);
- _item9.setDetails(Rect(279, 13, 305, 34), 2430, 33, -1, 18, 1, NULL);
- // CHECKME: initialized for the 2nd time??
- _item2.setDetails(Rect(11, 30, 37, 45), 2430, 33, -1, 18, 1, NULL);
- _item11.setDetails(Rect(116, 104, 148, 111), 2430, 39, -1, -1, 1, NULL);
- _item12.setDetails(Rect(66, 77, 84, 83), 2430, 39, -1, -1, 1, NULL);
- _item13.setDetails(Rect(117, 118, 201, 141), 2430, 9, -1, 11, 1, NULL);
- _item1.setDetails(Rect(0, 0, 320, 200), 2430, 0, -1, -1, 1, NULL);
+ _furnishings.setDetails(Rect(9, 58, 63, 92), 2430, 6, -1, -1, 1, NULL);
+ _rug1.setDetails(Rect(20, 89, 127, 107), 2430, 9, -1, 11, 1, NULL);
+ _mirror.setDetails(Rect(49, 7, 60, 27), 2430, 12, 13, 14, 1, NULL);
+ _garments.setDetails(Rect(69, 10, 95, 72), 2430, 15, -1, 14, 1, NULL);
+ _post.setDetails(Rect(198, 4, 222, 146), 2430, 30, 31, 32, 1, NULL);
+ _bed.setDetails(Rect(155, 40, 304, 120), 2430, 21, -1, 23, 1, NULL);
+ _towel.setDetails(Rect(249, 3, 261, 39), 2430, 24, 25, -1, 1, NULL);
+ _bottles1.setDetails(Rect(279, 13, 305, 34), 2430, 33, -1, 18, 1, NULL);
+ _bottles2.setDetails(Rect(11, 30, 37, 45), 2430, 33, -1, 18, 1, NULL);
+ _clothesPile1.setDetails(Rect(116, 104, 148, 111), 2430, 39, -1, -1, 1, NULL);
+ _clothesPile2.setDetails(Rect(66, 77, 84, 83), 2430, 39, -1, -1, 1, NULL);
+ _rug2.setDetails(Rect(117, 118, 201, 141), 2430, 9, -1, 11, 1, NULL);
+ _background.setDetails(Rect(0, 0, 320, 200), 2430, 0, -1, -1, 1, NULL);
if (R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] == 2000) {
R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] = 2430;
@@ -1673,7 +1661,7 @@ bool Scene2435::Astor::startAction(CursorType action, Event &event) {
}
}
-void Scene2435::Exit1::changeScene() {
+void Scene2435::SouthExit::changeScene() {
Scene2435 *scene = (Scene2435 *)R2_GLOBALS._sceneManager._scene;
_enabled = false;
@@ -1693,8 +1681,8 @@ void Scene2435::postInit(SceneObjectList *OwnerList) {
_stripManager.addSpeaker(&_quinnSpeaker);
_stripManager.addSpeaker(&_seekerSpeaker);
_stripManager.addSpeaker(&_pharishaSpeaker);
- _exit1.setDetails(Rect(142, 155, 207, 167), EXITCURSOR_S, 2000);
- _exit1.setDest(Common::Point(175, 160));
+ _southExit.setDetails(Rect(142, 155, 207, 167), EXITCURSOR_S, 2000);
+ _southExit.setDest(Common::Point(175, 160));
_astor.postInit();
_astor.setup(2005, 3, 1);
_astor.setPosition(Common::Point(219, 106));
@@ -1782,6 +1770,7 @@ void Scene2435::signal() {
_sceneMode = 20;
R2_GLOBALS._events.setCursor(CURSOR_ARROW);
_stripManager.start(709, this);
+ break;
default:
R2_GLOBALS._player.enableControl();
break;
@@ -1793,14 +1782,14 @@ void Scene2435::signal() {
*
*--------------------------------------------------------------------------*/
-bool Scene2440::Actor1::startAction(CursorType action, Event &event) {
+bool Scene2440::Companion::startAction(CursorType action, Event &event) {
return SceneActor::startAction(action, event);
}
bool Scene2440::OilLamp::startAction(CursorType action, Event &event) {
- Scene2440 *scene = (Scene2440 *)R2_GLOBALS._sceneManager._scene;
-
if ((action == CURSOR_USE) && (R2_GLOBALS._player._characterIndex == R2_SEEKER)) {
+ Scene2440 *scene = (Scene2440 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 2440;
scene->setAction(&scene->_sequenceManager, scene, 2440, &R2_GLOBALS._player, &scene->_oilLamp, NULL);
@@ -1810,7 +1799,7 @@ bool Scene2440::OilLamp::startAction(CursorType action, Event &event) {
return SceneActor::startAction(action, event);
}
-void Scene2440::Exit1::changeScene() {
+void Scene2440::SouthEastExit::changeScene() {
Scene2440 *scene = (Scene2440 *)R2_GLOBALS._sceneManager._scene;
_enabled = false;
@@ -1826,8 +1815,8 @@ void Scene2440::postInit(SceneObjectList *OwnerList) {
SceneExt::postInit();
R2_GLOBALS._sound1.play(200);
// Fix exit cursor, the original was using NW
- _exit1.setDetails(Rect(172, 155, 250, 167), EXITCURSOR_SE, 2000);
- _exit1.setDest(Common::Point(210, 160));
+ _southEastExit.setDetails(Rect(172, 155, 250, 167), EXITCURSOR_SE, 2000);
+ _southEastExit.setDest(Common::Point(210, 160));
if (R2_INVENTORY.getObjectScene(R2_ALCOHOL_LAMP_2) == 2440) {
_oilLamp.postInit();
_oilLamp.setup(2435, 1, 1);
@@ -1848,24 +1837,24 @@ void Scene2440::postInit(SceneObjectList *OwnerList) {
}
R2_GLOBALS._player.setPosition(Common::Point(210, 200));
if (R2_GLOBALS._player._characterScene[R2_QUINN] == R2_GLOBALS._player._characterScene[R2_SEEKER]) {
- _actor1.postInit();
+ _companion.postInit();
if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
- _actor1.setup(20, 5, 1);
- _actor1.setDetails(9002, 0, 4, 3, 1, (SceneItem *)NULL);
+ _companion.setup(20, 5, 1);
+ _companion.setDetails(9002, 0, 4, 3, 1, (SceneItem *)NULL);
} else {
- _actor1.setup(2008, 5, 1);
- _actor1.setDetails(9002, 0, 5, 3, 1, (SceneItem *)NULL);
+ _companion.setup(2008, 5, 1);
+ _companion.setDetails(9002, 0, 5, 3, 1, (SceneItem *)NULL);
}
- _actor1.setPosition(Common::Point(38, 119));
+ _companion.setPosition(Common::Point(38, 119));
}
- _item2.setDetails(Rect(125, 25, 142, 73), 2430, 15, -1, 14, 1, NULL);
- _item3.setDetails(Rect(124, 78, 237, 120), 2430, 36, -1, 38, 1, NULL);
- _item4.setDetails(Rect(250, 3, 265, 133), 2430, 30, 31, 32, 1, NULL);
- _item5.setDetails(Rect(91, 117, 203, 140), 2430, 9, -1, 11, 1, NULL);
- _item6.setDetails(Rect(48, 78, 103, 112), 2430, 6, -1, -1, 1, NULL);
- _item7.setDetails(Rect(48, 31, 73, 52), 2430, 33, -1, 18, 1, NULL);
- _item1.setDetails(Rect(0, 0, 320, 200), 2430, 0, -1, -1, 1, NULL);
+ _garments.setDetails(Rect(125, 25, 142, 73), 2430, 15, -1, 14, 1, NULL);
+ _bedspread.setDetails(Rect(124, 78, 237, 120), 2430, 36, -1, 38, 1, NULL);
+ _post.setDetails(Rect(250, 3, 265, 133), 2430, 30, 31, 32, 1, NULL);
+ _rug.setDetails(Rect(91, 117, 203, 140), 2430, 9, -1, 11, 1, NULL);
+ _furnishings.setDetails(Rect(48, 78, 103, 112), 2430, 6, -1, -1, 1, NULL);
+ _bottles.setDetails(Rect(48, 31, 73, 52), 2430, 33, -1, 18, 1, NULL);
+ _background.setDetails(Rect(0, 0, 320, 200), 2430, 0, -1, -1, 1, NULL);
R2_GLOBALS._player.disableControl();
@@ -1905,6 +1894,7 @@ void Scene2440::signal() {
* Scene 2445 - Spill Mountains:
*
*--------------------------------------------------------------------------*/
+
void Scene2445::postInit(SceneObjectList *OwnerList) {
loadScene(2445);
SceneExt::postInit();
@@ -1925,9 +1915,9 @@ void Scene2445::signal() {
*--------------------------------------------------------------------------*/
bool Scene2450::Parker::startAction(CursorType action, Event &event) {
- Scene2450 *scene = (Scene2450 *)R2_GLOBALS._sceneManager._scene;
-
if ((action == CURSOR_USE) && (R2_GLOBALS._player._characterIndex == R2_QUINN)) {
+ Scene2450 *scene = (Scene2450 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 2452;
scene->setAction(&scene->_sequenceManager, scene, 2452, &R2_GLOBALS._player, &scene->_parker, NULL);
@@ -1937,18 +1927,18 @@ bool Scene2450::Parker::startAction(CursorType action, Event &event) {
}
bool Scene2450::CareTaker::startAction(CursorType action, Event &event) {
- Scene2450 *scene = (Scene2450 *)R2_GLOBALS._sceneManager._scene;
-
if (action == CURSOR_TALK) {
R2_GLOBALS._player.disableControl();
- if (R2_GLOBALS._v565AE < 3) {
- ++R2_GLOBALS._v565AE;
+ if (R2_GLOBALS._stripModifier < 3) {
+ Scene2450 *scene = (Scene2450 *)R2_GLOBALS._sceneManager._scene;
+
+ ++R2_GLOBALS._stripModifier;
scene->_sceneMode = 20;
R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
if (R2_GLOBALS._player._characterIndex == R2_QUINN)
- scene->_stripManager.start(699 + (R2_GLOBALS._v565AE * 2), scene);
+ scene->_stripManager.start(699 + (R2_GLOBALS._stripModifier * 2), scene);
else
- scene->_stripManager.start(700 + (R2_GLOBALS._v565AE * 2), scene);
+ scene->_stripManager.start(700 + (R2_GLOBALS._stripModifier * 2), scene);
}
return true;
} else {
@@ -1956,10 +1946,10 @@ bool Scene2450::CareTaker::startAction(CursorType action, Event &event) {
}
}
-void Scene2450::Exit1::changeScene() {
- Scene2450 *scene = (Scene2450 *)R2_GLOBALS._sceneManager._scene;
-
+void Scene2450::SouthWestExit::changeScene() {
if ((R2_GLOBALS._player._characterIndex == R2_SEEKER) || (R2_GLOBALS.getFlag(61))) {
+ Scene2450 *scene = (Scene2450 *)R2_GLOBALS._sceneManager._scene;
+
_enabled = false;
R2_GLOBALS._events.setCursor(CURSOR_ARROW);
R2_GLOBALS._player.disableControl();
@@ -1969,7 +1959,7 @@ void Scene2450::Exit1::changeScene() {
R2_GLOBALS._player.addMover(mover, &pt, scene);
} else {
_moving = false;
- SceneItem::display(2450, 3, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ SceneItem::display(2450, 3, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, LIST_END);
Common::Point pt(60, 140);
NpcMover *mover = new NpcMover();
R2_GLOBALS._player.addMover(mover, &pt, NULL);
@@ -1990,8 +1980,8 @@ void Scene2450::postInit(SceneObjectList *OwnerList) {
_stripManager.addSpeaker(&_caretakerSpeaker);
if (R2_GLOBALS.getFlag(72)) {
- _exit1.setDetails(Rect(0, 143, 47, 168), EXITCURSOR_SW, 2000);
- _exit1.setDest(Common::Point(10, 160));
+ _southWestExit.setDetails(Rect(0, 143, 47, 168), EXITCURSOR_SW, 2000);
+ _southWestExit.setDest(Common::Point(10, 160));
}
if (!R2_GLOBALS.getFlag(61)) {
@@ -2006,7 +1996,7 @@ void Scene2450::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player.disableControl();
switch (R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex]) {
case 1900:
- R2_GLOBALS._v565AE = 0;
+ R2_GLOBALS._stripModifier = 0;
R2_GLOBALS._player._characterScene[R2_QUINN] = 2450;
R2_GLOBALS._player._characterScene[R2_SEEKER] = 2450;
R2_GLOBALS._player._oldCharacterScene[R2_QUINN] = 2450;
@@ -2068,7 +2058,7 @@ void Scene2450::postInit(SceneObjectList *OwnerList) {
_careTaker.setPosition(Common::Point(34, 153));
_careTaker.setDetails(2001, 40, -1, -1, 1, (SceneItem *)NULL);
- _exit1._enabled = false;
+ _southWestExit._enabled = false;
}
} else {
R2_GLOBALS._player.postInit();
@@ -2101,7 +2091,7 @@ void Scene2450::postInit(SceneObjectList *OwnerList) {
_careTaker.setPosition(Common::Point(34, 153));
_careTaker.setDetails(2001, 40, -1, -1, 1, (SceneItem *)NULL);
- _exit1._enabled = false;
+ _southWestExit._enabled = false;
}
}
R2_GLOBALS._player.enableControl();
@@ -2142,14 +2132,14 @@ void Scene2450::signal() {
g_globals->_sceneManager.changeScene(2000);
break;
case 20:
- if (R2_GLOBALS._v565AE == 3) {
+ if (R2_GLOBALS._stripModifier == 3) {
R2_GLOBALS._player.disableControl();
- R2_GLOBALS._v565AE = 4;
+ R2_GLOBALS._stripModifier = 4;
_sceneMode = 2454;
setAction(&_sequenceManager, this, 2454, &_careTaker, NULL);
} else {
R2_GLOBALS._player.enableControl(CURSOR_TALK);
- if (R2_GLOBALS._v565AE < 4)
+ if (R2_GLOBALS._stripModifier < 4)
R2_GLOBALS._player._canWalk = false;
}
break;
@@ -2180,7 +2170,7 @@ void Scene2450::signal() {
_stripManager.start(700, this);
break;
case 2454:
- _exit1._enabled = true;
+ _southWestExit._enabled = true;
R2_GLOBALS.setFlag(72);
_careTaker.remove();
if (R2_GLOBALS.getFlag(61)) {
@@ -2218,10 +2208,10 @@ void Scene2450::signal() {
*--------------------------------------------------------------------------*/
bool Scene2455::Lamp::startAction(CursorType action, Event &event) {
- Scene2455 *scene = (Scene2455 *)R2_GLOBALS._sceneManager._scene;
-
if (action == R2_GLASS_DOME) {
if ((R2_INVENTORY.getObjectScene(R2_ALCOHOL_LAMP_2) == 2455) || (R2_INVENTORY.getObjectScene(R2_ALCOHOL_LAMP_3) == 2455)) {
+ Scene2455 *scene = (Scene2455 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 2458;
scene->_pool._lookLineNum = 9;
@@ -2272,9 +2262,9 @@ bool Scene2455::Pool::startAction(CursorType action, Event &event) {
}
bool Scene2455::ScrithKey::startAction(CursorType action, Event &event) {
- Scene2455 *scene = (Scene2455 *)R2_GLOBALS._sceneManager._scene;
-
if (action == CURSOR_USE) {
+ Scene2455 *scene = (Scene2455 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 2459;
scene->setAction(&scene->_sequenceManager, scene, 2459, &R2_GLOBALS._player, &scene->_scrithKey, NULL);
@@ -2284,7 +2274,7 @@ bool Scene2455::ScrithKey::startAction(CursorType action, Event &event) {
return SceneActor::startAction(action, event);
}
-void Scene2455::Exit1::changeScene() {
+void Scene2455::NorthExit::changeScene() {
Scene2455 *scene = (Scene2455 *)R2_GLOBALS._sceneManager._scene;
_enabled = false;
@@ -2304,14 +2294,14 @@ void Scene2455::postInit(SceneObjectList *OwnerList) {
}
R2_GLOBALS._sound1.play(200);
- _exit1.setDetails(Rect(0, 0, 320, 15), EXITCURSOR_N, 2425);
+ _northExit.setDetails(Rect(0, 0, 320, 15), EXITCURSOR_N, 2425);
if (R2_INVENTORY.getObjectScene(R2_GLASS_DOME) == 2455) {
_scrithKey.postInit();
_scrithKey.setup(2456, 3, 1);
_scrithKey.setPosition(Common::Point(176, 165));
_scrithKey.setDetails(2455, 16, 1, -1, 1, (SceneItem *)NULL);
- } else if ((R2_INVENTORY.getObjectScene(R2_ALCOHOL_LAMP_3) == 2455) ||
+ } else if ((R2_INVENTORY.getObjectScene(R2_ALCOHOL_LAMP_3) == 2455) ||
(R2_INVENTORY.getObjectScene(R2_ALCOHOL_LAMP_2) == 2455)) {
_lamp.postInit();
_lamp.setup(2456, 3, 3);
@@ -2392,11 +2382,11 @@ void Scene2455::signal() {
}
/*--------------------------------------------------------------------------
- * Scene 2500 - Spill Mountains: Large Cave
+ * Scene 2500 - Spill Mountains: Large Ledge
*
*--------------------------------------------------------------------------*/
-void Scene2500::Exit1::changeScene() {
+void Scene2500::WestExit::changeScene() {
Scene2500 *scene = (Scene2500 *)R2_GLOBALS._sceneManager._scene;
_enabled = false;
@@ -2424,8 +2414,8 @@ void Scene2500::postInit(SceneObjectList *OwnerList) {
if (R2_GLOBALS._sceneManager._previousScene == -1)
R2_GLOBALS._sceneManager._previousScene = 2000;
- _exit1.setDetails(Rect(30, 50, 85, 105), EXITCURSOR_W, 2000);
- _exit1.setDest(Common::Point(84, 104));
+ _westExit.setDetails(Rect(30, 50, 85, 105), EXITCURSOR_W, 2000);
+ _westExit.setDest(Common::Point(84, 104));
R2_GLOBALS._player.postInit();
R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
@@ -2438,19 +2428,19 @@ void Scene2500::postInit(SceneObjectList *OwnerList) {
}
if (R2_GLOBALS._player._characterScene[R2_QUINN] == R2_GLOBALS._player._characterScene[R2_SEEKER]) {
- _actor1.postInit();
+ _companion.postInit();
if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
- _actor1.setup(21, 3, 1);
- _actor1.setDetails(9002, 1, -1, -1, 1, (SceneItem *)NULL);
+ _companion.setup(21, 3, 1);
+ _companion.setDetails(9002, 1, -1, -1, 1, (SceneItem *)NULL);
} else {
- _actor1.setup(2008, 3, 1);
- _actor1.changeZoom(50);
- _actor1.setDetails(9001, 0, -1, -1, 1, (SceneItem *)NULL);
+ _companion.setup(2008, 3, 1);
+ _companion.changeZoom(50);
+ _companion.setDetails(9001, 0, -1, -1, 1, (SceneItem *)NULL);
}
- _actor1.setPosition(Common::Point(141, 94));
+ _companion.setPosition(Common::Point(141, 94));
}
- _item1.setDetails(Rect(0, 0, 320, 200), 2430, 0, -1, -1, 1, NULL);
+ _background.setDetails(Rect(0, 0, 320, 200), 2430, 0, -1, -1, 1, NULL);
R2_GLOBALS._player.disableControl();
if (R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] == 2000) {
@@ -2461,9 +2451,9 @@ void Scene2500::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player.addMover(mover, &pt, this);
} else if (R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] == 3100) {
_sceneMode = 2500;
- _actor2.postInit();
- _actor3.postInit();
- setAction(&_sequenceManager, this, 2500, &R2_GLOBALS._player, &_actor2, &_actor3, NULL);
+ _quinn.postInit();
+ _ship.postInit();
+ setAction(&_sequenceManager, this, 2500, &R2_GLOBALS._player, &_quinn, &_ship, NULL);
} else {
R2_GLOBALS._player.setPosition(Common::Point(160, 150));
R2_GLOBALS._player.setStrip(3);
@@ -2480,7 +2470,7 @@ void Scene2500::signal() {
case 20:
R2_GLOBALS._player.disableControl();
_sceneMode = 2501;
- setAction(&_sequenceManager, this, 2501, &R2_GLOBALS._player, &_actor2, &_actor3, NULL);
+ setAction(&_sequenceManager, this, 2501, &R2_GLOBALS._player, &_quinn, &_ship, NULL);
break;
case 2500:
_sceneMode = 20;
@@ -2501,10 +2491,10 @@ void Scene2500::signal() {
*
*--------------------------------------------------------------------------*/
-bool Scene2525::Item5::startAction(CursorType action, Event &event) {
- Scene2525 *scene = (Scene2525 *)R2_GLOBALS._sceneManager._scene;
-
+bool Scene2525::StopCock::startAction(CursorType action, Event &event) {
if ((action == R2_REBREATHER_TANK) && (!R2_GLOBALS.getFlag(74))) {
+ Scene2525 *scene = (Scene2525 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 2526;
scene->setAction(&scene->_sequenceManager, scene, 2526, &R2_GLOBALS._player, NULL);
@@ -2515,22 +2505,22 @@ bool Scene2525::Item5::startAction(CursorType action, Event &event) {
}
bool Scene2525::GlassDome::startAction(CursorType action, Event &event) {
- Scene2525 *scene = (Scene2525 *)R2_GLOBALS._sceneManager._scene;
-
if (action != CURSOR_USE)
return SceneActor::startAction(action, event);
if (R2_GLOBALS._player._characterIndex == R2_SEEKER) {
+ Scene2525 *scene = (Scene2525 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 2525;
scene->setAction(&scene->_sequenceManager, scene, 2525, &R2_GLOBALS._player, &scene->_glassDome, NULL);
} else {
- SceneItem::display(2530, 33, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ SceneItem::display(2530, 33, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, LIST_END);
}
return true;
}
-void Scene2525::Exit1::changeScene() {
+void Scene2525::SouthExit::changeScene() {
Scene2525 *scene = (Scene2525 *)R2_GLOBALS._sceneManager._scene;
_enabled = false;
@@ -2549,7 +2539,7 @@ void Scene2525::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._sound1.play(200);
R2_GLOBALS._sound2.play(207);
- _exit1.setDetails(Rect(86, 155, 228, 168), EXITCURSOR_S, 2000);
+ _southExit.setDetails(Rect(86, 155, 228, 168), EXITCURSOR_S, 2000);
if (R2_INVENTORY.getObjectScene(R2_GLASS_DOME) == 2525) {
_glassDome.postInit();
@@ -2559,12 +2549,12 @@ void Scene2525::postInit(SceneObjectList *OwnerList) {
_glassDome.setDetails(2525, 27, -1, -1, 1, (SceneItem *)NULL);
}
- _actor2.postInit();
- _actor2.setup(2525, 1, 1);
- _actor2.setPosition(Common::Point(183, 114));
- _actor2.setDetails(2525, 15, -1, -1, 1, (SceneItem *)NULL);
- _actor2.animate(ANIM_MODE_2, NULL);
- _actor2._numFrames = 3;
+ _compressor.postInit();
+ _compressor.setup(2525, 1, 1);
+ _compressor.setPosition(Common::Point(183, 114));
+ _compressor.setDetails(2525, 15, -1, -1, 1, (SceneItem *)NULL);
+ _compressor.animate(ANIM_MODE_2, NULL);
+ _compressor._numFrames = 3;
R2_GLOBALS._player.postInit();
R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
@@ -2577,24 +2567,24 @@ void Scene2525::postInit(SceneObjectList *OwnerList) {
}
if (R2_GLOBALS._player._characterScene[R2_QUINN] == R2_GLOBALS._player._characterScene[R2_SEEKER]) {
- _actor1.postInit();
+ _companion.postInit();
if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
- _actor1.setup(20, 5, 1);
- _actor1.setDetails(9002, 0, 4, 3, 1, (SceneItem *)NULL);
+ _companion.setup(20, 5, 1);
+ _companion.setDetails(9002, 0, 4, 3, 1, (SceneItem *)NULL);
} else {
- _actor1.setup(2008, 5, 1);
- _actor1.setDetails(9001, 0, 5, 3, 1, (SceneItem *)NULL);
+ _companion.setup(2008, 5, 1);
+ _companion.setDetails(9001, 0, 5, 3, 1, (SceneItem *)NULL);
}
- _actor1.setPosition(Common::Point(209, 162));
+ _companion.setPosition(Common::Point(209, 162));
R2_GLOBALS._walkRegions.disableRegion(4);
}
- _item5.setDetails(Rect(125, 73, 140, 86), 2525, 6, -1, -1, 1, NULL);
- _item3.setDetails(Rect(137, 11, 163, 72), 2525, 12, -1, -1, 1, NULL);
- _item4.setDetails(Rect(204, 20, 234, 78), 2525, 12, -1, -1, 1, NULL);
- _item2.setDetails(Rect(102, 62, 230, 134), 2525, 0, -1, -1, 1, NULL);
- _item1.setDetails(Rect(0, 0, 320, 200), 2525, 24, -1, -1, 1, NULL);
+ _stopcock.setDetails(Rect(125, 73, 140, 86), 2525, 6, -1, -1, 1, NULL);
+ _pipes1.setDetails(Rect(137, 11, 163, 72), 2525, 12, -1, -1, 1, NULL);
+ _pipes2.setDetails(Rect(204, 20, 234, 78), 2525, 12, -1, -1, 1, NULL);
+ _machine.setDetails(Rect(102, 62, 230, 134), 2525, 0, -1, -1, 1, NULL);
+ _background.setDetails(Rect(0, 0, 320, 200), 2525, 24, -1, -1, 1, NULL);
R2_GLOBALS._player.disableControl();
@@ -2643,31 +2633,31 @@ void Scene2525::signal() {
*--------------------------------------------------------------------------*/
bool Scene2530::Flask::startAction(CursorType action, Event &event) {
- Scene2530 *scene = (Scene2530 *)R2_GLOBALS._sceneManager._scene;
-
if (action != CURSOR_USE)
return SceneActor::startAction(action, event);
if (R2_GLOBALS._player._characterIndex == R2_SEEKER) {
+ Scene2530 *scene = (Scene2530 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 2530;
scene->setAction(&scene->_sequenceManager, scene, 2530, &R2_GLOBALS._player, &scene->_flask, NULL);
} else {
- SceneItem::display(2530, 33, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ SceneItem::display(2530, 33, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, LIST_END);
}
return true;
}
bool Scene2530::Crank::startAction(CursorType action, Event &event) {
- Scene2530 *scene = (Scene2530 *)R2_GLOBALS._sceneManager._scene;
-
if (action != CURSOR_USE)
return SceneActor::startAction(action, event);
+ Scene2530 *scene = (Scene2530 *)R2_GLOBALS._sceneManager._scene;
+
if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
if (R2_GLOBALS.getFlag(73))
- SceneItem::display(2530, 35, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ SceneItem::display(2530, 35, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, LIST_END);
else {
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 2532;
@@ -2688,7 +2678,7 @@ bool Scene2530::Crank::startAction(CursorType action, Event &event) {
return true;
}
-void Scene2530::Exit1::changeScene() {
+void Scene2530::SouthExit::changeScene() {
Scene2530 *scene = (Scene2530 *)R2_GLOBALS._sceneManager._scene;
_enabled = false;
@@ -2705,8 +2695,8 @@ void Scene2530::postInit(SceneObjectList *OwnerList) {
loadScene(2530);
SceneExt::postInit();
- _exit1.setDetails(Rect(68, 155, 147, 168), EXITCURSOR_S, 2000);
- _exit1.setDest(Common::Point(108, 160));
+ _southExit.setDetails(Rect(68, 155, 147, 168), EXITCURSOR_S, 2000);
+ _southExit.setDest(Common::Point(108, 160));
if (R2_INVENTORY.getObjectScene(R2_PURE_GRAIN_ALCOHOL) == 2530) {
_flask.postInit();
@@ -2739,20 +2729,20 @@ void Scene2530::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player.setPosition(Common::Point(100, 200));
if (R2_GLOBALS._player._characterScene[R2_QUINN] == R2_GLOBALS._player._characterScene[R2_SEEKER]) {
- _actor1.postInit();
+ _companion.postInit();
if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
- _actor1.setup(20, 5, 1);
- _actor1.setDetails(9002, 0, 4, 3, 1, (SceneItem *)NULL);
+ _companion.setup(20, 5, 1);
+ _companion.setDetails(9002, 0, 4, 3, 1, (SceneItem *)NULL);
} else {
- _actor1.setup(2008, 5, 1);
- _actor1.setDetails(9001, 0, 5, 3, 1, (SceneItem *)NULL);
+ _companion.setup(2008, 5, 1);
+ _companion.setDetails(9001, 0, 5, 3, 1, (SceneItem *)NULL);
}
- _actor1.setPosition(Common::Point(20, 130));
+ _companion.setPosition(Common::Point(20, 130));
R2_GLOBALS._walkRegions.disableRegion(1);
}
- _item2.setDetails(Rect(108, 90, 135, 205), 2530, 22, -1, -1, 1, NULL);
- _item5.setDetails(Rect(115, 112, 206, 130), 2530, 25, -1, 27, 1, NULL);
+ _crank2.setDetails(Rect(108, 90, 135, 205), 2530, 22, -1, -1, 1, NULL);
+ _rope.setDetails(Rect(115, 112, 206, 130), 2530, 25, -1, 27, 1, NULL);
_shelf.setDetails(Rect(256, 64, 311, 85), 2530, 31, -1, 33, 1, NULL);
_background.setDetails(Rect(0, 0, 320, 200), 2530, 0, 1, -1, 1, NULL);
@@ -2802,42 +2792,42 @@ void Scene2530::signal() {
*--------------------------------------------------------------------------*/
bool Scene2535::RebreatherTank::startAction(CursorType action, Event &event) {
- Scene2535 *scene = (Scene2535 *)R2_GLOBALS._sceneManager._scene;
-
if (action != CURSOR_USE)
return SceneActor::startAction(action, event);
if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
+ Scene2535 *scene = (Scene2535 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.disableControl();
-
+
scene->_sceneMode = (R2_INVENTORY.getObjectScene(R2_REBREATHER_TANK) == 2535) ? 2536 : 2537;
- scene->setAction(&scene->_sequenceManager, scene, scene->_sceneMode,
+ scene->setAction(&scene->_sequenceManager, scene, scene->_sceneMode,
&R2_GLOBALS._player, &scene->_rebreatherTank, NULL);
} else {
- SceneItem::display(2530, 33, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ SceneItem::display(2530, 33, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, LIST_END);
}
return true;
}
bool Scene2535::TannerMask::startAction(CursorType action, Event &event) {
- Scene2535 *scene = (Scene2535 *)R2_GLOBALS._sceneManager._scene;
-
if (action != CURSOR_USE)
return SceneActor::startAction(action, event);
if (R2_GLOBALS._player._characterIndex == R2_SEEKER) {
+ Scene2535 *scene = (Scene2535 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 2535;
scene->setAction(&scene->_sequenceManager, scene, 2535, &R2_GLOBALS._player, &scene->_tannerMask, NULL);
} else {
- SceneItem::display(2530, 33, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ SceneItem::display(2530, 33, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, LIST_END);
}
return true;
}
-void Scene2535::Exit1::changeScene() {
+void Scene2535::SouthExit::changeScene() {
Scene2535 *scene = (Scene2535 *)R2_GLOBALS._sceneManager._scene;
_enabled = false;
@@ -2856,8 +2846,8 @@ void Scene2535::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS.setFlag(73);
R2_INVENTORY.setObjectScene(R2_REBREATHER_TANK, 2535);
}
- _exit1.setDetails(Rect(172, 155, 250, 167), EXITCURSOR_S, 2000);
- _exit1.setDest(Common::Point(210, 160));
+ _southExit.setDetails(Rect(172, 155, 250, 167), EXITCURSOR_S, 2000);
+ _southExit.setDest(Common::Point(210, 160));
if (R2_INVENTORY.getObjectScene(R2_TANNER_MASK) == 2535) {
_tannerMask.postInit();
@@ -2980,6 +2970,7 @@ void Scene2535::signal() {
* Scene 2600 - Spill Mountains: Exit
*
*--------------------------------------------------------------------------*/
+
Scene2600::Scene2600(): SceneExt() {
_rotation = NULL;
}
@@ -2994,6 +2985,8 @@ void Scene2600::postInit(SceneObjectList *OwnerList) {
loadScene(2600);
R2_GLOBALS._uiElements._active = false;
SceneExt::postInit();
+ R2_GLOBALS._interfaceY = SCREEN_HEIGHT;
+
R2_GLOBALS._sound1.fadeSound(214);
R2_GLOBALS._sound2.play(215);
_rotation = R2_GLOBALS._scenePalette.addRotation(176, 191, 1);
@@ -3008,6 +3001,7 @@ void Scene2600::postInit(SceneObjectList *OwnerList) {
void Scene2600::remove() {
R2_GLOBALS._sound1.fadeOut2(NULL);
R2_GLOBALS._sound2.fadeOut2(NULL);
+ R2_GLOBALS._uiElements._visible = true;
// _rotation->remove();
SceneExt::remove();
}
@@ -3023,7 +3017,7 @@ void Scene2600::signal() {
*--------------------------------------------------------------------------*/
Scene2700::Scene2700(): SceneExt() {
- _field412 = _field414 = _field416 = 0;
+ _areaMode = _moveMode = _stripNumber = 0;
_walkRect1.set(70, 122, 90, 132);
_walkRect2.set(150, 122, 160, 132);
@@ -3036,9 +3030,9 @@ Scene2700::Scene2700(): SceneExt() {
void Scene2700::synchronize(Serializer &s) {
SceneExt::synchronize(s);
- s.syncAsSint16LE(_field412);
- s.syncAsSint16LE(_field414);
- s.syncAsSint16LE(_field416);
+ s.syncAsSint16LE(_areaMode);
+ s.syncAsSint16LE(_moveMode);
+ s.syncAsSint16LE(_stripNumber);
}
void Scene2700::Action1::signal() {
@@ -3069,14 +3063,14 @@ void Scene2700::Action4::signal() {
scene->_ghoulHome9.animate(ANIM_MODE_8, 1, NULL);
}
-void Scene2700::Area1::process(Event &event) {
+void Scene2700::SouthExit::process(Event &event) {
SceneArea::process(event);
if ((event.eventType == EVENT_BUTTON_DOWN) && (R2_GLOBALS._player._canWalk) && (_bounds.contains(event.mousePos))) {
Scene2700 *scene = (Scene2700 *)R2_GLOBALS._sceneManager._scene;
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 10;
- scene->_field414 = 2703;
- switch (scene->_field412) {
+ scene->_moveMode = 2703;
+ switch (scene->_areaMode) {
case 0:
// No break on purpose
case 6:
@@ -3119,14 +3113,14 @@ void Scene2700::Area1::process(Event &event) {
}
}
-void Scene2700::Area2::process(Event &event) {
+void Scene2700::EastExit::process(Event &event) {
SceneArea::process(event);
if ((event.eventType == EVENT_BUTTON_DOWN) && (R2_GLOBALS._player._canWalk) && (_bounds.contains(event.mousePos))) {
Scene2700 *scene = (Scene2700 *)R2_GLOBALS._sceneManager._scene;
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 10;
- scene->_field414 = 2704;
- switch (scene->_field412) {
+ scene->_moveMode = 2704;
+ switch (scene->_areaMode) {
case 0: {
Common::Point pt(140, 162);
NpcMover *mover = new NpcMover();
@@ -3179,8 +3173,8 @@ void Scene2700::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._sound1.stop();
R2_GLOBALS._sound2.stop();
- _area1.setDetails(Rect(135, 160, 185, 168), SHADECURSOR_DOWN);
- _area2.setDetails(Rect(300, 90, 320, 135), EXITCURSOR_E);
+ _southExit.setDetails(Rect(135, 160, 185, 168), SHADECURSOR_DOWN);
+ _eastExit.setDetails(Rect(300, 90, 320, 135), EXITCURSOR_E);
_ghoulHome6.postInit();
_ghoulHome6.setup(2700, 1, 1);
@@ -3225,10 +3219,10 @@ void Scene2700::postInit(SceneObjectList *OwnerList) {
if (R2_GLOBALS._sceneManager._previousScene == 2750) {
_sceneMode = 2702;
- _field412 = 5;
+ _areaMode = 5;
setAction(&_sequenceManager, this, 2702, &R2_GLOBALS._player, NULL);
} else {
- _field412 = 0;
+ _areaMode = 0;
if (R2_GLOBALS._sceneManager._previousScene == 3900) {
_sceneMode = 2701;
setAction(&_sequenceManager, this, 2701, &R2_GLOBALS._player, NULL);
@@ -3243,26 +3237,26 @@ void Scene2700::postInit(SceneObjectList *OwnerList) {
void Scene2700::signal() {
switch (_sceneMode) {
case 10:
- switch (_field414) {
+ switch (_moveMode) {
case 1:
- switch (_field412) {
+ switch (_areaMode) {
case 0:
case 2:
case 4:
case 6:
- _field412 = 3;
+ _areaMode = 3;
R2_GLOBALS._player.setAction(&_sequenceManager, this, 2705, &R2_GLOBALS._player, NULL);
break;
case 3: {
- _sceneMode = _field414;
- _field412 = 1;
+ _sceneMode = _moveMode;
+ _areaMode = 1;
Common::Point pt(80, 127);
NpcMover *mover = new NpcMover();
R2_GLOBALS._player.addMover(mover, &pt, this);
break;
}
case 5:
- _field412 = 4;
+ _areaMode = 4;
R2_GLOBALS._player.setAction(&_sequenceManager, this, 2708, &R2_GLOBALS._player, NULL);
break;
default: // includes case 1
@@ -3270,24 +3264,24 @@ void Scene2700::signal() {
}
break;
case 2:
- switch (_field412) {
+ switch (_areaMode) {
case 0:
case 1:
case 6:
- _field412 = 3;
+ _areaMode = 3;
R2_GLOBALS._player.setAction(&_sequenceManager, this, 2706, &R2_GLOBALS._player, NULL);
break;
case 3:
case 4: {
- _sceneMode = _field414;
- _field412 = 2;
+ _sceneMode = _moveMode;
+ _areaMode = 2;
Common::Point pt(155, 127);
NpcMover *mover = new NpcMover();
R2_GLOBALS._player.addMover(mover, &pt, this);
break;
}
case 5:
- _field412 = 4;
+ _areaMode = 4;
R2_GLOBALS._player.setAction(&_sequenceManager, this, 2708, &R2_GLOBALS._player, NULL);
break;
default: // includes case 2
@@ -3295,21 +3289,21 @@ void Scene2700::signal() {
}
break;
case 3:
- switch (_field412) {
+ switch (_areaMode) {
case 0:
case 1:
case 2:
case 4:
case 6: {
- _sceneMode = _field414;
- _field412 = 3;
+ _sceneMode = _moveMode;
+ _areaMode = 3;
Common::Point pt(115, 152);
NpcMover *mover = new NpcMover();
R2_GLOBALS._player.addMover(mover, &pt, this);
break;
}
case 5:
- _field412 = 4;
+ _areaMode = 4;
R2_GLOBALS._player.setAction(&_sequenceManager, this, 2708, &R2_GLOBALS._player, NULL);
break;
default: // includes case 3
@@ -3317,21 +3311,21 @@ void Scene2700::signal() {
}
break;
case 4:
- switch (_field412) {
+ switch (_areaMode) {
case 0:
case 1:
case 6:
- _field412 = 3;
+ _areaMode = 3;
R2_GLOBALS._player.setAction(&_sequenceManager, this, 2706, &R2_GLOBALS._player, NULL);
break;
case 2:
case 3:
- _field412 = 4;
+ _areaMode = 4;
R2_GLOBALS._player.setAction(&_sequenceManager, this, 2709, &R2_GLOBALS._player, NULL);
break;
case 4:
case 5:
- _sceneMode = _field414;
+ _sceneMode = _moveMode;
R2_GLOBALS._player.setAction(&_sequenceManager, this, 2704, &R2_GLOBALS._player, NULL);
break;
default:
@@ -3339,21 +3333,21 @@ void Scene2700::signal() {
}
break;
case 5:
- switch (_field412) {
+ switch (_areaMode) {
case 0:
case 1:
case 6:
- _field412 = 3;
+ _areaMode = 3;
R2_GLOBALS._player.setAction(&_sequenceManager, this, 2706, &R2_GLOBALS._player, NULL);
break;
case 2:
case 3:
- _field412 = 4;
+ _areaMode = 4;
R2_GLOBALS._player.setAction(&_sequenceManager, this, 2709, &R2_GLOBALS._player, NULL);
break;
case 4: {
- _sceneMode = _field414;
- _field412 = 5;
+ _sceneMode = _moveMode;
+ _areaMode = 5;
Common::Point pt(285, 132);
NpcMover *mover = new NpcMover();
R2_GLOBALS._player.addMover(mover, &pt, this);
@@ -3364,11 +3358,11 @@ void Scene2700::signal() {
}
break;
case 6:
- switch (_field412) {
+ switch (_areaMode) {
case 0:
case 3: {
- _sceneMode = _field414;
- _field412 = 6;
+ _sceneMode = _moveMode;
+ _areaMode = 6;
Common::Point pt(250, 162);
NpcMover *mover = new NpcMover();
R2_GLOBALS._player.addMover(mover, &pt, this);
@@ -3377,11 +3371,11 @@ void Scene2700::signal() {
case 1:
case 2:
case 4:
- _field412 = 3;
+ _areaMode = 3;
R2_GLOBALS._player.setAction(&_sequenceManager, this, 2707, &R2_GLOBALS._player, NULL);
break;
case 5:
- _field412 = 4;
+ _areaMode = 4;
R2_GLOBALS._player.setAction(&_sequenceManager, this, 2708, &R2_GLOBALS._player, NULL);
break;
default:
@@ -3389,21 +3383,21 @@ void Scene2700::signal() {
}
break;
case 2703:
- switch (_field412) {
+ switch (_areaMode) {
case 0:
case 3:
case 6:
- _sceneMode = _field414;
+ _sceneMode = _moveMode;
setAction(&_sequenceManager, this, 2703, &R2_GLOBALS._player, NULL);
break;
case 1:
case 2:
case 4:
- _field412 = 3;
+ _areaMode = 3;
R2_GLOBALS._player.setAction(&_sequenceManager, this, 2707, &R2_GLOBALS._player, NULL);
break;
case 5:
- _field412 = 4;
+ _areaMode = 4;
R2_GLOBALS._player.setAction(&_sequenceManager, this, 2708, &R2_GLOBALS._player, NULL);
break;
default:
@@ -3411,21 +3405,21 @@ void Scene2700::signal() {
}
break;
case 2704:
- switch (_field412) {
+ switch (_areaMode) {
case 0:
case 1:
case 6:
- _field412 = 3;
+ _areaMode = 3;
R2_GLOBALS._player.setAction(&_sequenceManager, this, 2706, &R2_GLOBALS._player, NULL);
break;
case 2:
case 3:
- _field412 = 4;
+ _areaMode = 4;
R2_GLOBALS._player.setAction(&_sequenceManager, this, 2709, &R2_GLOBALS._player, NULL);
break;
case 4:
case 5:
- _sceneMode = _field414;
+ _sceneMode = _moveMode;
R2_GLOBALS._player.setAction(&_sequenceManager, this, 2704, &R2_GLOBALS._player, NULL);
break;
default:
@@ -3433,23 +3427,23 @@ void Scene2700::signal() {
}
break;
case 2710:
- switch (_field412) {
+ switch (_areaMode) {
case 0:
case 1:
case 3:
- _field412 = 3;
+ _areaMode = 3;
R2_GLOBALS._player.setAction(&_sequenceManager, this, 2707, &R2_GLOBALS._player, NULL);
break;
case 2:
case 5: {
- _sceneMode = _field414;
+ _sceneMode = _moveMode;
Common::Point pt(164, 160);
NpcMover *mover = new NpcMover();
R2_GLOBALS._player.addMover(mover, &pt, this);
break;
}
case 4:
- _field412 = 4;
+ _areaMode = 4;
R2_GLOBALS._player.setAction(&_sequenceManager, this, 2708, &R2_GLOBALS._player, NULL);
break;
default:
@@ -3463,7 +3457,7 @@ void Scene2700::signal() {
case 11:
R2_INVENTORY.setObjectScene(R2_FLUTE, 0);
R2_GLOBALS._player.disableControl();
- _field412 = 0;
+ _areaMode = 0;
_sceneMode = 2700;
setAction(&_sequenceManager, this, 2700, &_nej, NULL);
break;
@@ -3471,22 +3465,22 @@ void Scene2700::signal() {
R2_GLOBALS._sound1.play(234);
R2_GLOBALS._events.setCursor(CURSOR_WALK);
_sceneMode = 2711;
- _stripManager.start(_field416, this);
+ _stripManager.start(_stripNumber, this);
break;
case 13:
R2_GLOBALS._events.setCursor(CURSOR_WALK);
_sceneMode = 2712;
- _stripManager.start(_field416, this);
+ _stripManager.start(_stripNumber, this);
break;
case 14:
R2_GLOBALS._events.setCursor(CURSOR_WALK);
_sceneMode = 2713;
- _stripManager.start(_field416, this);
+ _stripManager.start(_stripNumber, this);
break;
case 15:
R2_GLOBALS._events.setCursor(CURSOR_WALK);
_sceneMode = 11;
- _stripManager.start(_field416, this);
+ _stripManager.start(_stripNumber, this);
break;
case 2700:
_nej.remove();
@@ -3500,26 +3494,26 @@ void Scene2700::signal() {
break;
case 2710:
// Start of Nej assault
- _field416 = 1200;
+ _stripNumber = 1200;
_sceneMode = 12;
_nej.postInit();
setAction(&_sequenceManager, this, 2710, &R2_GLOBALS._player, &_nej, NULL);
break;
case 2711:
R2_GLOBALS._player.disableControl();
- _field416 = 1201;
+ _stripNumber = 1201;
_sceneMode = 13;
setAction(&_sequenceManager, this, 2711, &R2_GLOBALS._player, &_nej, NULL);
break;
case 2712:
R2_GLOBALS._player.disableControl();
- _field416 = 1202;
+ _stripNumber = 1202;
_sceneMode = 14;
setAction(&_sequenceManager, this, 2712, &R2_GLOBALS._player, &_nej, NULL);
break;
case 2713:
R2_GLOBALS._player.disableControl();
- _field416 = 1203;
+ _stripNumber = 1203;
_sceneMode = 15;
setAction(&_sequenceManager, this, 2713, &R2_GLOBALS._player, &_nej, NULL);
break;
@@ -3533,11 +3527,11 @@ void Scene2700::process(Event &event) {
if (R2_GLOBALS._events.getCursor() == R2_FLUTE) {
if (R2_GLOBALS._player._bounds.contains(event.mousePos)) {
_sceneMode = 10;
- _field414 = 2710;
+ _moveMode = 2710;
R2_GLOBALS._player.disableControl();
R2_GLOBALS._events.setCursor(CURSOR_WALK);
- switch (_field412) {
+ switch (_areaMode) {
case 0: {
_sceneMode = 2710;
Common::Point pt(164, 160);
@@ -3585,7 +3579,7 @@ void Scene2700::process(Event &event) {
break;
}
} else {
- SceneItem::display(2700, 3, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ SceneItem::display(2700, 3, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, LIST_END);
}
event.handled = true;
@@ -3594,37 +3588,37 @@ void Scene2700::process(Event &event) {
if (!_walkRect1.contains(R2_GLOBALS._player._position)) {
event.handled = true;
_sceneMode = 10;
- _field414 = 1;
+ _moveMode = 1;
}
} else if (_walkRect2.contains(event.mousePos)) {
if (!_walkRect2.contains(R2_GLOBALS._player._position)) {
event.handled = true;
_sceneMode = 10;
- _field414 = 2;
+ _moveMode = 2;
}
} else if (_walkRect3.contains(event.mousePos)) {
if (!_walkRect3.contains(R2_GLOBALS._player._position)) {
event.handled = true;
_sceneMode = 10;
- _field414 = 3;
+ _moveMode = 3;
}
} else if (_walkRect4.contains(event.mousePos)) {
if (!_walkRect4.contains(R2_GLOBALS._player._position)) {
event.handled = true;
_sceneMode = 10;
- _field414 = 4;
+ _moveMode = 4;
}
} else if (_walkRect5.contains(event.mousePos)) {
if (!_walkRect5.contains(R2_GLOBALS._player._position)) {
event.handled = true;
_sceneMode = 10;
- _field414 = 5;
+ _moveMode = 5;
}
} else if (_walkRect6.contains(event.mousePos)) {
if (!_walkRect6.contains(R2_GLOBALS._player._position)) {
event.handled = true;
_sceneMode = 10;
- _field414 = 6;
+ _moveMode = 6;
}
} else {
event.handled = true;
@@ -3632,9 +3626,9 @@ void Scene2700::process(Event &event) {
}
if (_sceneMode == 10) {
R2_GLOBALS._player.disableControl();
- switch (_field412) {
+ switch (_areaMode) {
case 0:
- if (_field414 >= 6) {
+ if (_moveMode >= 6) {
Common::Point pt(205, 162);
NpcMover *mover = new NpcMover();
R2_GLOBALS._player.addMover(mover, &pt, this);
@@ -3657,11 +3651,11 @@ void Scene2700::process(Event &event) {
break;
}
case 3:
- if (_field414 == 1) {
+ if (_moveMode == 1) {
Common::Point pt(80, 137);
NpcMover *mover = new NpcMover();
R2_GLOBALS._player.addMover(mover, &pt, this);
- } else if (_field414 == 6) {
+ } else if (_moveMode == 6) {
Common::Point pt(140, 162);
NpcMover *mover = new NpcMover();
R2_GLOBALS._player.addMover(mover, &pt, this);
@@ -3672,7 +3666,7 @@ void Scene2700::process(Event &event) {
}
break;
case 4:
- if (_field414 == 5) {
+ if (_moveMode == 5) {
Common::Point pt(235, 132);
NpcMover *mover = new NpcMover();
R2_GLOBALS._player.addMover(mover, &pt, this);
@@ -3709,15 +3703,15 @@ void Scene2700::process(Event &event) {
*--------------------------------------------------------------------------*/
Scene2750::Scene2750(): SceneExt() {
- _field412 = _field414 = _field416 = 0;
+ _areaMode = _moveMode = _stripNumber = 0;
}
void Scene2750::synchronize(Serializer &s) {
SceneExt::synchronize(s);
- s.syncAsSint16LE(_field412);
- s.syncAsSint16LE(_field414);
- s.syncAsSint16LE(_field416);
+ s.syncAsSint16LE(_areaMode);
+ s.syncAsSint16LE(_moveMode);
+ s.syncAsSint16LE(_stripNumber);
}
void Scene2750::Action1::signal() {
@@ -3727,20 +3721,20 @@ void Scene2750::Action1::signal() {
case 1:
setDelay(60 + R2_GLOBALS._randomSource.getRandomNumber(240));
_actionIndex = 2;
- scene->_actor5.show();
- scene->_actor5.animate(ANIM_MODE_8, 1, NULL);
+ scene->_bird2.show();
+ scene->_bird2.animate(ANIM_MODE_8, 1, NULL);
break;
case 2:
setDelay(600 + R2_GLOBALS._randomSource.getRandomNumber(600));
_actionIndex = 0;
- scene->_actor5.show();
- scene->_actor3.animate(ANIM_MODE_2, NULL);
+ scene->_bird2.show();
+ scene->_bird1.animate(ANIM_MODE_2, NULL);
break;
default:
setDelay(30);
_actionIndex = 1;
- scene->_actor3.animate(ANIM_MODE_6, NULL);
- scene->_actor4.animate(ANIM_MODE_8, 1, NULL);
+ scene->_bird1.animate(ANIM_MODE_6, NULL);
+ scene->_folliage1.animate(ANIM_MODE_8, 1, NULL);
break;
}
}
@@ -3749,20 +3743,20 @@ void Scene2750::Action2::signal() {
Scene2750 *scene = (Scene2750 *)R2_GLOBALS._sceneManager._scene;
setDelay(600 + R2_GLOBALS._randomSource.getRandomNumber(300));
- scene->_actor6.animate(ANIM_MODE_8, 1, NULL);
+ scene->_folliage2.animate(ANIM_MODE_8, 1, NULL);
}
void Scene2750::Action3::signal() {
Scene2750 *scene = (Scene2750 *)R2_GLOBALS._sceneManager._scene;
- if (scene->_actor7._position.x <= 320) {
+ if (scene->_folliage3._position.x <= 320) {
setDelay(1800 + R2_GLOBALS._randomSource.getRandomNumber(600));
} else {
setDelay(60);
- scene->_actor7.setPosition(Common::Point(-10, 25));
+ scene->_folliage3.setPosition(Common::Point(-10, 25));
Common::Point pt(330, 45);
NpcMover *mover = new NpcMover();
- scene->_actor7.addMover(mover, &pt, NULL);
+ scene->_folliage3.addMover(mover, &pt, NULL);
}
}
@@ -3770,38 +3764,38 @@ void Scene2750::Action4::signal() {
Scene2750 *scene = (Scene2750 *)R2_GLOBALS._sceneManager._scene;
setDelay(600 + R2_GLOBALS._randomSource.getRandomNumber(300));
- scene->_actor8.animate(ANIM_MODE_8, 1, NULL);
+ scene->_folliage4.animate(ANIM_MODE_8, 1, NULL);
}
void Scene2750::Action5::signal() {
Scene2750 *scene = (Scene2750 *)R2_GLOBALS._sceneManager._scene;
setDelay(600 + R2_GLOBALS._randomSource.getRandomNumber(300));
- scene->_actor9.animate(ANIM_MODE_8, 1, NULL);
+ scene->_folliage5.animate(ANIM_MODE_8, 1, NULL);
}
void Scene2750::Action6::signal() {
Scene2750 *scene = (Scene2750 *)R2_GLOBALS._sceneManager._scene;
setDelay(600 + R2_GLOBALS._randomSource.getRandomNumber(300));
- scene->_actor10.animate(ANIM_MODE_8, 1, NULL);
+ scene->_folliage6.animate(ANIM_MODE_8, 1, NULL);
}
void Scene2750::Action7::signal() {
Scene2750 *scene = (Scene2750 *)R2_GLOBALS._sceneManager._scene;
setDelay(600 + R2_GLOBALS._randomSource.getRandomNumber(300));
- scene->_actor11.animate(ANIM_MODE_8, 1, NULL);
+ scene->_folliage7.animate(ANIM_MODE_8, 1, NULL);
}
-void Scene2750::Area1::process(Event &event) {
+void Scene2750::WestExit::process(Event &event) {
SceneArea::process(event);
if ((event.eventType == EVENT_BUTTON_DOWN) && (R2_GLOBALS._player._canWalk) && (_bounds.contains(event.mousePos))) {
Scene2750 *scene = (Scene2750 *)R2_GLOBALS._sceneManager._scene;
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 10;
- scene->_field414 = 2752;
- switch (scene->_field412) {
+ scene->_moveMode = 2752;
+ switch (scene->_areaMode) {
case 1: {
scene->_sceneMode = 2752;
scene->setAction(&scene->_sequenceManager, scene, 2752, &R2_GLOBALS._player, NULL);
@@ -3825,14 +3819,14 @@ void Scene2750::Area1::process(Event &event) {
}
}
-void Scene2750::Area2::process(Event &event) {
+void Scene2750::EastExit::process(Event &event) {
SceneArea::process(event);
if ((event.eventType == EVENT_BUTTON_DOWN) && (R2_GLOBALS._player._canWalk) && (_bounds.contains(event.mousePos))) {
Scene2750 *scene = (Scene2750 *)R2_GLOBALS._sceneManager._scene;
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 10;
- scene->_field414 = 2753;
- switch (scene->_field412) {
+ scene->_moveMode = 2753;
+ switch (scene->_areaMode) {
case 1: {
Common::Point pt(140, 142);
NpcMover *mover = new NpcMover();
@@ -3860,76 +3854,76 @@ void Scene2750::postInit(SceneObjectList *OwnerList) {
loadScene(2750);
R2_GLOBALS._sound2.stop();
SceneExt::postInit();
- _area1.setDetails(Rect(0, 90, 20, 135), EXITCURSOR_W);
- _area2.setDetails(Rect(300, 90, 320, 135), EXITCURSOR_E);
+ _westExit.setDetails(Rect(0, 90, 20, 135), EXITCURSOR_W);
+ _eastExit.setDetails(Rect(300, 90, 320, 135), EXITCURSOR_E);
- _rect1.set(30, 127, 155, 147);
- _rect2.set(130, 142, 210, 167);
- _rect3.set(-1, 137, 290, 147);
+ _walkRect1.set(30, 127, 155, 147);
+ _walkRect2.set(130, 142, 210, 167);
+ _walkRect3.set(-1, 137, 290, 147);
if (R2_INVENTORY.getObjectScene(R2_FLUTE) == 0) {
R2_GLOBALS._sound1.changeSound(235);
- _actor2.postInit();
- _actor2.setup(2751, 1, 1);
- _actor2.setPosition(Common::Point(104, 158));
- _actor2.animate(ANIM_MODE_2, NULL);
- }
-
- _actor3.postInit();
- _actor3.setup(2750, 1, 1);
- _actor3.setPosition(Common::Point(188, 34));
- _actor3.animate(ANIM_MODE_2, NULL);
- _actor3._numFrames = 16;
-
- _actor4.postInit();
- _actor4.setup(2700, 4, 1);
- _actor4.setPosition(Common::Point(188, 37));
- _actor4.fixPriority(26);
-
- _actor5.postInit();
- _actor5.setup(2750, 2, 1);
- _actor5.setPosition(Common::Point(188, 34));
- _actor5.hide();
-
- _actor3.setAction(&_action1);
-
- _actor6.postInit();
- _actor6.setup(2750, 3, 1);
- _actor6.setPosition(Common::Point(9, 167));
- _actor6.fixPriority(252);
- _actor6.setAction(&_action2);
-
- _actor7.postInit();
- _actor7.setup(2750, 4, 1);
- _actor7.setPosition(Common::Point(-10, 25));
- _actor7.animate(ANIM_MODE_1, NULL);
- _actor7.setStrip2(4);
- _actor7._moveRate = 20;
- _actor7.setAction(&_action3);
-
- _actor8.postInit();
- _actor8.fixPriority(26);
- _actor8.setup(2750, 5, 1);
- _actor8.setPosition(Common::Point(258, 33));
- _actor8.setAction(&_action4);
-
- _actor9.postInit();
- _actor9.fixPriority(26);
- _actor9.setup(2750, 6, 1);
- _actor9.setPosition(Common::Point(61, 38));
- _actor9.setAction(&_action5);
-
- _actor10.postInit();
- _actor10.fixPriority(26);
- _actor10.setup(2750, 7, 1);
- _actor10.setPosition(Common::Point(69, 37));
- _actor10.setAction(&_action6);
-
- _actor11.postInit();
- _actor11.fixPriority(26);
- _actor11.setup(2750, 8, 1);
- _actor11.setPosition(Common::Point(80, 35));
- _actor11.setAction(&_action7);
+ _fire.postInit();
+ _fire.setup(2751, 1, 1);
+ _fire.setPosition(Common::Point(104, 158));
+ _fire.animate(ANIM_MODE_2, NULL);
+ }
+
+ _bird1.postInit();
+ _bird1.setup(2750, 1, 1);
+ _bird1.setPosition(Common::Point(188, 34));
+ _bird1.animate(ANIM_MODE_2, NULL);
+ _bird1._numFrames = 16;
+
+ _folliage1.postInit();
+ _folliage1.setup(2700, 4, 1);
+ _folliage1.setPosition(Common::Point(188, 37));
+ _folliage1.fixPriority(26);
+
+ _bird2.postInit();
+ _bird2.setup(2750, 2, 1);
+ _bird2.setPosition(Common::Point(188, 34));
+ _bird2.hide();
+
+ _bird1.setAction(&_action1);
+
+ _folliage2.postInit();
+ _folliage2.setup(2750, 3, 1);
+ _folliage2.setPosition(Common::Point(9, 167));
+ _folliage2.fixPriority(252);
+ _folliage2.setAction(&_action2);
+
+ _folliage3.postInit();
+ _folliage3.setup(2750, 4, 1);
+ _folliage3.setPosition(Common::Point(-10, 25));
+ _folliage3.animate(ANIM_MODE_1, NULL);
+ _folliage3.setStrip2(4);
+ _folliage3._moveRate = 20;
+ _folliage3.setAction(&_action3);
+
+ _folliage4.postInit();
+ _folliage4.fixPriority(26);
+ _folliage4.setup(2750, 5, 1);
+ _folliage4.setPosition(Common::Point(258, 33));
+ _folliage4.setAction(&_action4);
+
+ _folliage5.postInit();
+ _folliage5.fixPriority(26);
+ _folliage5.setup(2750, 6, 1);
+ _folliage5.setPosition(Common::Point(61, 38));
+ _folliage5.setAction(&_action5);
+
+ _folliage6.postInit();
+ _folliage6.fixPriority(26);
+ _folliage6.setup(2750, 7, 1);
+ _folliage6.setPosition(Common::Point(69, 37));
+ _folliage6.setAction(&_action6);
+
+ _folliage7.postInit();
+ _folliage7.fixPriority(26);
+ _folliage7.setup(2750, 8, 1);
+ _folliage7.setPosition(Common::Point(80, 35));
+ _folliage7.setAction(&_action7);
_ghoulHome1.setDetails(Rect(29, 50, 35, 56), 2750, 3, -1, 5, 1, NULL);
_ghoulHome2.setDetails(Rect(47, 36, 54, 42), 2750, 3, -1, 5, 1, NULL);
@@ -3961,42 +3955,44 @@ void Scene2750::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player.setStrip(6);
R2_GLOBALS._player.animate(ANIM_MODE_NONE, NULL);
R2_GLOBALS._player.setPosition(Common::Point(81, 165));
- R2_GLOBALS._events.setCursor(CURSOR_WALK);
- _field416 = 1204;
+
+ R2_GLOBALS._events.setCursor(CURSOR_ARROW);
+ _stripNumber = 1204;
_sceneMode = 11;
- _stripManager.start(_field416, this);
+ _stripManager.start(_stripNumber, this);
} else {
_sceneMode = 2750;
- _field412 = 1;
+ _areaMode = 1;
R2_GLOBALS._player.setAction(&_sequenceManager, this, 2750, &R2_GLOBALS._player, NULL);
}
} else if (R2_GLOBALS._sceneManager._previousScene == 2800) {
_sceneMode = 2751;
- _field412 = 3;
+ _areaMode = 3;
R2_GLOBALS._player.setAction(&_sequenceManager, this, 2751, &R2_GLOBALS._player, NULL);
} else {
- _field412 = 1;
+ _areaMode = 1;
R2_GLOBALS._player.setPosition(Common::Point(90, 137));
R2_GLOBALS._player.setStrip(3);
R2_GLOBALS._player.enableControl();
}
}
+
void Scene2750::signal() {
switch (_sceneMode) {
case 10:
- switch (_field414) {
+ switch (_moveMode) {
case 1:
- switch (_field412) {
+ switch (_areaMode) {
case 2: {
- _sceneMode = _field414;
- _field412 = 1;
+ _sceneMode = _moveMode;
+ _areaMode = 1;
Common::Point pt(90, 137);
NpcMover *mover = new NpcMover();
R2_GLOBALS._player.addMover(mover, &pt, this);
}
break;
case 3: {
- _field412 = 2;
+ _areaMode = 2;
Common::Point pt(140, 142);
NpcMover *mover = new NpcMover();
R2_GLOBALS._player.addMover(mover, &pt, this);
@@ -4007,25 +4003,25 @@ void Scene2750::signal() {
}
break;
case 2: {
- _sceneMode = _field414;
- _field412 = 2;
+ _sceneMode = _moveMode;
+ _areaMode = 2;
Common::Point pt(170, 162);
NpcMover *mover = new NpcMover();
R2_GLOBALS._player.addMover(mover, &pt, this);
}
break;
case 3:
- switch (_field412) {
+ switch (_areaMode) {
case 1: {
- _field412 = 2;
+ _areaMode = 2;
Common::Point pt(210, 142);
NpcMover *mover = new NpcMover();
R2_GLOBALS._player.addMover(mover, &pt, this);
}
break;
case 2: {
- _sceneMode = _field414;
- _field412 = 3;
+ _sceneMode = _moveMode;
+ _areaMode = 3;
Common::Point pt(270, 142);
NpcMover *mover = new NpcMover();
R2_GLOBALS._player.addMover(mover, &pt, this);
@@ -4036,20 +4032,20 @@ void Scene2750::signal() {
}
break;
case 2752:
- switch (_field412) {
+ switch (_areaMode) {
case 1:
- _sceneMode = _field414;
+ _sceneMode = _moveMode;
setAction(&_sequenceManager, this, 2752, &R2_GLOBALS._player, NULL);
break;
case 2: {
- _field412 = 1;
+ _areaMode = 1;
Common::Point pt(20, 132);
NpcMover *mover = new NpcMover();
R2_GLOBALS._player.addMover(mover, &pt, this);
}
break;
case 3: {
- _field412 = 2;
+ _areaMode = 2;
Common::Point pt(140, 142);
NpcMover *mover = new NpcMover();
R2_GLOBALS._player.addMover(mover, &pt, this);
@@ -4060,23 +4056,23 @@ void Scene2750::signal() {
}
break;
case 2753:
- switch (_field412) {
+ switch (_areaMode) {
case 1: {
- _field412 = 2;
+ _areaMode = 2;
Common::Point pt(210, 142);
NpcMover *mover = new NpcMover();
R2_GLOBALS._player.addMover(mover, &pt, this);
}
break;
case 2: {
- _field412 = 3;
+ _areaMode = 3;
Common::Point pt(300, 132);
NpcMover *mover = new NpcMover();
R2_GLOBALS._player.addMover(mover, &pt, this);
}
break;
case 3:
- _sceneMode = _field414;
+ _sceneMode = _moveMode;
setAction(&_sequenceManager, this, 2753, &R2_GLOBALS._player, NULL);
break;
default:
@@ -4102,24 +4098,25 @@ void Scene2750::signal() {
}
void Scene2750::process(Event &event) {
- if ((R2_GLOBALS._player._canWalk) && (event.eventType == EVENT_BUTTON_DOWN) && (R2_GLOBALS._events.getCursor() == R2_NEGATOR_GUN)) {
- if (_rect1.contains(event.mousePos)) {
- if (!_rect1.contains(R2_GLOBALS._player._position)) {
+ if ((R2_GLOBALS._player._canWalk) && (event.eventType == EVENT_BUTTON_DOWN)
+ && (R2_GLOBALS._events.getCursor() == R2_NEGATOR_GUN)) {
+ if (_walkRect1.contains(event.mousePos)) {
+ if (!_walkRect1.contains(R2_GLOBALS._player._position)) {
event.handled = true;
_sceneMode = 10;
- _field414 = 1;
+ _moveMode = 1;
}
- } else if (_rect2.contains(event.mousePos)) {
- if (!_rect2.contains(R2_GLOBALS._player._position)) {
+ } else if (_walkRect2.contains(event.mousePos)) {
+ if (!_walkRect2.contains(R2_GLOBALS._player._position)) {
event.handled = true;
_sceneMode = 10;
- _field414 = 2;
+ _moveMode = 2;
}
- } else if (_rect3.contains(event.mousePos)) {
- if (!_rect3.contains(R2_GLOBALS._player._position)) {
+ } else if (_walkRect3.contains(event.mousePos)) {
+ if (!_walkRect3.contains(R2_GLOBALS._player._position)) {
event.handled = true;
_sceneMode = 10;
- _field414 = 3;
+ _moveMode = 3;
}
} else {
event.handled = true;
@@ -4128,7 +4125,7 @@ void Scene2750::process(Event &event) {
if (_sceneMode == 10) {
R2_GLOBALS._player.disableControl();
- switch (_field412) {
+ switch (_areaMode) {
case 1: {
Common::Point pt(140, 142);
NpcMover *mover = new NpcMover();
@@ -4136,7 +4133,7 @@ void Scene2750::process(Event &event) {
}
break;
case 2:
- if (_field414 == 1) {
+ if (_moveMode == 1) {
Common::Point pt(140, 142);
NpcMover *mover = new NpcMover();
R2_GLOBALS._player.addMover(mover, &pt, this);
@@ -4166,19 +4163,19 @@ void Scene2750::process(Event &event) {
*--------------------------------------------------------------------------*/
Scene2800::Scene2800(): SceneExt() {
- _field412 = 0;
+ _stripNumber = 0;
}
void Scene2800::synchronize(Serializer &s) {
SceneExt::synchronize(s);
- s.syncAsSint16LE(_field412);
+ s.syncAsSint16LE(_stripNumber);
}
bool Scene2800::Outpost::startAction(CursorType action, Event &event) {
- Scene2800 *scene = (Scene2800 *)R2_GLOBALS._sceneManager._scene;
-
if ((action == CURSOR_USE) && (R2_GLOBALS.getFlag(47))) {
+ Scene2800 *scene = (Scene2800 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 2805;
scene->setAction(&scene->_sequenceManager, scene, 2805, &R2_GLOBALS._player, NULL);
@@ -4194,16 +4191,16 @@ bool Scene2800::Guard::startAction(CursorType action, Event &event) {
R2_GLOBALS._player.disableControl();
R2_GLOBALS._events.setCursor(CURSOR_WALK);
R2_GLOBALS.setFlag(47);
- scene->_field412 = 1205;
+ scene->_stripNumber = 1205;
scene->_sceneMode = 2803;
- scene->_stripManager.start(scene->_field412, scene);
+ scene->_stripManager.start(scene->_stripNumber, scene);
return true;
} else if (action == R2_SONIC_STUNNER) {
R2_GLOBALS._events.setCursor(CURSOR_ARROW);
R2_GLOBALS._player.disableControl();
R2_GLOBALS.setFlag(47);
scene->_sceneMode = 10;
- scene->setAction(&scene->_sequenceManager, scene, 2802, &R2_GLOBALS._player, &scene->_actor2, &scene->_guard, NULL);
+ scene->setAction(&scene->_sequenceManager, scene, 2802, &R2_GLOBALS._player, &scene->_nej, &scene->_guard, NULL);
return true;
} else
return SceneActor::startAction(action, event);
@@ -4216,10 +4213,10 @@ void Scene2800::Action1::signal() {
setDelay(120);
Common::Point pt(330, 25);
NpcMover *mover = new NpcMover();
- scene->_object1.addMover(mover, &pt, NULL);
+ scene->_bird.addMover(mover, &pt, NULL);
} else {
setDelay(1800 + R2_GLOBALS._randomSource.getRandomNumber(600));
- scene->_object1.setPosition(Common::Point(-10, 45));
+ scene->_bird.setPosition(Common::Point(-10, 45));
}
}
@@ -4330,7 +4327,7 @@ void Scene2800::Action2::signal() {
R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
R2_GLOBALS._player.setObjectWrapper(new SceneObjectWrapper());
- Common::Point pt(100, 64);
+ Common::Point pt(64, 100);
NpcMover *mover = new NpcMover();
R2_GLOBALS._player.addMover(mover, &pt, this);
break;
@@ -4360,8 +4357,8 @@ void Scene2800::Action2::signal() {
}
case 13:
R2_GLOBALS._events.setCursor(CURSOR_WALK);
- scene->_field412 = 1207;
- scene->_stripManager.start(scene->_field412, this);
+ scene->_stripNumber = 1207;
+ scene->_stripManager.start(scene->_stripNumber, this);
break;
case 14: {
R2_GLOBALS._player.disableControl();
@@ -4427,20 +4424,20 @@ void Scene2800::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._sound2.stop();
SceneExt::postInit();
- _object1.postInit();
- _object1.setup(2750, 4, 1);
- _object1.setPosition(Common::Point(-10, 25));
- _object1.animate(ANIM_MODE_1, NULL);
- _object1.setStrip2(4);
- _object1._moveRate = 20;
- _object1.setAction(&_action1);
-
- _actor3.postInit();
- _actor3.setup(2802, 1, 1);
- _actor3.setPosition(Common::Point(116, 80));
- _actor3.fixPriority(111);
- _actor3.animate(ANIM_MODE_2, NULL);
- _actor3._numFrames = 6;
+ _bird.postInit();
+ _bird.setup(2750, 4, 1);
+ _bird.setPosition(Common::Point(-10, 25));
+ _bird.animate(ANIM_MODE_1, NULL);
+ _bird.setStrip2(4);
+ _bird._moveRate = 20;
+ _bird.setAction(&_action1);
+
+ _lightBar.postInit();
+ _lightBar.setup(2802, 1, 1);
+ _lightBar.setPosition(Common::Point(116, 80));
+ _lightBar.fixPriority(111);
+ _lightBar.animate(ANIM_MODE_2, NULL);
+ _lightBar._numFrames = 6;
if (!R2_GLOBALS.getFlag(47)) {
_guard.postInit();
@@ -4454,7 +4451,7 @@ void Scene2800::postInit(SceneObjectList *OwnerList) {
_guard.setDetails(2800, -1, -1, -1, 1, (SceneItem *)NULL);
}
- _item1.setDetails(Rect(0, 0, 320, 200), 2800, -1, -1, -1, 1, NULL);
+ _background.setDetails(Rect(0, 0, 320, 200), 2800, -1, -1, -1, 1, NULL);
_stripManager.setColors(60, 255);
_stripManager.setFontNumber(3);
@@ -4467,12 +4464,12 @@ void Scene2800::postInit(SceneObjectList *OwnerList) {
if (R2_GLOBALS.getFlag(47)) {
_outpost.setDetails(Rect(76, 45, 155, 90), 2800, 3, -1, -1, 2, NULL);
} else {
- _actor2.postInit();
- _actor2.setup(2752, 5, 1);
- _actor2.animate(ANIM_MODE_NONE, NULL);
- _actor2.changeZoom(100);
- _actor2._moveDiff = Common::Point(2, 1);
- _actor2.setPosition(Common::Point(101, 148));
+ _nej.postInit();
+ _nej.setup(2752, 5, 1);
+ _nej.animate(ANIM_MODE_NONE, NULL);
+ _nej.changeZoom(100);
+ _nej._moveDiff = Common::Point(2, 1);
+ _nej.setPosition(Common::Point(101, 148));
}
}
@@ -4494,7 +4491,8 @@ void Scene2800::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player.enableControl();
} else {
_sceneMode = 2801;
- R2_GLOBALS._player.setAction(&_sequenceManager, this, 2801, &R2_GLOBALS._player, &_actor2, &_guard, NULL);
+ R2_GLOBALS._player.setAction(&_sequenceManager, this, 2801, &R2_GLOBALS._player,
+ &_nej, &_guard, NULL);
}
}
@@ -4503,13 +4501,13 @@ void Scene2800::signal() {
case 10:
R2_GLOBALS._sound1.play(238);
R2_GLOBALS._events.setCursor(CURSOR_WALK);
- _field412 = 1206;
+ _stripNumber = 1206;
_sceneMode = 2804;
- _stripManager.start(_field412, this);
+ _stripManager.start(_stripNumber, this);
break;
case 11:
- _actor2.remove();
- _object1.setAction(NULL);
+ _nej.remove();
+ _bird.setAction(NULL);
R2_GLOBALS._player.enableControl(CURSOR_WALK);
R2_GLOBALS._player._moveDiff = Common::Point(3, 2);
_outpost.setDetails(Rect(76, 45, 155, 90), 2800, 3, -1, -1, 2, NULL);
@@ -4529,15 +4527,15 @@ void Scene2800::signal() {
case 2803:
R2_GLOBALS._player.disableControl();
_sceneMode = 10;
- setAction(&_sequenceManager, this, 2803, &R2_GLOBALS._player, &_actor2, &_guard, NULL);
+ setAction(&_sequenceManager, this, 2803, &R2_GLOBALS._player, &_nej, &_guard, NULL);
break;
case 2804:
R2_GLOBALS._player.disableControl();
_sceneMode = 11;
- setAction(&_sequenceManager, this, 2804, &R2_GLOBALS._player, &_actor2, NULL);
+ setAction(&_sequenceManager, this, 2804, &R2_GLOBALS._player, &_nej, NULL);
break;
case 2805:
- _object1.remove();
+ _bird.remove();
setAction(&_action2);
break;
default:
@@ -4612,8 +4610,8 @@ bool Scene2900::KnobLeft::startAction(CursorType action, Event &event) {
switch (action) {
case CURSOR_USE:
- if (scene->_field416 || scene->_altitudeChanging ||
- scene->_field425 != scene->_field426) {
+ if (scene->_majorMinorFlag || scene->_altitudeChanging ||
+ scene->_xAmount != scene->_xComparison) {
// Let your altitude stablize first
SceneItem::display2(2900, 17);
} else if (R2_GLOBALS._balloonAltitude / 48 == 0) {
@@ -4624,7 +4622,7 @@ bool Scene2900::KnobLeft::startAction(CursorType action, Event &event) {
R2_GLOBALS._sound2.fadeSound(282);
scene->_altitudeChanging = true;
scene->_altitudeMajorChange = -1;
- scene->_field426 = 100 - ((R2_GLOBALS._balloonAltitude / 48) - 1) * 25;
+ scene->_xComparison = 100 - ((R2_GLOBALS._balloonAltitude / 48) - 1) * 25;
}
break;
@@ -4645,12 +4643,12 @@ bool Scene2900::KnobLeft::startAction(CursorType action, Event &event) {
}
bool Scene2900::KnobRight::startAction(CursorType action, Event &event) {
- Scene2900 *scene = (Scene2900 *)R2_GLOBALS._sceneManager._scene;
-
switch (action) {
- case CURSOR_USE:
- if (scene->_field416 || scene->_altitudeChanging ||
- scene->_field425 != scene->_field426) {
+ case CURSOR_USE: {
+ Scene2900 *scene = (Scene2900 *)R2_GLOBALS._sceneManager._scene;
+
+ if (scene->_majorMinorFlag || scene->_altitudeChanging ||
+ scene->_xAmount != scene->_xComparison) {
// Let your altitude stablize first
SceneItem::display2(2900, 17);
} else if (R2_GLOBALS._balloonAltitude / 48 >= 3) {
@@ -4661,9 +4659,10 @@ bool Scene2900::KnobRight::startAction(CursorType action, Event &event) {
R2_GLOBALS._sound2.fadeSound(212);
scene->_altitudeChanging = true;
scene->_altitudeMajorChange = 1;
- scene->_field426 = 100 - ((R2_GLOBALS._balloonAltitude / 48) + 1) * 25;
+ scene->_xComparison = 100 - ((R2_GLOBALS._balloonAltitude / 48) + 1) * 25;
}
break;
+ }
case CURSOR_LOOK:
SceneItem::display2(2900, 12);
@@ -4682,9 +4681,9 @@ bool Scene2900::KnobRight::startAction(CursorType action, Event &event) {
}
bool Scene2900::Skip::startAction(CursorType action, Event &event) {
- Scene2900 *scene = (Scene2900 *)R2_GLOBALS._sceneManager._scene;
-
if (action == CURSOR_USE) {
+ Scene2900 *scene = (Scene2900 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 12;
scene->signal();
@@ -4699,22 +4698,22 @@ void Scene2900::Action1::signal() {
Scene2900 *scene = (Scene2900 *)R2_GLOBALS._sceneManager._scene;
setDelay(3);
- if (!scene->_field416 && !scene->_altitudeChanging) {
- scene->_field427 = 2;
- scene->_field412 = 0;
- } else if (scene->_field416) {
+ if (!scene->_majorMinorFlag && !scene->_altitudeChanging) {
+ scene->_fadeCounter = 2;
+ scene->_controlsActiveChanging = false;
+ } else if (scene->_majorMinorFlag) {
R2_GLOBALS._sound2.fadeOut2(NULL);
- } else if (scene->_field427 == 0) {
+ } else if (scene->_fadeCounter == 0) {
R2_GLOBALS._sound2.fadeOut2(NULL);
- } else if (scene->_field412 == 0) {
+ } else if (!scene->_controlsActiveChanging) {
scene->_knobLeftContent.hide();
scene->_knobRightContent.hide();
- scene->_field412 = 1;
+ scene->_controlsActiveChanging = true;
} else {
- --scene->_field427;
+ --scene->_fadeCounter;
scene->_knobLeftContent.show();
scene->_knobRightContent.show();
- scene->_field412 = 0;
+ scene->_controlsActiveChanging = false;
}
}
@@ -4722,10 +4721,6 @@ void Scene2900::Action1::signal() {
Scene2900::Map::Map() {
_mapWidth = _mapHeight = 0;
- _field4 = 0;
- _field6 = 0;
- _field8 = 0;
- _fieldA = 0;
_resNum = 0;
_xV = _yV = 0;
_bounds = Rect(40, 0, 280, 150);
@@ -4847,7 +4842,7 @@ int Scene2900::Map::adjustRect(Common::Rect &r1, const Common::Rect &r2) {
return -1;
}
-void Scene2900::Map::drawBlock(const byte *data, int xp, int yp,
+void Scene2900::Map::drawBlock(const byte *data, int xp, int yp,
const Rect &bounds, const Rect &updateRect) {
Rect blockRect(xp, yp, xp + 160, yp + 100);
const byte *src = data;
@@ -4931,48 +4926,48 @@ void Scene2900::Map::moveLine(int xpSrc, int ypSrc, int xpDest, int ypDest, int
/*------------------------------------------------------------------------*/
Scene2900::Scene2900(): SceneExt() {
- _field412 = 0;
+ _controlsActiveChanging = false;
_altitudeChanging = false;
- _field416 = false;
+ _majorMinorFlag = false;
_balloonLocation = Common::Point(550, 550);
- _field41C = 0;
+ _altitudeMinorChange = 0;
_altitudeMajorChange = 0;
_balloonScreenPos = Common::Point(160, 100);
_newAltitude = 0;
- _field425 = 100;
- _field426 = 100;
- _field427 = 0;
- _field8F8 = false;
+ _xAmount = 100;
+ _xComparison = 100;
+ _fadeCounter = 0;
+ _paletteReloadNeeded = false;
}
void Scene2900::synchronize(Serializer &s) {
SceneExt::synchronize(s);
- s.syncAsSint16LE(_field412);
+ s.syncAsSint16LE(_controlsActiveChanging);
s.syncAsSint16LE(_altitudeChanging);
- s.syncAsSint16LE(_field416);
- s.syncAsSint16LE(_field41C);
+ s.syncAsSint16LE(_majorMinorFlag);
+ s.syncAsSint16LE(_altitudeMinorChange);
s.syncAsSint16LE(_altitudeMajorChange);
s.syncAsSint16LE(_balloonLocation.x);
s.syncAsSint16LE(_balloonLocation.y);
s.syncAsSint16LE(_balloonScreenPos.x);
s.syncAsSint16LE(_balloonScreenPos.y);
s.syncAsSint16LE(_newAltitude);
- s.syncAsSint16LE(_field425);
- s.syncAsSint16LE(_field426);
- s.syncAsSint16LE(_field427);
- s.syncAsSint16LE(_field8F8);
+ s.syncAsSint16LE(_xAmount);
+ s.syncAsSint16LE(_xComparison);
+ s.syncAsSint16LE(_fadeCounter);
+ s.syncAsSint16LE(_paletteReloadNeeded);
_map.synchronize(s);
}
void Scene2900::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._uiElements._active = false;
- // TODO: Determine correct colours
+ // TODO: Determine correct colors
R2_GLOBALS._gfxColors.foreground = 228;
R2_GLOBALS._fontColors.background = 12;
R2_GLOBALS._fontColors.foreground = 22;
-
+
_map.load(2950);
loadScene(2900);
@@ -4982,7 +4977,7 @@ void Scene2900::postInit(SceneObjectList *OwnerList) {
_leftEdge.setup(2900, 6, 1, 22, 0, 25);
_rightEdge.setup(2900, 6, 1, 280, 0, 25);
_knob.setup(2900, 1, 3, 228, 199, 25);
-
+
_altimeterContent.postInit();
_altimeterContent.setVisage(2900);
_altimeterContent.setStrip(2);
@@ -4995,7 +4990,7 @@ void Scene2900::postInit(SceneObjectList *OwnerList) {
_knobLeftContent.setFrame(1);
_knobLeftContent.setPosition(Common::Point(209, 199));
_knobLeftContent.fixPriority(200);
-
+
_knobRightContent.postInit();
_knobRightContent.setVisage(2900);
_knobRightContent.setStrip(1);
@@ -5028,7 +5023,7 @@ void Scene2900::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player._moveDiff = Common::Point(2, 2);
R2_GLOBALS._player.disableControl();
- if (R2_GLOBALS._sceneManager._previousScene == 2350 &&
+ if (R2_GLOBALS._sceneManager._previousScene == 2350 &&
R2_GLOBALS._balloonPosition.x == 0 && R2_GLOBALS._balloonPosition.y == 0) {
R2_GLOBALS._balloonAltitude = 5;
_map.setPosition(Common::Point(_balloonLocation.x - 120, _balloonLocation.y - 100));
@@ -5047,7 +5042,7 @@ void Scene2900::postInit(SceneObjectList *OwnerList) {
_balloonLocation.x -= 70;
else if ((R2_GLOBALS._balloonAltitude % 8) == 7)
_balloonLocation.x += 70;
-
+
if (_balloonLocation.x <= 120)
_balloonScreenPos.x = _balloonLocation.x + 40;
else if (_balloonLocation.x >= 680)
@@ -5058,23 +5053,23 @@ void Scene2900::postInit(SceneObjectList *OwnerList) {
if (_balloonLocation.y <= 100)
_balloonScreenPos.y = _balloonLocation.y;
- _field425 = _field426 = 100 - (R2_GLOBALS._balloonAltitude / 48) * 25;
+ _xAmount = _xComparison = 100 - (R2_GLOBALS._balloonAltitude / 48) * 25;
_map.setPosition(Common::Point(_balloonLocation.x - 120, _balloonLocation.y - 100));
_sceneMode = 11;
- R2_GLOBALS._player.changeZoom(_field425);
+ R2_GLOBALS._player.changeZoom(_xAmount);
R2_GLOBALS._player.setPosition(_balloonScreenPos);
R2_GLOBALS._player.enableControl();
R2_GLOBALS._player._canWalk = false;
- _altimeterContent.setPosition(Common::Point(109 - _field425, 189));
+ _altimeterContent.setPosition(Common::Point(109 - _xAmount, 189));
}
R2_GLOBALS._sound1.play(211);
}
void Scene2900::remove() {
- // TODO: Figure out correct colours
+ // TODO: Figure out correct colors
R2_GLOBALS._gfxColors.foreground = 59;
R2_GLOBALS._fontColors.background = 4;
R2_GLOBALS._fontColors.foreground = 15;
@@ -5084,7 +5079,7 @@ void Scene2900::remove() {
R2_GLOBALS._sound1.fadeOut2(NULL);
R2_GLOBALS._sound2.stop();
-
+
R2_GLOBALS._interfaceY = UI_INTERFACE_Y;
SceneExt::remove();
}
@@ -5108,51 +5103,51 @@ void Scene2900::dispatch() {
if (_sceneMode == 11) {
_balloonLocation.x += balloonData[R2_GLOBALS._balloonAltitude].x;
_balloonLocation.y += balloonData[R2_GLOBALS._balloonAltitude].y;
- _field41C = balloonData[R2_GLOBALS._balloonAltitude].v3;
+ _altitudeMinorChange = balloonData[R2_GLOBALS._balloonAltitude].v3;
- if (_field41C == 0) {
- _field416 = false;
+ if (_altitudeMinorChange == 0) {
+ _majorMinorFlag = false;
} else {
- _field416 = true;
+ _majorMinorFlag = true;
_altitudeChanging = false;
- _field426 = 100 - ((R2_GLOBALS._balloonAltitude / 48) + _field41C) * 25;
+ _xComparison = 100 - ((R2_GLOBALS._balloonAltitude / 48) + _altitudeMinorChange) * 25;
}
// Zooming/altitude balloon change
- if (_field425 == _field426) {
- _field416 = false;
+ if (_xAmount == _xComparison) {
+ _majorMinorFlag = false;
} else {
- if (!_field416) {
- _field425 = _field425 - _altitudeMajorChange;
+ if (!_majorMinorFlag) {
+ _xAmount = _xAmount - _altitudeMajorChange;
} else {
- _field425 = _field425 - _field41C;
+ _xAmount = _xAmount - _altitudeMinorChange;
}
- if (_field41C == -1 || _altitudeMajorChange == -1) {
+ if (_altitudeMinorChange == -1 || _altitudeMajorChange == -1) {
if (_altimeterContent._frame == 1) {
_altimeterContent.setFrame2(10);
} else {
_altimeterContent.setFrame2(_altimeterContent._frame - 1);
}
- } else if (_field41C == -1 || _altitudeMajorChange == 1) {
+ } else if (_altitudeMinorChange == -1 || _altitudeMajorChange == 1) {
if (_altimeterContent._frame == 10)
_altimeterContent.setFrame2(1);
else
_altimeterContent.setFrame2(_altimeterContent._frame + 1);
}
- _altimeterContent.setPosition(Common::Point(109 - _field425, 189));
- R2_GLOBALS._player.changeZoom(_field425);
+ _altimeterContent.setPosition(Common::Point(109 - _xAmount, 189));
+ R2_GLOBALS._player.changeZoom(_xAmount);
}
- if (!_field8F8) {
+ if (!_paletteReloadNeeded) {
R2_GLOBALS._scenePalette.loadPalette(2950);
R2_GLOBALS._scenePalette.refresh();
}
R2_GLOBALS._balloonPosition = _map.setPosition(
- Common::Point(_balloonLocation.x - 120, _balloonLocation.y - 100), !_field8F8);
- _field8F8 = true;
+ Common::Point(_balloonLocation.x - 120, _balloonLocation.y - 100), !_paletteReloadNeeded);
+ _paletteReloadNeeded = true;
if (_balloonLocation.x <= 120)
_balloonScreenPos.x = _balloonLocation.x + 40;
@@ -5164,7 +5159,7 @@ void Scene2900::dispatch() {
R2_GLOBALS._player.setPosition(_balloonScreenPos);
- if ((_balloonLocation.x % 100) == 50 && (_balloonLocation.y % 100) == 50 && !_field416) {
+ if ((_balloonLocation.x % 100) == 50 && (_balloonLocation.y % 100) == 50 && !_majorMinorFlag) {
// At an altitude change point, so calculate new altitude
_newAltitude = R2_GLOBALS._balloonAltitude;
if (_altitudeChanging) {
diff --git a/engines/tsage/ringworld2/ringworld2_scenes2.h b/engines/tsage/ringworld2/ringworld2_scenes2.h
index f90126b5a1..3960d93f94 100644
--- a/engines/tsage/ringworld2/ringworld2_scenes2.h
+++ b/engines/tsage/ringworld2/ringworld2_scenes2.h
@@ -69,9 +69,9 @@ public:
bool _exitingFlag;
int _mazePlayerMode;
- NamedHotspot _item1;
- SceneActor _object1;
- SceneActor _objList1[11];
+ NamedHotspot _background;
+ SceneActor _companion;
+ SceneActor _persons[11];
WestExit _westExit;
EastExit _eastExit;
SouthExit _southExit;
@@ -92,10 +92,10 @@ public:
};
class Scene2350 : public SceneExt {
- class Actor2 : public SceneActor {
+ class Companion : public SceneActor {
virtual bool startAction(CursorType action, Event &event);
};
- class Actor3 : public SceneActor {
+ class Balloon : public SceneActor {
virtual bool startAction(CursorType action, Event &event);
};
@@ -106,14 +106,13 @@ class Scene2350 : public SceneExt {
virtual void changeScene();
};
public:
-
SpeakerQuinn _quinnSpeaker;
SpeakerPharisha _pharishaSpeaker;
- NamedHotspot _item1;
- SceneActor _actor1;
- Actor2 _actor2;
- Actor3 _actor3;
- Actor3 _actor4;
+ NamedHotspot _background;
+ SceneActor _person;
+ Companion _companion;
+ Balloon _balloon;
+ Balloon _harness;
ExitUp _exitUp;
ExitWest _exitWest;
SequenceManager _sequenceManager;
@@ -121,19 +120,18 @@ public:
virtual void postInit(SceneObjectList *OwnerList = NULL);
virtual void remove();
virtual void signal();
- virtual void process(Event &event);
};
class Scene2400 : public SceneExt {
- class Exit1 : public SceneExit {
+ class WestExit : public SceneExit {
virtual void changeScene();
};
- class Exit2 : public SceneExit {
+ class EastExit : public SceneExit {
virtual void changeScene();
};
public:
- Exit1 _exit1;
- Exit2 _exit2;
+ WestExit _westExit;
+ EastExit _eastExit;
SequenceManager _sequenceManager;
virtual void postInit(SceneObjectList *OwnerList = NULL);
@@ -153,7 +151,7 @@ class Scene2425 : public SceneExt {
public:
virtual bool startAction(CursorType action, Event &event);
};
- class Item4 : public NamedHotspot {
+ class Background : public NamedHotspot {
public:
virtual bool startAction(CursorType action, Event &event);
};
@@ -167,7 +165,7 @@ class Scene2425 : public SceneExt {
bool startAction(CursorType action, Event &event);
};
- class Exit1 : public SceneExit {
+ class SouthEastExit : public SceneExit {
public:
virtual void changeScene();
};
@@ -175,11 +173,11 @@ public:
RopeDest1 _ropeDest1;
RopeDest2 _ropeDest2;
Crevasse _crevasse;
- Item4 _item4;
+ Background _background;
Rope _rope;
Pictographs _pictographs1;
Pictographs _pictographs2;
- Exit1 _exit1;
+ SouthEastExit _southEastExit;
SequenceManager _sequenceManager;
virtual void postInit(SceneObjectList *OwnerList = NULL);
@@ -188,7 +186,7 @@ public:
};
class Scene2430 : public SceneExt {
- class Actor1 : public SceneActor {
+ class Companion : public SceneActor {
public:
bool startAction(CursorType action, Event &event);
};
@@ -201,28 +199,28 @@ class Scene2430 : public SceneExt {
bool startAction(CursorType action, Event &event);
};
- class Exit1 : public SceneExit {
+ class SouthExit : public SceneExit {
public:
virtual void changeScene();
};
public:
- NamedHotspot _item1;
- NamedHotspot _item2;
- NamedHotspot _item3;
- NamedHotspot _item4;
- NamedHotspot _item5;
- NamedHotspot _item6;
- NamedHotspot _item7;
- NamedHotspot _item8;
- NamedHotspot _item9;
- NamedHotspot _item10;
- NamedHotspot _item11;
- NamedHotspot _item12;
- NamedHotspot _item13;
- Actor1 _actor1;
+ NamedHotspot _background;
+ NamedHotspot _bottles2;
+ NamedHotspot _furnishings;
+ NamedHotspot _rug1;
+ NamedHotspot _mirror;
+ NamedHotspot _garments;
+ NamedHotspot _bed;
+ NamedHotspot _towel;
+ NamedHotspot _bottles1;
+ NamedHotspot _post;
+ NamedHotspot _clothesPile1;
+ NamedHotspot _clothesPile2;
+ NamedHotspot _rug2;
+ Companion _companion;
GunPowder _gunPowder;
OilLamp _oilLamp;
- Exit1 _exit1;
+ SouthExit _southExit;
SequenceManager _sequenceManager;
virtual void postInit(SceneObjectList *OwnerList = NULL);
@@ -239,7 +237,7 @@ class Scene2435 : public SceneExt {
bool startAction(CursorType action, Event &event);
};
- class Exit1 : public SceneExit {
+ class SouthExit : public SceneExit {
public:
virtual void changeScene();
};
@@ -252,7 +250,7 @@ public:
NamedHotspot _rightWindow;
Companion _companion;
Astor _astor;
- Exit1 _exit1;
+ SouthExit _southExit;
SequenceManager _sequenceManager;
virtual void postInit(SceneObjectList *OwnerList = NULL);
@@ -261,7 +259,7 @@ public:
};
class Scene2440 : public SceneExt {
- class Actor1 : public SceneActor {
+ class Companion : public SceneActor {
public:
bool startAction(CursorType action, Event &event);
};
@@ -270,21 +268,21 @@ class Scene2440 : public SceneExt {
bool startAction(CursorType action, Event &event);
};
- class Exit1 : public SceneExit {
+ class SouthEastExit : public SceneExit {
public:
virtual void changeScene();
};
public:
- NamedHotspot _item1;
- NamedHotspot _item2;
- NamedHotspot _item3;
- NamedHotspot _item4;
- NamedHotspot _item5;
- NamedHotspot _item6;
- NamedHotspot _item7;
- Actor1 _actor1;
+ NamedHotspot _background;
+ NamedHotspot _garments;
+ NamedHotspot _bedspread;
+ NamedHotspot _post;
+ NamedHotspot _rug;
+ NamedHotspot _furnishings;
+ NamedHotspot _bottles;
+ Companion _companion;
OilLamp _oilLamp;
- Exit1 _exit1;
+ SouthEastExit _southEastExit;
SequenceManager _sequenceManager;
virtual void postInit(SceneObjectList *OwnerList = NULL);
@@ -310,7 +308,7 @@ class Scene2450 : public SceneExt {
bool startAction(CursorType action, Event &event);
};
- class Exit1 : public SceneExit {
+ class SouthWestExit : public SceneExit {
public:
virtual void changeScene();
};
@@ -324,7 +322,7 @@ public:
SceneActor _companion;
Parker _parker;
CareTaker _careTaker;
- Exit1 _exit1;
+ SouthWestExit _southWestExit;
SequenceManager _sequenceManager;
virtual void postInit(SceneObjectList *OwnerList = NULL);
@@ -346,7 +344,7 @@ class Scene2455 : public SceneExt {
bool startAction(CursorType action, Event &event);
};
- class Exit1 : public SceneExit {
+ class NorthExit : public SceneExit {
public:
virtual void changeScene();
};
@@ -355,7 +353,7 @@ public:
Lamp _lamp;
Pool _pool;
ScrithKey _scrithKey;
- Exit1 _exit1;
+ NorthExit _northExit;
SequenceManager _sequenceManager;
virtual void postInit(SceneObjectList *OwnerList = NULL);
@@ -364,7 +362,7 @@ public:
};
class Scene2500 : public SceneExt {
- class Exit1 : public SceneExit {
+ class WestExit : public SceneExit {
public:
virtual void changeScene();
};
@@ -373,11 +371,11 @@ public:
SpeakerSeeker _seekerSpeaker;
SpeakerMiranda _mirandaSpeaker;
SpeakerWebbster2500 _webbsterSpeaker;
- NamedHotspot _item1;
- SceneActor _actor1;
- SceneActor _actor2;
- SceneActor _actor3;
- Exit1 _exit1;
+ NamedHotspot _background;
+ SceneActor _companion;
+ SceneActor _quinn;
+ SceneActor _ship;
+ WestExit _westExit;
SequenceManager _sequenceManager;
virtual void postInit(SceneObjectList *OwnerList = NULL);
@@ -385,7 +383,7 @@ public:
};
class Scene2525 : public SceneExt {
- class Item5 : public NamedHotspot {
+ class StopCock : public NamedHotspot {
public:
virtual bool startAction(CursorType action, Event &event);
};
@@ -395,20 +393,20 @@ class Scene2525 : public SceneExt {
bool startAction(CursorType action, Event &event);
};
- class Exit1 : public SceneExit {
+ class SouthExit : public SceneExit {
public:
virtual void changeScene();
};
public:
- NamedHotspot _item1;
- NamedHotspot _item2;
- NamedHotspot _item3;
- NamedHotspot _item4;
- Item5 _item5;
- SceneActor _actor1;
- SceneActor _actor2;
+ NamedHotspot _background;
+ NamedHotspot _machine;
+ NamedHotspot _pipes1;
+ NamedHotspot _pipes2;
+ StopCock _stopcock;
+ SceneActor _companion;
+ SceneActor _compressor;
GlassDome _glassDome;
- Exit1 _exit1;
+ SouthExit _southExit;
SequenceManager _sequenceManager;
virtual void postInit(SceneObjectList *OwnerList = NULL);
@@ -426,20 +424,20 @@ class Scene2530 : public SceneExt {
bool startAction(CursorType action, Event &event);
};
- class Exit1 : public SceneExit {
+ class SouthExit : public SceneExit {
public:
virtual void changeScene();
};
public:
NamedHotspot _background;
- NamedHotspot _item2;
+ NamedHotspot _crank2;
NamedHotspot _shelf;
NamedHotspot _item4;
- NamedHotspot _item5;
- SceneActor _actor1;
+ NamedHotspot _rope;
+ SceneActor _companion;
Flask _flask;
Crank _crank;
- Exit1 _exit1;
+ SouthExit _southExit;
SequenceManager _sequenceManager;
virtual void postInit(SceneObjectList *OwnerList = NULL);
@@ -456,7 +454,7 @@ class Scene2535 : public SceneExt {
bool startAction(CursorType action, Event &event);
};
- class Exit1 : public SceneExit {
+ class SouthExit : public SceneExit {
public:
virtual void changeScene();
};
@@ -472,7 +470,7 @@ public:
SceneActor _rope;
RebreatherTank _rebreatherTank;
TannerMask _tannerMask;
- Exit1 _exit1;
+ SouthExit _southExit;
SequenceManager _sequenceManager;
virtual void postInit(SceneObjectList *OwnerList = NULL);
@@ -509,11 +507,11 @@ class Scene2700 : public SceneExt {
void signal();
};
- class Area1: public SceneArea {
+ class SouthExit: public SceneArea {
public:
void process(Event &event);
};
- class Area2: public SceneArea {
+ class EastExit: public SceneArea {
public:
void process(Event &event);
};
@@ -535,12 +533,12 @@ public:
Action2 _action2;
Action3 _action3;
Action4 _action4;
- Area1 _area1;
- Area2 _area2;
+ SouthExit _southExit;
+ EastExit _eastExit;
Rect _walkRect1, _walkRect2, _walkRect3;
Rect _walkRect4, _walkRect5, _walkRect6;
SequenceManager _sequenceManager;
- int _field412, _field414, _field416;
+ int _areaMode, _moveMode, _stripNumber;
Scene2700();
virtual void synchronize(Serializer &s);
@@ -579,11 +577,11 @@ class Scene2750 : public SceneExt {
void signal();
};
- class Area1: public SceneArea {
+ class WestExit: public SceneArea {
public:
void process(Event &event);
};
- class Area2: public SceneArea {
+ class EastExit: public SceneArea {
public:
void process(Event &event);
};
@@ -596,16 +594,16 @@ public:
NamedHotspot _ghoulHome3;
NamedHotspot _ghoulHome4;
SceneActor _nej;
- SceneActor _actor2;
- SceneActor _actor3;
- SceneActor _actor4;
- SceneActor _actor5;
- SceneActor _actor6;
- SceneActor _actor7;
- SceneActor _actor8;
- SceneActor _actor9;
- SceneActor _actor10;
- SceneActor _actor11;
+ SceneActor _fire;
+ SceneActor _bird1;
+ SceneActor _folliage1;
+ SceneActor _bird2;
+ SceneActor _folliage2;
+ SceneActor _folliage3;
+ SceneActor _folliage4;
+ SceneActor _folliage5;
+ SceneActor _folliage6;
+ SceneActor _folliage7;
Action1 _action1;
Action2 _action2;
Action3 _action3;
@@ -613,11 +611,11 @@ public:
Action5 _action5;
Action6 _action6;
Action7 _action7;
- Area1 _area1;
- Area2 _area2;
- Rect _rect1, _rect2, _rect3;
+ WestExit _westExit;
+ EastExit _eastExit;
+ Rect _walkRect1, _walkRect2, _walkRect3;
SequenceManager _sequenceManager;
- int _field412, _field414, _field416;
+ int _areaMode, _moveMode, _stripNumber;
Scene2750();
virtual void synchronize(Serializer &s);
@@ -651,16 +649,16 @@ public:
SpeakerQuinn2800 _quinnSpeaker;
SpeakerNej2800 _nejSpeaker;
SpeakerGuard2800 _guardSpeaker;
- NamedHotspot _item1;
+ NamedHotspot _background;
Outpost _outpost;
Guard _guard;
- SceneActor _actor2;
- SceneActor _actor3;
- SceneObject _object1;
+ SceneActor _nej;
+ SceneActor _lightBar;
+ SceneObject _bird;
Action1 _action1;
Action2 _action2;
SequenceManager _sequenceManager;
- int _field412;
+ int _stripNumber;
Scene2800();
virtual void synchronize(Serializer &s);
@@ -710,10 +708,6 @@ class Scene2900 : public SceneExt {
void drawBlock(const byte *data, int xp, int yp, const Rect &r1, const Rect &r2);
public:
int _mapWidth, _mapHeight;
- int _field4;
- int _field6;
- int _field8;
- int _fieldA;
int _resNum;
int _xV, _yV;
Rect _bounds;
@@ -741,18 +735,18 @@ public:
Map _map;
SceneText _skipText;
- int _field412;
+ bool _controlsActiveChanging;
bool _altitudeChanging;
- bool _field416;
- int _field41C;
+ bool _majorMinorFlag;
+ int _altitudeMinorChange;
int _altitudeMajorChange;
Common::Point _balloonLocation;
Common::Point _balloonScreenPos;
int _newAltitude;
- int _field425;
- int _field426;
- int _field427;
- bool _field8F8;
+ int _xAmount;
+ int _xComparison;
+ int _fadeCounter;
+ bool _paletteReloadNeeded;
Scene2900();
virtual void synchronize(Serializer &s);
diff --git a/engines/tsage/ringworld2/ringworld2_scenes3.cpp b/engines/tsage/ringworld2/ringworld2_scenes3.cpp
index 6898ede304..e55ae8ff70 100644
--- a/engines/tsage/ringworld2/ringworld2_scenes3.cpp
+++ b/engines/tsage/ringworld2/ringworld2_scenes3.cpp
@@ -35,13 +35,13 @@ namespace Ringworld2 {
*--------------------------------------------------------------------------*/
Scene3100::Scene3100() {
- _field412 = 0;
+ _fadeSound = false;
}
void Scene3100::synchronize(Serializer &s) {
SceneExt::synchronize(s);
- s.syncAsSint16LE(_field412);
+ s.syncAsSint16LE(_fadeSound);
}
bool Scene3100::Guard::startAction(CursorType action, Event &event) {
@@ -84,20 +84,21 @@ void Scene3100::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player._characterIndex = R2_QUINN;
R2_GLOBALS._player.disableControl();
- _actor1.postInit();
- _item2.setDetails(Rect(212, 97, 320, 114), 3100, 3, -1, -1, 1, NULL);
- _item1.setDetails(Rect(0, 0, 480, 200), 3100, 0, -1, -1, 1, NULL);
- _field412 = 0;
+ _hammerHead.postInit();
+ _hammerHead2.setDetails(Rect(212, 97, 320, 114), 3100, 3, -1, -1, 1, NULL);
+ _background.setDetails(Rect(0, 0, 480, 200), 3100, 0, -1, -1, 1, NULL);
+ _fadeSound = false;
if (R2_GLOBALS._sceneManager._previousScene == 1000) {
if (R2_GLOBALS._player._oldCharacterScene[R2_QUINN] == 3100) {
_sceneMode = 3102;
- _actor3.postInit();
- _actor4.postInit();
- _actor5.postInit();
+ _ghoul.postInit();
+ _technicians.postInit();
+ _deadBodies.postInit();
R2_GLOBALS._sound1.play(274);
_sound1.fadeSound(130);
- setAction(&_sequenceManager, this, 3102, &_actor1, &R2_GLOBALS._player, &_actor3, &_actor4, &_actor5, NULL);
+ setAction(&_sequenceManager, this, 3102, &_hammerHead, &R2_GLOBALS._player,
+ &_ghoul, &_technicians, &_deadBodies, NULL);
} else {
_guard.postInit();
_guard.setup(3110, 5, 1);
@@ -105,27 +106,28 @@ void Scene3100::postInit(SceneObjectList *OwnerList) {
_guard.setPosition(Common::Point(10, 149));
_guard.setDetails(3100, 6, -1, -1, 2, (SceneItem *)NULL);
- _actor4.postInit();
- _actor4.setup(3103, 1, 1);
- _actor4.setPosition(Common::Point(278, 113));
- _actor4.setDetails(3100, 9, -1, -1, 2, (SceneItem *)NULL);
- _actor4.animate(ANIM_MODE_2, NULL);
+ _technicians.postInit();
+ _technicians.setup(3103, 1, 1);
+ _technicians.setPosition(Common::Point(278, 113));
+ _technicians.setDetails(3100, 9, -1, -1, 2, (SceneItem *)NULL);
+ _technicians.animate(ANIM_MODE_2, NULL);
- _field412 = 1;
- _actor1.setDetails(3100, 3, -1, -1, 2, (SceneItem *)NULL);
+ _fadeSound = true;
+ _hammerHead.setDetails(3100, 3, -1, -1, 2, (SceneItem *)NULL);
R2_GLOBALS._sound1.play(243);
R2_GLOBALS._sound2.play(130);
_sceneMode = 3100;
- setAction(&_sequenceManager, this, 3100, &R2_GLOBALS._player, &_actor1, NULL);
+ setAction(&_sequenceManager, this, 3100, &R2_GLOBALS._player, &_hammerHead, NULL);
}
} else if (R2_GLOBALS._sceneManager._previousScene == 3255) {
_sceneMode = 3101;
- _actor2.postInit();
- _actor3.postInit();
- _field412 = 1;
+ _miranda.postInit();
+ _ghoul.postInit();
+ _fadeSound = true;
- setAction(&_sequenceManager, this, 3101, &R2_GLOBALS._player, &_actor1, &_actor2, &_actor3, NULL);
+ setAction(&_sequenceManager, this, 3101, &R2_GLOBALS._player, &_hammerHead,
+ &_miranda, &_ghoul, NULL);
} else {
_guard.postInit();
_guard.setup(3110, 5, 1);
@@ -133,16 +135,16 @@ void Scene3100::postInit(SceneObjectList *OwnerList) {
_guard.setPosition(Common::Point(10, 149));
_guard.setDetails(3100, 6, -1, -1, 2, (SceneItem *)NULL);
- _actor4.postInit();
- _actor4.setup(3103, 1, 1);
- _actor4.setPosition(Common::Point(278, 113));
- _actor4.setDetails(3100, 9, -1, -1, 2, (SceneItem *)NULL);
- _actor4.animate(ANIM_MODE_2, NULL);
+ _technicians.postInit();
+ _technicians.setup(3103, 1, 1);
+ _technicians.setPosition(Common::Point(278, 113));
+ _technicians.setDetails(3100, 9, -1, -1, 2, (SceneItem *)NULL);
+ _technicians.animate(ANIM_MODE_2, NULL);
- _actor1.postInit();
- _actor1.setup(3104, 4, 1);
- _actor1.setPosition(Common::Point(143, 104));
- _actor1.setDetails(3100, 3, -1, -1, 2, (SceneItem *)NULL);
+ _hammerHead.postInit();
+ _hammerHead.setup(3104, 4, 1);
+ _hammerHead.setPosition(Common::Point(143, 104));
+ _hammerHead.setDetails(3100, 3, -1, -1, 2, (SceneItem *)NULL);
R2_GLOBALS._player.setup(3110, 3, 1);
R2_GLOBALS._player.changeZoom(50);
@@ -189,13 +191,13 @@ void Scene3100::signal() {
}
void Scene3100::dispatch() {
- if ((_sceneMode == 3100) && (_field412 != 0) && (R2_GLOBALS._player._position.y == 104)) {
- _field412 = 0;
+ if ((_sceneMode == 3100) && _fadeSound && (R2_GLOBALS._player._position.y == 104)) {
+ _fadeSound = false;
R2_GLOBALS._sound2.fadeOut2(NULL);
}
- if ((_sceneMode == 3101) && (_field412 != 0) && (R2_GLOBALS._player._position.y < 104)) {
- _field412 = 0;
+ if ((_sceneMode == 3101) && _fadeSound && (R2_GLOBALS._player._position.y < 104)) {
+ _fadeSound = false;
_sound1.fadeSound(130);
}
@@ -208,33 +210,33 @@ void Scene3100::dispatch() {
*--------------------------------------------------------------------------*/
Scene3125::Scene3125() {
- _field412 = 0;
+ _soundPlayed = false;
}
void Scene3125::synchronize(Serializer &s) {
SceneExt::synchronize(s);
- s.syncAsSint16LE(_field412);
+ s.syncAsSint16LE(_soundPlayed);
}
bool Scene3125::Background::startAction(CursorType action, Event &event) {
- Scene3125 *scene = (Scene3125 *)R2_GLOBALS._sceneManager._scene;
-
switch (action) {
case CURSOR_USE:
if (_useLineNum != -1)
- SceneItem::display(_resNum, _useLineNum, 0, 280, 1, 160, 9, 1, 2, 20, 7, 154, -999);
+ SceneItem::display(_resNum, _useLineNum, 0, 280, 1, 160, 9, 1, 2, 20, 7, 154, LIST_END);
break;
case CURSOR_LOOK:
if (_lookLineNum != -1)
- SceneItem::display(_resNum, _lookLineNum, 0, 280, 1, 160, 9, 1, 2, 20, 7, 154, -999);
+ SceneItem::display(_resNum, _lookLineNum, 0, 280, 1, 160, 9, 1, 2, 20, 7, 154, LIST_END);
break;
case CURSOR_TALK:
if (_talkLineNum != -1)
- SceneItem::display(_resNum, _talkLineNum, 0, 280, 1, 160, 9, 1, 2, 20, 7, 154, -999);
+ SceneItem::display(_resNum, _talkLineNum, 0, 280, 1, 160, 9, 1, 2, 20, 7, 154, LIST_END);
break;
- default:
+ default: {
+ Scene3125 *scene = (Scene3125 *)R2_GLOBALS._sceneManager._scene;
return scene->display(action, event);
+ }
break;
}
@@ -242,19 +244,20 @@ bool Scene3125::Background::startAction(CursorType action, Event &event) {
}
bool Scene3125::Table::startAction(CursorType action, Event &event) {
- Scene3125 *scene = (Scene3125 *)R2_GLOBALS._sceneManager._scene;
-
switch (action) {
- case CURSOR_USE:
+ case CURSOR_USE: {
+ Scene3125 *scene = (Scene3125 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 3125;
- scene->setAction(&scene->_sequenceManager1, scene, 3125, &R2_GLOBALS._player, NULL);
+ scene->setAction(&scene->_sequenceManager, scene, 3125, &R2_GLOBALS._player, NULL);
+ }
break;
case CURSOR_LOOK:
- SceneItem::display(3125, 15, 0, 280, 1, 160, 9, 1, 2, 20, 7, 154, -999);
+ SceneItem::display(3125, 15, 0, 280, 1, 160, 9, 1, 2, 20, 7, 154, LIST_END);
break;
case CURSOR_TALK:
- SceneItem::display(3125, 13, 0, 280, 1, 160, 9, 1, 2, 20, 7, 154, -999);
+ SceneItem::display(3125, 13, 0, 280, 1, 160, 9, 1, 2, 20, 7, 154, LIST_END);
break;
default:
return SceneHotspot::startAction(action, event);
@@ -265,22 +268,23 @@ bool Scene3125::Table::startAction(CursorType action, Event &event) {
}
bool Scene3125::Computer::startAction(CursorType action, Event &event) {
- Scene3125 *scene = (Scene3125 *)R2_GLOBALS._sceneManager._scene;
-
switch (action) {
- case CURSOR_USE:
+ case CURSOR_USE: {
+ Scene3125 *scene = (Scene3125 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.disableControl();
scene->_ghoul4.postInit();
scene->_sceneMode = 3126;
- scene->setAction(&scene->_sequenceManager1, scene, 3126, &R2_GLOBALS._player,
- &scene->_ghoul1, &scene->_ghoul2, &scene->_ghoul3, &scene->_door,
+ scene->setAction(&scene->_sequenceManager, scene, 3126, &R2_GLOBALS._player,
+ &scene->_ghoul1, &scene->_ghoul2, &scene->_ghoul3, &scene->_door,
&scene->_ghoul4, NULL);
+ }
break;
case CURSOR_LOOK:
- SceneItem::display(3125, 9, 0, 280, 1, 160, 9, 1, 2, 20, 7, 154, -999);
+ SceneItem::display(3125, 9, 0, 280, 1, 160, 9, 1, 2, 20, 7, 154, LIST_END);
break;
case CURSOR_TALK:
- SceneItem::display(3125, 13, 0, 280, 1, 160, 9, 1, 2, 20, 7, 154, -999);
+ SceneItem::display(3125, 13, 0, 280, 1, 160, 9, 1, 2, 20, 7, 154, LIST_END);
break;
default:
return SceneHotspot::startAction(action, event);
@@ -291,21 +295,21 @@ bool Scene3125::Computer::startAction(CursorType action, Event &event) {
}
bool Scene3125::Door::startAction(CursorType action, Event &event) {
- Scene3125 *scene = (Scene3125 *)R2_GLOBALS._sceneManager._scene;
-
if (action != CURSOR_USE)
return SceneActor::startAction(action, event);
+ Scene3125 *scene = (Scene3125 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 3176;
- scene->setAction(&scene->_sequenceManager1, scene, 3176, &R2_GLOBALS._player, &scene->_door, NULL);
+ scene->setAction(&scene->_sequenceManager, scene, 3176, &R2_GLOBALS._player, &scene->_door, NULL);
return true;
}
void Scene3125::postInit(SceneObjectList *OwnerList) {
loadScene(3125);
SceneExt::postInit();
- _field412 = 0;
+ _soundPlayed = false;
_door.postInit();
_door.setup(3175, 1, 1);
@@ -336,7 +340,7 @@ void Scene3125::postInit(SceneObjectList *OwnerList) {
if (R2_GLOBALS._player._oldCharacterScene[R2_MIRANDA] == 3250) {
_sceneMode = 3175;
- setAction(&_sequenceManager1, this, 3175, &R2_GLOBALS._player, &_door, NULL);
+ setAction(&_sequenceManager, this, 3175, &R2_GLOBALS._player, &_door, NULL);
} else {
R2_GLOBALS._player.setup(30, 5, 1);
R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
@@ -349,9 +353,9 @@ void Scene3125::postInit(SceneObjectList *OwnerList) {
void Scene3125::signal() {
switch (_sceneMode) {
case 3125:
- SceneItem::display(3125, 3, 0, 280, 1, 160, 9, 1, 2, 20, 7, 154, -999);
+ SceneItem::display(3125, 3, 0, 280, 1, 160, 9, 1, 2, 20, 7, 154, LIST_END);
_sceneMode = 3127;
- setAction(&_sequenceManager1, this, 3127, &R2_GLOBALS._player, NULL);
+ setAction(&_sequenceManager, this, 3127, &R2_GLOBALS._player, NULL);
break;
case 3126:
R2_GLOBALS.setFlag(79);
@@ -366,9 +370,9 @@ void Scene3125::signal() {
}
void Scene3125::dispatch() {
- if ((_sceneMode == 3126) && (_ghoul1._frame == 2) && (_field412 == 0)) {
- _field412 = 1;
+ if ((_sceneMode == 3126) && (_ghoul1._frame == 2) && !_soundPlayed) {
R2_GLOBALS._sound1.play(265);
+ _soundPlayed = true;
}
Scene::dispatch();
}
@@ -394,12 +398,12 @@ bool Scene3150::LightFixture::startAction(CursorType action, Event &event) {
if ((R2_INVENTORY.getObjectScene(R2_LIGHT_BULB) != 3150) && (R2_GLOBALS.getFlag(75))) {
R2_GLOBALS._player.disableControl();
scene->_bulbOrWire.postInit();
- scene->_bulbOrWire._effect = 3;
+ scene->_bulbOrWire._effect = EFFECT_SHADED2;
scene->_bulbOrWire._shade = 5;
scene->_sceneMode = 3155;
scene->setAction(&scene->_sequenceManager, scene, 3155, &R2_GLOBALS._player, &scene->_bulbOrWire, NULL);
} else {
- SceneItem::display(3150, 42, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ SceneItem::display(3150, 42, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, LIST_END);
}
return true;
default:
@@ -415,18 +419,18 @@ bool Scene3150::Toilet::startAction(CursorType action, Event &event) {
case R2_PILLOW:
R2_GLOBALS._player.disableControl();
scene->_water.postInit();
- scene->_water._effect = 6;
+ scene->_water._effect = EFFECT_SHADED2;
scene->_water._shade = 3;
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 3158;
scene->setAction(&scene->_sequenceManager, scene, 3158, &R2_GLOBALS._player, &scene->_water, NULL);
return true;
case R2_FOOD_TRAY:
- if ((R2_INVENTORY.getObjectScene(R2_LIGHT_BULB) != 3150) &&
- (R2_INVENTORY.getObjectScene(R2_SUPERCONDUCTOR_WIRE) == 3150)
+ if ((R2_INVENTORY.getObjectScene(R2_LIGHT_BULB) != 3150) &&
+ (R2_INVENTORY.getObjectScene(R2_SUPERCONDUCTOR_WIRE) == 3150)
&& (R2_GLOBALS.getFlag(75))) {
scene->_foodTray.postInit();
- scene->_foodTray._effect = 6;
+ scene->_foodTray._effect = EFFECT_SHADED2;
scene->_foodTray._shade = 3;
scene->_foodTray.setDetails(3150, 30, -1, -1, 2, (SceneItem *)NULL);
@@ -434,7 +438,7 @@ bool Scene3150::Toilet::startAction(CursorType action, Event &event) {
scene->_sceneMode = 3159;
scene->setAction(&scene->_sequenceManager, scene, 3159, &R2_GLOBALS._player, &scene->_foodTray, NULL);
} else {
- SceneItem::display(3150, 42, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ SceneItem::display(3150, 42, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, LIST_END);
}
return true;
default:
@@ -444,17 +448,18 @@ bool Scene3150::Toilet::startAction(CursorType action, Event &event) {
}
bool Scene3150::Water::startAction(CursorType action, Event &event) {
- Scene3150 *scene = (Scene3150 *)R2_GLOBALS._sceneManager._scene;
-
switch (action) {
- case CURSOR_USE:
+ case CURSOR_USE: {
if (R2_GLOBALS.getFlag(75))
return SceneActor::startAction(action, event);
+ Scene3150 *scene = (Scene3150 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 3151;
scene->setAction(&scene->_sequenceManager, scene, 3151, &R2_GLOBALS._player, &scene->_water, NULL);
return true;
+ }
case R2_FOOD_TRAY:
return false;
default:
@@ -464,21 +469,21 @@ bool Scene3150::Water::startAction(CursorType action, Event &event) {
}
bool Scene3150::FoodTray::startAction(CursorType action, Event &event) {
- Scene3150 *scene = (Scene3150 *)R2_GLOBALS._sceneManager._scene;
-
if ((action != CURSOR_USE) || (R2_GLOBALS.getFlag(77)))
return SceneActor::startAction(action, event);
+ Scene3150 *scene = (Scene3150 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 3157;
scene->setAction(&scene->_sequenceManager, scene, 3157, &R2_GLOBALS._player, &scene->_foodTray, NULL);
return true;
}
-bool Scene3150::Actor6::startAction(CursorType action, Event &event) {
- Scene3150 *scene = (Scene3150 *)R2_GLOBALS._sceneManager._scene;
-
+bool Scene3150::ToiletFlush::startAction(CursorType action, Event &event) {
if (action == CURSOR_USE) {
+ Scene3150 *scene = (Scene3150 *)R2_GLOBALS._sceneManager._scene;
+
if (R2_GLOBALS.getFlag(75)) {
if (R2_GLOBALS.getFlag(77)) {
R2_GLOBALS._player.disableControl();
@@ -487,10 +492,10 @@ bool Scene3150::Actor6::startAction(CursorType action, Event &event) {
scene->setAction(&scene->_sequenceManager, scene, 3152, &R2_GLOBALS._player, NULL);
} else {
scene->_sceneMode = 3153;
- scene->setAction(&scene->_sequenceManager, scene, 3152, &R2_GLOBALS._player, &scene->_water, NULL);
+ scene->setAction(&scene->_sequenceManager, scene, 3153, &R2_GLOBALS._player, &scene->_water, NULL);
}
} else {
- SceneItem::display(3150, 42, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ SceneItem::display(3150, 42, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, LIST_END);
}
} else {
R2_GLOBALS._player.disableControl();
@@ -504,9 +509,9 @@ bool Scene3150::Actor6::startAction(CursorType action, Event &event) {
}
bool Scene3150::AirVent::startAction(CursorType action, Event &event) {
- Scene3150 *scene = (Scene3150 *)R2_GLOBALS._sceneManager._scene;
-
if ((action == R2_LASER_HACKSAW) && (!R2_GLOBALS.getFlag(80))) {
+ Scene3150 *scene = (Scene3150 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 3160;
scene->setAction(&scene->_sequenceManager, scene, 3160, &R2_GLOBALS._player, &scene->_airVent, NULL);
@@ -577,7 +582,7 @@ void Scene3150::postInit(SceneObjectList *OwnerList) {
_guard.postInit();
_guard.setup(3154, 1, 16);
_guard.setPosition(Common::Point(104, 129));
- _guard._effect = 6;
+ _guard._effect = EFFECT_SHADED2;
_guard._shade = 3;
_guard.setDetails(3150, 24, -1, -1, -1, (SceneItem *)NULL);
}
@@ -607,7 +612,7 @@ void Scene3150::postInit(SceneObjectList *OwnerList) {
}
_water.fixPriority(110);
_water.setPosition(Common::Point(83, 88));
- _water._effect = 6;
+ _water._effect = EFFECT_SHADED2;
_water._shade = 3;
} else {
_water.setup(3152, 7, 3);
@@ -624,10 +629,10 @@ void Scene3150::postInit(SceneObjectList *OwnerList) {
if (R2_INVENTORY.getObjectScene(R2_SUPERCONDUCTOR_WIRE) == 3150) {
_bulbOrWire.postInit();
- _bulbOrWire.setup(3152, 7, 3);
+ _bulbOrWire.setup(3152, 7, 2);
_bulbOrWire.setPosition(Common::Point(70, 55));
_bulbOrWire.fixPriority(111);
- _bulbOrWire._effect = 6;
+ _bulbOrWire._effect = EFFECT_SHADED2;
_bulbOrWire._shade = 5;
}
@@ -637,7 +642,7 @@ void Scene3150::postInit(SceneObjectList *OwnerList) {
_foodTray.setup(3152, 7, 8);
_foodTray.setPosition(Common::Point(82, 92));
_foodTray.fixPriority(111);
- _foodTray._effect = 6;
+ _foodTray._effect = EFFECT_SHADED2;
_foodTray._shade = 3;
} else {
_foodTray.setup(3152, 7, 7);
@@ -662,7 +667,7 @@ void Scene3150::postInit(SceneObjectList *OwnerList) {
case 0:
_sceneMode = 3150;
_guard.postInit();
- _guard._effect = 6;
+ _guard._effect = EFFECT_SHADED2;
_guard._shade = 5;
setAction(&_sequenceManager, this, 3150, &R2_GLOBALS._player, &_guard, &_doorBars, NULL);
break;
@@ -683,22 +688,24 @@ void Scene3150::postInit(SceneObjectList *OwnerList) {
break;
}
default:
- if ((R2_GLOBALS._v56AA0 == 1) && (R2_INVENTORY.getObjectScene(R2_ANCIENT_SCROLLS) == 2000) && (R2_GLOBALS._player._oldCharacterScene[R2_QUINN] == 3100)) {
- ++R2_GLOBALS._v56AA0;
+ if ((R2_GLOBALS._mirandaJailState == 1) && (R2_INVENTORY.getObjectScene(R2_ANCIENT_SCROLLS) == 2000)
+ && (R2_GLOBALS._player._oldCharacterScene[R2_QUINN] == 3100)) {
+ // Moving story on to Miranda getting food delivered
+ ++R2_GLOBALS._mirandaJailState;
_sceneMode = 3156;
_guard.postInit();
- _guard._effect = 6;
+ _guard._effect = EFFECT_SHADED2;
_guard._shade = 3;
_doorBars.postInit();
_foodTray.postInit();
- _foodTray._effect = 6;
+ _foodTray._effect = EFFECT_SHADED2;
_foodTray._shade = 3;
setAction(&_sequenceManager, this, 3156, &R2_GLOBALS._player, &_guard, &_doorBars, &_foodTray, NULL);
} else {
- if (R2_GLOBALS._v56AA0 != 2)
- ++R2_GLOBALS._v56AA0;
+ if ((R2_GLOBALS._mirandaJailState != 1) && (R2_GLOBALS._mirandaJailState != 2))
+ ++R2_GLOBALS._mirandaJailState;
R2_GLOBALS._player.setup(30, 3, 1);
R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
@@ -787,12 +794,12 @@ void Scene3150::signal() {
void Scene3150::dispatch() {
if (_foodTray._position.x == 155) {
- _foodTray._effect = 0;
+ _foodTray._effect = EFFECT_NONE;
_foodTray._shade = 0;
}
if (_guard._visage == 3154) {
- _guard._effect = 0;
+ _guard._effect = EFFECT_NONE;
_guard._shade = 0;
}
@@ -804,25 +811,23 @@ void Scene3150::dispatch() {
*
*--------------------------------------------------------------------------*/
-bool Scene3175::Item1::startAction(CursorType action, Event &event) {
- Scene3175 *scene = (Scene3175 *)R2_GLOBALS._sceneManager._scene;
-
+bool Scene3175::RoomItem::startAction(CursorType action, Event &event) {
switch (action) {
case CURSOR_USE:
if (_useLineNum != -1) {
- SceneItem::display(_resNum, _useLineNum, 0, 280, 1, 160, 9, 1, 2, 20, 7, 154, -999);
+ SceneItem::display(_resNum, _useLineNum, 0, 280, 1, 160, 9, 1, 2, 20, 7, 154, LIST_END);
return true;
}
break;
case CURSOR_LOOK:
if (_lookLineNum != -1) {
- SceneItem::display(_resNum, _lookLineNum, 0, 280, 1, 160, 9, 1, 2, 20, 7, 154, -999);
+ SceneItem::display(_resNum, _lookLineNum, 0, 280, 1, 160, 9, 1, 2, 20, 7, 154, LIST_END);
return true;
}
break;
case CURSOR_TALK:
if (_talkLineNum != -1) {
- SceneItem::display(_resNum, _talkLineNum, 0, 280, 1, 160, 9, 1, 2, 20, 7, 154, -999);
+ SceneItem::display(_resNum, _talkLineNum, 0, 280, 1, 160, 9, 1, 2, 20, 7, 154, LIST_END);
return true;
}
break;
@@ -830,28 +835,27 @@ bool Scene3175::Item1::startAction(CursorType action, Event &event) {
break;
}
+ Scene3175 *scene = (Scene3175 *)R2_GLOBALS._sceneManager._scene;
return scene->display(action, event);
}
bool Scene3175::Corpse::startAction(CursorType action, Event &event) {
- Scene3175 *scene = (Scene3175 *)R2_GLOBALS._sceneManager._scene;
-
switch (action) {
case CURSOR_USE:
if (_useLineNum != -1) {
- SceneItem::display(_resNum, _useLineNum, 0, 280, 1, 160, 9, 1, 2, 20, 7, 154, -999);
+ SceneItem::display(_resNum, _useLineNum, 0, 280, 1, 160, 9, 1, 2, 20, 7, 154, LIST_END);
return true;
}
break;
case CURSOR_LOOK:
if (_lookLineNum != -1) {
- SceneItem::display(_resNum, _lookLineNum, 0, 280, 1, 160, 9, 1, 2, 20, 7, 154, -999);
+ SceneItem::display(_resNum, _lookLineNum, 0, 280, 1, 160, 9, 1, 2, 20, 7, 154, LIST_END);
return true;
}
break;
case CURSOR_TALK:
if (_talkLineNum != -1) {
- SceneItem::display(_resNum, _talkLineNum, 0, 280, 1, 160, 9, 1, 2, 20, 7, 154, -999);
+ SceneItem::display(_resNum, _talkLineNum, 0, 280, 1, 160, 9, 1, 2, 20, 7, 154, LIST_END);
return true;
}
break;
@@ -859,25 +863,27 @@ bool Scene3175::Corpse::startAction(CursorType action, Event &event) {
break;
}
+ Scene3175 *scene = (Scene3175 *)R2_GLOBALS._sceneManager._scene;
return scene->display(action, event);
}
bool Scene3175::Door::startAction(CursorType action, Event &event) {
- Scene3175 *scene = (Scene3175 *)R2_GLOBALS._sceneManager._scene;
-
switch (action) {
- case CURSOR_USE:
+ case CURSOR_USE: {
+ Scene3175 *scene = (Scene3175 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 3176;
scene->setAction(&scene->_sequenceManager, scene, 3176, &R2_GLOBALS._player, &scene->_door, NULL);
return true;
+ }
break;
case CURSOR_LOOK:
- SceneItem::display(3175, 9, 0, 280, 1, 160, 9, 1, 2, 20, 7, 154, -999);
+ SceneItem::display(3175, 9, 0, 280, 1, 160, 9, 1, 2, 20, 7, 154, LIST_END);
return true;
break;
case CURSOR_TALK:
- SceneItem::display(3175, 10, 0, 280, 1, 160, 9, 1, 2, 20, 7, 154, -999);
+ SceneItem::display(3175, 10, 0, 280, 1, 160, 9, 1, 2, 20, 7, 154, LIST_END);
return true;
break;
default:
@@ -895,17 +901,17 @@ void Scene3175::postInit(SceneObjectList *OwnerList) {
_door.setPosition(Common::Point(35, 72));
_door.setDetails(3175, 9, 10, -1, 1, (SceneItem *)NULL);
- _actor2.postInit();
- _actor2.setup(3175, 2, 1);
- _actor2.setPosition(Common::Point(87, 148));
+ _computer.postInit();
+ _computer.setup(3175, 2, 1);
+ _computer.setPosition(Common::Point(87, 148));
_corpse.postInit();
_corpse.setup(3175, 3, 1);
_corpse.setPosition(Common::Point(199, 117));
_corpse.setDetails(3175, 15, 16, 17, 1, (SceneItem *)NULL);
- _item2.setDetails(12, 3175, 3, 1, 5);
- _item3.setDetails(11, 3175, 6, 7, 8);
+ _table.setDetails(12, 3175, 3, 1, 5);
+ _autopsies.setDetails(11, 3175, 6, 7, 8);
_background.setDetails(Rect(0, 0, 320, 200), 3175, 0, 1, 2, 1, NULL);
R2_GLOBALS._player.postInit();
@@ -934,6 +940,7 @@ void Scene3175::signal() {
* Scene 3200 - Cutscene : Guards - Discussion
*
*--------------------------------------------------------------------------*/
+
void Scene3200::postInit(SceneObjectList *OwnerList) {
loadScene(3200);
R2_GLOBALS._uiElements._active = false;
@@ -947,11 +954,12 @@ void Scene3200::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player.hide();
R2_GLOBALS._player.disableControl();
- _actor1.postInit();
- _actor3.postInit();
- _actor2.postInit();
+ _rocko.postInit();
+ _jocko.postInit();
+ _socko.postInit();
- setAction(&_sequenceManager, this, 3200 + R2_GLOBALS._randomSource.getRandomNumber(1), &_actor1, &_actor2, &_actor3, NULL);
+ setAction(&_sequenceManager, this, 3200 + R2_GLOBALS._randomSource.getRandomNumber(1),
+ &_rocko, &_jocko, &_socko, NULL);
}
void Scene3200::signal() {
@@ -962,6 +970,7 @@ void Scene3200::signal() {
* Scene 3210 - Cutscene : Captain and Private - Discussion
*
*--------------------------------------------------------------------------*/
+
void Scene3210::postInit(SceneObjectList *OwnerList) {
loadScene(3210);
R2_GLOBALS._uiElements._active = false;
@@ -974,10 +983,11 @@ void Scene3210::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player.hide();
R2_GLOBALS._player.disableControl();
- _actor1.postInit();
- _actor2.postInit();
+ _captain.postInit();
+ _private.postInit();
- setAction(&_sequenceManager, this, 3210 + R2_GLOBALS._randomSource.getRandomNumber(1), &_actor1, &_actor2, NULL);
+ setAction(&_sequenceManager, this, 3210 + R2_GLOBALS._randomSource.getRandomNumber(1),
+ &_captain, &_private, NULL);
}
void Scene3210::signal() {
@@ -988,6 +998,7 @@ void Scene3210::signal() {
* Scene 3220 - Cutscene : Guards in cargo zone
*
*--------------------------------------------------------------------------*/
+
void Scene3220::postInit(SceneObjectList *OwnerList) {
loadScene(3220);
R2_GLOBALS._uiElements._active = false;
@@ -1000,10 +1011,11 @@ void Scene3220::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player.hide();
R2_GLOBALS._player.disableControl();
- _actor1.postInit();
- _actor2.postInit();
+ _rocko.postInit();
+ _jocko.postInit();
- setAction(&_sequenceManager, this, 3220 + R2_GLOBALS._randomSource.getRandomNumber(1), &_actor1, &_actor2, NULL);
+ setAction(&_sequenceManager, this, 3220 + R2_GLOBALS._randomSource.getRandomNumber(1),
+ &_rocko, &_jocko, NULL);
}
void Scene3220::signal() {
@@ -1014,6 +1026,7 @@ void Scene3220::signal() {
* Scene 3230 - Cutscene : Guards on duty
*
*--------------------------------------------------------------------------*/
+
void Scene3230::postInit(SceneObjectList *OwnerList) {
loadScene(3230);
R2_GLOBALS._uiElements._active = false;
@@ -1026,11 +1039,12 @@ void Scene3230::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player.hide();
R2_GLOBALS._player.disableControl();
- _actor1.postInit();
- _actor2.postInit();
- _actor3.postInit();
+ _rocko.postInit();
+ _jocko.postInit();
+ _ghoul.postInit();
- setAction(&_sequenceManager, this, 3230 + R2_GLOBALS._randomSource.getRandomNumber(1), &_actor1, &_actor2, &_actor3, NULL);
+ setAction(&_sequenceManager, this, 3230 + R2_GLOBALS._randomSource.getRandomNumber(1),
+ &_rocko, &_jocko, &_ghoul, NULL);
}
void Scene3230::signal() {
@@ -1055,10 +1069,11 @@ void Scene3240::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player.hide();
R2_GLOBALS._player.disableControl();
- _actor1.postInit();
- _actor2.postInit();
+ _teal.postInit();
+ _webbster.postInit();
- setAction(&_sequenceManager, this, 3240 + R2_GLOBALS._randomSource.getRandomNumber(1), &_actor1, &_actor2, NULL);
+ setAction(&_sequenceManager, this, 3240 + R2_GLOBALS._randomSource.getRandomNumber(1),
+ &_teal, &_webbster, NULL);
}
void Scene3240::signal() {
@@ -1082,17 +1097,18 @@ void Scene3245::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player.hide();
R2_GLOBALS._player.disableControl();
- _actor1.postInit();
- _actor2.postInit();
+ _ralf.postInit();
+ _tomko.postInit();
if (R2_GLOBALS._scientistConvIndex < 4)
++R2_GLOBALS._scientistConvIndex;
if (R2_GLOBALS._scientistConvIndex >= 4) {
- SceneItem::display(1200, 7, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ SceneItem::display(1200, 7, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, LIST_END);
signal();
} else {
- setAction(&_sequenceManager, this, 3244 + R2_GLOBALS._scientistConvIndex, &_actor1, &_actor2, NULL);
+ setAction(&_sequenceManager, this, 3244 + R2_GLOBALS._scientistConvIndex,
+ &_ralf, &_tomko, NULL);
}
}
@@ -1106,24 +1122,22 @@ void Scene3245::signal() {
*--------------------------------------------------------------------------*/
bool Scene3250::Item::startAction(CursorType action, Event &event) {
- Scene3250 *scene = (Scene3250 *)R2_GLOBALS._sceneManager._scene;
-
switch (action) {
case CURSOR_USE:
if (_useLineNum != -1) {
- SceneItem::display(_resNum, _useLineNum, 0, 280, 1, 160, 9, 1, 2, 20, 7, 154, -999);
+ SceneItem::display(_resNum, _useLineNum, 0, 280, 1, 160, 9, 1, 2, 20, 7, 154, LIST_END);
return true;
}
break;
case CURSOR_LOOK:
if (_lookLineNum != -1) {
- SceneItem::display(_resNum, _lookLineNum, 0, 280, 1, 160, 9, 1, 2, 20, 7, 154, -999);
+ SceneItem::display(_resNum, _lookLineNum, 0, 280, 1, 160, 9, 1, 2, 20, 7, 154, LIST_END);
return true;
}
break;
case CURSOR_TALK:
if (_talkLineNum != -1) {
- SceneItem::display(_resNum, _talkLineNum, 0, 280, 1, 160, 9, 1, 2, 20, 7, 154, -999);
+ SceneItem::display(_resNum, _talkLineNum, 0, 280, 1, 160, 9, 1, 2, 20, 7, 154, LIST_END);
return true;
}
break;
@@ -1131,15 +1145,15 @@ bool Scene3250::Item::startAction(CursorType action, Event &event) {
break;
}
+ Scene3250 *scene = (Scene3250 *)R2_GLOBALS._sceneManager._scene;
return scene->display(action, event);
}
bool Scene3250::Door::startAction(CursorType action, Event &event) {
- Scene3250 *scene = (Scene3250 *)R2_GLOBALS._sceneManager._scene;
-
if (action != CURSOR_USE)
return SceneActor::startAction(action, event);
+ Scene3250 *scene = (Scene3250 *)R2_GLOBALS._sceneManager._scene;
R2_GLOBALS._player.disableControl();
switch(_position.x) {
@@ -1198,20 +1212,20 @@ void Scene3250::postInit(SceneObjectList *OwnerList) {
switch (R2_GLOBALS._player._oldCharacterScene[R2_MIRANDA]) {
case 1200:
_sceneMode = 3250;
- _actor4.postInit();
- R2_GLOBALS._player._effect = 0;
- setAction(&_sequenceManager, this, 3250, &R2_GLOBALS._player, &_actor4, NULL);
+ _grate.postInit();
+ R2_GLOBALS._player._effect = EFFECT_NONE;
+ setAction(&_sequenceManager, this, 3250, &R2_GLOBALS._player, &_grate, NULL);
break;
case 3125:
if (R2_GLOBALS.getFlag(79)) {
_sceneMode = 3254;
_ghoul1.postInit();
- _ghoul1._effect = 1;
+ _ghoul1._effect = EFFECT_SHADED;
_ghoul2.postInit();
- _ghoul2._effect = 1;
+ _ghoul2._effect = EFFECT_SHADED;
_ghoul3.postInit();
- _ghoul3._effect = 1;
- setAction(&_sequenceManager, this, 3254, &R2_GLOBALS._player, &_rightDoor,
+ _ghoul3._effect = EFFECT_SHADED;
+ setAction(&_sequenceManager, this, 3254, &R2_GLOBALS._player, &_rightDoor,
&_ghoul1, &_ghoul2, &_ghoul3, &_leftDoor, NULL);
} else {
_sceneMode = 3252;
@@ -1240,7 +1254,7 @@ void Scene3250::postInit(SceneObjectList *OwnerList) {
void Scene3250::signal() {
switch(_sceneMode) {
case 3250:
- R2_GLOBALS._player._effect = 1;
+ R2_GLOBALS._player._effect = EFFECT_SHADED;
R2_GLOBALS._player.enableControl();
break;
case 3254:
@@ -1262,7 +1276,7 @@ void Scene3250::signal() {
void Scene3250::dispatch() {
if ((R2_GLOBALS._player._visage == 3250) && (R2_GLOBALS._player._strip == 3) && (R2_GLOBALS._player._effect == 0)) {
- R2_GLOBALS._player._effect = 6;
+ R2_GLOBALS._player._effect = EFFECT_SHADED2;
R2_GLOBALS._player._shade = 6;
}
@@ -1291,10 +1305,10 @@ void Scene3255::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._sound1.play(267);
R2_GLOBALS._sound2.play(268);
_sceneMode = 3257;
- _actor3.postInit();
+ _door.postInit();
_quinn.postInit();
- _quinn._effect = 1;
- setAction(&_sequenceManager, this, 3257, &R2_GLOBALS._player, &_quinn, &_actor3, NULL);
+ _quinn._effect = EFFECT_SHADED;
+ setAction(&_sequenceManager, this, 3257, &R2_GLOBALS._player, &_quinn, &_door, NULL);
} else {
_teal.postInit();
_teal.setup(303, 1, 1);
@@ -1315,8 +1329,8 @@ void Scene3255::signal() {
_ghoul1.postInit();
_ghoul2.postInit();
_ghoul3.postInit();
- setAction(&_sequenceManager, this, 3258, &R2_GLOBALS._player, &_quinn,
- &_actor3, &_ghoul1, &_ghoul2, &_ghoul3, NULL);
+ setAction(&_sequenceManager, this, 3258, &R2_GLOBALS._player, &_quinn,
+ &_door, &_ghoul1, &_ghoul2, &_ghoul3, NULL);
break;
case 3256:
R2_GLOBALS._sceneManager.changeScene(3250);
@@ -1330,7 +1344,7 @@ void Scene3255::signal() {
R2_GLOBALS._sceneManager.changeScene(3100);
break;
default:
- SceneItem::display(3255, 0, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ SceneItem::display(3255, 0, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, LIST_END);
_sceneMode = 3256;
setAction(&_sequenceManager, this, 3256, &R2_GLOBALS._player, NULL);
}
@@ -1342,9 +1356,9 @@ void Scene3255::dispatch() {
if (_ghoul1._position.y <= 110)
_ghoul1._shade = 6 - (_ghoul1._position.y - 95) / 3;
else
- _ghoul1._effect = 1;
+ _ghoul1._effect = EFFECT_SHADED;
} else {
- _ghoul1._effect = 6;
+ _ghoul1._effect = EFFECT_SHADED2;
_ghoul1._shade = 6;
}
@@ -1352,9 +1366,9 @@ void Scene3255::dispatch() {
if (_ghoul2._position.y <= 110)
_ghoul2._shade = 6 - (_ghoul2._position.y - 95) / 3;
else
- _ghoul2._effect = 1;
+ _ghoul2._effect = EFFECT_SHADED;
} else {
- _ghoul2._effect = 6;
+ _ghoul2._effect = EFFECT_SHADED2;
_ghoul2._shade = 6;
}
@@ -1362,16 +1376,16 @@ void Scene3255::dispatch() {
if (_ghoul3._position.y <= 110)
_ghoul3._shade = 6 - (_ghoul3._position.y - 95) / 3;
else
- _ghoul3._effect = 1;
+ _ghoul3._effect = EFFECT_SHADED;
} else {
- _ghoul3._effect = 6;
+ _ghoul3._effect = EFFECT_SHADED2;
_ghoul3._shade = 6;
}
}
if ((R2_GLOBALS._player._position.x > 250) && (R2_GLOBALS._player._shade == 1)) {
- R2_GLOBALS._player._effect = 6;
- _quinn._effect = 6;
+ R2_GLOBALS._player._effect = EFFECT_SHADED2;
+ _quinn._effect = EFFECT_SHADED2;
}
Scene::dispatch();
}
@@ -1382,11 +1396,11 @@ void Scene3255::dispatch() {
*--------------------------------------------------------------------------*/
bool Scene3260::Door::startAction(CursorType action, Event &event) {
- Scene3260 *scene = (Scene3260 *)R2_GLOBALS._sceneManager._scene;
-
if (action != CURSOR_USE)
return SceneActor::startAction(action, event);
+ Scene3260 *scene = (Scene3260 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 3271;
scene->setAction(&scene->_sequenceManager, scene, 3271, &R2_GLOBALS._player, &scene->_door, NULL);
@@ -1394,11 +1408,11 @@ bool Scene3260::Door::startAction(CursorType action, Event &event) {
}
bool Scene3260::Toolbox::startAction(CursorType action, Event &event) {
- Scene3260 *scene = (Scene3260 *)R2_GLOBALS._sceneManager._scene;
-
if (action != CURSOR_USE)
return SceneActor::startAction(action, event);
+ Scene3260 *scene = (Scene3260 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 3272;
scene->setAction(&scene->_sequenceManager, scene, 3272, &R2_GLOBALS._player, &scene->_toolbox, NULL);
@@ -1466,23 +1480,23 @@ void Scene3260::postInit(SceneObjectList *OwnerList) {
_screen6.setDetails(3260, 3, 1, 5, 1, (SceneItem *)NULL);
_screen6.setAction(&_action6, &_screen6);
- _actor7.postInit();
- _actor7.setup(3260, 2, 1);
- _actor7.setPosition(Common::Point(190, 22));
- _actor7.setDetails(3260, 3, 1, 5, 1, (SceneItem *)NULL);
- _actor7.setAction(&_action7, &_actor7);
+ _screen7.postInit();
+ _screen7.setup(3260, 2, 1);
+ _screen7.setPosition(Common::Point(190, 22));
+ _screen7.setDetails(3260, 3, 1, 5, 1, (SceneItem *)NULL);
+ _screen7.setAction(&_action7, &_screen7);
- _actor8.postInit();
- _actor8.setup(3260, 2, 1);
- _actor8.setPosition(Common::Point(142, 14));
- _actor8.setDetails(3260, 3, 1, 5, 1, (SceneItem *)NULL);
- _actor8.setAction(&_action8, &_actor8);
+ _screen8.postInit();
+ _screen8.setup(3260, 2, 1);
+ _screen8.setPosition(Common::Point(142, 14));
+ _screen8.setDetails(3260, 3, 1, 5, 1, (SceneItem *)NULL);
+ _screen8.setAction(&_action8, &_screen8);
- _actor9.postInit();
- _actor9.setup(3260, 2, 1);
- _actor9.setPosition(Common::Point(166, 6));
- _actor9.setDetails(3260, 3, 1, 5, 1, (SceneItem *)NULL);
- _actor9.setAction(&_action9, &_actor9);
+ _screen9.postInit();
+ _screen9.setup(3260, 2, 1);
+ _screen9.setPosition(Common::Point(166, 6));
+ _screen9.setDetails(3260, 3, 1, 5, 1, (SceneItem *)NULL);
+ _screen9.setAction(&_action9, &_screen9);
_securityConsole.postInit();
_securityConsole.setup(3260, 3, 1);
@@ -1509,7 +1523,7 @@ void Scene3260::postInit(SceneObjectList *OwnerList) {
_lightingConsole.setDetails(3260, 9, 1, 11, 1, (SceneItem *)NULL);
_lightingConsole.animate(ANIM_MODE_2, NULL);
- _item1.setDetails(Rect(0, 0, 320, 200), 3260, 0, 1, 2, 1, NULL);
+ _background.setDetails(Rect(0, 0, 320, 200), 3260, 0, 1, 2, 1, NULL);
R2_GLOBALS._player.postInit();
if (R2_GLOBALS._player._oldCharacterScene[R2_MIRANDA] == 3275) {
@@ -1538,7 +1552,7 @@ void Scene3260::signal() {
case 3272:
_sceneMode = 3273;
R2_GLOBALS._events.setCursor(CURSOR_WALK);
- SceneItem::display(3260, 15, 0, 280, 1, 160, 9, 1, 2, 20, 7, 154, -999);
+ SceneItem::display(3260, 15, 0, 280, 1, 160, 9, 1, 2, 20, 7, 154, LIST_END);
R2_GLOBALS._player.disableControl();
R2_INVENTORY.setObjectScene(R2_TOOLBOX, 3);
R2_INVENTORY.setObjectScene(R2_LASER_HACKSAW, 3);
@@ -1560,11 +1574,11 @@ void Scene3260::signal() {
*--------------------------------------------------------------------------*/
bool Scene3275::Door::startAction(CursorType action, Event &event) {
- Scene3275 *scene = (Scene3275 *)R2_GLOBALS._sceneManager._scene;
-
if (action != CURSOR_USE)
return SceneActor::startAction(action, event);
+ Scene3275 *scene = (Scene3275 *)R2_GLOBALS._sceneManager._scene;
+
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 3275;
scene->setAction(&scene->_sequenceManager, scene, 3275, &R2_GLOBALS._player, &scene->_door, NULL);
@@ -1596,9 +1610,9 @@ void Scene3275::postInit(SceneObjectList *OwnerList) {
_cellExit.setDetails(Rect(398, 60, 439, 118), SHADECURSOR_UP, 3150);
_cellExit.setDest(Common::Point(418, 128));
- _actor1.postInit();
- _actor1.setup(3275, 1, 7);
- _actor1.setPosition(Common::Point(419, 119));
+ _doorFrame.postInit();
+ _doorFrame.setup(3275, 1, 7);
+ _doorFrame.setPosition(Common::Point(419, 119));
_door.postInit();
_door.setup(3275, 2, 1);
@@ -1657,8 +1671,8 @@ void Scene3275::signal() {
void Scene3350::postInit(SceneObjectList *OwnerList) {
loadScene(3350);
- SceneExt::postInit();
R2_GLOBALS._uiElements._active = false;
+ SceneExt::postInit();
R2_GLOBALS._interfaceY = SCREEN_HEIGHT;
R2_GLOBALS._sound2.play(310);
@@ -1669,27 +1683,27 @@ void Scene3350::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player.hide();
R2_GLOBALS._player.disableControl();
- _actor1.postInit();
- _actor1.hide();
- _actor2.postInit();
- _actor2.hide();
- _actor3.postInit();
- _actor3.hide();
- _actor4.postInit();
- _actor4.hide();
- _actor9.postInit();
- _actor9.hide();
- _actor8.postInit();
- _actor8.hide();
- _actor5.postInit();
- _actor5.hide();
- _actor6.postInit();
- _actor6.hide();
- _actor7.postInit();
- _actor7.hide();
+ _miranda.postInit();
+ _miranda.hide();
+ _seeker.postInit();
+ _seeker.hide();
+ _webbster.postInit();
+ _webbster.hide();
+ _seatedPeople.postInit();
+ _seatedPeople.hide();
+ _shipFront.postInit();
+ _shipFront.hide();
+ _canopy.postInit();
+ _canopy.hide();
+ _ship.postInit();
+ _ship.hide();
+ _landedShip.postInit();
+ _landedShip.hide();
+ _shipShadow.postInit();
+ _shipShadow.hide();
_sceneMode = 3350;
- setAction(&_sequenceManager, this, _sceneMode, &_actor5, &_actor6, &_actor7, NULL);
+ setAction(&_sequenceManager, this, _sceneMode, &_ship, &_landedShip, &_shipShadow, NULL);
}
void Scene3350::remove() {
@@ -1701,11 +1715,13 @@ void Scene3350::signal() {
switch (_sceneMode) {
case 3350:
_sceneMode = 3351;
- setAction(&_sequenceManager, this, 3351, &_actor4, &_actor9, &_actor8, NULL);
+ setAction(&_sequenceManager, this, 3351, &_seatedPeople, &_shipFront, &_canopy, NULL);
break;
case 3351:
_sceneMode = 3352;
- setAction(&_sequenceManager, this, 3352, &_actor4, &R2_GLOBALS._player, &_actor1, &_actor2, &_actor3, NULL);
+ setAction(&_sequenceManager, this, 3352, &_seatedPeople, &R2_GLOBALS._player,
+ &_miranda, &_seeker, &_webbster, NULL);
+ break;
case 3352:
R2_GLOBALS._sceneManager.changeScene(3395);
break;
@@ -1723,8 +1739,7 @@ void Scene3350::signal() {
void Scene3375::synchronize(Serializer &s) {
SceneExt::synchronize(s);
- s.syncAsSint16LE(_field1488);
- s.syncAsSint16LE(_field1492);
+ s.syncAsSint16LE(_newSceneMode);
for (int i = 0; i < 4; ++i)
s.syncAsSint16LE(_sceneAreas[i]);
}
@@ -1749,11 +1764,11 @@ void Scene3375::enterArea(int sceneMode) {
R2_GLOBALS._player.setPosition(Common::Point(148, 230));
_companion1.setPosition(Common::Point(191, 274));
- _companion1._effect = 1;
+ _companion1._effect = EFFECT_SHADED;
_companion2.setPosition(Common::Point(124, 255));
- _companion2._effect = 1;
+ _companion2._effect = EFFECT_SHADED;
_webbster.setPosition(Common::Point(155, 245));
- _webbster._effect = 1;
+ _webbster._effect = EFFECT_SHADED;
break;
case 3381:
--R2_GLOBALS._walkwaySceneNumber;
@@ -1767,11 +1782,11 @@ void Scene3375::enterArea(int sceneMode) {
R2_GLOBALS._player.setPosition(Common::Point(201, 131));
_companion1.setPosition(Common::Point(231, 127));
- _companion1._effect = 1;
+ _companion1._effect = EFFECT_SHADED;
_companion2.setPosition(Common::Point(231, 127));
- _companion2._effect = 1;
+ _companion2._effect = EFFECT_SHADED;
_webbster.setPosition(Common::Point(231, 127));
- _webbster._effect = 1;
+ _webbster._effect = EFFECT_SHADED;
break;
default:
R2_GLOBALS._player.setPosition(Common::Point(192, 155));
@@ -1807,11 +1822,11 @@ void Scene3375::enterArea(int sceneMode) {
}
bool Scene3375::Companion2::startAction(CursorType action, Event &event) {
- Scene3375 *scene = (Scene3375 *)R2_GLOBALS._sceneManager._scene;
-
if (action != CURSOR_TALK)
return SceneActor::startAction(action, event);
+ Scene3375 *scene = (Scene3375 *)R2_GLOBALS._sceneManager._scene;
+
scene->_sceneMode = 9999;
if (R2_GLOBALS._player._characterIndex == R2_SEEKER)
scene->_stripManager.start(3302, scene);
@@ -1822,11 +1837,11 @@ bool Scene3375::Companion2::startAction(CursorType action, Event &event) {
}
bool Scene3375::Companion1::startAction(CursorType action, Event &event) {
- Scene3375 *scene = (Scene3375 *)R2_GLOBALS._sceneManager._scene;
-
if (action != CURSOR_TALK)
return SceneActor::startAction(action, event);
+ Scene3375 *scene = (Scene3375 *)R2_GLOBALS._sceneManager._scene;
+
scene->_sceneMode = 9999;
if (R2_GLOBALS._player._characterIndex == R2_MIRANDA)
scene->_stripManager.start(3302, scene);
@@ -1837,11 +1852,11 @@ bool Scene3375::Companion1::startAction(CursorType action, Event &event) {
}
bool Scene3375::Webbster::startAction(CursorType action, Event &event) {
- Scene3375 *scene = (Scene3375 *)R2_GLOBALS._sceneManager._scene;
-
if (action != CURSOR_TALK)
return SceneActor::startAction(action, event);
+ Scene3375 *scene = (Scene3375 *)R2_GLOBALS._sceneManager._scene;
+
scene->_sceneMode = 9999;
scene->_stripManager.start(3303, scene);
@@ -1849,8 +1864,6 @@ bool Scene3375::Webbster::startAction(CursorType action, Event &event) {
}
bool Scene3375::Door::startAction(CursorType action, Event &event) {
- Scene3375 *scene = (Scene3375 *)R2_GLOBALS._sceneManager._scene;
-
if (action != CURSOR_USE)
return SceneActor::startAction(action, event);
@@ -1868,8 +1881,10 @@ bool Scene3375::Door::startAction(CursorType action, Event &event) {
R2_GLOBALS._player.disableControl(CURSOR_ARROW);
+ Scene3375 *scene = (Scene3375 *)R2_GLOBALS._sceneManager._scene;
+
scene->_sceneMode = 3375;
- scene->setAction(&scene->_sequenceManager, scene, 3375, &R2_GLOBALS._player,
+ scene->setAction(&scene->_sequenceManager, scene, 3375, &R2_GLOBALS._player,
&scene->_companion1, &scene->_companion2, &scene->_webbster, &scene->_door, NULL);
return true;
@@ -1912,12 +1927,12 @@ void Scene3375::DownExit::changeScene() {
Scene3375 *scene = (Scene3375 *)R2_GLOBALS._sceneManager._scene;
_moving = false;
- R2_GLOBALS._player._effect = 6;
+ R2_GLOBALS._player._effect = EFFECT_SHADED2;
R2_GLOBALS._player._shade = 4;
R2_GLOBALS._player.disableControl(CURSOR_ARROW);
scene->_sceneMode = 3377;
- scene->_field1488 = 3381;
+ scene->_newSceneMode = 3381;
if (R2_GLOBALS._walkwaySceneNumber != 0) {
R2_GLOBALS._walkRegions.enableRegion(2);
@@ -1934,12 +1949,12 @@ void Scene3375::RightExit::changeScene() {
Scene3375 *scene = (Scene3375 *)R2_GLOBALS._sceneManager._scene;
_moving = false;
- R2_GLOBALS._player._effect = 6;
+ R2_GLOBALS._player._effect = EFFECT_SHADED2;
R2_GLOBALS._player._shade = 4;
R2_GLOBALS._player.disableControl(CURSOR_ARROW);
scene->_sceneMode = 3378;
- scene->_field1488 = 3380;
+ scene->_newSceneMode = 3380;
if (R2_GLOBALS._walkwaySceneNumber != 0) {
R2_GLOBALS._walkRegions.enableRegion(2);
@@ -1953,7 +1968,7 @@ void Scene3375::RightExit::changeScene() {
}
Scene3375::Scene3375() {
- _field1488 = _field1492 = 0;
+ _newSceneMode = 0;
_sceneAreas[0] = 3376;
_sceneAreas[1] = 3377;
@@ -1981,11 +1996,11 @@ void Scene3375::postInit(SceneObjectList *OwnerList) {
setZoomPercents(126, 55, 200, 167);
R2_GLOBALS._player.postInit();
- if (R2_GLOBALS._player._characterIndex == R2_SEEKER) {
+ if (R2_GLOBALS._player._characterIndex == R2_SEEKER)
R2_GLOBALS._player._moveDiff = Common::Point(5, 3);
- } else {
+ else
R2_GLOBALS._player._moveDiff = Common::Point(3, 2);
- }
+
R2_GLOBALS._player.changeZoom(-1);
switch (R2_GLOBALS._player._characterIndex) {
@@ -2021,7 +2036,7 @@ void Scene3375::postInit(SceneObjectList *OwnerList) {
_companion1._moveDiff = Common::Point(5, 3);
}
_companion1.changeZoom(-1);
- _companion1._effect = 1;
+ _companion1._effect = EFFECT_SHADED;
int tmpStrip, tmpVisage;
if (R2_GLOBALS._sceneManager._previousScene == 3385)
@@ -2040,7 +2055,7 @@ void Scene3375::postInit(SceneObjectList *OwnerList) {
_companion2.postInit();
_companion2._moveDiff = Common::Point(3, 2);
_companion2.changeZoom(-1);
- _companion2._effect = 1;
+ _companion2._effect = EFFECT_SHADED;
if (R2_GLOBALS._sceneManager._previousScene == 3385)
tmpStrip = 1;
else
@@ -2058,7 +2073,7 @@ void Scene3375::postInit(SceneObjectList *OwnerList) {
_webbster._moveRate = 7;
_webbster._moveDiff = Common::Point(5, 3);
_webbster.changeZoom(-1);
- _webbster._effect = 1;
+ _webbster._effect = EFFECT_SHADED;
if (R2_GLOBALS._sceneManager._previousScene == 3385)
tmpStrip = 1;
else
@@ -2113,10 +2128,10 @@ void Scene3375::signalCase3379() {
_sceneMode = 1;
ADD_MOVER(R2_GLOBALS._player, 70, R2_GLOBALS._player._position.y);
R2_GLOBALS._sceneManager._previousScene = 3375;
- R2_GLOBALS._player._effect = 1;
- _companion1._effect = 1;
- _companion2._effect = 1;
- _webbster._effect = 1;
+ R2_GLOBALS._player._effect = EFFECT_SHADED;
+ _companion1._effect = EFFECT_SHADED;
+ _companion2._effect = EFFECT_SHADED;
+ _webbster._effect = EFFECT_SHADED;
return;
//R2_GLOBALS._walkRegions.disableRegion(1);
@@ -2146,10 +2161,10 @@ void Scene3375::signalCase3379() {
break;
}
R2_GLOBALS._sceneManager._previousScene = 3375;
- R2_GLOBALS._player._effect = 1;
- _companion1._effect = 1;
- _companion2._effect = 1;
- _webbster._effect = 1;
+ R2_GLOBALS._player._effect = EFFECT_SHADED;
+ _companion1._effect = EFFECT_SHADED;
+ _companion2._effect = EFFECT_SHADED;
+ _webbster._effect = EFFECT_SHADED;
R2_GLOBALS._player.enableControl(CURSOR_WALK);
}
@@ -2167,14 +2182,23 @@ void Scene3375::signal() {
case 3377:
// No break on purpose
case 3378:
- _sceneMode = _field1488;
- _field1488 = 0;
- _companion1._effect = 6;
+ _sceneMode = _newSceneMode;
+ _newSceneMode = 0;
+
+ _companion1._effect = EFFECT_SHADED2;
_companion1._shade = 4;
- _companion2._effect = 6;
+ _companion2._effect = EFFECT_SHADED2;
_companion2._shade = 4;
- _webbster._effect = 6;
+ _webbster._effect = EFFECT_SHADED2;
_webbster._shade = 4;
+
+ // HACK: Reset zooms in order to avoid giant characters on the upper right of the screen
+ R2_GLOBALS._player.setZoom(-1);
+ _companion1.setZoom(-1);
+ _companion2.setZoom(-1);
+ _webbster.setZoom(-1);
+ //
+
enterArea(_sceneMode);
break;
case 3379:
@@ -2186,6 +2210,7 @@ void Scene3375::signal() {
else
R2_GLOBALS._player.setStrip(3);
R2_GLOBALS._player.enableControl(CURSOR_TALK);
+ break;
default:
_companion1.setPriority(130);
_companion2.setPriority(132);
@@ -2197,24 +2222,24 @@ void Scene3375::signal() {
void Scene3375::dispatch() {
if ((R2_GLOBALS._player._position.y >= 168) && (R2_GLOBALS._player._effect == 1))
- R2_GLOBALS._player._effect = 6;
+ R2_GLOBALS._player._effect = EFFECT_SHADED2;
else if ((R2_GLOBALS._player._position.y < 168) && (R2_GLOBALS._player._effect == 6))
- R2_GLOBALS._player._effect = 1;
+ R2_GLOBALS._player._effect = EFFECT_SHADED;
if ((_companion1._position.y >= 168) && (_companion1._effect == 1))
- _companion1._effect = 6;
+ _companion1._effect = EFFECT_SHADED2;
else if ((_companion1._position.y < 168) && (_companion1._effect == 6))
- _companion1._effect = 1;
+ _companion1._effect = EFFECT_SHADED;
if ((_companion2._position.y >= 168) && (_companion2._effect == 1))
- _companion2._effect = 6;
+ _companion2._effect = EFFECT_SHADED2;
else if ((_companion2._position.y < 168) && (_companion2._effect == 6))
- _companion2._effect = 1;
+ _companion2._effect = EFFECT_SHADED;
if ((_webbster._position.y >= 168) && (_webbster._effect == 1))
- _webbster._effect = 6;
+ _webbster._effect = EFFECT_SHADED2;
else if ((_webbster._position.y < 168) && (_webbster._effect == 6))
- _webbster._effect = 1;
+ _webbster._effect = EFFECT_SHADED;
Scene::dispatch();
}
@@ -2225,21 +2250,21 @@ void Scene3375::dispatch() {
*--------------------------------------------------------------------------*/
Scene3385::Scene3385() {
- _field11B2 = 0;
+ _playerStrip = 0;
}
void Scene3385::synchronize(Serializer &s) {
SceneExt::synchronize(s);
- s.syncAsSint16LE(_field11B2);
+ s.syncAsSint16LE(_playerStrip);
}
bool Scene3385::Companion1::startAction(CursorType action, Event &event) {
- Scene3385 *scene = (Scene3385 *)R2_GLOBALS._sceneManager._scene;
-
if (action != CURSOR_TALK)
return SceneActor::startAction(action, event);
+ Scene3385 *scene = (Scene3385 *)R2_GLOBALS._sceneManager._scene;
+
scene->_sceneMode = 9999;
if (R2_GLOBALS._player._characterIndex == R2_SEEKER)
scene->_stripManager.start(3302, scene);
@@ -2250,11 +2275,11 @@ bool Scene3385::Companion1::startAction(CursorType action, Event &event) {
}
bool Scene3385::Companion2::startAction(CursorType action, Event &event) {
- Scene3385 *scene = (Scene3385 *)R2_GLOBALS._sceneManager._scene;
-
if (action != CURSOR_TALK)
return SceneActor::startAction(action, event);
+ Scene3385 *scene = (Scene3385 *)R2_GLOBALS._sceneManager._scene;
+
scene->_sceneMode = 9999;
if (R2_GLOBALS._player._characterIndex == R2_MIRANDA)
scene->_stripManager.start(3302, scene);
@@ -2265,11 +2290,11 @@ bool Scene3385::Companion2::startAction(CursorType action, Event &event) {
}
bool Scene3385::Webbster::startAction(CursorType action, Event &event) {
- Scene3385 *scene = (Scene3385 *)R2_GLOBALS._sceneManager._scene;
-
if (action != CURSOR_TALK)
return SceneActor::startAction(action, event);
+ Scene3385 *scene = (Scene3385 *)R2_GLOBALS._sceneManager._scene;
+
scene->_sceneMode = 9999;
scene->_stripManager.start(3303, scene);
@@ -2277,8 +2302,6 @@ bool Scene3385::Webbster::startAction(CursorType action, Event &event) {
}
bool Scene3385::Door::startAction(CursorType action, Event &event) {
- Scene3385 *scene = (Scene3385 *)R2_GLOBALS._sceneManager._scene;
-
if (action != CURSOR_USE)
return SceneActor::startAction(action, event);
@@ -2286,23 +2309,25 @@ bool Scene3385::Door::startAction(CursorType action, Event &event) {
if (R2_GLOBALS._sceneManager._previousScene == 3375)
R2_GLOBALS._sound2.play(314);
+ Scene3385 *scene = (Scene3385 *)R2_GLOBALS._sceneManager._scene;
+
scene->_sceneMode = 3386;
- scene->setAction(&scene->_sequenceManager, scene, 3386, &R2_GLOBALS._player,
- &scene->_companion1, &scene->_companion2, &scene->_webbster, &scene->_door,
+ scene->setAction(&scene->_sequenceManager, scene, 3386, &R2_GLOBALS._player,
+ &scene->_companion1, &scene->_companion2, &scene->_webbster, &scene->_door,
NULL);
return true;
}
-void Scene3385::Exit1::changeScene() {
+void Scene3385::SouthExit::changeScene() {
Scene3385 *scene = (Scene3385 *)R2_GLOBALS._sceneManager._scene;
R2_GLOBALS._player.disableControl(CURSOR_ARROW);
scene->_sceneMode = 3387;
if (R2_GLOBALS._sceneManager._previousScene == 3375)
- scene->setAction(&scene->_sequenceManager, scene, scene->_sceneMode,
- &R2_GLOBALS._player, &scene->_companion1, &scene->_companion2,
+ scene->setAction(&scene->_sequenceManager, scene, scene->_sceneMode,
+ &R2_GLOBALS._player, &scene->_companion1, &scene->_companion2,
&scene->_webbster, NULL);
else
scene->signal();
@@ -2336,9 +2361,9 @@ void Scene3385::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player._characterScene[R2_MIRANDA] = 3385;
if (R2_GLOBALS._sceneManager._previousScene == 3375)
- _field11B2 = 3;
+ _playerStrip = 3;
else
- _field11B2 = 4;
+ _playerStrip = 4;
setZoomPercents(102, 40, 200, 160);
R2_GLOBALS._player.postInit();
@@ -2351,11 +2376,11 @@ void Scene3385::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player.changeZoom(-1);
if (R2_GLOBALS._player._characterIndex == R2_SEEKER)
- R2_GLOBALS._player.setup(20, _field11B2, 1);
+ R2_GLOBALS._player.setup(20, _playerStrip, 1);
else if (R2_GLOBALS._player._characterIndex == R2_MIRANDA)
- R2_GLOBALS._player.setup(30, _field11B2, 1);
+ R2_GLOBALS._player.setup(30, _playerStrip, 1);
else
- R2_GLOBALS._player.setup(10, _field11B2, 1);
+ R2_GLOBALS._player.setup(10, _playerStrip, 1);
R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
R2_GLOBALS._player.disableControl();
@@ -2369,35 +2394,35 @@ void Scene3385::postInit(SceneObjectList *OwnerList) {
_companion1._moveDiff = Common::Point(5, 3);
}
_companion1.changeZoom(-1);
- _companion1._effect = 1;
+ _companion1._effect = EFFECT_SHADED;
if (R2_GLOBALS._player._characterIndex == R2_SEEKER)
- _companion1.setup(10, _field11B2, 1);
+ _companion1.setup(10, _playerStrip, 1);
else
- _companion1.setup(20, _field11B2, 1);
+ _companion1.setup(20, _playerStrip, 1);
_companion1.animate(ANIM_MODE_1, NULL);
_companion1.setDetails(3385, -1, -1, -1, 1, (SceneItem *) NULL);
_companion2.postInit();
_companion2._moveDiff = Common::Point(3, 2);
_companion2.changeZoom(-1);
- _companion2._effect = 1;
+ _companion2._effect = EFFECT_SHADED;
if (R2_GLOBALS._player._characterIndex == R2_MIRANDA)
- _companion2.setup(10, _field11B2, 1);
+ _companion2.setup(10, _playerStrip, 1);
else
- _companion2.setup(30, _field11B2, 1);
+ _companion2.setup(30, _playerStrip, 1);
_companion2.animate(ANIM_MODE_1, NULL);
_companion2.setDetails(3385, -1, -1, -1, 1, (SceneItem *) NULL);
_webbster.postInit();
_webbster._moveDiff = Common::Point(3, 2);
_webbster.changeZoom(-1);
- _webbster._effect = 1;
- _webbster.setup(40, _field11B2, 1);
+ _webbster._effect = EFFECT_SHADED;
+ _webbster.setup(40, _playerStrip, 1);
_webbster.animate(ANIM_MODE_1, NULL);
_webbster.setDetails(3385, 15, -1, -1, 1, (SceneItem *) NULL);
- _exit1.setDetails(Rect(103, 152, 217, 170), SHADECURSOR_DOWN, 3395);
- _exit1.setDest(Common::Point(158, 151));
+ _southExit.setDetails(Rect(103, 152, 217, 170), SHADECURSOR_DOWN, 3395);
+ _southExit.setDest(Common::Point(158, 151));
_door.postInit();
_door.setPosition(Common::Point(160, 100));
@@ -2462,21 +2487,21 @@ void Scene3385::signal() {
*--------------------------------------------------------------------------*/
Scene3395::Scene3395() {
- _field142E = 0;
+ _playerStrip = 0;
}
void Scene3395::synchronize(Serializer &s) {
SceneExt::synchronize(s);
- s.syncAsSint16LE(_field142E);
+ s.syncAsSint16LE(_playerStrip);
}
bool Scene3395::Companion1::startAction(CursorType action, Event &event) {
- Scene3395 *scene = (Scene3395 *)R2_GLOBALS._sceneManager._scene;
-
if (action != CURSOR_TALK)
return SceneActor::startAction(action, event);
+ Scene3395 *scene = (Scene3395 *)R2_GLOBALS._sceneManager._scene;
+
scene->_sceneMode = 9999;
if (R2_GLOBALS._player._characterIndex == R2_SEEKER)
scene->_stripManager.start(3302, scene);
@@ -2487,11 +2512,11 @@ bool Scene3395::Companion1::startAction(CursorType action, Event &event) {
}
bool Scene3395::Companion2::startAction(CursorType action, Event &event) {
- Scene3395 *scene = (Scene3395 *)R2_GLOBALS._sceneManager._scene;
-
if (action != CURSOR_TALK)
return SceneActor::startAction(action, event);
+ Scene3395 *scene = (Scene3395 *)R2_GLOBALS._sceneManager._scene;
+
scene->_sceneMode = 9999;
if (R2_GLOBALS._player._characterIndex == R2_MIRANDA)
scene->_stripManager.start(3302, scene);
@@ -2502,11 +2527,11 @@ bool Scene3395::Companion2::startAction(CursorType action, Event &event) {
}
bool Scene3395::Webbster::startAction(CursorType action, Event &event) {
- Scene3395 *scene = (Scene3395 *)R2_GLOBALS._sceneManager._scene;
-
if (action != CURSOR_TALK)
return SceneActor::startAction(action, event);
+ Scene3395 *scene = (Scene3395 *)R2_GLOBALS._sceneManager._scene;
+
scene->_sceneMode = 9999;
scene->_stripManager.start(3303, scene);
@@ -2514,8 +2539,6 @@ bool Scene3395::Webbster::startAction(CursorType action, Event &event) {
}
bool Scene3395::Door::startAction(CursorType action, Event &event) {
- Scene3395 *scene = (Scene3395 *)R2_GLOBALS._sceneManager._scene;
-
if (action != CURSOR_USE)
return SceneActor::startAction(action, event);
@@ -2523,9 +2546,11 @@ bool Scene3395::Door::startAction(CursorType action, Event &event) {
if (R2_GLOBALS._sceneManager._previousScene == 3385)
R2_GLOBALS._sound2.play(314);
+ Scene3395 *scene = (Scene3395 *)R2_GLOBALS._sceneManager._scene;
+
scene->_sceneMode = 3396;
- scene->setAction(&scene->_sequenceManager, scene, 3396, &R2_GLOBALS._player,
- &scene->_companion1, &scene->_companion2, &scene->_webbster, &scene->_door,
+ scene->setAction(&scene->_sequenceManager, scene, 3396, &R2_GLOBALS._player,
+ &scene->_companion1, &scene->_companion2, &scene->_webbster, &scene->_door,
NULL);
return true;
@@ -2559,9 +2584,9 @@ void Scene3395::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player._characterScene[R2_MIRANDA] = 3395;
if (R2_GLOBALS._sceneManager._previousScene == 3385)
- _field142E = 3;
+ _playerStrip = 3;
else
- _field142E = 4;
+ _playerStrip = 4;
setZoomPercents(51, 40, 200, 137);
R2_GLOBALS._player.postInit();
@@ -2574,11 +2599,11 @@ void Scene3395::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player.changeZoom(-1);
if (R2_GLOBALS._player._characterIndex == R2_SEEKER)
- R2_GLOBALS._player.setup(20, _field142E, 1);
+ R2_GLOBALS._player.setup(20, _playerStrip, 1);
else if (R2_GLOBALS._player._characterIndex == R2_MIRANDA)
- R2_GLOBALS._player.setup(30, _field142E, 1);
+ R2_GLOBALS._player.setup(30, _playerStrip, 1);
else
- R2_GLOBALS._player.setup(10, _field142E, 1);
+ R2_GLOBALS._player.setup(10, _playerStrip, 1);
R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
R2_GLOBALS._player.disableControl();
@@ -2592,30 +2617,30 @@ void Scene3395::postInit(SceneObjectList *OwnerList) {
_companion1._moveDiff = Common::Point(5, 3);
}
_companion1.changeZoom(-1);
- _companion1._effect = 1;
+ _companion1._effect = EFFECT_SHADED;
if (R2_GLOBALS._player._characterIndex == R2_SEEKER)
- _companion1.setup(10, _field142E, 1);
+ _companion1.setup(10, _playerStrip, 1);
else
- _companion1.setup(20, _field142E, 1);
+ _companion1.setup(20, _playerStrip, 1);
_companion1.animate(ANIM_MODE_1, NULL);
_companion1.setDetails(3395, -1, -1, -1, 1, (SceneItem *) NULL);
_companion2.postInit();
_companion2._moveDiff = Common::Point(3, 2);
_companion2.changeZoom(-1);
- _companion2._effect = 1;
+ _companion2._effect = EFFECT_SHADED;
if (R2_GLOBALS._player._characterIndex == R2_MIRANDA)
- _companion2.setup(10, _field142E, 1);
+ _companion2.setup(10, _playerStrip, 1);
else
- _companion2.setup(30, _field142E, 1);
+ _companion2.setup(30, _playerStrip, 1);
_companion2.animate(ANIM_MODE_1, NULL);
_companion2.setDetails(3395, -1, -1, -1, 1, (SceneItem *) NULL);
_webbster.postInit();
_webbster._moveDiff = Common::Point(3, 2);
_webbster.changeZoom(-1);
- _webbster._effect = 1;
- _webbster.setup(40, _field142E, 1);
+ _webbster._effect = EFFECT_SHADED;
+ _webbster.setup(40, _playerStrip, 1);
_webbster.animate(ANIM_MODE_1, NULL);
_webbster.setDetails(3395, 18, -1, -1, 1, (SceneItem *) NULL);
@@ -2685,13 +2710,13 @@ void Scene3395::signal() {
*--------------------------------------------------------------------------*/
Scene3400::Scene3400() {
- _field157C = 0;
+ _soundFaded = false;
}
void Scene3400::synchronize(Serializer &s) {
SceneExt::synchronize(s);
- s.syncAsSint16LE(_field157C);
+ s.syncAsSint16LE(_soundFaded);
}
void Scene3400::postInit(SceneObjectList *OwnerList) {
@@ -2699,8 +2724,7 @@ void Scene3400::postInit(SceneObjectList *OwnerList) {
_sceneBounds = Rect(160, 0, 480, 200);
loadScene(3400);
- _field157C = 0;
- R2_GLOBALS._v558B6.set(60, 0, 260, 200);
+ _soundFaded = false;
SceneExt::postInit();
R2_GLOBALS._sound1.play(317);
@@ -2717,10 +2741,10 @@ void Scene3400::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player._characterScene[R2_SEEKER] = 3400;
R2_GLOBALS._player._characterScene[R2_MIRANDA] = 3400;
- _actor7.postInit();
- _actor7.setup(3403, 1, 1);
- _actor7.setPosition(Common::Point(190, 103));
- _actor7.fixPriority(89);
+ _manholeCover.postInit();
+ _manholeCover.setup(3403, 1, 1);
+ _manholeCover.setPosition(Common::Point(190, 103));
+ _manholeCover.fixPriority(89);
R2_GLOBALS._player.postInit();
if (R2_GLOBALS._player._characterIndex == R2_SEEKER)
@@ -2749,7 +2773,7 @@ void Scene3400::postInit(SceneObjectList *OwnerList) {
_companion1._moveDiff = Common::Point(5, 3);
}
_companion1.changeZoom(-1);
- _companion1._effect = 1;
+ _companion1._effect = EFFECT_SHADED;
_companion1.setPosition(Common::Point(247, 63));
if (R2_GLOBALS._player._characterIndex == R2_SEEKER)
_companion1.setup(10, 5, 1);
@@ -2760,7 +2784,7 @@ void Scene3400::postInit(SceneObjectList *OwnerList) {
_companion2.postInit();
_companion2._moveDiff = Common::Point(3, 2);
_companion2.changeZoom(-1);
- _companion2._effect = 1;
+ _companion2._effect = EFFECT_SHADED;
_companion2.setPosition(Common::Point(225, 63));
if (R2_GLOBALS._player._characterIndex == R2_MIRANDA)
_companion2.setup(10, 5, 1);
@@ -2772,16 +2796,16 @@ void Scene3400::postInit(SceneObjectList *OwnerList) {
_webbster._numFrames = 7;
_webbster._moveDiff = Common::Point(5, 3);
_webbster.changeZoom(-1);
- _webbster._effect = 1;
+ _webbster._effect = EFFECT_SHADED;
_webbster.setPosition(Common::Point(235, 61));
_webbster.setup(40, 3, 1);
_webbster.animate(ANIM_MODE_1, NULL);
- _actor6.postInit();
- _actor6.setup(3400, 1, 6);
- _actor6.setPosition(Common::Point(236, 51));
- _actor6.fixPriority(51);
- _actor6.animate(ANIM_MODE_6, NULL);
+ _door.postInit();
+ _door.setup(3400, 1, 6);
+ _door.setPosition(Common::Point(236, 51));
+ _door.fixPriority(51);
+ _door.animate(ANIM_MODE_6, NULL);
R2_GLOBALS.clearFlag(71);
_sceneMode = 3400;
@@ -2797,7 +2821,7 @@ void Scene3400::remove() {
void Scene3400::signal() {
switch (_sceneMode) {
case 3305: {
- warning("STUB: sub_1D227()");
+ // First part of discussion
_tealSpeaker._object1.hide();
_teal.show();
_teal.setStrip(1);
@@ -2809,6 +2833,7 @@ void Scene3400::signal() {
}
break;
case 3306:
+ // Teal picks up the sapphire
R2_GLOBALS._sound2.play(318);
_companion1.setStrip(2);
R2_GLOBALS._player.setStrip(6);
@@ -2819,25 +2844,26 @@ void Scene3400::signal() {
_stripManager.start(3307, this);
if (R2_GLOBALS._player._characterIndex == R2_SEEKER) {
_sceneMode = 3400;
- R2_GLOBALS._player.setAction(&_sequenceManager, this, 3400, &R2_GLOBALS._player, &_teal, &_actor8, NULL);
+ R2_GLOBALS._player.setAction(&_sequenceManager, this, 3400, &R2_GLOBALS._player, &_teal, &_sapphire, NULL);
} else {
_sceneMode = 3408;
- _companion1.setAction(&_sequenceManager, this, 3408, &_companion1, &_teal, &_actor8, NULL);
+ _companion1.setAction(&_sequenceManager, this, 3408, &_companion1, &_teal, &_sapphire, NULL);
}
break;
case 3307:
case 3404:
case 3408:
- if (_field157C == 0) {
+ // A tasp!
+ if (!_soundFaded) {
R2_GLOBALS._sound2.fadeOut2(NULL);
- _field157C = 1;
+ _soundFaded = true;
} else {
_sceneMode = 3308;
_stripManager.start(3308, this);
}
break;
case 3308:
- warning("STUB: sub_1D227()");
+ // Characters teleport one after the other
_companion1.setStrip(2);
R2_GLOBALS._player.setStrip(6);
_companion2.setStrip(6);
@@ -2845,46 +2871,47 @@ void Scene3400::signal() {
_teal.setStrip(1);
_sceneMode = 3403;
if (R2_GLOBALS._player._characterIndex == R2_SEEKER)
- setAction(&_sequenceManager, this, 3403, &R2_GLOBALS._player, &_webbster, &_actor7, NULL);
+ setAction(&_sequenceManager, this, 3403, &R2_GLOBALS._player, &_webbster, &_manholeCover, NULL);
else
- setAction(&_sequenceManager, this, 3403, &_companion1, &_webbster, &_actor7, NULL);
+ setAction(&_sequenceManager, this, 3403, &_companion1, &_webbster, &_manholeCover, NULL);
break;
case 3309:
- warning("STUB: sub_1D227()");
+ // Miranda teleports away
_teal.setStrip(1);
_sceneMode = 3405;
if (R2_GLOBALS._player._characterIndex == R2_MIRANDA)
- setAction(&_sequenceManager, this, 3405, &R2_GLOBALS._player, &_actor7, NULL);
+ setAction(&_sequenceManager, this, 3405, &R2_GLOBALS._player, &_manholeCover, NULL);
else
- setAction(&_sequenceManager, this, 3405, &_companion2, &_actor7, NULL);
+ setAction(&_sequenceManager, this, 3405, &_companion2, &_manholeCover, NULL);
break;
case 3310:
- warning("STUB: sub_1D227()");
+ // Quinn teleports away
_teal.setStrip(1);
_sceneMode = 3406;
if (R2_GLOBALS._player._characterIndex == R2_QUINN)
- setAction(&_sequenceManager, this, 3406, &R2_GLOBALS._player, &_actor7, NULL);
+ setAction(&_sequenceManager, this, 3406, &R2_GLOBALS._player, &_manholeCover, NULL);
else if (R2_GLOBALS._player._characterIndex == R2_SEEKER)
- setAction(&_sequenceManager, this, 3406, &_companion1, &_actor7, NULL);
+ setAction(&_sequenceManager, this, 3406, &_companion1, &_manholeCover, NULL);
else if (R2_GLOBALS._player._characterIndex == R2_MIRANDA)
- setAction(&_sequenceManager, this, 3406, &_companion2, &_actor7, NULL);
+ setAction(&_sequenceManager, this, 3406, &_companion2, &_manholeCover, NULL);
break;
case 3311:
- warning("STUB: sub_1D227()");
+ // Teal teleports away
_tealSpeaker._object1.hide();
_teal.show();
_teal.setStrip(1);
_sceneMode = 3407;
- setAction(&_sequenceManager, this, 3407, &_teal, &_actor7, NULL);
+ setAction(&_sequenceManager, this, 3407, &_teal, &_manholeCover, NULL);
break;
case 3400: {
- _actor8.postInit();
- _actor8.hide();
+ // Teal enters the room
+ _sapphire.postInit();
+ _sapphire.hide();
_teal.postInit();
_teal._numFrames = 7;
_teal._moveDiff = Common::Point(3, 2);
_teal.changeZoom(-1);
- _teal._effect = 1;
+ _teal._effect = EFFECT_SHADED;
_teal.setPosition(Common::Point(-15, 90));
_teal.setup(3402, 1, 1);
_teal.animate(ANIM_MODE_1, NULL);
@@ -2899,123 +2926,133 @@ void Scene3400::signal() {
}
break;
case 3401:
+ // Teal first speech
_sceneMode = 3305;
_stripManager.start(3305, this);
break;
case 3402:
+ // Betrayal of Webbster
_sceneMode = 3306;
_stripManager.start(3306, this);
break;
case 3403:
+ // Teal: "Miranda..."
R2_GLOBALS._scrollFollower = &R2_GLOBALS._player;
_sceneMode = 3309;
_stripManager.start(3309, this);
break;
case 3405:
+ // Teal: "And Quinn..."
_sceneMode = 3310;
_stripManager.start(3310, this);
break;
case 3406:
+ // Teal final sentence before teleporting
_sceneMode = 3311;
_stripManager.start(3311, this);
break;
case 3407:
+ // End of scene
R2_GLOBALS._sceneManager.changeScene(3600);
break;
default:
+ // Unexpected scene mode
R2_GLOBALS._player.enableControl();
break;
}
}
/*--------------------------------------------------------------------------
- * Scene 3500 - Cavern Maze
+ * Scene 3500 - Flub tube maze
*
*--------------------------------------------------------------------------*/
Scene3500::Action1::Action1() {
- _field1E = 0;
- _field20 = 0;
- _field22 = 0;
- _field24 = 0;
+ _direction = 0;
+ _headingRightFl = false;
+ _turningFl = false;
}
void Scene3500::Action1::synchronize(Serializer &s) {
Action::synchronize(s);
- s.syncAsSint16LE(_field1E);
- s.syncAsSint16LE(_field20);
- s.syncAsSint16LE(_field22);
- s.syncAsSint16LE(_field24);
+ s.syncAsSint16LE(_direction);
+ s.syncAsSint16LE(_headingRightFl);
+ if (s.getVersion() < 13) {
+ int useless = 0;
+ s.syncAsSint32LE(useless);
+ }
+ s.syncAsSint16LE(_turningFl);
}
-void Scene3500::Action1::sub108670(int arg1) {
+void Scene3500::Action1::handleHorzButton(int direction) {
Scene3500 *scene = (Scene3500 *)R2_GLOBALS._sceneManager._scene;
- _field1E = arg1;
- _field20 = 1;
- _field24 = 1;
+ // Direction: -1 == Left, 1 == Right
+ _direction = direction;
+ _headingRightFl = true;
+ _turningFl = true;
- scene->_actor9.setStrip(2);
- scene->_actor9.show();
+ scene->_tunnelHorzCircle.setStrip(2);
+ scene->_tunnelHorzCircle.show();
- if (_field1E == 1)
- scene->_actor6.show();
+ if (_direction == 1)
+ scene->_symbolRight.show();
else
- scene->_actor5.show();
+ scene->_symbolLeft.show();
- if (scene->_actor1._frame % 2 == 0) {
- scene->_actor1._frameChange = _field1E;
- scene->_actor1.setFrame(scene->_actor1.changeFrame());
+ if (scene->_shuttle._frame % 2 == 0) {
+ scene->_shuttle._frameChange = _direction;
+ scene->_shuttle.setFrame(scene->_shuttle.changeFrame());
}
setActionIndex(0);
}
-void Scene3500::Action1::sub108732(int arg1) {
+void Scene3500::Action1::turnShuttle(bool arg1) {
Scene3500 *scene = (Scene3500 *)R2_GLOBALS._sceneManager._scene;
- _field20 = arg1;
- _field1E = -_field1E;
+ _headingRightFl = arg1;
+ _direction = -_direction;
- if (_field1E == 1) {
- scene->_actor6.show();
- scene->_actor5.hide();
+ if (_direction == 1) {
+ scene->_symbolRight.show();
+ scene->_symbolLeft.hide();
} else {
- scene->_actor5.show();
- scene->_actor6.hide();
+ scene->_symbolLeft.show();
+ scene->_symbolRight.hide();
}
switch (_actionIndex) {
case 4:
- scene->_actor1._frameChange = _field1E;
- scene->_actor1.setFrame(scene->_actor1.changeFrame());
+ scene->_shuttle._frameChange = _direction;
+ scene->_shuttle.setFrame(scene->_shuttle.changeFrame());
// No break on purpose
case 3:
_actionIndex = 10;
setDelay(0);
break;
case 5: {
- scene->_fieldAF8 = 160;
+ scene->_moverVertX = 160;
Common::Point pt(160, 73);
NpcMover *mover = new NpcMover();
- scene->_actor8.addMover(mover, &pt, NULL);
+ scene->_tunnelVertCircle.addMover(mover, &pt, NULL);
- scene->_fieldB9E = 160 - (_field1E * 2 * 160);
- Common::Point pt2(scene->_fieldB9E, 73);
+ scene->_moverHorzX = 160 - (_direction * 2 * 160);
+ Common::Point pt2(scene->_moverHorzX, 73);
NpcMover *mover2 = new NpcMover();
- scene->_actor9.addMover(mover2, &pt2, this);
+ scene->_tunnelHorzCircle.addMover(mover2, &pt2, this);
_actionIndex = 11;
}
break;
case 6:
- scene->_actor1._frameChange = _field1E;
- scene->_actor1.setFrame(scene->_actor1.changeFrame());
+ scene->_shuttle._frameChange = _direction;
+ scene->_shuttle.setFrame(scene->_shuttle.changeFrame());
setDelay(1);
// No break on purpose
case 8:
- scene->_actor9.setStrip(2);
+ scene->_tunnelHorzCircle.setStrip(2);
_actionIndex = 1;
break;
default:
@@ -3029,156 +3066,155 @@ void Scene3500::Action1::signal() {
switch(_actionIndex++) {
case 0:
R2_GLOBALS._player.disableControl();
- scene->_field1286 = 0;
- if (scene->_field1270 != 0) {
- scene->_field1270 = 0;
+ scene->_directionChangesEnabled = false;
+ if (scene->_speed != 0) {
+ scene->_speed = 0;
scene->_mazeChangeAmount = 0;
- scene->_field1272 = 0;
+ scene->_updateIdxChangeFl = false;
scene->_rotation->_idxChange = 0;
}
break;
case 1:
- if ((scene->_actor1._frame % 2) == 1) {
+ if ((scene->_shuttle._frame % 2) == 1) {
setDelay(1);
return;
}
// No break on purpose
case 3:
- scene->_actor1._frameChange = _field1E;
- scene->_actor1.setFrame(scene->_actor1.changeFrame());
+ scene->_shuttle._frameChange = _direction;
+ scene->_shuttle.setFrame(scene->_shuttle.changeFrame());
setDelay(1);
break;
case 4: {
- int si = scene->_mazeUI.getCellFromMapXY(Common::Point(scene->_mazePosition.x + 70, scene->_mazePosition.y + 46));
+ int cellId = scene->_mazeUI.getCellFromMapXY(Common::Point(scene->_mazePosition.x + 70, scene->_mazePosition.y + 46));
int var2 = scene->_mazeUI.cellFromX(scene->_mazePosition.x + 70) - 70;
int var4 = scene->_mazeUI.cellFromY(scene->_mazePosition.y + 46) - 46;
int di = abs(var2 - scene->_mazePosition.x);
int var6 = abs(var4 - scene->_mazePosition.y);
- if ((scene->_actor1._frame % 2) != 0) {
- scene->_actor1._frameChange = _field1E;
- scene->_actor1.setFrame(scene->_actor1.changeFrame());
+ if ((scene->_shuttle._frame % 2) != 0) {
+ scene->_shuttle._frameChange = _direction;
+ scene->_shuttle.setFrame(scene->_shuttle.changeFrame());
}
// Get the new direction starting on
- int var8 = (scene->_action1._field1E * 2 + scene->_mazeDirection);
- if (var8 > MAZEDIR_NORTHWEST)
- var8 = MAZEDIR_NORTH;
- else if (var8 < MAZEDIR_NORTH)
- var8 = MAZEDIR_WEST;
+ int direction = (scene->_action1._direction * 2 + scene->_mazeDirection);
+ if (direction > MAZEDIR_NORTHWEST)
+ direction = MAZEDIR_NORTH;
+ else if (direction < MAZEDIR_NORTH)
+ direction = MAZEDIR_WEST;
// Check whether movement is allowed in that direction. If so, then
// movement is started again
- switch (var8) {
+ switch (direction) {
case MAZEDIR_NORTH:
- if ( ((si != 2) && (si != 3) && (si != 6) && (si != 1) && (si != 23) && (si != 24) && (si != 4) && (si != 11))
+ if ( ((cellId != 2) && (cellId != 3) && (cellId != 6) && (cellId != 1) && (cellId != 23) && (cellId != 24) && (cellId != 4) && (cellId != 11))
|| (var6 != 0)) {
- if ((si != 25) && (si != 26) && (si != 5) && (si != 14) && (si != 15))
- _field20 = 0;
+ if ((cellId != 25) && (cellId != 26) && (cellId != 5) && (cellId != 14) && (cellId != 15))
+ _headingRightFl = false;
else if ((var6 != 0) || (di <= 3)) // useless, skipped: "|| (di == 0)"
- _field20 = 0;
+ _headingRightFl = false;
else
- _field20 = 1;
+ _headingRightFl = true;
} else
- _field20 = 1;
+ _headingRightFl = true;
break;
case MAZEDIR_EAST:
- if ( ((si != 12) && (si != 13) && (si != 11) && (si != 16) && (si != 26) && (si != 24) && (si != 15) && (si != 6) && (si != 31))
+ if ( ((cellId != 12) && (cellId != 13) && (cellId != 11) && (cellId != 16) && (cellId != 26) && (cellId != 24) && (cellId != 15) && (cellId != 6) && (cellId != 31))
|| (di != 0)) {
- if ((si != 25) && (si != 23) && (si != 14) && (si != 5) && (si != 4))
- _field20 = 0;
+ if ((cellId != 25) && (cellId != 23) && (cellId != 14) && (cellId != 5) && (cellId != 4))
+ _headingRightFl = false;
else if ((di != 0) || (var6 <= 3)) // useless, skipped: "|| (var6 == 0)"
- _field20 = 0;
+ _headingRightFl = false;
else
- _field20 = 1;
+ _headingRightFl = true;
} else
- _field20 = 1;
+ _headingRightFl = true;
break;
case MAZEDIR_SOUTH:
- if ( ((si != 2) && (si != 3) && (si != 6) && (si != 1) && (si != 25) && (si != 26) && (si != 5) && (si != 16) && (si != 31))
+ if ( ((cellId != 2) && (cellId != 3) && (cellId != 6) && (cellId != 1) && (cellId != 25) && (cellId != 26) && (cellId != 5) && (cellId != 16) && (cellId != 31))
|| (var6 != 0)) {
- if ((si != 23) && (si != 24) && (si != 4) && (si != 14) && (si != 15))
- _field20 = 0;
+ if ((cellId != 23) && (cellId != 24) && (cellId != 4) && (cellId != 14) && (cellId != 15))
+ _headingRightFl = false;
else if ((var6 != 0) || (di <= 3)) // useless, skipped: "|| (di == 0)"
- _field20 = 0;
+ _headingRightFl = false;
else
- _field20 = 1;
+ _headingRightFl = true;
} else
- _field20 = 1;
+ _headingRightFl = true;
break;
case MAZEDIR_WEST:
- if ( ((si != 12) && (si != 13) && (si != 11) && (si != 16) && (si != 25) && (si != 23) && (si != 14) && (si != 1) && (si != 31))
+ if ( ((cellId != 12) && (cellId != 13) && (cellId != 11) && (cellId != 16) && (cellId != 25) && (cellId != 23) && (cellId != 14) && (cellId != 1) && (cellId != 31))
|| (var6 != 0)) {
- if ((si != 26) && (si != 24) && (si != 15) && (si != 5) && (si != 4))
- _field20 = 0;
+ if ((cellId != 26) && (cellId != 24) && (cellId != 15) && (cellId != 5) && (cellId != 4))
+ _headingRightFl = false;
else if ((var6 <= 0) || (di != 0)) // useless, skipped: "|| (var6 == 0)"
- _field20 = 0;
+ _headingRightFl = false;
else
- _field20 = 1;
+ _headingRightFl = true;
} else
- _field20 = 1;
+ _headingRightFl = true;
default:
break;
}
}
// No break on purpose
case 2: {
- scene->_actor8.setPosition(Common::Point(160, 73));
- scene->_actor8._moveDiff.x = 160 - scene->_mazeChangeAmount;
- scene->_fieldAF8 = 160 - ((_field1E * 2) * 160);
- Common::Point pt(scene->_fieldAF8, 73);
+ scene->_tunnelVertCircle.setPosition(Common::Point(160, 73));
+ scene->_tunnelVertCircle._moveDiff.x = 160 - scene->_mazeChangeAmount;
+ scene->_moverVertX = 160 - ((_direction * 2) * 160);
+ Common::Point pt(scene->_moverVertX, 73);
NpcMover *mover = new NpcMover();
- scene->_actor8.addMover(mover, &pt, this);
+ scene->_tunnelVertCircle.addMover(mover, &pt, this);
- scene->_actor9.setPosition(Common::Point(160 + ((_field1E * 2) * 160), 73));
- scene->_actor9._moveDiff.x = 160 - scene->_mazeChangeAmount;
- scene->_fieldB9E = 160;
- Common::Point pt2(scene->_fieldB9E, 73);
+ scene->_tunnelHorzCircle.setPosition(Common::Point(160 + ((_direction * 2) * 160), 73));
+ scene->_tunnelHorzCircle._moveDiff.x = 160 - scene->_mazeChangeAmount;
+ scene->_moverHorzX = 160;
+ Common::Point pt2(scene->_moverHorzX, 73);
NpcMover *mover2 = new NpcMover();
- scene->_actor9.addMover(mover2, &pt2, NULL);
+ scene->_tunnelHorzCircle.addMover(mover2, &pt2, NULL);
}
break;
case 5:
- scene->_actor1._frameChange = _field1E;
- scene->_mazeDirection = scene->_actor1.changeFrame();
- scene->_actor1.setFrame(scene->_mazeDirection);
+ scene->_shuttle._frameChange = _direction;
+ scene->_mazeDirection = scene->_shuttle.changeFrame();
+ scene->_shuttle.setFrame(scene->_mazeDirection);
setDelay(1);
break;
case 6:
- scene->_actor8.setPosition(Common::Point(160, 73));
- if (_field20 == 0)
- scene->_actor8.setStrip(1);
+ scene->_tunnelVertCircle.setPosition(Common::Point(160, 73));
+ if (!_headingRightFl)
+ scene->_tunnelVertCircle.setStrip(1);
else
- scene->_actor8.setStrip(2);
- scene->_actor8.fixPriority(1);
+ scene->_tunnelVertCircle.setStrip(2);
+ scene->_tunnelVertCircle.fixPriority(1);
- scene->_actor9.setPosition(Common::Point(-160, 73));
- scene->_actor9.setStrip(9);
- scene->_actor9.fixPriority(11);
- scene->_actor9.hide();
+ scene->_tunnelHorzCircle.setPosition(Common::Point(-160, 73));
+ scene->_tunnelHorzCircle.setStrip(9);
+ scene->_tunnelHorzCircle.fixPriority(11);
+ scene->_tunnelHorzCircle.hide();
setDelay(1);
break;
case 7:
- if ((scene->_actor1._frame % 2) == 0) {
- scene->_actor1._frameChange = _field1E;
- scene->_mazeDirection = scene->_actor1.changeFrame();
- scene->_actor1.setFrame(scene->_mazeDirection);
+ if ((scene->_shuttle._frame % 2) == 0) {
+ scene->_shuttle._frameChange = _direction;
+ scene->_mazeDirection = scene->_shuttle.changeFrame();
+ scene->_shuttle.setFrame(scene->_mazeDirection);
}
setDelay(1);
break;
case 8: {
R2_GLOBALS._player.enableControl();
R2_GLOBALS._player._canWalk = false;
- scene->_field1286 = 1;
- if ((scene->_actor1._frame % 2) == 0) {
- scene->_actor1._frameChange = _field1E;
- scene->_actor1.setFrame(scene->_actor1.changeFrame());
+ scene->_directionChangesEnabled = true;
+ if ((scene->_shuttle._frame % 2) == 0) {
+ scene->_shuttle._frameChange = _direction;
+ scene->_shuttle.setFrame(scene->_shuttle.changeFrame());
}
- // All the var_8 initialization was missing in the original
+ // CHECKME: All the var_8 initialization was missing in the original
// but it's clearly a cut and paste error from case 4.
// The following code allows the switch to work properly.
- warning("Checkme: fix for dead code");
- int var_8 = (_field1E * 2 + scene->_mazeDirection);
+ int var_8 = (_direction * 2 + scene->_mazeDirection);
if (var_8 > 7)
var_8 = 1;
else if (var_8 < 1)
@@ -3199,47 +3235,47 @@ void Scene3500::Action1::signal() {
default:
break;
}
- scene->_actor5.hide();
- scene->_actor6.hide();
- _field24 = 0;
- if (_field20 == 0) {
- scene->_actor7.sub1094ED();
- if (scene->_mazeChangeAmount == scene->_field1270)
+ scene->_symbolLeft.hide();
+ scene->_symbolRight.hide();
+ _turningFl = false;
+ if (!_headingRightFl) {
+ scene->_throttle.updateSpeed();
+ if (scene->_mazeChangeAmount == scene->_speed)
scene->_aSound1.play(276);
}
break;
}
case 10: {
- scene->_fieldAF8 = 160;
+ scene->_moverVertX = 160;
Common::Point pt(160, 73);
NpcMover *mover = new NpcMover();
- scene->_actor8.addMover(mover, &pt, NULL);
+ scene->_tunnelVertCircle.addMover(mover, &pt, NULL);
- scene->_fieldB9E = 160 - (_field1E * 2 * 160);
- Common::Point pt2(scene->_fieldB9E, 73);
+ scene->_moverHorzX = 160 - (_direction * 2 * 160);
+ Common::Point pt2(scene->_moverHorzX, 73);
NpcMover *mover2 = new NpcMover();
- scene->_actor9.addMover(mover2, &pt2, this);
+ scene->_tunnelHorzCircle.addMover(mover2, &pt2, this);
_actionIndex = 6;
}
break;
case 11: {
- scene->_actor8.setStrip(2);
- scene->_actor8.setPosition(Common::Point(160, 73));
- scene->_fieldAF8 = 160 - (_field1E * 2 * 160);
- Common::Point pt(scene->_fieldAF8, 73);
+ scene->_tunnelVertCircle.setStrip(2);
+ scene->_tunnelVertCircle.setPosition(Common::Point(160, 73));
+ scene->_moverVertX = 160 - (_direction * 2 * 160);
+ Common::Point pt(scene->_moverVertX, 73);
NpcMover *mover = new NpcMover();
- scene->_actor8.addMover(mover, &pt, NULL);
- scene->_actor8.fixPriority(11);
- if (_field20 == 0)
- scene->_actor9.setStrip(1);
+ scene->_tunnelVertCircle.addMover(mover, &pt, NULL);
+ scene->_tunnelVertCircle.fixPriority(11);
+ if (!_headingRightFl)
+ scene->_tunnelHorzCircle.setStrip(1);
else
- scene->_actor9.setStrip(2);
- scene->_actor9.setPosition(Common::Point(160 - (_field1E * 2 * 160), 73));
- scene->_fieldB9E = 160;
- Common::Point pt2(scene->_fieldB9E, 73);
+ scene->_tunnelHorzCircle.setStrip(2);
+ scene->_tunnelHorzCircle.setPosition(Common::Point(160 - (_direction * 2 * 160), 73));
+ scene->_moverHorzX = 160;
+ Common::Point pt2(scene->_moverHorzX, 73);
NpcMover *mover2 = new NpcMover();
- scene->_actor9.addMover(mover2, &pt2, this);
- scene->_actor9.fixPriority(1);
+ scene->_tunnelHorzCircle.addMover(mover2, &pt2, this);
+ scene->_tunnelHorzCircle.fixPriority(1);
_actionIndex = 5;
}
break;
@@ -3261,231 +3297,24 @@ void Scene3500::Action1::dispatch() {
/*--------------------------------------------------------------------------*/
Scene3500::Action2::Action2() {
- _field1E = 0;
+ _direction = 0;
}
void Scene3500::Action2::synchronize(Serializer &s) {
Action::synchronize(s);
- s.syncAsSint16LE(_field1E);
-}
-
-/*--------------------------------------------------------------------------*/
-
-Scene3500::Item4::Item4() {
- _field34 = 0;
-}
-
-void Scene3500::Item4::synchronize(Serializer &s) {
- NamedHotspot::synchronize(s);
-
- s.syncAsSint16LE(_field34);
-}
-
-/*--------------------------------------------------------------------------*/
-
-Scene3500::Actor7::Actor7() {
- _fieldA4 = 0;
- _fieldA6 = 0;
- _fieldA8 = 0;
- _fieldAA = 0;
- _fieldAC = 0;
- _fieldAE = 0;
-}
-
-void Scene3500::Actor7::synchronize(Serializer &s) {
- SceneActor::synchronize(s);
-
- s.syncAsSint16LE(_fieldA4);
- s.syncAsSint16LE(_fieldA6);
- s.syncAsSint16LE(_fieldA8);
- s.syncAsSint16LE(_fieldAA);
- s.syncAsSint16LE(_fieldAC);
- s.syncAsSint16LE(_fieldAE);
-}
-
-void Scene3500::Actor7::sub109466(int arg1, int arg2, int arg3, int arg4, int arg5) {
- _fieldAE = 0;
- _fieldA4 = arg1;
- _fieldA6 = arg2;
- _fieldA8 = arg3;
- _fieldAA = arg4;
- _fieldAC = _fieldAA / _fieldA8;
-
- postInit();
- setup(1050, 3, 1);
- fixPriority(255);
- sub109663(arg5);
-}
-
-void Scene3500::Actor7::sub1094ED() {
- Scene3500 *scene = (Scene3500 *)R2_GLOBALS._sceneManager._scene;
-
- scene->_field1270 = _position.x - _fieldA4;
-}
-
-void Scene3500::Actor7::sub109663(int arg1){
- sub109693(Common::Point(_fieldA4 + arg1, _fieldA6 - (_fieldAC * arg1)));
-}
-
-void Scene3500::Actor7::sub109693(Common::Point Pt) {
- setPosition(Pt);
-}
-
-/*--------------------------------------------------------------------------*/
-
-int Scene3500::MazeUI3500::cellFromX(int x) {
- return (_cellSize.x / 2) + x - (x % _cellSize.x);
-}
-
-int Scene3500::MazeUI3500::cellFromY(int y) {
- return (_cellSize.y / 2) + y - (y % _cellSize.y) - 1;
-}
-
-int Scene3500::MazeUI3500::getCellFromMapXY(Common::Point pt) {
- int cellX = pt.x / _cellSize.x;
- int cellY = pt.y / _cellSize.y;
-
- if ((cellX >= 0) && (cellY >= 0) && (cellX < _mapCells.x) && (cellY < _mapCells.y)) {
- return (int16)READ_LE_UINT16(_mapData + (_mapCells.x * cellY + cellX) * 2);
- } else
- return -1;
-}
-
-bool Scene3500::MazeUI3500::setMazePosition2(Common::Point &p) {
- bool retVal = setMazePosition(p);
- p = _mapOffset;
-
- return retVal;
-}
-
-Scene3500::Scene3500() {
- _fieldAF8 = 0;
- _fieldB9E = 0;
- _rotation = NULL;
- _mazeChangeAmount = 0;
- _field1270 = 0;
- _field1272 = 0;
- _field1274 = 0;
- _mazeDirection = MAZEDIR_NONE;
- _field1278 = 0;
- _mazePosition.x = 0;
- _mazePosition.y = 0;
- _field127E = 0;
- _field1280 = 0;
- _field1282 = 0;
- _field1284 = 0;
- _field1286 = 0;
-}
-
-void Scene3500::synchronize(Serializer &s) {
- SceneExt::synchronize(s);
- SYNC_POINTER(_rotation);
-
- s.syncAsSint16LE(_fieldAF8);
- s.syncAsSint16LE(_fieldB9E);
- s.syncAsSint16LE(_mazeChangeAmount);
- s.syncAsSint16LE(_field1270);
- s.syncAsSint16LE(_field1272);
- s.syncAsSint16LE(_field1274);
- s.syncAsSint16LE(_mazeDirection);
- s.syncAsSint16LE(_field1278);
- s.syncAsSint16LE(_mazePosition.x);
- s.syncAsSint16LE(_mazePosition.y);
- s.syncAsSint16LE(_field127E);
- s.syncAsSint16LE(_field1280);
- s.syncAsSint16LE(_field1282);
- s.syncAsSint16LE(_field1284);
- s.syncAsSint16LE(_field1286);
-}
-
-void Scene3500::sub107F71(int arg1) {
- switch (arg1) {
- case -1:
- _actor7.sub1094ED();
- if (_field1270 != 0) {
- _field1270--;
- _actor7.sub109663(_field1270);
- }
- if (_action1._field24 != 0)
- _field1270 = 0;
- break;
- case 1:
- _actor7.sub1094ED();
- if (_field1270 < 16) {
- ++_field1270;
- _actor7.sub109663(_field1270);
- }
- if (_action1._field24 != 0)
- _field1270 = 0;
- break;
- case 88:
- if ((_action == 0) || (_action1._field24 == 0)) {
- // The original makes a second useless check on action, skipped
- _action2.sub10831F(2);
- if ((_action) && ((_action2.getActionIndex() != 0) || (_action2._field1E != 2))) {
- _action2.signal();
- } else {
- _actor9.setAction(&_action2, &_actor9, NULL);
- }
- }
- break;
- case 96:
- if ((_action) && (_action1._field24 != 0) && (_action2._field1E != 1)) {
- _field1278 = 0;
- _action1.sub108732(0);
- } else if ((_action) && (_field1278 == 0) && (_action1._field24 != 0)) {
- _field1278 = arg1;
- } else if ((_action) && (_action1._field24 == 0)) {
- _action1.sub108670(1);
- _action1.signal();
- } else if (_action == 0) {
- _action1.sub108670(1);
- setAction(&_action1, &_actor1, NULL);
- }
- break;
- case 104:
- if ((_action == 0) || (_action1._field24 == 0)) {
- _action2.sub10831F(-1);
- if ((_action) && ((_action2.getActionIndex() != 0) || (_action2._field1E != -1))) {
- _action2.signal();
- } else {
- _actor9.setAction(&_action2, &_actor9, NULL);
- }
- }
- break;
- case 112:
- if ((_action) && (_action1._field24 != 0) && (_action2._field1E != -1)) {
- _field1278 = 0;
- _action1.sub108732(0);
- } else if ((_action) && (_field1278 == 0) && (_action1._field24 != 0)) {
- _field1278 = arg1;
- } else if ((_action) && (_action1._field24 == 0)) {
- _action1.sub108670(-1);
- _action1.signal();
- } else if (_action == 0) {
- _action1.sub108670(-1);
- setAction(&_action1, &_actor1, NULL);
- }
- break;
- default:
- _field1270 = arg1;
- _actor7.sub109663(arg1);
- if (_action1._field24 != 0) {
- _field1270 = 0;
- }
- break;
- }
+ s.syncAsSint16LE(_direction);
}
-void Scene3500::Action2::sub10831F(int arg1) {
+void Scene3500::Action2::handleVertButton(int direction) {
Scene3500 *scene = (Scene3500 *)R2_GLOBALS._sceneManager._scene;
- _field1E = arg1;
- if (_field1E == -1)
- scene->_actor3.setFrame2(3);
+ // Directions : 2 == up, -1 == down
+ _direction = direction;
+ if (_direction == -1)
+ scene->_horizontalSpeedDisplay.setFrame2(3);
else
- scene->_actor3.setFrame2(1);
+ scene->_horizontalSpeedDisplay.setFrame2(1);
setActionIndex(0);
}
@@ -3493,57 +3322,57 @@ void Scene3500::Action2::sub10831F(int arg1) {
void Scene3500::Action2::signal() {
Scene3500 *scene = (Scene3500 *)R2_GLOBALS._sceneManager._scene;
- int si;
- int di;
+ int vertX;
+ int horzX;
switch (_actionIndex++) {
case 0: {
- if (scene->_actor8._mover) {
- si = scene->_fieldAF8;
- di = scene->_fieldB9E;
+ if (scene->_tunnelVertCircle._mover) {
+ vertX = scene->_moverVertX;
+ horzX = scene->_moverHorzX;
} else {
- scene->_fieldAF8 = scene->_actor8._position.x;
- si = scene->_fieldAF8;
- scene->_fieldB9E = scene->_actor9._position.y;
- di = scene->_fieldB9E;
+ scene->_moverVertX = scene->_tunnelVertCircle._position.x;
+ vertX = scene->_moverVertX;
+ scene->_moverHorzX = scene->_tunnelHorzCircle._position.y;
+ horzX = scene->_moverHorzX;
}
- scene->_actor8._moveDiff.y = 9 - (scene->_mazeChangeAmount / 2);
- Common::Point pt(si, 73 - (_field1E * 12));
+ scene->_tunnelVertCircle._moveDiff.y = 9 - (scene->_mazeChangeAmount / 2);
+ Common::Point pt(vertX, 73 - (_direction * 12));
NpcMover *mover = new NpcMover();
- scene->_actor8.addMover(mover, &pt, NULL);
+ scene->_tunnelVertCircle.addMover(mover, &pt, NULL);
- scene->_actor9._moveDiff.y = 9 - (scene->_mazeChangeAmount / 2);
- Common::Point pt2(di, 73 - (_field1E * 12));
+ scene->_tunnelHorzCircle._moveDiff.y = 9 - (scene->_mazeChangeAmount / 2);
+ Common::Point pt2(horzX, 73 - (_direction * 12));
NpcMover *mover2 = new NpcMover();
- scene->_actor9.addMover(mover2, &pt2, NULL);
+ scene->_tunnelHorzCircle.addMover(mover2, &pt2, NULL);
scene->_mazeChangeAmount = (scene->_mazeChangeAmount / 2) + (scene->_mazeChangeAmount % 2);
setDelay(17 - scene->_mazeChangeAmount);
}
break;
case 1: {
R2_GLOBALS._sound2.play(339);
- if (scene->_actor8._mover) {
- si = scene->_fieldAF8;
- di = scene->_fieldB9E;
+ if (scene->_tunnelVertCircle._mover) {
+ vertX = scene->_moverVertX;
+ horzX = scene->_moverHorzX;
} else {
- si = scene->_actor8._position.x;
- di = scene->_actor9._position.x;
+ vertX = scene->_tunnelVertCircle._position.x;
+ horzX = scene->_tunnelHorzCircle._position.x;
}
- scene->_actor7.sub1094ED();
+ scene->_throttle.updateSpeed();
- scene->_actor8._moveDiff.y = 9 - (scene->_mazeChangeAmount / 2);
- Common::Point pt(si, 73);
+ scene->_tunnelVertCircle._moveDiff.y = 9 - (scene->_mazeChangeAmount / 2);
+ Common::Point pt(vertX, 73);
NpcMover *mover = new NpcMover();
- scene->_actor8.addMover(mover, &pt, NULL);
+ scene->_tunnelVertCircle.addMover(mover, &pt, NULL);
- scene->_actor9._moveDiff.y = 9 - (scene->_mazeChangeAmount / 2);
- Common::Point pt2(di, 73);
+ scene->_tunnelHorzCircle._moveDiff.y = 9 - (scene->_mazeChangeAmount / 2);
+ Common::Point pt2(horzX, 73);
NpcMover *mover2 = new NpcMover();
- scene->_actor9.addMover(mover2, &pt2, NULL);
+ scene->_tunnelHorzCircle.addMover(mover2, &pt2, NULL);
- scene->_actor3.setFrame2(2);
+ scene->_horizontalSpeedDisplay.setFrame2(2);
}
break;
default:
@@ -3551,66 +3380,187 @@ void Scene3500::Action2::signal() {
}
}
-bool Scene3500::Item4::startAction(CursorType action, Event &event) {
+/*--------------------------------------------------------------------------*/
+
+Scene3500::DirectionButton::DirectionButton() {
+ _movementId = 0;
+}
+
+void Scene3500::DirectionButton::synchronize(Serializer &s) {
+ NamedHotspot::synchronize(s);
+
+ s.syncAsSint16LE(_movementId);
+}
+
+bool Scene3500::DirectionButton::startAction(CursorType action, Event &event) {
Scene3500 *scene = (Scene3500 *)R2_GLOBALS._sceneManager._scene;
- if (scene->_field1286 == 0)
+ if (!scene->_directionChangesEnabled) {
return true;
-
- if (scene->_field1286 != 4)
+ } else if (action == CURSOR_USE) {
+ R2_GLOBALS._sound2.play(14, nullptr, 63);
+ scene->doMovement(_movementId);
+ return true;
+ } else {
return SceneHotspot::startAction(action, event);
+ }
+}
- R2_GLOBALS._sound2.play(14);
- scene->sub107F71(_field34);
+/*--------------------------------------------------------------------------*/
- return true;
+Scene3500::Throttle::Throttle() {
+ _deltaX = 1;
+ _deltaY = 0;
+ _slideDeltaY = 0;
+ _deltaMouseY = 0;
}
-void Scene3500::Actor7::process(Event &event) {
+void Scene3500::Throttle::synchronize(Serializer &s) {
+ SceneActor::synchronize(s);
+
+ s.syncAsSint16LE(_pos.x);
+ s.syncAsSint16LE(_pos.y);
+ s.syncAsSint16LE(_deltaX);
+ s.syncAsSint16LE(_deltaY);
+ s.syncAsSint16LE(_slideDeltaY);
+ s.syncAsSint16LE(_deltaMouseY);
+}
+
+void Scene3500::Throttle::init(int xp, int yp, int dx, int dy, int speed) {
+ _deltaMouseY = 0;
+ _pos = Common::Point(xp, yp);
+ _deltaX = dx;
+ _deltaY = dy;
+ _slideDeltaY = _deltaY / _deltaX;
+
+ postInit();
+ setup(1050, 3, 1);
+ fixPriority(255);
+ setSpeed(speed);
+}
+
+void Scene3500::Throttle::updateSpeed() {
+ Scene3500 *scene = (Scene3500 *)R2_GLOBALS._sceneManager._scene;
+
+ scene->_speed = _position.x - _pos.x;
+}
+
+void Scene3500::Throttle::setSpeed(int arg1){
+ changePosition(Common::Point(_pos.x + arg1, _pos.y - (_slideDeltaY * arg1)));
+}
+
+void Scene3500::Throttle::changePosition(const Common::Point &pt) {
+ setPosition(pt);
+}
+
+void Scene3500::Throttle::process(Event &event) {
Scene3500 *scene = (Scene3500 *)R2_GLOBALS._sceneManager._scene;
- if (scene->_field1286 == 0)
+ if (!scene->_directionChangesEnabled)
return;
if ((event.eventType == EVENT_BUTTON_DOWN) && (R2_GLOBALS._events.getCursor() == CURSOR_USE) && (_bounds.contains(event.mousePos))) {
- _fieldAE = 1 + event.mousePos.y - _position.y;
+ _deltaMouseY = 1 + event.mousePos.y - _position.y;
event.eventType = EVENT_NONE;
}
- if ((event.eventType == EVENT_BUTTON_UP) && (_fieldAE != 0)) {
- _fieldAE = 0;
+ if ((event.eventType == EVENT_BUTTON_UP) && (_deltaMouseY != 0)) {
+ _deltaMouseY = 0;
event.handled = true;
- if (scene->_action1._field24 == 0)
- sub1094ED();
+ if (!scene->_action1._turningFl)
+ updateSpeed();
}
- if (_fieldAE == 0)
+ if (_deltaMouseY == 0)
return;
R2_GLOBALS._sound2.play(338);
event.handled = true;
- int cx = event.mousePos.y - _fieldAE + 1;
- if (_fieldA6 >= cx) {
- if (_fieldA6 - _fieldAA <= cx)
- sub109693(Common::Point(((_fieldA6 - cx) / 2) + _fieldA4 + ((_fieldA6 - cx) % 2), cx));
+ int cx = event.mousePos.y - _deltaMouseY + 1;
+ if (_pos.y >= cx) {
+ if (_pos.y - _deltaY <= cx)
+ changePosition(Common::Point(((_pos.y - cx) / 2) + _pos.x + ((_pos.y - cx) % 2), cx));
else
- sub109693(Common::Point(_fieldA4 + _fieldA8, _fieldA6 - _fieldAA));
+ changePosition(Common::Point(_pos.x + _deltaX, _pos.y - _deltaY));
} else {
- sub109693(Common::Point(_fieldA4, _fieldA6));
+ changePosition(Common::Point(_pos.x, _pos.y));
}
}
-bool Scene3500::Actor7::startAction(CursorType action, Event &event) {
+bool Scene3500::Throttle::startAction(CursorType action, Event &event) {
Scene3500 *scene = (Scene3500 *)R2_GLOBALS._sceneManager._scene;
- if (scene->_field1286 == 0)
+ if (!scene->_directionChangesEnabled) {
return true;
-
- if (scene->_field1286 == 4)
+ } else if (action == CURSOR_USE) {
return false;
+ } else {
+ return SceneActor::startAction(action, event);
+ }
+}
- return SceneActor::startAction(action, event);
+/*--------------------------------------------------------------------------*/
+
+int16 Scene3500::MazeUI3500::cellFromX(int x) {
+ return (_cellSize.x / 2) + x - (x % _cellSize.x);
+}
+
+int16 Scene3500::MazeUI3500::cellFromY(int y) {
+ return (_cellSize.y / 2) + y - (y % _cellSize.y) - 1;
+}
+
+int Scene3500::MazeUI3500::getCellFromMapXY(Common::Point pt) {
+ int cellX = pt.x / _cellSize.x;
+ int cellY = pt.y / _cellSize.y;
+
+ if ((cellX >= 0) && (cellY >= 0) && (cellX < _mapCells.x) && (cellY < _mapCells.y)) {
+ return (int16)READ_LE_UINT16(_mapData + (_mapCells.x * cellY + cellX) * 2);
+ } else
+ return -1;
+}
+
+bool Scene3500::MazeUI3500::setMazePosition2(Common::Point &p) {
+ bool retVal = setMazePosition(p);
+ p = _mapOffset;
+
+ return retVal;
+}
+
+/*--------------------------------------------------------------------------*/
+
+Scene3500::Scene3500() {
+ _moverVertX = 0;
+ _moverHorzX = 0;
+ _rotation = NULL;
+ _mazeChangeAmount = 0;
+ _speed = 0;
+ _updateIdxChangeFl = false;
+ _mazeDirection = MAZEDIR_NONE;
+ _nextMove = 0;
+ _mazePosition.x = 0;
+ _mazePosition.y = 0;
+ _postFixupFl = true; // Set to true in fixup()
+ _exitCounter = 0;
+ _directionChangesEnabled = false;
+}
+
+void Scene3500::synchronize(Serializer &s) {
+ SceneExt::synchronize(s);
+ SYNC_POINTER(_rotation);
+
+ s.syncAsSint16LE(_moverVertX);
+ s.syncAsSint16LE(_moverHorzX);
+ s.syncAsSint16LE(_mazeChangeAmount);
+ s.syncAsSint16LE(_speed);
+ s.syncAsSint16LE(_updateIdxChangeFl);
+ s.syncAsSint16LE(_mazeDirection);
+ s.syncAsSint16LE(_nextMove);
+ s.syncAsSint16LE(_mazePosition.x);
+ s.syncAsSint16LE(_mazePosition.y);
+ s.syncAsSint16LE(_postFixupFl);
+ s.syncAsSint16LE(_exitCounter);
+ s.syncAsSint16LE(_directionChangesEnabled);
}
void Scene3500::postInit(SceneObjectList *OwnerList) {
@@ -3618,19 +3568,18 @@ void Scene3500::postInit(SceneObjectList *OwnerList) {
loadScene(1050);
R2_GLOBALS._uiElements._active = false;
- R2_GLOBALS._interfaceY = 200;
+ R2_GLOBALS._interfaceY = SCREEN_HEIGHT;
- R2_GLOBALS._v5589E.set(0, 0, 320, 200);
R2_GLOBALS._sound1.play(305);
R2_GLOBALS._player._characterIndex = R2_QUINN;
R2_GLOBALS._player._characterScene[R2_QUINN] = 3500;
R2_GLOBALS._player._characterScene[R2_SEEKER] = 3500;
R2_GLOBALS._player._characterScene[R2_MIRANDA] = 3500;
- _field1284 = 0;
- _field1282 = 0;
- _field1278 = 0;
- _field1272 = 1;
- _field1270 = 4;
+ _exitCounter = 0;
+ _postFixupFl = false;
+ _nextMove = 0;
+ _updateIdxChangeFl = true;
+ _speed = 4;
_mazeChangeAmount = 4;
_mazePosition = Common::Point(860, 891);
_rotation = R2_GLOBALS._scenePalette.addRotation(240, 254, -1);
@@ -3654,78 +3603,78 @@ void Scene3500::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._scenePalette._palette[(3 * i) + 2] = tmpPal[(3 * i) + 2];
}
- _actor7.sub109466(38, 165, 16, 32, _field1270);
- _actor7.setDetails(3500, 6, 7, -1, 1, (SceneItem *)NULL);
+ _throttle.init(38, 165, 16, 32, _speed);
+ _throttle.setDetails(3500, 6, 7, -1, 1, (SceneItem *)NULL);
R2_GLOBALS._sound1.play(276);
- _item4._field34 = 88;
- _item4.setDetails(88, 3500, 18, 10, -1);
+ _pitchDown._movementId = 88;
+ _pitchDown.setDetails(88, 3500, 18, 10, -1);
- _item5._field34 = 112;
- _item5.setDetails(112, 3500, 9, 10, -1);
+ _turnLeft._movementId = 112;
+ _turnLeft.setDetails(112, 3500, 9, 10, -1);
- _item6._field34 = 104;
- _item6.setDetails(104, 3500, 15, 10, -1);
+ _pitchUp._movementId = 104;
+ _pitchUp.setDetails(104, 3500, 15, 10, -1);
- _item7._field34 = 96;
- _item7.setDetails(96, 3500, 12, 10, -1);
+ _turnRight._movementId = 96;
+ _turnRight.setDetails(96, 3500, 12, 10, -1);
- _actor8.postInit();
- _actor8.setup(1050, 1, 1);
- _actor8.setPosition(Common::Point(160, 73));
- _actor8.fixPriority(1);
+ _tunnelVertCircle.postInit();
+ _tunnelVertCircle.setup(1050, 1, 1);
+ _tunnelVertCircle.setPosition(Common::Point(160, 73));
+ _tunnelVertCircle.fixPriority(1);
- _actor9.postInit();
- _actor9.setup(1050, 2, 1);
- _actor9.setPosition(Common::Point(-160, 73));
- _actor9.fixPriority(11);
- _actor9.hide();
+ _tunnelHorzCircle.postInit();
+ _tunnelHorzCircle.setup(1050, 2, 1);
+ _tunnelHorzCircle.setPosition(Common::Point(-160, 73));
+ _tunnelHorzCircle.fixPriority(11);
+ _tunnelHorzCircle.hide();
- _item2.setDetails(27, 3500, 21, -1, -1);
- _item3.setDetails(Rect(160, 89, 299, 182), 3500, 3, -1, -1, 1, NULL);
- _item1.setDetails(Rect(0, 0, 320, 200), 3500, 0, -1, 2, 1, NULL);
+ _outsideView.setDetails(27, 3500, 21, -1, -1);
+ _mapScreen.setDetails(Rect(160, 89, 299, 182), 3500, 3, -1, -1, 1, NULL);
+ _background.setDetails(Rect(0, 0, 320, 200), 3500, 0, -1, 2, 1, NULL);
- _actor1.postInit();
+ _shuttle.postInit();
_mazeDirection = MAZEDIR_NORTH;
- _actor1.setup(1004, 1, _mazeDirection);
- _actor1.setPosition(Common::Point(230, 135));
- _actor1.fixPriority(200);
- _actor1._frameChange = 1;
-
- _actor5.postInit();
- _actor5.setup(1004, 3, 1);
- _actor5.setPosition(Common::Point(117, 163));
- _actor5.fixPriority(200);
- _actor5.hide();
-
- _actor4.postInit();
- _actor4.setup(1004, 3, 2);
- _actor4.setPosition(Common::Point(126, 163));
- _actor4.fixPriority(200);
-
- _actor6.postInit();
- _actor6.setup(1004, 3, 3);
- _actor6.setPosition(Common::Point(135, 163));
- _actor6.fixPriority(200);
- _actor6.hide();
-
- _actor2.postInit();
- _actor2.setup(1004, 4, _mazeChangeAmount + 1);
- _actor2.setPosition(Common::Point(126, 137));
- _actor2.fixPriority(200);
-
- _actor3.postInit();
- _actor3.setup(1004, 5, 2);
- _actor3.setPosition(Common::Point(126, 108));
- _actor3.fixPriority(200);
+ _shuttle.setup(1004, 1, _mazeDirection);
+ _shuttle.setPosition(Common::Point(230, 135));
+ _shuttle.fixPriority(200);
+ _shuttle._frameChange = 1;
+
+ _symbolLeft.postInit();
+ _symbolLeft.setup(1004, 3, 1);
+ _symbolLeft.setPosition(Common::Point(117, 163));
+ _symbolLeft.fixPriority(200);
+ _symbolLeft.hide();
+
+ _symbolVertical.postInit();
+ _symbolVertical.setup(1004, 3, 2);
+ _symbolVertical.setPosition(Common::Point(126, 163));
+ _symbolVertical.fixPriority(200);
+
+ _symbolRight.postInit();
+ _symbolRight.setup(1004, 3, 3);
+ _symbolRight.setPosition(Common::Point(135, 163));
+ _symbolRight.fixPriority(200);
+ _symbolRight.hide();
+
+ _verticalSpeedDisplay.postInit();
+ _verticalSpeedDisplay.setup(1004, 4, _mazeChangeAmount + 1);
+ _verticalSpeedDisplay.setPosition(Common::Point(126, 137));
+ _verticalSpeedDisplay.fixPriority(200);
+
+ _horizontalSpeedDisplay.postInit();
+ _horizontalSpeedDisplay.setup(1004, 5, 2);
+ _horizontalSpeedDisplay.setPosition(Common::Point(126, 108));
+ _horizontalSpeedDisplay.fixPriority(200);
_mazeUI.setDisplayBounds(Rect(160, 89, 299, 182));
_mazeUI.load(2);
_mazeUI.setMazePosition(_mazePosition);
- _action1._field24 = 0;
+ _action1._turningFl = false;
_mazeUI.draw();
- _field1286 = 1;
+ _directionChangesEnabled = true;
R2_GLOBALS._player.postInit();
R2_GLOBALS._player.hide();
@@ -3734,6 +3683,99 @@ void Scene3500::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player._canWalk = false;
}
+void Scene3500::doMovement(int id) {
+ switch (id) {
+ case -1:
+ _throttle.updateSpeed();
+ if (_speed != 0) {
+ _speed--;
+ _throttle.setSpeed(_speed);
+ }
+ if (_action1._turningFl)
+ _speed = 0;
+ break;
+ case 1:
+ _throttle.updateSpeed();
+ if (_speed < 16) {
+ ++_speed;
+ _throttle.setSpeed(_speed);
+ }
+ if (_action1._turningFl)
+ _speed = 0;
+ break;
+ case 88:
+ // Up button has been pressed
+ // The original was doing a double check on action, only one is here.
+ if (!_action || (!_action1._turningFl)) {
+ _action2.handleVertButton(2);
+ if (_action && ((_action2.getActionIndex() != 0) || (_action2._direction != 2))) {
+ _action2.signal();
+ } else {
+ _tunnelHorzCircle.setAction(&_action2, &_tunnelHorzCircle, NULL);
+ }
+ }
+ break;
+ case 96:
+ // Right button has been pressed
+ if (!_action || !_action1._turningFl || (_action1._direction == 1)) {
+ if (_action && (_nextMove == 0) && (_action1._turningFl)) {
+ _nextMove = id;
+ } else if (_action && (!_action1._turningFl)) {
+ _action1.handleHorzButton(1);
+ _action1.signal();
+ } else if (!_action) {
+ _action1.handleHorzButton(1);
+ setAction(&_action1, &_shuttle, NULL);
+ }
+
+ } else {
+ if (_nextMove != 0)
+ _nextMove = 0;
+
+ _action1.turnShuttle(false);
+ }
+ break;
+ case 104:
+ // Down button has been pressed
+ if (!_action || (!_action1._turningFl)) {
+ _action2.handleVertButton(-1);
+ if ((_action) && ((_action2.getActionIndex() != 0) || (_action2._direction != -1))) {
+ _action2.signal();
+ } else {
+ _tunnelHorzCircle.setAction(&_action2, &_tunnelHorzCircle, NULL);
+ }
+ }
+ break;
+ case 112:
+ // Left button has been pressed
+ if (!_action || !_action1._turningFl || (_action1._direction == 1)) {
+ if (_action && (_nextMove == 0) && (_action1._turningFl)) {
+ _nextMove = id;
+ } else if (_action && (!_action1._turningFl)) {
+ _action1.handleHorzButton(-1);
+ _action1.signal();
+ } else if (!_action) {
+ _action1.handleHorzButton(-1);
+ setAction(&_action1, &_shuttle, NULL);
+ }
+
+ } else {
+ if (_nextMove != 0)
+ _nextMove = 0;
+
+ _action1.turnShuttle(false);
+ }
+ break;
+ default:
+ _speed = id;
+ _throttle.setSpeed(id);
+ if (_action1._turningFl) {
+ _speed = 0;
+ }
+ break;
+ }
+}
+
void Scene3500::remove() {
R2_GLOBALS._sound2.fadeOut2(NULL);
SceneExt::remove();
@@ -3742,69 +3784,69 @@ void Scene3500::remove() {
void Scene3500::signal() {
R2_GLOBALS._player.enableControl(CURSOR_USE);
R2_GLOBALS._player._canWalk = false;
- _field1286 = 1;
+ _directionChangesEnabled = true;
}
void Scene3500::process(Event &event) {
- if (_field1286 == 0)
+ if (!_directionChangesEnabled)
return;
if (event.eventType == EVENT_KEYPRESS) {
switch (event.kbd.keycode) {
case Common::KEYCODE_KP7:
R2_GLOBALS._sound2.play(338);
- sub107F71(16);
+ doMovement(16);
event.handled = true;
break;
case Common::KEYCODE_UP:
case Common::KEYCODE_KP8:
R2_GLOBALS._sound2.play(14, NULL, 63);
- sub107F71(88);
+ doMovement(88);
event.handled = true;
break;
case Common::KEYCODE_KP9:
- if (_field1270 < 16)
+ if (_speed < 16)
R2_GLOBALS._sound2.play(338);
- sub107F71(1);
+ doMovement(1);
event.handled = true;
break;
case Common::KEYCODE_KP4:
case Common::KEYCODE_LEFT:
R2_GLOBALS._sound2.play(14, NULL, 63);
- sub107F71(112);
+ doMovement(112);
event.handled = true;
break;
case Common::KEYCODE_KP6:
case Common::KEYCODE_RIGHT:
R2_GLOBALS._sound2.play(14, NULL, 63);
- sub107F71(96);
+ doMovement(96);
event.handled = true;
break;
case Common::KEYCODE_KP1:
R2_GLOBALS._sound2.play(338);
- sub107F71(0);
+ doMovement(0);
event.handled = true;
break;
case Common::KEYCODE_KP2:
case Common::KEYCODE_DOWN:
R2_GLOBALS._sound2.play(14, NULL, 63);
- sub107F71(104);
+ doMovement(104);
event.handled = true;
break;
case Common::KEYCODE_KP3:
- if (_field1270 != 0)
+ if (_speed != 0)
R2_GLOBALS._sound2.play(338);
- sub107F71(-1);
+ doMovement(-1);
event.handled = true;
break;
case Common::KEYCODE_KP0:
R2_GLOBALS._sound2.play(338);
- sub107F71(8);
+ doMovement(8);
event.handled = true;
break;
case Common::KEYCODE_KP_PERIOD:
R2_GLOBALS._sound2.play(338);
- sub107F71(4);
+ doMovement(4);
event.handled = true;
break;
default:
@@ -3813,19 +3855,19 @@ void Scene3500::process(Event &event) {
}
if (!event.handled)
- _actor7.process(event);
+ _throttle.process(event);
if (!event.handled)
- _item4.process(event);
+ _pitchDown.process(event);
if (!event.handled)
- _item5.process(event);
+ _turnLeft.process(event);
if (!event.handled)
- _item6.process(event);
+ _pitchUp.process(event);
if (!event.handled)
- _item7.process(event);
+ _turnRight.process(event);
Scene::process(event);
}
@@ -3834,104 +3876,104 @@ void Scene3500::dispatch() {
Rect tmpRect;
Scene::dispatch();
- if (((_actor1._frame % 2) == 0) && (_action1._field24 == 0)) {
- _actor1.setFrame(_actor1.changeFrame());
- _mazeDirection = _actor1._frame;
+ if (((_shuttle._frame % 2) == 0) && (!_action1._turningFl)) {
+ _shuttle.setFrame(_shuttle.changeFrame());
+ _mazeDirection = _shuttle._frame;
}
- int oldField1278;
- if ((_field1278 != 0) && (_action1._field24 == 0)) {
- oldField1278 = _field1278;
- _field1278 = 0;
- sub107F71(oldField1278);
+
+ if ((_nextMove != 0) && (!_action1._turningFl)) {
+ int move = _nextMove;
+ _nextMove = 0;
+ doMovement(move);
}
if (!_rotation)
return;
- int newMazeX = 0;
- int newMazeY = 0;
- int var_4 = 0;
- int var_6 = 0;
- int var_8 = 0;
- int var_a = 0;
- int dx = 0;
+ int16 newMazeX = 0;
+ int16 newMazeY = 0;
+ int16 mazePosX = 0;
+ int16 mazePosY = 0;
+ int deltaX = 0;
+ int deltaY = 0;
+ int tmpCellId = 0;
int cellId = 0;
- if ((_mazeChangeAmount == 0) && (_field1282 == 0)) {
- if (_field1284 == 2)
+ if ((_mazeChangeAmount == 0) && !_postFixupFl) {
+ if (_exitCounter == 2)
R2_GLOBALS._sceneManager.changeScene(1000);
} else {
- _field1282 = 0;
+ _postFixupFl = false;
tmpRect.set(160, 89, 299, 182);
newMazeX = _mazePosition.x;
newMazeY = _mazePosition.y;
- var_4 = _mazeUI.cellFromX(newMazeX + 70) - 70;
- var_6 = _mazeUI.cellFromY(_mazePosition.y + 46) - 46;
- var_8 = abs(var_4 - newMazeX);
- var_a = abs(var_6 - newMazeY);
- dx = 0;
+ mazePosX = _mazeUI.cellFromX(newMazeX + 70) - 70;
+ mazePosY = _mazeUI.cellFromY(_mazePosition.y + 46) - 46;
+ deltaX = abs(mazePosX - newMazeX);
+ deltaY = abs(mazePosY - newMazeY);
+ tmpCellId = 0;
switch (_mazeDirection) {
case MAZEDIR_NORTH:
cellId = _mazeUI.getCellFromMapXY(Common::Point(newMazeX + 70, newMazeY + 46));
if (((cellId == 2) || (cellId == 3) || (cellId == 6) || (cellId == 1)) ||
- ((cellId == 25 || cellId == 26 || cellId == 5 || cellId == 14 || cellId == 15) && var_8 > 3)) {
+ ((cellId == 25 || cellId == 26 || cellId == 5 || cellId == 14 || cellId == 15) && deltaX > 3)) {
R2_GLOBALS._sound2.play(339);
_rotation->_idxChange = 0;
- _field1270 = 0;
+ _speed = 0;
_mazeChangeAmount = 0;
- _field1272 = 0;
- if (_action1._field24 == 0)
- _actor8.hide();
+ _updateIdxChangeFl = false;
+ if (!_action1._turningFl)
+ _tunnelVertCircle.hide();
} else {
- var_6 = _mazeUI.cellFromY(newMazeY + 46) - 46;
+ mazePosY = _mazeUI.cellFromY(newMazeY + 46) - 46;
newMazeY = _mazePosition.y - _mazeChangeAmount;
- dx = _mazeUI.getCellFromMapXY(Common::Point(newMazeX + 70, newMazeY + 46));
- if (((cellId == 23) || (cellId == 24) || (cellId == 4)) && (cellId != dx)) {
- newMazeY = var_6;
+ tmpCellId = _mazeUI.getCellFromMapXY(Common::Point(newMazeX + 70, newMazeY + 46));
+ if (((cellId == 23) || (cellId == 24) || (cellId == 4)) && (cellId != tmpCellId)) {
+ newMazeY = mazePosY;
R2_GLOBALS._sound2.play(339);
_rotation->_idxChange = 0;
- _field1270 = 0;
+ _speed = 0;
_mazeChangeAmount = 0;
- _field1272 = 0;
- if (_action1._field24 == 0)
- _actor8.hide();
- } else if ((cellId == 11) && (cellId != dx)) {
- newMazeY = var_6 + 3;
+ _updateIdxChangeFl = false;
+ if (!_action1._turningFl)
+ _tunnelVertCircle.hide();
+ } else if ((cellId == 11) && (cellId != tmpCellId)) {
+ newMazeY = mazePosY + 3;
R2_GLOBALS._sound2.play(339);
_rotation->_idxChange = 0;
- _field1270 = 0;
+ _speed = 0;
_mazeChangeAmount = 0;
- _field1272 = 0;
- if (_action1._field24 == 0)
- _actor8.hide();
+ _updateIdxChangeFl = false;
+ if (!_action1._turningFl)
+ _tunnelVertCircle.hide();
} else {
- var_6 = _mazeUI.cellFromY(newMazeY + 46) - 46;
- var_a = abs(var_6 - newMazeY);
+ mazePosY = _mazeUI.cellFromY(newMazeY + 46) - 46;
+ deltaY = abs(mazePosY - newMazeY);
cellId = _mazeUI.getCellFromMapXY(Common::Point(newMazeX + 70, newMazeY + 46));
- if ( (((cellId == 23) || (cellId == 24) || (cellId == 4)) && (newMazeY <= var_6) && (_mazePosition.y>= var_6))
- || (((cellId == 25) || (cellId == 26) || (cellId == 5) || (cellId == 14) || (cellId == 15)) && (_mazeChangeAmount >= var_a) && (_mazeChangeAmount > 3) && (_action1._field24 != 0)) ) {
- newMazeY = var_6;
+ if ( (((cellId == 23) || (cellId == 24) || (cellId == 4)) && (newMazeY <= mazePosY) && (_mazePosition.y>= mazePosY))
+ || (((cellId == 25) || (cellId == 26) || (cellId == 5) || (cellId == 14) || (cellId == 15)) && (_mazeChangeAmount >= deltaY) && (_mazeChangeAmount > 3) && (_action1._turningFl != 0)) ) {
+ newMazeY = mazePosY;
if ((cellId != 25) && (cellId != 26) && (cellId != 5) && (cellId != 14) && (cellId == 15))
R2_GLOBALS._sound2.play(339);
_rotation->_idxChange = 0;
- _field1270 = 0;
+ _speed = 0;
_mazeChangeAmount = 0;
- _field1272 = 0;
- if (_action1._field24 == 0)
- _actor8.hide();
- } else if ((cellId == 11) && (var_6 + 3 >= newMazeY) && (_mazePosition.y >= var_6 + 3)) {
+ _updateIdxChangeFl = false;
+ if (!_action1._turningFl)
+ _tunnelVertCircle.hide();
+ } else if ((cellId == 11) && (mazePosY + 3 >= newMazeY) && (_mazePosition.y >= mazePosY + 3)) {
R2_GLOBALS._sound2.play(339);
_rotation->_idxChange = 0;
- _field1270 = 0;
+ _speed = 0;
_mazeChangeAmount = 0;
- _field1272 = 0;
- if (_action1._field24 == 0)
- _actor8.hide();
- } else if (((cellId == 25) || (cellId == 26) || (cellId == 5) || (cellId == 14) || (cellId == 15)) && (var_8 != 0) && (var_8 <= 3)) {
- newMazeX = var_4;
+ _updateIdxChangeFl = false;
+ if (!_action1._turningFl)
+ _tunnelVertCircle.hide();
+ } else if (((cellId == 25) || (cellId == 26) || (cellId == 5) || (cellId == 14) || (cellId == 15)) && (deltaX != 0) && (deltaX <= 3)) {
+ newMazeX = mazePosX;
R2_GLOBALS._sound2.play(339);
} else {
// Nothing
@@ -3942,62 +3984,62 @@ void Scene3500::dispatch() {
case MAZEDIR_EAST:
cellId = _mazeUI.getCellFromMapXY(Common::Point(newMazeX + 70, newMazeY + 46));
if ( ((cellId == 12) || (cellId == 13) || (cellId == 11) || (cellId == 16) || (cellId == 31))
- || (((cellId == 25) || (cellId == 23) || (cellId == 14) || (cellId == 5) || (cellId == 4)) && (var_a > 3)) ) {
+ || (((cellId == 25) || (cellId == 23) || (cellId == 14) || (cellId == 5) || (cellId == 4)) && (deltaY > 3)) ) {
R2_GLOBALS._sound2.play(339);
_rotation->_idxChange = 0;
- _field1270 = 0;
+ _speed = 0;
_mazeChangeAmount = 0;
- _field1272 = 0;
- if (_action1._field24 == 0)
- _actor8.hide();
+ _updateIdxChangeFl = false;
+ if (!_action1._turningFl)
+ _tunnelVertCircle.hide();
} else {
- var_4 = _mazeUI.cellFromX(newMazeX + 70) - 70;
+ mazePosX = _mazeUI.cellFromX(newMazeX + 70) - 70;
newMazeX = _mazePosition.x + _mazeChangeAmount;
- dx = _mazeUI.getCellFromMapXY(Common::Point(newMazeX + 70, newMazeY + 46));
- if (((cellId == 26) || (cellId == 24) || (cellId == 15)) && (cellId != dx)) {
- newMazeX = var_4;
+ tmpCellId = _mazeUI.getCellFromMapXY(Common::Point(newMazeX + 70, newMazeY + 46));
+ if (((cellId == 26) || (cellId == 24) || (cellId == 15)) && (cellId != tmpCellId)) {
+ newMazeX = mazePosX;
R2_GLOBALS._sound2.play(339);
_rotation->_idxChange = 0;
- _field1270 = 0;
+ _speed = 0;
_mazeChangeAmount = 0;
- _field1272 = 0;
- if (_action1._field24 == 0)
- _actor8.hide();
- } else if ((cellId == 6) && (cellId != dx)) {
- newMazeX = var_4 - 5;
+ _updateIdxChangeFl = false;
+ if (!_action1._turningFl)
+ _tunnelVertCircle.hide();
+ } else if ((cellId == 6) && (cellId != tmpCellId)) {
+ newMazeX = mazePosX - 5;
R2_GLOBALS._sound2.play(339);
_rotation->_idxChange = 0;
- _field1270 = 0;
+ _speed = 0;
_mazeChangeAmount = 0;
- _field1272 = 0;
- if (_action1._field24 == 0)
- _actor8.hide();
+ _updateIdxChangeFl = false;
+ if (!_action1._turningFl)
+ _tunnelVertCircle.hide();
} else {
- var_4 = _mazeUI.cellFromX(newMazeX + 70) - 70;
- var_8 = abs(newMazeX - var_4);
+ mazePosX = _mazeUI.cellFromX(newMazeX + 70) - 70;
+ deltaX = abs(newMazeX - mazePosX);
cellId = _mazeUI.getCellFromMapXY(Common::Point(newMazeX + 70, newMazeY + 46));
- if ( (((cellId == 26) || (cellId == 24) || (cellId == 15)) && (newMazeX >= var_4) && (_mazePosition.x <= var_4))
- || (((cellId == 25) || (cellId == 23) || (cellId == 14) || (cellId == 5) || (cellId == 4)) && (_mazeChangeAmount >= var_8) && (_mazeChangeAmount <= 3) && (_action1._field24 != 0)) ) {
- newMazeX = var_4;
+ if ( (((cellId == 26) || (cellId == 24) || (cellId == 15)) && (newMazeX >= mazePosX) && (_mazePosition.x <= mazePosX))
+ || (((cellId == 25) || (cellId == 23) || (cellId == 14) || (cellId == 5) || (cellId == 4)) && (_mazeChangeAmount >= deltaX) && (_mazeChangeAmount <= 3) && (_action1._turningFl != 0)) ) {
+ newMazeX = mazePosX;
if ((cellId == 25) || (cellId == 23) || (cellId == 14) || (cellId == 5) || (cellId == 4))
R2_GLOBALS._sound2.play(339);
_rotation->_idxChange = 0;
- _field1270 = 0;
+ _speed = 0;
_mazeChangeAmount = 0;
- _field1272 = 0;
- if (_action1._field24 == 0)
- _actor8.hide();
- } else if ((cellId == 6) && (var_4 - 5 <= newMazeX) && (_mazePosition.x <= var_4 - 5)) {
- newMazeX = var_4 - 5;
+ _updateIdxChangeFl = false;
+ if (!_action1._turningFl)
+ _tunnelVertCircle.hide();
+ } else if ((cellId == 6) && (mazePosX - 5 <= newMazeX) && (_mazePosition.x <= mazePosX - 5)) {
+ newMazeX = mazePosX - 5;
R2_GLOBALS._sound2.play(339);
_rotation->_idxChange = 0;
- _field1270 = 0;
+ _speed = 0;
_mazeChangeAmount = 0;
- _field1272 = 0;
- if (_action1._field24 == 0)
- _actor8.hide();
- } else if (((cellId == 25) || (cellId == 23) || (cellId == 14) || (cellId == 5) || (cellId == 4)) && (var_a != 0) && (var_a <= 3)) {
- newMazeY = var_6;
+ _updateIdxChangeFl = false;
+ if (!_action1._turningFl)
+ _tunnelVertCircle.hide();
+ } else if (((cellId == 25) || (cellId == 23) || (cellId == 14) || (cellId == 5) || (cellId == 4)) && (deltaY != 0) && (deltaY <= 3)) {
+ newMazeY = mazePosY;
R2_GLOBALS._sound2.play(339);
} else {
// Nothing
@@ -4008,84 +4050,84 @@ void Scene3500::dispatch() {
case MAZEDIR_SOUTH:
cellId = _mazeUI.getCellFromMapXY(Common::Point(newMazeX + 70, newMazeY + 46));
if ( ((cellId == 2) || (cellId == 3) || (cellId == 6) || (cellId == 1))
- || (((cellId == 23) || (cellId == 24) || (cellId == 4) || (cellId == 14) || (cellId == 15)) && (var_8 > 3)) ) {
+ || (((cellId == 23) || (cellId == 24) || (cellId == 4) || (cellId == 14) || (cellId == 15)) && (deltaX > 3)) ) {
R2_GLOBALS._sound2.play(339);
_rotation->_idxChange = 0;
- _field1270 = 0;
+ _speed = 0;
_mazeChangeAmount = 0;
- _field1272 = 0;
- if (_action1._field24 == 0)
- _actor8.hide();
+ _updateIdxChangeFl = false;
+ if (!_action1._turningFl)
+ _tunnelVertCircle.hide();
} else {
- var_6 = _mazeUI.cellFromY(newMazeY + 46) - 46;
+ mazePosY = _mazeUI.cellFromY(newMazeY + 46) - 46;
newMazeY = _mazePosition.y + _mazeChangeAmount;
- dx = _mazeUI.getCellFromMapXY(Common::Point(newMazeX + 70, newMazeY + 46));
+ tmpCellId = _mazeUI.getCellFromMapXY(Common::Point(newMazeX + 70, newMazeY + 46));
- if (((cellId == 25) || (cellId == 26) || (cellId == 5)) && (cellId != dx)) {
+ if (((cellId == 25) || (cellId == 26) || (cellId == 5)) && (cellId != tmpCellId)) {
R2_GLOBALS._sound2.play(339);
_rotation->_idxChange = 0;
- _field1270 = 0;
+ _speed = 0;
_mazeChangeAmount = 0;
- _field1272 = 0;
- if (_action1._field24 == 0)
- _actor8.hide();
- } else if ((cellId == 16) && (cellId != dx)) {
- newMazeY = var_6 - 3;
+ _updateIdxChangeFl = false;
+ if (!_action1._turningFl)
+ _tunnelVertCircle.hide();
+ } else if ((cellId == 16) && (cellId != tmpCellId)) {
+ newMazeY = mazePosY - 3;
R2_GLOBALS._sound2.play(339);
_rotation->_idxChange = 0;
- _field1270 = 0;
+ _speed = 0;
_mazeChangeAmount = 0;
- _field1272 = 0;
- if (_action1._field24 == 0)
- _actor8.hide();
- } else if ((cellId == 31) && (cellId != dx)) {
- newMazeY = var_6 + 4;
+ _updateIdxChangeFl = false;
+ if (!_action1._turningFl)
+ _tunnelVertCircle.hide();
+ } else if ((cellId == 31) && (cellId != tmpCellId)) {
+ newMazeY = mazePosY + 4;
R2_GLOBALS._sound2.play(339);
_rotation->_idxChange = 0;
- _field1270 = 0;
+ _speed = 0;
_mazeChangeAmount = 0;
- _field1272 = 0;
- if (_action1._field24 == 0)
- _actor8.hide();
+ _updateIdxChangeFl = false;
+ if (!_action1._turningFl)
+ _tunnelVertCircle.hide();
} else {
- var_6 = _mazeUI.cellFromY(newMazeY + 46) - 46;
- var_a = abs(newMazeY - var_6);
+ mazePosY = _mazeUI.cellFromY(newMazeY + 46) - 46;
+ deltaY = abs(newMazeY - mazePosY);
cellId = _mazeUI.getCellFromMapXY(Common::Point(newMazeX + 70, newMazeY + 46));
- if ( (((cellId == 25) || (cellId == 26) || (cellId == 5)) && (newMazeY >= var_6) && (_mazePosition.y <= var_6))
- || (((cellId == 23) || (cellId == 24) || (cellId == 4) || (cellId == 14) || (cellId == 15)) && (_mazeChangeAmount >= var_a) && (_mazeChangeAmount <= 3) && (_action1._field24 != 0)) ){
- newMazeY = var_6;
+ if ( (((cellId == 25) || (cellId == 26) || (cellId == 5)) && (newMazeY >= mazePosY) && (_mazePosition.y <= mazePosY))
+ || (((cellId == 23) || (cellId == 24) || (cellId == 4) || (cellId == 14) || (cellId == 15)) && (_mazeChangeAmount >= deltaY) && (_mazeChangeAmount <= 3) && (_action1._turningFl != 0)) ){
+ newMazeY = mazePosY;
if ((cellId != 23) && (cellId != 24) && (cellId != 4) && (cellId != 14) && (cellId != 15))
R2_GLOBALS._sound2.play(339);
_rotation->_idxChange = 0;
- _field1270 = 0;
+ _speed = 0;
_mazeChangeAmount = 0;
- _field1272 = 0;
- if (_action1._field24 == 0)
- _actor8.hide();
- } else if ((cellId == 16) && (var_6 - 3 <= newMazeY) && (_mazePosition.y <= var_6 - 3)) {
- newMazeY = var_6 - 3;
+ _updateIdxChangeFl = false;
+ if (!_action1._turningFl)
+ _tunnelVertCircle.hide();
+ } else if ((cellId == 16) && (mazePosY - 3 <= newMazeY) && (_mazePosition.y <= mazePosY - 3)) {
+ newMazeY = mazePosY - 3;
R2_GLOBALS._sound2.play(339);
_rotation->_idxChange = 0;
- _field1270 = 0;
+ _speed = 0;
_mazeChangeAmount = 0;
- _field1272 = 0;
- if (_action1._field24 == 0)
- _actor8.hide();
- } else if ((cellId == 31) && (var_6 + 4 <= newMazeY) && (_mazePosition.y <= var_6 + 4)) {
- newMazeY = var_6 + 4;
+ _updateIdxChangeFl = false;
+ if (!_action1._turningFl)
+ _tunnelVertCircle.hide();
+ } else if ((cellId == 31) && (mazePosY + 4 <= newMazeY) && (_mazePosition.y <= mazePosY + 4)) {
+ newMazeY = mazePosY + 4;
_rotation->_idxChange = 0;
- _field1270 = 0;
+ _speed = 0;
_mazeChangeAmount = 0;
- _field1272 = 0;
- if (_action1._field24 == 0)
- _actor8.hide();
+ _updateIdxChangeFl = false;
+ if (!_action1._turningFl)
+ _tunnelVertCircle.hide();
if ((newMazeX == 660) && (_mazeChangeAmount + 306 <= newMazeY) && (newMazeY <= 307))
- ++_field1284;
+ ++_exitCounter;
else
R2_GLOBALS._sound2.play(339);
- } else if (((cellId == 23) || (cellId == 24) || (cellId == 4) || (cellId == 14) || (cellId == 15)) && (var_8 != 0) && (var_8 <= 3)) {
- newMazeX = var_4;
+ } else if (((cellId == 23) || (cellId == 24) || (cellId == 4) || (cellId == 14) || (cellId == 15)) && (deltaX != 0) && (deltaX <= 3)) {
+ newMazeX = mazePosX;
R2_GLOBALS._sound2.play(339);
} else {
// Nothing
@@ -4096,62 +4138,62 @@ void Scene3500::dispatch() {
case MAZEDIR_WEST:
cellId = _mazeUI.getCellFromMapXY(Common::Point(newMazeX + 70, newMazeY + 46));
if ( ((cellId == 12) || (cellId == 13) || (cellId == 11) || (cellId == 16) || (cellId == 31))
- || (((cellId == 26) || (cellId == 24) || (cellId == 15) || (cellId == 5) || (cellId == 4)) && (var_a > 3)) ) {
+ || (((cellId == 26) || (cellId == 24) || (cellId == 15) || (cellId == 5) || (cellId == 4)) && (deltaY > 3)) ) {
R2_GLOBALS._sound2.play(339);
_rotation->_idxChange = 0;
- _field1270 = 0;
+ _speed = 0;
_mazeChangeAmount = 0;
- _field1272 = 0;
- if (_action1._field24 == 0)
- _actor8.hide();
+ _updateIdxChangeFl = false;
+ if (!_action1._turningFl)
+ _tunnelVertCircle.hide();
} else {
- var_4 = _mazeUI.cellFromX(newMazeX + 70) - 70;
+ mazePosX = _mazeUI.cellFromX(newMazeX + 70) - 70;
newMazeX = _mazePosition.x - _mazeChangeAmount;
- dx = _mazeUI.getCellFromMapXY(Common::Point(newMazeX + 70, newMazeY + 46));
- if (((cellId == 25) || (cellId == 23) || (cellId == 14)) && (cellId != dx)) {
- newMazeX = var_4;
+ tmpCellId = _mazeUI.getCellFromMapXY(Common::Point(newMazeX + 70, newMazeY + 46));
+ if (((cellId == 25) || (cellId == 23) || (cellId == 14)) && (cellId != tmpCellId)) {
+ newMazeX = mazePosX;
R2_GLOBALS._sound2.play(339);
_rotation->_idxChange = 0;
- _field1270 = 0;
+ _speed = 0;
_mazeChangeAmount = 0;
- _field1272 = 0;
- if (_action1._field24 == 0)
- _actor8.hide();
- } else if ((cellId == 1) && (cellId != dx)) {
- newMazeX = var_4 + 5;
+ _updateIdxChangeFl = false;
+ if (!_action1._turningFl)
+ _tunnelVertCircle.hide();
+ } else if ((cellId == 1) && (cellId != tmpCellId)) {
+ newMazeX = mazePosX + 5;
R2_GLOBALS._sound2.play(339);
_rotation->_idxChange = 0;
- _field1270 = 0;
+ _speed = 0;
_mazeChangeAmount = 0;
- _field1272 = 0;
- if (_action1._field24 == 0)
- _actor8.hide();
+ _updateIdxChangeFl = false;
+ if (!_action1._turningFl)
+ _tunnelVertCircle.hide();
} else {
- var_4 = _mazeUI.cellFromX(newMazeX + 70) - 70;
- var_8 = abs(var_4 - newMazeX);
+ mazePosX = _mazeUI.cellFromX(newMazeX + 70) - 70;
+ deltaX = abs(mazePosX - newMazeX);
cellId = _mazeUI.getCellFromMapXY(Common::Point(newMazeX + 70, newMazeY + 46));
- if ( (((cellId == 25) || (cellId == 23) || (cellId == 14)) && (newMazeX <= var_4) && (_mazePosition.x >= var_4))
- || (((cellId == 26) || (cellId == 24) || (cellId == 15) || (cellId == 5) || (cellId == 4)) && (_mazeChangeAmount >= var_8) && (_mazeChangeAmount <= 3) && (_action1._field24 != 0)) ) {
- newMazeX = var_4;
+ if ( (((cellId == 25) || (cellId == 23) || (cellId == 14)) && (newMazeX <= mazePosX) && (_mazePosition.x >= mazePosX))
+ || (((cellId == 26) || (cellId == 24) || (cellId == 15) || (cellId == 5) || (cellId == 4)) && (_mazeChangeAmount >= deltaX) && (_mazeChangeAmount <= 3) && (_action1._turningFl)) ) {
+ newMazeX = mazePosX;
if ((cellId == 26) || (cellId == 24) || (cellId == 15) || (cellId == 5) || (cellId == 4))
R2_GLOBALS._sound2.play(339);
_rotation->_idxChange = 0;
- _field1270 = 0;
+ _speed = 0;
_mazeChangeAmount = 0;
- _field1272 = 0;
- if (_action1._field24 == 0)
- _actor8.hide();
- } else if ((cellId == 1) && (newMazeX >= var_4 + 5) && (_mazePosition.x >= var_4 + 5)) {
- newMazeX = var_4 + 5;
+ _updateIdxChangeFl = false;
+ if (!_action1._turningFl)
+ _tunnelVertCircle.hide();
+ } else if ((cellId == 1) && (newMazeX >= mazePosX + 5) && (_mazePosition.x >= mazePosX + 5)) {
+ newMazeX = mazePosX + 5;
R2_GLOBALS._sound2.play(339);
_rotation->_idxChange = 0;
- _field1270 = 0;
+ _speed = 0;
_mazeChangeAmount = 0;
- _field1272 = 0;
- if (_action1._field24 == 0)
- _actor8.hide();
- } else if (((cellId == 26) || (cellId == 24) || (cellId == 15) || (cellId == 5) || (cellId == 4)) && (var_a != 0) && (var_a <= 3)) {
- newMazeY = var_6;
+ _updateIdxChangeFl = false;
+ if (!_action1._turningFl)
+ _tunnelVertCircle.hide();
+ } else if (((cellId == 26) || (cellId == 24) || (cellId == 15) || (cellId == 5) || (cellId == 4)) && (deltaY != 0) && (deltaY <= 3)) {
+ newMazeY = mazePosY;
R2_GLOBALS._sound2.play(339);
} else {
// Nothing
@@ -4163,32 +4205,32 @@ void Scene3500::dispatch() {
break;
}
- if (_field1284 < 2) {
+ if (_exitCounter < 2) {
_mazePosition.x = newMazeX;
_mazePosition.y = newMazeY;
if (_mazeUI.setMazePosition2(_mazePosition) != 0) {
- _field1272 = 0;
+ _updateIdxChangeFl = false;
_mazeChangeAmount = 0;
- _field1270 = 0;
+ _speed = 0;
_rotation->setDelay(0);
_rotation->_idxChange = 0;
}
_mazeUI.draw();
- if (_field1284 != 0)
- ++_field1284;
+ if (_exitCounter != 0)
+ ++_exitCounter;
}
}
- if (_field1272 == 0) {
- if (_mazeChangeAmount != _field1270) {
- if (_mazeChangeAmount >= _field1270) {
+ if (!_updateIdxChangeFl) {
+ if (_mazeChangeAmount != _speed) {
+ if (_mazeChangeAmount >= _speed) {
if (_mazeChangeAmount == 1) {
- if (_action1._field24 != 0) {
- if ( ((_mazeDirection == 1) && (var_8 == 0) && (var_a != 0) && (var_a <= 3) && ((cellId == 25) || (cellId == 26) || (cellId == 5) || (cellId == 14) || (cellId == 15)))
- || ((_mazeDirection == 3) && (var_a == 0) && (var_8 != 0) && (var_8 <= 3) && ((cellId == 25) || (cellId == 23) || (cellId == 14) || (cellId == 5) || (cellId == 4)))
- || ((_mazeDirection == 5) && (var_8 == 0) && (var_a != 0) && (var_a <= 3) && ((cellId == 23) || (cellId == 24) || (cellId == 4) || (cellId == 14) || (cellId == 15)))
- || ((_mazeDirection == 7) && (var_a == 0) && (var_8 != 0) && (var_8 <= 3) && ((cellId == 26) || (cellId == 24) || (cellId == 15) || (cellId == 5) || (cellId == 4))) ){
+ if (_action1._turningFl) {
+ if ( ((_mazeDirection == 1) && (deltaX == 0) && (deltaY != 0) && (deltaY <= 3) && ((cellId == 25) || (cellId == 26) || (cellId == 5) || (cellId == 14) || (cellId == 15)))
+ || ((_mazeDirection == 3) && (deltaY == 0) && (deltaX != 0) && (deltaX <= 3) && ((cellId == 25) || (cellId == 23) || (cellId == 14) || (cellId == 5) || (cellId == 4)))
+ || ((_mazeDirection == 5) && (deltaX == 0) && (deltaY != 0) && (deltaY <= 3) && ((cellId == 23) || (cellId == 24) || (cellId == 4) || (cellId == 14) || (cellId == 15)))
+ || ((_mazeDirection == 7) && (deltaY == 0) && (deltaX != 0) && (deltaX <= 3) && ((cellId == 26) || (cellId == 24) || (cellId == 15) || (cellId == 5) || (cellId == 4))) ){
_mazeChangeAmount = 1;
} else
_mazeChangeAmount--;
@@ -4198,67 +4240,60 @@ void Scene3500::dispatch() {
_mazeChangeAmount--;
} else
++_mazeChangeAmount;
- _field1272 = 1;
+ _updateIdxChangeFl = true;
}
- _actor2.setFrame2(_mazeChangeAmount + 1);
+ _verticalSpeedDisplay.setFrame2(_mazeChangeAmount + 1);
}
- if (_field1272 == 1) {
+ if (_updateIdxChangeFl) {
if (_mazeChangeAmount == 0)
_rotation->_idxChange = 0;
else if (_mazeChangeAmount > 8)
_rotation->_idxChange = 2;
else
_rotation->_idxChange = 1;
- }
- if (_field1272 != 0)
- _field1272--;
+ _updateIdxChangeFl = false;
+ }
if (_mazeChangeAmount != 0) {
- R2_GLOBALS._player._uiEnabled = false;
- if (_mazeChangeAmount != _field1270)
+ R2_GLOBALS._player._uiEnabled = false;
+ if (_mazeChangeAmount != _speed)
_aSound1.play(276);
} else {
R2_GLOBALS._player._uiEnabled = true;
_aSound1.fadeOut2(NULL);
}
-
- if (_rotation->_currIndex != _field1274)
- _field1274 = _rotation->_currIndex;
}
/*--------------------------------------------------------------------------
- * Scene 3600 -
+ * Scene 3600 - Cutscene - walking at gunpoint
*
*--------------------------------------------------------------------------*/
+
Scene3600::Scene3600() {
- _field2548 = 0;
- _field254A = 0;
- _field254C = 0;
- _field254E = 0;
- _field2550 = false;
+ _tealDead = false;
+ _lightEntered = false;
+ _ghoulTeleported = false;
}
void Scene3600::synchronize(Serializer &s) {
SceneExt::synchronize(s);
- s.syncAsSint16LE(_field2548);
- s.syncAsSint16LE(_field254A);
- s.syncAsSint16LE(_field254C);
- s.syncAsSint16LE(_field254E);
- s.syncAsSint16LE(_field2550);
+ s.syncAsSint16LE(_tealDead);
+ s.syncAsSint16LE(_lightEntered);
+ s.syncAsSint16LE(_ghoulTeleported);
}
Scene3600::Action3600::Action3600() {
- _field1E = 0;
- _field20 = 0;
+ _part2Fl = false;
+ _fadePct = 0;
}
void Scene3600::Action3600::synchronize(Serializer &s) {
Action::synchronize(s);
- s.syncAsSint16LE(_field1E);
- s.syncAsSint16LE(_field20);
+ s.syncAsSint16LE(_part2Fl);
+ s.syncAsSint16LE(_fadePct);
}
void Scene3600::Action3600::signal() {
@@ -4270,17 +4305,17 @@ void Scene3600::Action3600::signal() {
setDelay(60);
break;
case 1:
- if (_field1E == 0) {
- _field1E = 1;
- scene->_actor2.setAction(NULL);
+ if (!_part2Fl) {
+ _part2Fl = true;
+ scene->_steppingDisk.setAction(NULL);
R2_GLOBALS._sound2.play(330, NULL, 0);
R2_GLOBALS._sound2.fade(127, 5, 10, false, NULL);
}
+
setDelay(1);
- warning("TODO: Palette fader using parameter 2 = 256");
- R2_GLOBALS._scenePalette.fade((const byte *)&scene->_palette1._palette, true, _field20);
- if (_field20 > 0)
- _field20 -= 2;
+ R2_GLOBALS._scenePalette.fade((const byte *)&scene->_palette1._palette, true, _fadePct);
+ if (_fadePct > 0)
+ _fadePct -= 2;
break;
case 2:
R2_GLOBALS._sound2.stop();
@@ -4305,14 +4340,14 @@ void Scene3600::Action2::signal() {
R2_GLOBALS._events.proc1();
R2_GLOBALS._player.enableControl();
_actionIndex = 3619;
- scene->_actor13._state = 0;
+ scene->_protector._state = 0;
// No break on purpose
case 3619: {
++_actionIndex;
- scene->_actor13.setup(3127, 2, 1);
- scene->_actor13.animate(ANIM_MODE_1, NULL);
+ scene->_protector.setup(3127, 2, 1);
+ scene->_protector.animate(ANIM_MODE_1, NULL);
NpcMover *mover = new NpcMover();
- scene->_actor13.addMover(mover, &scene->_actor13._field8A, scene);
+ scene->_protector.addMover(mover, &scene->_protector._actorDestPos, scene);
}
break;
default:
@@ -4322,10 +4357,10 @@ void Scene3600::Action2::signal() {
}
}
-bool Scene3600::Item5::startAction(CursorType action, Event &event) {
+bool Scene3600::LightShaft::startAction(CursorType action, Event &event) {
Scene3600 *scene = (Scene3600 *)R2_GLOBALS._sceneManager._scene;
- if ((action != CURSOR_USE) || (scene->_action1._field1E == 0))
+ if ((action != CURSOR_USE) || !scene->_action1._part2Fl)
return SceneItem::startAction(action, event);
R2_GLOBALS._walkRegions.enableRegion(2);
@@ -4333,10 +4368,10 @@ bool Scene3600::Item5::startAction(CursorType action, Event &event) {
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 3624;
- scene->_actor10.setStrip2(-1);
- scene->_actor11.setStrip2(-1);
- scene->_actor12.setStrip2(-1);
- scene->_actor4.setStrip2(-1);
+ scene->_quinn.setStrip2(-1);
+ scene->_seeker.setStrip2(-1);
+ scene->_miranda.setStrip2(-1);
+ scene->_webbster.setStrip2(-1);
if (R2_GLOBALS._player._characterIndex == R2_SEEKER)
R2_GLOBALS._player.setAction(&scene->_sequenceManager3, scene, 3611, &R2_GLOBALS._player, NULL);
@@ -4348,25 +4383,25 @@ bool Scene3600::Item5::startAction(CursorType action, Event &event) {
return true;
}
-bool Scene3600::Actor13::startAction(CursorType action, Event &event) {
+bool Scene3600::Protector::startAction(CursorType action, Event &event) {
Scene3600 *scene = (Scene3600 *)R2_GLOBALS._sceneManager._scene;
switch(action) {
case CURSOR_TALK:
- if (!_action)
+ if (_action)
return SceneActor::startAction(action, event);
scene->_protectorSpeaker._displayMode = 1;
if (!R2_GLOBALS._player._mover)
R2_GLOBALS._player.addMover(NULL);
- if (!scene->_actor10._mover)
- scene->_actor10.addMover(NULL);
- if (!scene->_actor11._mover)
- scene->_actor11.addMover(NULL);
- if (!scene->_actor12._mover)
- scene->_actor12.addMover(NULL);
- if (!scene->_actor4._mover)
- scene->_actor4.addMover(NULL);
+ if (!scene->_quinn._mover)
+ scene->_quinn.addMover(NULL);
+ if (!scene->_seeker._mover)
+ scene->_seeker.addMover(NULL);
+ if (!scene->_miranda._mover)
+ scene->_miranda.addMover(NULL);
+ if (!scene->_webbster._mover)
+ scene->_webbster.addMover(NULL);
setup(3127, 2, 1);
scene->_sceneMode = 3327;
@@ -4380,6 +4415,7 @@ bool Scene3600::Actor13::startAction(CursorType action, Event &event) {
R2_GLOBALS._sound3.play(43);
else
R2_GLOBALS._sound3.play(99);
+
if (_state != 0) {
_state = 1;
setup(3128, 1, 1);
@@ -4403,16 +4439,13 @@ bool Scene3600::Actor13::startAction(CursorType action, Event &event) {
void Scene3600::postInit(SceneObjectList *OwnerList) {
if (R2_GLOBALS._sceneManager._previousScene == 3600) {
R2_GLOBALS._scrollFollower = &R2_GLOBALS._player;
- R2_GLOBALS._v558B6.set(60, 0, 260, 200);
} else {
- R2_GLOBALS._scrollFollower = &_actor2;
+ R2_GLOBALS._scrollFollower = &_steppingDisk;
_sceneBounds = Rect(160, 0, 480, 200);
- R2_GLOBALS._v558B6.set(25, 0, 260, 200);
}
loadScene(3600);
SceneExt::postInit();
- _field254C = 0;
_stripManager.setColors(60, 255);
_stripManager.setFontNumber(3);
@@ -4427,62 +4460,61 @@ void Scene3600::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player._characterScene[R2_SEEKER] = 3600;
R2_GLOBALS._player._characterScene[R2_MIRANDA] = 3600;
- _item2.setDetails(33, 3600, 6, -1, -1);
- _item3.setDetails(Rect(3, 3, 22, 45), 3600, 9, -1, -1, 1, NULL);
- _item4.setDetails(Rect(449, 3, 475, 45), 3600, 9, -1, -1, 1, NULL);
+ _console.setDetails(33, 3600, 6, -1, -1);
+ _tapestry1.setDetails(Rect(3, 3, 22, 45), 3600, 9, -1, -1, 1, NULL);
+ _tapestry2.setDetails(Rect(449, 3, 475, 45), 3600, 9, -1, -1, 1, NULL);
- _actor10.postInit();
- _actor10._moveDiff = Common::Point(3, 2);
- _actor10.changeZoom(-1);
- _actor10._effect = 1;
+ _quinn.postInit();
+ _quinn._moveDiff = Common::Point(3, 2);
+ _quinn.changeZoom(-1);
+ _quinn._effect = EFFECT_SHADED;
- if (R2_GLOBALS._player._characterIndex != 1)
- _actor10.setDetails(9001, 0, -1, -1, 1, (SceneItem *) NULL);
+ if (R2_GLOBALS._player._characterIndex != R2_QUINN)
+ _quinn.setDetails(9001, 0, -1, -1, 1, (SceneItem *) NULL);
- _actor11.postInit();
- _actor11._numFrames = 7;
- _actor11._moveDiff = Common::Point(5, 3);
- _actor11.changeZoom(-1);
- _actor11._effect = 1;
+ _seeker.postInit();
+ _seeker._numFrames = 7;
+ _seeker._moveDiff = Common::Point(5, 3);
+ _seeker.changeZoom(-1);
+ _seeker._effect = EFFECT_SHADED;
- if (R2_GLOBALS._player._characterIndex != 2)
- _actor11.setDetails(9002, 1, -1, -1, 1, (SceneItem *) NULL);
+ if (R2_GLOBALS._player._characterIndex != R2_SEEKER)
+ _seeker.setDetails(9002, 1, -1, -1, 1, (SceneItem *) NULL);
- _actor12.postInit();
- _actor12._moveDiff = Common::Point(3, 2);
- _actor12.changeZoom(-1);
- _actor12._effect = 1;
+ _miranda.postInit();
+ _miranda._moveDiff = Common::Point(3, 2);
+ _miranda.changeZoom(-1);
+ _miranda._effect = EFFECT_SHADED;
- if (R2_GLOBALS._player._characterIndex != 3)
- _actor12.setDetails(9003, 1, -1, -1, 1, (SceneItem *) NULL);
+ if (R2_GLOBALS._player._characterIndex != R2_MIRANDA)
+ _miranda.setDetails(9003, 1, -1, -1, 1, (SceneItem *) NULL);
R2_GLOBALS._player.postInit();
R2_GLOBALS._player.changeZoom(-1);
R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
R2_GLOBALS._player.disableControl();
- _actor4.postInit();
- _actor4._numFrames = 7;
- _actor4._moveDiff = Common::Point(5, 3);
- _actor4.changeZoom(-1);
- _actor4._effect = 1;
- _actor4.setDetails(3600, 27, -1, -1, 1, (SceneItem *) NULL);
+ _webbster.postInit();
+ _webbster._numFrames = 7;
+ _webbster._moveDiff = Common::Point(5, 3);
+ _webbster.changeZoom(-1);
+ _webbster._effect = EFFECT_SHADED;
+ _webbster.setDetails(3600, 27, -1, -1, 1, (SceneItem *) NULL);
- _actor5.postInit();
- _actor5._numFrames = 7;
- _actor5._moveDiff = Common::Point(3, 2);
- _actor5.changeZoom(-1);
- _actor5._effect = 1;
- _actor5.setDetails(3600, 12, -1, -1, 1, (SceneItem *) NULL);
+ _teal.postInit();
+ _teal._numFrames = 7;
+ _teal._moveDiff = Common::Point(3, 2);
+ _teal.changeZoom(-1);
+ _teal._effect = EFFECT_SHADED;
+ _teal.setDetails(3600, 12, -1, -1, 1, (SceneItem *) NULL);
_palette1.loadPalette(0);
_palette1.loadPalette(3601);
if (R2_GLOBALS._sceneManager._previousScene == 3600) {
- _item5._sceneRegionId = 200;
- _item5.setDetails(3600, 30, -1, -1, 5, &_actor4);
- _field254A = 1;
- _field2548 = 1;
+ _lightShaft._sceneRegionId = 200;
+ _lightShaft.setDetails(3600, 30, -1, -1, 5, &_webbster);
+ _tealDead = true;
R2_GLOBALS._walkRegions.disableRegion(2);
R2_GLOBALS._walkRegions.disableRegion(7);
@@ -4490,119 +4522,117 @@ void Scene3600::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._walkRegions.disableRegion(15);
R2_GLOBALS._walkRegions.disableRegion(16);
- _actor10.setup(10, 5, 11);
- _actor10.animate(ANIM_MODE_1, NULL);
+ _quinn.setup(10, 5, 11);
+ _quinn.animate(ANIM_MODE_1, NULL);
- _actor11.setup(20, 5, 11);
- _actor11.animate(ANIM_MODE_1, NULL);
+ _seeker.setup(20, 5, 11);
+ _seeker.animate(ANIM_MODE_1, NULL);
- _actor12.setup(30, 5, 11);
- _actor12.animate(ANIM_MODE_1, NULL);
+ _miranda.setup(30, 5, 11);
+ _miranda.animate(ANIM_MODE_1, NULL);
if (R2_GLOBALS._player._characterIndex == R2_SEEKER) {
- _actor10.setPosition(Common::Point(76, 148));
- _actor11.setPosition(Common::Point(134, 148));
- _actor12.setPosition(Common::Point(100, 148));
+ _quinn.setPosition(Common::Point(76, 148));
+ _seeker.setPosition(Common::Point(134, 148));
+ _miranda.setPosition(Common::Point(100, 148));
R2_GLOBALS._player._moveDiff = Common::Point(5, 3);
- R2_GLOBALS._player.setup(20, _actor11._strip, 1);
- R2_GLOBALS._player.setPosition(_actor11._position);
- _actor11.hide();
+ R2_GLOBALS._player.setup(20, _seeker._strip, 1);
+ R2_GLOBALS._player.setPosition(_seeker._position);
+ _seeker.hide();
} else if (R2_GLOBALS._player._characterIndex == R2_MIRANDA) {
- _actor10.setPosition(Common::Point(110, 148));
- _actor11.setPosition(Common::Point(76, 148));
- _actor12.setPosition(Common::Point(134, 148));
+ _quinn.setPosition(Common::Point(110, 148));
+ _seeker.setPosition(Common::Point(76, 148));
+ _miranda.setPosition(Common::Point(134, 148));
R2_GLOBALS._player._moveDiff = Common::Point(3, 2);
- R2_GLOBALS._player.setup(30, _actor12._strip, 1);
- R2_GLOBALS._player.setPosition(_actor12._position);
- _actor12.hide();
+ R2_GLOBALS._player.setup(30, _miranda._strip, 1);
+ R2_GLOBALS._player.setPosition(_miranda._position);
+ _miranda.hide();
} else {
- _actor10.setPosition(Common::Point(134, 148));
- _actor11.setPosition(Common::Point(76, 148));
- _actor12.setPosition(Common::Point(110, 148));
+ _quinn.setPosition(Common::Point(134, 148));
+ _seeker.setPosition(Common::Point(76, 148));
+ _miranda.setPosition(Common::Point(110, 148));
R2_GLOBALS._player._moveDiff = Common::Point(3, 2);
- R2_GLOBALS._player.setup(10, _actor10._strip, 1);
- R2_GLOBALS._player.setPosition(_actor10._position);
- _actor10.hide();
+ R2_GLOBALS._player.setup(10, _quinn._strip, 1);
+ R2_GLOBALS._player.setPosition(_quinn._position);
+ _quinn.hide();
}
- _actor4.setPosition(Common::Point(47, 149));
- _actor4.setup(40, 1, 11);
- _actor4.animate(ANIM_MODE_1, NULL);
+ _webbster.setPosition(Common::Point(47, 149));
+ _webbster.setup(40, 1, 11);
+ _webbster.animate(ANIM_MODE_1, NULL);
- _actor5.setPosition(Common::Point(367, 148));
- _actor5.setup(3601, 7, 5);
+ _teal.setPosition(Common::Point(367, 148));
+ _teal.setup(3601, 7, 5);
if (!R2_GLOBALS.getFlag(71)) {
- _actor13.postInit();
- _actor13._state = 0;
- _actor13._field8A = Common::Point(226, 152);
- _actor13._moveDiff = Common::Point(3, 2);
- _actor13.setPosition(Common::Point(284, 152));
- _actor13.setup(3127, 2, 1);
- _actor13.changeZoom(-1);
- _actor13.setDetails(3600, 15, -1, 17, 1, (SceneItem *) NULL);
+ _protector.postInit();
+ _protector._state = 0;
+ _protector._actorDestPos = Common::Point(226, 152);
+ _protector._moveDiff = Common::Point(3, 2);
+ _protector.setPosition(Common::Point(284, 152));
+ _protector.setup(3127, 2, 1);
+ _protector.changeZoom(-1);
+ _protector.setDetails(3600, 15, -1, 17, 1, (SceneItem *) NULL);
}
R2_GLOBALS._sound2.play(330);
- _actor3.postInit();
- _actor3.setPosition(Common::Point(84, 156));
- _actor3.fixPriority(158);
- _actor3.setup(3601, 5, 1);
- _actor3.animate(ANIM_MODE_2, NULL);
-
- _action1._field1E = 1;
- _action1._field20 = 0;
+ _consoleLights.postInit();
+ _consoleLights.setPosition(Common::Point(84, 156));
+ _consoleLights.fixPriority(158);
+ _consoleLights.setup(3601, 5, 1);
+ _consoleLights.animate(ANIM_MODE_2, NULL);
+
+ _action1._part2Fl = true;
+ _action1._fadePct = 0;
_action1.setActionIndex(1);
- _actor3.setAction(&_action1);
+ _consoleLights.setAction(&_action1);
_sceneMode = 3623;
g_globals->_events.setCursor(CURSOR_ARROW);
R2_GLOBALS._player.enableControl(CURSOR_WALK);
} else {
- _field254A = 0;
- _field2548 = 0;
+ _tealDead = false;
R2_GLOBALS._walkRegions.disableRegion(17);
R2_GLOBALS._walkRegions.disableRegion(18);
- _actor10.setPosition(Common::Point(393, 148));
- _actor11.setPosition(Common::Point(364, 153));
- _actor12.setPosition(Common::Point(413, 164));
+ _quinn.setPosition(Common::Point(393, 148));
+ _seeker.setPosition(Common::Point(364, 153));
+ _miranda.setPosition(Common::Point(413, 164));
R2_GLOBALS._player.hide();
- _actor4.setPosition(Common::Point(373, 164));
-
- _actor5.setup(3403, 8, 11);
- _actor5.setPosition(Common::Point(403, 155));
+ _webbster.setPosition(Common::Point(373, 164));
- _actor12.setup(3403, 7, 1);
+ _teal.setup(3403, 8, 11);
+ _teal.setPosition(Common::Point(403, 155));
- _actor13.setPosition(Common::Point(405, 155));
+ _protector.setup(3403, 7, 1);
+ _protector.setPosition(Common::Point(405, 155));
- _actor2.postInit();
- _actor2.setup(3600, 2, 1);
- _actor2.setPosition(Common::Point(403, 161));
- _actor2.fixPriority(149);
- _actor2.changeZoom(-1);
+ _steppingDisk.postInit();
+ _steppingDisk.setup(3600, 2, 1);
+ _steppingDisk.setPosition(Common::Point(403, 161));
+ _steppingDisk.fixPriority(149);
+ _steppingDisk.changeZoom(-1);
- _action1._field1E = 0;
- _action1._field20 = 90;
+ _action1._part2Fl = false;
+ _action1._fadePct = 90;
_sceneMode = 3600;
- setAction(&_sequenceManager1, this, 3600, &_actor11, &_actor10, &_actor12, &_actor4, &_actor5, &_actor2, NULL);
- _field254E = 0;
+ setAction(&_sequenceManager1, this, 3600, &_seeker, &_quinn, &_miranda,
+ &_webbster, &_teal, &_steppingDisk, NULL);
}
- _field254E = 0;
- _field2550 = R2_GLOBALS.getFlag(71);
+ _lightEntered = false;
+ _ghoulTeleported = R2_GLOBALS.getFlag(71);
R2_GLOBALS._sound1.play(326);
- _item1.setDetails(Rect(0, 0, 480, 200), 3600, 0, -1, -1, 1, NULL);
+ _background.setDetails(Rect(0, 0, 480, 200), 3600, 0, -1, -1, 1, NULL);
}
void Scene3600::remove() {
- _actor3.animate(ANIM_MODE_NONE, NULL);
- _actor3.setAction(NULL);
+ _consoleLights.animate(ANIM_MODE_NONE, NULL);
+ _consoleLights.setAction(NULL);
R2_GLOBALS._sound2.fadeOut2(NULL);
R2_GLOBALS._sound1.fadeOut2(NULL);
R2_GLOBALS._scrollFollower = &R2_GLOBALS._player;
@@ -4612,55 +4642,60 @@ void Scene3600::remove() {
void Scene3600::signal() {
switch (_sceneMode) {
case 3320:
- // TODO: warning("STUB: sub_1D227()");
+ // Move to the console
R2_GLOBALS._walkRegions.disableRegion(14);
- R2_GLOBALS._scrollFollower = &_actor11;
+ R2_GLOBALS._scrollFollower = &_seeker;
_tealSpeaker._object1.hide();
- _actor5.show();
- _actor5.setStrip(2);
+ _teal.show();
+ _teal.setStrip(2);
if (R2_GLOBALS._player._characterIndex == R2_SEEKER)
_sceneMode = 3602;
else if (R2_GLOBALS._player._characterIndex == R2_MIRANDA)
_sceneMode = 3603;
else
_sceneMode = 3601;
- setAction(&_sequenceManager1, this, _sceneMode, &_actor11, &_actor10, &_actor12, &_actor4, &_actor5, NULL);
+ setAction(&_sequenceManager1, this, _sceneMode, &_seeker, &_quinn,
+ &_miranda, &_webbster, &_teal, NULL);
break;
case 3321:
- warning("STUB: sub_1D227()");
+ // Teal activates console
R2_GLOBALS._scrollFollower = &R2_GLOBALS._player;
- _tealSpeaker.proc16();
- _actor5.show();
- _actor5.setStrip(1);
- _actor3.postInit();
+ _tealSpeaker.stopSpeaking();
+ _teal.show();
+ _teal.setStrip(1);
+ _consoleLights.postInit();
_sceneMode = 3604;
- setAction(&_sequenceManager1, this, _sceneMode, &_actor5, &_actor3, &_actor10, &_actor11, &_actor12, &_actor4, NULL);
+ setAction(&_sequenceManager1, this, _sceneMode, &_teal, &_consoleLights,
+ &_quinn, &_seeker, &_miranda, &_webbster, NULL);
break;
case 3322:
- warning("STUB: sub_1D227()");
- _quinnSpeaker.proc16();
+ // Teal walks toward the teleport pod, the goule protector appears
+ _quinnSpeaker.stopSpeaking();
_quinnSpeaker._displayMode = 1;
- _tealSpeaker.proc16();
+ _tealSpeaker.stopSpeaking();
_tealSpeaker._displayMode = 7;
- R2_GLOBALS._scrollFollower = &_actor5;
+ R2_GLOBALS._scrollFollower = &_teal;
_sceneMode = 3605;
- setAction(&_sequenceManager1, this, _sceneMode, &_actor5, &_actor13, &_actor2, NULL);
+ setAction(&_sequenceManager1, this, _sceneMode, &_teal, &_protector, &_steppingDisk, NULL);
break;
case 3323:
- if (_field254A == 0)
- _field254A = 1;
+ // Goule protector eats Teal guts then moves
+
+ if (!_tealDead)
+ _tealDead = true;
else {
- warning("STUB: sub_1D227()");
- _protectorSpeaker.proc16();
- _actor13.show();
- _actor13.setup(3258, 6, 1);
+ _protectorSpeaker.stopSpeaking();
+ _protector.show();
+ _protector.setup(3258, 6, 1);
+
_sceneMode = 3607;
- _actor13.setAction(&_sequenceManager1, this, _sceneMode, &_actor13, NULL);
- R2_GLOBALS._v558C2 = 1;
- _protectorSpeaker.proc16();
+ _protector.setAction(&_sequenceManager1, this, _sceneMode, &_protector, NULL);
+
+ _protectorSpeaker.stopSpeaking();
_protectorSpeaker._displayMode = 1;
_quinnSpeaker._displayMode = 1;
- _actor13.show();
+ _protector.show();
+
R2_GLOBALS._scrollFollower = &R2_GLOBALS._player;
R2_GLOBALS._walkRegions.enableRegion(17);
R2_GLOBALS._walkRegions.enableRegion(18);
@@ -4669,7 +4704,8 @@ void Scene3600::signal() {
R2_GLOBALS._walkRegions.disableRegion(14);
R2_GLOBALS._walkRegions.disableRegion(15);
R2_GLOBALS._walkRegions.disableRegion(16);
- _actor13.setAction(&_action1);
+
+ _consoleLights.setAction(&_action1);
}
break;
case 3324:
@@ -4677,9 +4713,8 @@ void Scene3600::signal() {
case 3607:
g_globals->_events.setCursor(CURSOR_ARROW);
R2_GLOBALS._player.enableControl(CURSOR_WALK);
- _actor13.fixPriority(-1);
+ _protector.fixPriority(-1);
_sceneMode = 3623;
- _field2548 = 1;
break;
case 3327:
g_globals->_events.setCursor(CURSOR_ARROW);
@@ -4687,61 +4722,63 @@ void Scene3600::signal() {
_sceneMode = 3623;
break;
case 3450:
+ // Speech of Teal and Quinn
R2_GLOBALS._sound1.stop();
- _actor1.hide();
- _actor6.hide();
- g_globals->gfxManager()._bounds.moveTo(Common::Point(40, 0));
+ _protector3400.hide();
+ _door3400.hide();
+
+ _sceneBounds = Rect(40, 0, SCREEN_WIDTH + 40, SCREEN_HEIGHT);
setZoomPercents(142, 80, 167, 105);
loadScene(3600);
R2_GLOBALS._uiElements.show();
- _item5._sceneRegionId = 200;
- _item5.setDetails(3600, 30, -1, -1, 5, &_actor4);
-
- _actor3.show();
- _actor10.show();
- _actor11.show();
- _actor12.show();
- _actor4.show();
- _actor5.show();
-
- _actor5.setPosition(Common::Point(298, 151));
-
- _actor13.postInit();
- _actor13._state = 0;
- _actor13._field8A = Common::Point(226, 152);
- _actor13._moveDiff = Common::Point(5, 3);
- _actor13.setup(3403, 7, 1);
- _actor13.setPosition(Common::Point(405, 155));
- _actor13.changeZoom(-1);
- _actor13.addMover(NULL);
- _actor13.animate(ANIM_MODE_NONE);
- _actor13.hide();
- _actor13.setDetails(3600, 15, -1, 17, 5, &_item5);
-
- _actor2.setup(3600, 2, 1);
- _actor2.setPosition(Common::Point(403, 161));
- _actor2.fixPriority(149);
- _actor2.changeZoom(-1);
- _actor2.show();
+ _lightShaft._sceneRegionId = 200;
+ _lightShaft.setDetails(3600, 30, -1, -1, 5, &_webbster);
+
+ _consoleLights.show();
+ _quinn.show();
+ _seeker.show();
+ _miranda.show();
+ _webbster.show();
+ _teal.show();
+
+ _teal.setPosition(Common::Point(298, 151));
+
+ _protector.postInit();
+ _protector._state = 0;
+ _protector._actorDestPos = Common::Point(226, 152);
+ _protector._moveDiff = Common::Point(5, 3);
+ _protector.setup(3403, 7, 1);
+ _protector.setPosition(Common::Point(405, 155));
+ _protector.changeZoom(-1);
+ _protector.addMover(NULL);
+ _protector.animate(ANIM_MODE_NONE);
+ _protector.hide();
+ _protector.setDetails(3600, 15, -1, 17, 5, &_lightShaft);
+
+ _steppingDisk.setup(3600, 2, 1);
+ _steppingDisk.setPosition(Common::Point(403, 161));
+ _steppingDisk.fixPriority(149);
+ _steppingDisk.changeZoom(-1);
+ _steppingDisk.show();
_quinnSpeaker._displayMode = 2;
_tealSpeaker._displayMode = 2;
if (R2_GLOBALS._player._characterIndex == R2_SEEKER) {
R2_GLOBALS._player._moveDiff = Common::Point(5, 3);
- R2_GLOBALS._player.setup(20, _actor11._strip, 1);
- R2_GLOBALS._player.setPosition(_actor11._position);
- _actor11.hide();
+ R2_GLOBALS._player.setup(20, _seeker._strip, 1);
+ R2_GLOBALS._player.setPosition(_seeker._position);
+ _seeker.hide();
} else if (R2_GLOBALS._player._characterIndex == R2_MIRANDA) {
R2_GLOBALS._player._moveDiff = Common::Point(3, 2);
- R2_GLOBALS._player.setup(30, _actor12._strip, 1);
- R2_GLOBALS._player.setPosition(_actor12._position);
- _actor12.hide();
+ R2_GLOBALS._player.setup(30, _miranda._strip, 1);
+ R2_GLOBALS._player.setPosition(_miranda._position);
+ _miranda.hide();
} else {
R2_GLOBALS._player._moveDiff = Common::Point(3, 2);
- R2_GLOBALS._player.setup(10, _actor10._strip, 1);
- R2_GLOBALS._player.setPosition(_actor10._position);
- _actor10.hide();
+ R2_GLOBALS._player.setup(10, _quinn._strip, 1);
+ R2_GLOBALS._player.setPosition(_quinn._position);
+ _quinn.hide();
}
R2_GLOBALS._player.show();
R2_GLOBALS._sound1.play(326);
@@ -4750,6 +4787,7 @@ void Scene3600::signal() {
R2_GLOBALS._sound2.play(329);
break;
case 3600:
+ // First speech by Teal
_sceneMode = 3320;
_stripManager.start(3320, this);
break;
@@ -4758,53 +4796,56 @@ void Scene3600::signal() {
case 3602:
// No break on purpose
case 3603:
+ // Teal speech near the console
R2_GLOBALS._walkRegions.disableRegion(2);
R2_GLOBALS._walkRegions.disableRegion(7);
- R2_GLOBALS._v558B6.set(60, 0, 260, 200);
_tealSpeaker._displayMode = 1;
_sceneMode = 3321;
_stripManager.start(3321, this);
break;
case 3604:
+ // Goule Protector forces the door
R2_GLOBALS._sound2.fadeOut2(NULL);
R2_GLOBALS._sound1.stop();
R2_GLOBALS._walkRegions.enableRegion(2);
R2_GLOBALS._walkRegions.enableRegion(7);
- _actor2.hide();
- _actor3.hide();
+ _steppingDisk.hide();
+ _consoleLights.hide();
R2_GLOBALS._player.hide();
- _actor10.hide();
- _actor11.hide();
- _actor12.hide();
- _actor4.hide();
- _actor5.hide();
+ _quinn.hide();
+ _seeker.hide();
+ _miranda.hide();
+ _webbster.hide();
+ _teal.hide();
- g_globals->gfxManager()._bounds.moveTo(Common::Point(60, 0));
+ _sceneBounds = Rect(60, 0, SCREEN_WIDTH + 60, SCREEN_HEIGHT);
setZoomPercents(51, 46, 180, 200);
loadScene(3400);
R2_GLOBALS._uiElements.show();
- _actor1.postInit();
+ _protector3400.postInit();
- _actor2.setup(3403, 1, 1);
- _actor2.setPosition(Common::Point(190, 103));
- _actor2.fixPriority(89);
- _actor2.show();
+ _steppingDisk.setup(3403, 1, 1);
+ _steppingDisk.setPosition(Common::Point(190, 103));
+ _steppingDisk.fixPriority(89);
+ _steppingDisk.show();
- _actor6.postInit();
- _actor6.setup(3400, 1, 6);
- _actor6.setPosition(Common::Point(236, 51));
- _actor6.fixPriority(51);
- R2_GLOBALS._scrollFollower = &_actor6;
+ _door3400.postInit();
+ _door3400.setup(3400, 1, 6);
+ _door3400.setPosition(Common::Point(236, 51));
+ _door3400.fixPriority(51);
+ R2_GLOBALS._scrollFollower = &_door3400;
R2_GLOBALS._sound1.play(323);
_sceneMode = 3450;
- setAction(&_sequenceManager1, this, 3450, &_actor1, &_actor6, NULL);
+ setAction(&_sequenceManager1, this, 3450, &_protector3400, &_door3400, NULL);
break;
case 3605:
- _actor13.setup(3258, 4, 1);
- _actor13.setAction(&_sequenceManager1, this, 3606, &_actor5, &_actor13, &_actor2, NULL);
+ // Goule protector jumps on Teal
+ _protector.setup(3258, 4, 1);
+ _protector.setAction(&_sequenceManager1, this, 3606, &_teal, &_protector,
+ &_steppingDisk, NULL);
_sceneMode = 3323;
_stripManager.start(3323, this);
@@ -4812,21 +4853,22 @@ void Scene3600::signal() {
case 3620:
// No break on purpose
case 3623:
- if ((_actor13._position.x == 226) && (_actor13._position.y == 152) && (_action1._field1E != 0) && (_actor13._visage == 3127) && (!R2_GLOBALS.getFlag(71))) {
+ if ((_protector._position.x == 226) && (_protector._position.y == 152)
+ && _action1._part2Fl && (_protector._visage == 3127) && (!R2_GLOBALS.getFlag(71))) {
R2_GLOBALS._sound2.stop();
R2_GLOBALS._sound2.play(331);
R2_GLOBALS.setFlag(71);
_sceneMode = 3626;
- setAction(&_sequenceManager1, this, 3626, &_actor13, NULL);
+ setAction(&_sequenceManager1, this, 3626, &_protector, NULL);
}
break;
case 3624:
R2_GLOBALS._player.disableControl();
- if ((_field254E != 0) && (_actor10._position.x == 229) && (_actor10._position.y == 154) && (_actor11._position.x == 181) && (_actor11._position.y == 154) && (_actor12._position.x == 207) && (_actor12._position.y == 154) && (_actor4._position.x == 155) && (_actor4._position.y == 154)) {
+ if (_lightEntered && (_quinn._position.x == 229) && (_quinn._position.y == 154) && (_seeker._position.x == 181) && (_seeker._position.y == 154) && (_miranda._position.x == 207) && (_miranda._position.y == 154) && (_webbster._position.x == 155) && (_webbster._position.y == 154)) {
R2_GLOBALS._sound2.stop();
R2_GLOBALS._sound2.play(331);
_sceneMode = 3625;
- setAction(&_sequenceManager1, this, 3625, &_actor10, &_actor11, &_actor12, &_actor4, NULL);
+ setAction(&_sequenceManager1, this, 3625, &_quinn, &_seeker, &_miranda, &_webbster, NULL);
}
break;
case 3625:
@@ -4834,7 +4876,7 @@ void Scene3600::signal() {
R2_GLOBALS._sceneManager.changeScene(3700);
break;
case 3626:
- _actor13.setPosition(Common::Point(0, 0));
+ _protector.setPosition(Common::Point(0, 0));
_action1.setActionIndex(2);
if (R2_GLOBALS._events.getCursor() > R2_LAST_INVENT) {
R2_GLOBALS._events.setCursor(CURSOR_USE);
@@ -4851,25 +4893,26 @@ void Scene3600::signal() {
}
void Scene3600::process(Event &event) {
- if ((event.eventType == EVENT_BUTTON_DOWN) && (R2_GLOBALS._events.getCursor() == CURSOR_ARROW) && (event.mousePos.x > 237) && (!R2_GLOBALS.getFlag(71))) {
- SceneItem::display(3600, 17, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7 -999);
+ if ((event.eventType == EVENT_BUTTON_DOWN) && (R2_GLOBALS._events.getCursor() == CURSOR_ARROW)
+ && (event.mousePos.x > 237) && (!R2_GLOBALS.getFlag(71))) {
+ SceneItem::display(3600, 17, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, LIST_END);
event.handled = true;
}
Scene::process(event);
}
void Scene3600::dispatch() {
- if ((R2_GLOBALS._player.getRegionIndex() == 200) && (_action1._field1E != 0) && (_field254E == 0)){
+ if ((R2_GLOBALS._player.getRegionIndex() == 200) && _action1._part2Fl && !_lightEntered) {
R2_GLOBALS._sound2.fadeOut2(NULL);
- if (_actor13._mover)
- _actor13.addMover(NULL);
+ if (_protector._mover)
+ _protector.addMover(NULL);
+
if (R2_GLOBALS._player._action)
R2_GLOBALS._player.setAction(NULL);
if (R2_GLOBALS._player._mover)
R2_GLOBALS._player.addMover(NULL);
- _field254C = 0;
- _field254E = 1;
+ _lightEntered = true;
R2_GLOBALS._walkRegions.enableRegion(2);
R2_GLOBALS._walkRegions.enableRegion(7);
@@ -4877,46 +4920,47 @@ void Scene3600::dispatch() {
_sceneMode = 3624;
- _actor10.setStrip(-1);
- _actor11.setStrip(-1);
- _actor12.setStrip(-1);
- _actor4.setStrip(-1);
+ _quinn.setStrip(-1);
+ _seeker.setStrip(-1);
+ _miranda.setStrip(-1);
+ _webbster.setStrip(-1);
R2_GLOBALS._player.hide();
if (R2_GLOBALS._player._characterIndex == R2_SEEKER) {
- _actor11.setPosition(R2_GLOBALS._player._position);
- _actor11.show();
+ _seeker.setPosition(R2_GLOBALS._player._position);
+ _seeker.show();
} else if (R2_GLOBALS._player._characterIndex == R2_MIRANDA) {
- _actor12.setPosition(R2_GLOBALS._player._position);
- _actor12.show();
+ _miranda.setPosition(R2_GLOBALS._player._position);
+ _miranda.show();
} else {
- _actor10.setPosition(R2_GLOBALS._player._position);
- _actor10.show();
+ _quinn.setPosition(R2_GLOBALS._player._position);
+ _quinn.show();
}
- _actor10.setAction(&_sequenceManager2, this, 3610, &_actor10, NULL);
- _actor11.setAction(&_sequenceManager3, this, 3611, &_actor11, NULL);
- _actor12.setAction(&_sequenceManager4, this, 3612, &_actor12, NULL);
- _actor4.setAction(&_sequenceManager1, this, 3613, &_actor4, NULL);
+ _quinn.setAction(&_sequenceManager2, this, 3610, &_quinn, NULL);
+ _seeker.setAction(&_sequenceManager3, this, 3611, &_seeker, NULL);
+ _miranda.setAction(&_sequenceManager4, this, 3612, &_miranda, NULL);
+ _webbster.setAction(&_sequenceManager1, this, 3613, &_webbster, NULL);
}
- if ((_actor13.getRegionIndex() == 200) && (_action1._field1E != 0) && (_field254E == 0)){
+ if ((_protector.getRegionIndex() == 200) && _action1._part2Fl && !_ghoulTeleported) {
R2_GLOBALS._sound2.fadeOut2(NULL);
_sceneMode = 3620;
- _field2550 = 1;
+ _ghoulTeleported = true;
R2_GLOBALS._player.disableControl();
if (R2_GLOBALS._player._mover)
R2_GLOBALS._player.addMover(NULL);
- if (_actor10._mover)
- _actor10.addMover(NULL);
- if (_actor11._mover)
- _actor11.addMover(NULL);
- if (_actor12._mover)
- _actor12.addMover(NULL);
- if (_actor4._mover)
- _actor4.addMover(NULL);
+ if (_quinn._mover)
+ _quinn.addMover(NULL);
+ if (_seeker._mover)
+ _seeker.addMover(NULL);
+ if (_miranda._mover)
+ _miranda.addMover(NULL);
+ if (_webbster._mover)
+ _webbster.addMover(NULL);
}
+
Scene::dispatch();
}
@@ -4924,10 +4968,13 @@ void Scene3600::dispatch() {
* Scene 3700 - Cutscene - Teleport outside
*
*--------------------------------------------------------------------------*/
+
void Scene3700::postInit(SceneObjectList *OwnerList) {
loadScene(3700);
R2_GLOBALS._uiElements._active = false;
+ R2_GLOBALS._uiElements._visible = false;
SceneExt::postInit();
+ R2_GLOBALS._interfaceY = SCREEN_HEIGHT;
_stripManager.setColors(60, 255);
_stripManager.setFontNumber(3);
@@ -4935,30 +4982,31 @@ void Scene3700::postInit(SceneObjectList *OwnerList) {
_stripManager.addSpeaker(&_seekerSpeaker);
_stripManager.addSpeaker(&_mirandaSpeaker);
- _actor1.postInit();
- _actor1._moveDiff = Common::Point(3, 2);
+ _quinn.postInit();
+ _quinn._moveDiff = Common::Point(3, 2);
- _actor2.postInit();
- _actor2._numFrames = 7;
- _actor2._moveDiff = Common::Point(5, 3);
- _actor2.hide();
+ _seeker.postInit();
+ _seeker._numFrames = 7;
+ _seeker._moveDiff = Common::Point(5, 3);
+ _seeker.hide();
- _actor3.postInit();
- _actor3._moveDiff = Common::Point(3, 2);
- _actor3.hide();
+ _miranda.postInit();
+ _miranda._moveDiff = Common::Point(3, 2);
+ _miranda.hide();
- _actor4.postInit();
- _actor4._numFrames = 7;
- _actor4._moveDiff = Common::Point(5, 3);
- _actor4.hide();
+ _webbster.postInit();
+ _webbster._numFrames = 7;
+ _webbster._moveDiff = Common::Point(5, 3);
+ _webbster.hide();
- _actor5.postInit();
+ _teleportPad.postInit();
- R2_GLOBALS._player.postInit();
+ R2_GLOBALS._player.disableControl();
R2_GLOBALS._sound1.play(332);
_sceneMode = 3700;
- setAction(&_sequenceManager, this, 3700, &_actor1, &_actor2, &_actor3, &_actor4, &_actor5, NULL);
+ setAction(&_sequenceManager, this, 3700, &_quinn, &_seeker, &_miranda,
+ &_webbster, &_teleportPad, NULL);
}
void Scene3700::remove() {
@@ -4971,13 +5019,12 @@ void Scene3700::signal() {
case 3328:
// No break on purpose
case 3329:
- warning("STUB: sub_1D227()");
_sceneMode = 3701;
- setAction(&_sequenceManager, this, 3701, &_actor2, &_actor3, &_actor4, NULL);
+ setAction(&_sequenceManager, this, 3701, &_seeker, &_miranda, &_webbster, NULL);
break;
case 3700:
- _actor1.setup(10, 6, 1);
- _actor2.setup(20, 5, 1);
+ _quinn.setup(10, 6, 1);
+ _seeker.setup(20, 5, 1);
if (R2_GLOBALS.getFlag(71)) {
_sceneMode = 3329;
_stripManager.start(3329, this);
@@ -5168,7 +5215,7 @@ void Scene3800::initExits() {
_southExit._moving = false;
_westExit._moving = false;
- loadScene(R2_GLOBALS._v566A6);
+ loadScene(R2_GLOBALS._maze3800SceneNumb);
R2_GLOBALS._uiElements.draw();
}
@@ -5184,20 +5231,23 @@ void Scene3800::enterArea() {
R2_GLOBALS._player.setStrip(3);
R2_GLOBALS._player.changeZoom(-1);
R2_GLOBALS._player._moveDiff = Common::Point(3, 2);
- _actor1.postInit();
- _actor1.fixPriority(10);
- _actor1.changeZoom(-1);
- _actor1.setVisage(1110);
- _actor1._effect = 5;
- _actor1._field9C = this->_field312;
- R2_GLOBALS._player._linkedActor = &_actor1;
+
+ _quinnShadow.postInit();
+ _quinnShadow.fixPriority(10);
+ _quinnShadow.changeZoom(-1);
+ _quinnShadow.setVisage(1110);
+ _quinnShadow._effect = EFFECT_SHADOW_MAP;
+ _quinnShadow._shadowMap = this->_shadowPaletteMap;
+ R2_GLOBALS._player._linkedActor = &_quinnShadow;
+
switch (R2_GLOBALS._sceneManager._previousScene) {
case 2600:
- _object1.postInit();
- _object2.postInit();
- _actor1.hide();
+ _balloon.postInit();
+ _harness.postInit();
+ _quinnShadow.hide();
_sceneMode = 3800;
- setAction(&_sequenceManager1, this, 3800, &R2_GLOBALS._player, &_object1, &_object2, NULL);
+ setAction(&_sequenceManager1, this, 3800, &R2_GLOBALS._player,
+ &_balloon, &_harness, NULL);
break;
case 3900:
_sceneMode = 15;
@@ -5233,6 +5283,7 @@ void Scene3800::enterArea() {
default:
break;
}
+ break;
default:
R2_GLOBALS._player.enableControl(CURSOR_WALK);
break;
@@ -5296,7 +5347,7 @@ void Scene3800::postInit(SceneObjectList *OwnerList) {
_westExit.setDetails(Rect(0, 87, 14, 168), EXITCURSOR_W, 3800);
_westExit.setDest(Common::Point(7, 145));
- _rect1.set(0, 0, 320, 87);
+ _skylineRect.set(0, 0, 320, 87);
_background.setDetails(Rect(0, 0, 320, 200), 3800, 0, 1, 2, 1, (SceneItem *) NULL);
enterArea();
@@ -5305,45 +5356,43 @@ void Scene3800::postInit(SceneObjectList *OwnerList) {
void Scene3800::signal() {
switch (_sceneMode) {
case 11:
- R2_GLOBALS._v566A6 += 15;
- if (R2_GLOBALS._v566A6 > 3815)
- R2_GLOBALS._v566A6 -= 20;
+ R2_GLOBALS._maze3800SceneNumb += 15;
+ if (R2_GLOBALS._maze3800SceneNumb > 3815)
+ R2_GLOBALS._maze3800SceneNumb -= 20;
initExits();
enterArea();
break;
case 12:
- R2_GLOBALS._v566A6 += 5;
- if (R2_GLOBALS._v566A6 > 3815)
- R2_GLOBALS._v566A6 = 3800;
+ R2_GLOBALS._maze3800SceneNumb += 5;
+ if (R2_GLOBALS._maze3800SceneNumb > 3815)
+ R2_GLOBALS._maze3800SceneNumb = 3800;
initExits();
enterArea();
break;
case 13:
- R2_GLOBALS._v566A6 -= 15;
- if (R2_GLOBALS._v566A6 < 3800)
- R2_GLOBALS._v566A6 += 20;
+ R2_GLOBALS._maze3800SceneNumb -= 15;
+ if (R2_GLOBALS._maze3800SceneNumb < 3800)
+ R2_GLOBALS._maze3800SceneNumb += 20;
initExits();
enterArea();
break;
case 14:
- R2_GLOBALS._v566A6 -= 5;
- if (R2_GLOBALS._v566A6 < 3800)
- R2_GLOBALS._v566A6 = 3815;
+ R2_GLOBALS._maze3800SceneNumb -= 5;
+ if (R2_GLOBALS._maze3800SceneNumb < 3800)
+ R2_GLOBALS._maze3800SceneNumb = 3815;
initExits();
enterArea();
break;
case 15:
- R2_GLOBALS._v56AAB = 0;
R2_GLOBALS._player.enableControl();
break;
case 16:
g_globals->_sceneManager.changeScene(3900);
break;
case 3800:
- _actor1.show();
- _object1.remove();
- _object2.remove();
- R2_GLOBALS._v56AAB = 0;
+ _quinnShadow.show();
+ _balloon.remove();
+ _harness.remove();
R2_GLOBALS._player.enableControl();
break;
case 3805:
@@ -5367,18 +5416,19 @@ void Scene3800::signal() {
}
void Scene3800::process(Event &event) {
- if ((R2_GLOBALS._player._uiEnabled) && (event.eventType == EVENT_BUTTON_DOWN) && (_rect1.contains(event.mousePos))) {
+ if ((R2_GLOBALS._player._uiEnabled) && (event.eventType == EVENT_BUTTON_DOWN)
+ && (_skylineRect.contains(event.mousePos))) {
event.handled = true;
switch (R2_GLOBALS._events.getCursor()) {
- case R2_NEGATOR_GUN:
+ case CURSOR_WALK:
R2_GLOBALS._player.addMover(NULL);
R2_GLOBALS._player.updateAngle(event.mousePos);
break;
- case R2_STEPPING_DISKS:
- SceneItem::display(3800, 5, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ case CURSOR_LOOK:
+ SceneItem::display(3800, 3, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, LIST_END);
break;
- case R2_ATTRACTOR_UNIT:
- SceneItem::display(3800, 3, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ case CURSOR_USE:
+ SceneItem::display(3800, 5, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, LIST_END);
break;
default:
event.handled = false;
@@ -5475,7 +5525,7 @@ void Scene3900::Exit5::changeScene() {
}
void Scene3900::postInit(SceneObjectList *OwnerList) {
- if ((R2_GLOBALS._desertPreviousDirection == 2)
+ if ((R2_GLOBALS._desertPreviousDirection == 2)
&& (R2_GLOBALS._sceneManager._previousScene != 2700))
loadScene(3825);
else
@@ -5493,13 +5543,13 @@ void Scene3900::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player.changeZoom(-1);
R2_GLOBALS._player._moveDiff = Common::Point(3, 2);
- _actor1.postInit();
- _actor1.fixPriority(10);
- _actor1.changeZoom(-1);
- _actor1.setVisage(1110);
- _actor1._effect = 5;
- _actor1._field9C = _field312;
- R2_GLOBALS._player._linkedActor = &_actor1;
+ _quinnShadow.postInit();
+ _quinnShadow.fixPriority(10);
+ _quinnShadow.changeZoom(-1);
+ _quinnShadow.setVisage(1110);
+ _quinnShadow._effect = EFFECT_SHADOW_MAP;
+ _quinnShadow._shadowMap = _shadowPaletteMap;
+ R2_GLOBALS._player._linkedActor = &_quinnShadow;
if ((R2_GLOBALS._desertPreviousDirection == 2) && (R2_GLOBALS._sceneManager._previousScene != 2700)) {
// loadScene(3825);
@@ -5515,8 +5565,8 @@ void Scene3900::postInit(SceneObjectList *OwnerList) {
_westExit._enabled = false;
- _exit5.setDetails(Rect(0, 87, 29, 168), EXITCURSOR_W, 3900);
- _exit5.setDest(Common::Point(24, 135));
+ _westEnterForest.setDetails(Rect(0, 87, 29, 168), EXITCURSOR_W, 3900);
+ _westEnterForest.setDest(Common::Point(24, 135));
} else {
// loadScene(3820);
R2_GLOBALS._desertCorrectDirection = 2;
@@ -5531,12 +5581,12 @@ void Scene3900::postInit(SceneObjectList *OwnerList) {
_westExit._insideArea = false;
_westExit._moving = false;
- _exit5.setDetails(Rect(290, 87, 320, 168), EXITCURSOR_E, 3900);
- _exit5.setDest(Common::Point(295, 135));
+ _westEnterForest.setDetails(Rect(290, 87, 320, 168), EXITCURSOR_E, 3900);
+ _westEnterForest.setDest(Common::Point(295, 135));
}
- _exit5._enabled = true;
- _exit5._insideArea = false;
- _exit5._moving = false;
+ _westEnterForest._enabled = true;
+ _westEnterForest._insideArea = false;
+ _westEnterForest._moving = false;
scalePalette(65, 65, 65);
@@ -5552,8 +5602,8 @@ void Scene3900::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._uiElements.draw();
- _rect1.set(0, 0, 320, 87);
- _item1.setDetails(Rect(0, 0, 320, 200), 3800, 0, 1, 2, 1, (SceneItem *)NULL);
+ _skylineRect.set(0, 0, 320, 87);
+ _background.setDetails(Rect(0, 0, 320, 200), 3800, 0, 1, 2, 1, (SceneItem *)NULL);
if (R2_GLOBALS._sceneManager._previousScene == 3800) {
_sceneMode = 11;
switch (R2_GLOBALS._desertPreviousDirection) {
@@ -5609,7 +5659,6 @@ void Scene3900::signal() {
case 11:
// No break on purpose
case 12:
- R2_GLOBALS._v56AAB = 0;
R2_GLOBALS._player.enableControl(CURSOR_WALK);
break;
case 13:
@@ -5639,18 +5688,19 @@ void Scene3900::signal() {
}
void Scene3900::process(Event &event) {
- if ((R2_GLOBALS._player._uiEnabled) && (event.eventType == EVENT_BUTTON_DOWN) && (_rect1.contains(event.mousePos))) {
+ if ((R2_GLOBALS._player._uiEnabled) && (event.eventType == EVENT_BUTTON_DOWN)
+ && (_skylineRect.contains(event.mousePos))) {
event.handled = true;
switch (R2_GLOBALS._events.getCursor()) {
- case R2_NEGATOR_GUN:
+ case CURSOR_WALK:
R2_GLOBALS._player.addMover(NULL);
R2_GLOBALS._player.updateAngle(event.mousePos);
break;
- case R2_STEPPING_DISKS:
- SceneItem::display(3800, 5, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ case CURSOR_USE:
+ SceneItem::display(3800, 5, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, LIST_END);
break;
- case R2_ATTRACTOR_UNIT:
- SceneItem::display(3800, 3, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
+ case CURSOR_LOOK:
+ SceneItem::display(3800, 3, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, LIST_END);
break;
default:
event.handled = false;
diff --git a/engines/tsage/ringworld2/ringworld2_scenes3.h b/engines/tsage/ringworld2/ringworld2_scenes3.h
index f9a4bf73ff..e6f74d6e53 100644
--- a/engines/tsage/ringworld2/ringworld2_scenes3.h
+++ b/engines/tsage/ringworld2/ringworld2_scenes3.h
@@ -45,15 +45,15 @@ class Scene3100 : public SceneExt {
virtual bool startAction(CursorType action, Event &event);
};
public:
- int _field412;
+ bool _fadeSound;
SpeakerGuard _guardSpeaker;
- NamedHotspot _item1;
- NamedHotspot _item2;
- SceneActor _actor1;
- SceneActor _actor2;
- SceneActor _actor3;
- SceneActor _actor4;
- SceneActor _actor5;
+ NamedHotspot _background;
+ NamedHotspot _hammerHead2;
+ SceneActor _hammerHead;
+ SceneActor _miranda;
+ SceneActor _ghoul;
+ SceneActor _technicians;
+ SceneActor _deadBodies;
Guard _guard;
ASoundExt _sound1;
SequenceManager _sequenceManager;
@@ -84,7 +84,7 @@ class Scene3125 : public SceneExt {
virtual bool startAction(CursorType action, Event &event);
};
public:
- int _field412;
+ bool _soundPlayed;
Background _background;
Door _door;
Table _table;
@@ -93,9 +93,7 @@ public:
SceneActor _ghoul2;
SceneActor _ghoul3;
SceneActor _ghoul4;
- SequenceManager _sequenceManager1;
- // Second sequence manager... Unused?
- SequenceManager _sequenceManager2;
+ SequenceManager _sequenceManager;
Scene3125();
virtual void postInit(SceneObjectList *OwnerList = NULL);
@@ -119,7 +117,7 @@ class Scene3150 : public SceneExt {
class FoodTray : public SceneActor {
virtual bool startAction(CursorType action, Event &event);
};
- class Actor6 : public SceneActor {
+ class ToiletFlush : public SceneActor {
virtual bool startAction(CursorType action, Event &event);
};
class AirVent : public SceneActor {
@@ -146,7 +144,7 @@ public:
SceneActor _bulbOrWire;
Water _water;
FoodTray _foodTray;
- Actor6 _toiletFlush;
+ ToiletFlush _toiletFlush;
AirVent _airVent;
DoorExit _doorExit;
VentExit _ventExit;
@@ -158,7 +156,7 @@ public:
};
class Scene3175 : public SceneExt {
- class Item1 : public NamedHotspot {
+ class RoomItem : public NamedHotspot {
public:
virtual bool startAction(CursorType action, Event &event);
};
@@ -170,11 +168,11 @@ class Scene3175 : public SceneExt {
virtual bool startAction(CursorType action, Event &event);
};
public:
- Item1 _background;
- Item1 _item2;
- Item1 _item3;
+ RoomItem _background;
+ RoomItem _table;
+ RoomItem _autopsies;
Door _door;
- SceneActor _actor2;
+ SceneActor _computer;
Corpse _corpse;
SequenceManager _sequenceManager;
@@ -187,9 +185,9 @@ public:
SpeakerRocko3200 _rockoSpeaker;
SpeakerJocko3200 _jockoSpeaker;
SpeakerSocko3200 _sockoSpeaker;
- SceneActor _actor1;
- SceneActor _actor2;
- SceneActor _actor3;
+ SceneActor _rocko;
+ SceneActor _jocko;
+ SceneActor _socko;
SequenceManager _sequenceManager;
virtual void postInit(SceneObjectList *OwnerList = NULL);
@@ -200,8 +198,8 @@ class Scene3210 : public SceneExt {
public:
SpeakerCaptain3210 _captainSpeaker;
SpeakerPrivate3210 _privateSpeaker;
- SceneActor _actor1;
- SceneActor _actor2;
+ SceneActor _captain;
+ SceneActor _private;
SequenceManager _sequenceManager;
virtual void postInit(SceneObjectList *OwnerList = NULL);
@@ -212,8 +210,8 @@ class Scene3220 : public SceneExt {
public:
SpeakerRocko3220 _rockoSpeaker;
SpeakerJocko3220 _jockoSpeaker;
- SceneActor _actor1;
- SceneActor _actor2;
+ SceneActor _rocko;
+ SceneActor _jocko;
SequenceManager _sequenceManager;
virtual void postInit(SceneObjectList *OwnerList = NULL);
@@ -224,9 +222,9 @@ class Scene3230 : public SceneExt {
public:
SpeakerRocko3230 _rockoSpeaker;
SpeakerJocko3230 _jockoSpeaker;
- SceneActor _actor1;
- SceneActor _actor2;
- SceneActor _actor3;
+ SceneActor _rocko;
+ SceneActor _jocko;
+ SceneActor _ghoul;
SequenceManager _sequenceManager;
virtual void postInit(SceneObjectList *OwnerList = NULL);
@@ -238,8 +236,8 @@ public:
SpeakerTeal3240 _tealSpeaker;
SpeakerWebbster3240 _webbsterSpeaker;
SpeakerMiranda _mirandaSpeaker;
- SceneActor _actor1;
- SceneActor _actor2;
+ SceneActor _teal;
+ SceneActor _webbster;
SequenceManager _sequenceManager;
virtual void postInit(SceneObjectList *OwnerList = NULL);
@@ -250,8 +248,8 @@ class Scene3245 : public SceneExt {
public:
SpeakerRalf3245 _ralfSpeaker;
SpeakerTomko3245 _tomkoSpeaker;
- SceneActor _actor1;
- SceneActor _actor2;
+ SceneActor _ralf;
+ SceneActor _tomko;
SequenceManager _sequenceManager;
virtual void postInit(SceneObjectList *OwnerList = NULL);
@@ -275,7 +273,7 @@ public:
Door _leftDoor;
Door _topDoor;
Door _rightDoor;
- Door _actor4;
+ Door _grate;
SceneActor _ghoul1;
SceneActor _ghoul2;
SceneActor _ghoul3;
@@ -290,7 +288,7 @@ class Scene3255 : public SceneExt {
public:
SceneActor _teal;
SceneActor _guard;
- SceneActor _actor3;
+ SceneActor _door;
SceneActor _quinn;
SceneActor _ghoul1;
SceneActor _ghoul2;
@@ -317,16 +315,16 @@ class Scene3260 : public SceneExt {
void signal();
};
public:
- NamedHotspot _item1;
+ NamedHotspot _background;
SceneActor _sceeen1;
SceneActor _screen2;
SceneActor _screen3;
SceneActor _screen4;
SceneActor _screen5;
SceneActor _screen6;
- SceneActor _actor7;
- SceneActor _actor8;
- SceneActor _actor9;
+ SceneActor _screen7;
+ SceneActor _screen8;
+ SceneActor _screen9;
SceneActor _securityConsole;
SceneActor _computerConsole;
SceneActor _lightingConsole;
@@ -366,7 +364,7 @@ public:
NamedHotspot _emptyCell2;
NamedHotspot _securityBeams1;
NamedHotspot _securityBeams2;
- SceneActor _actor1;
+ SceneActor _doorFrame;
Door _door;
CellExit _cellExit;
SequenceManager _sequenceManager;
@@ -377,15 +375,15 @@ public:
class Scene3350 : public SceneExt {
public:
- SceneActor _actor1;
- SceneActor _actor2;
- SceneActor _actor3;
- SceneActor _actor4;
- SceneActor _actor5;
- SceneActor _actor6;
- SceneActor _actor7;
- SceneActor _actor8;
- SceneActor _actor9;
+ SceneActor _miranda;
+ SceneActor _seeker;
+ SceneActor _webbster;
+ SceneActor _seatedPeople;
+ SceneActor _ship;
+ SceneActor _landedShip;
+ SceneActor _shipShadow;
+ SceneActor _canopy;
+ SceneActor _shipFront;
SequenceManager _sequenceManager;
PaletteRotation *_rotation;
@@ -439,9 +437,8 @@ public:
DownExit _downExit;
RightExit _rightExit;
SequenceManager _sequenceManager;
- int _field1488;
+ int _newSceneMode;
int _sceneAreas[4];
- int _field1492;
Scene3375();
virtual void postInit(SceneObjectList *OwnerList = NULL);
@@ -465,7 +462,7 @@ class Scene3385 : public SceneExt {
virtual bool startAction(CursorType action, Event &event);
};
- class Exit1 : public SceneExit {
+ class SouthExit : public SceneExit {
public:
virtual void changeScene();
};
@@ -485,11 +482,11 @@ public:
Companion2 _companion2;
Webbster _webbster;
Door _door;
- Exit1 _exit1;
+ SouthExit _southExit;
Action1 _action1;
SequenceManager _sequenceManager;
- int _field11B2;
+ int _playerStrip;
Scene3385();
virtual void postInit(SceneObjectList *OwnerList = NULL);
@@ -531,7 +528,7 @@ public:
Action1 _action1;
SequenceManager _sequenceManager;
- int _field142E;
+ int _playerStrip;
Scene3395();
virtual void postInit(SceneObjectList *OwnerList = NULL);
@@ -551,12 +548,11 @@ public:
SceneActor _companion2;
SceneActor _webbster;
SceneActor _teal;
- SceneActor _actor5;
- SceneActor _actor6;
- SceneActor _actor7;
- SceneActor _actor8;
+ SceneActor _door;
+ SceneActor _manholeCover;
+ SceneActor _sapphire;
SequenceManager _sequenceManager;
- int16 _field157C;
+ bool _soundFaded;
Scene3400();
virtual void postInit(SceneObjectList *OwnerList = NULL);
@@ -568,114 +564,104 @@ public:
class Scene3500 : public SceneExt {
class Action1: public Action {
public:
- int _field1E;
- int _field20;
- int _field22;
- int _field24;
+ int _direction;
+ bool _headingRightFl;
+ bool _turningFl;
Action1();
virtual void synchronize(Serializer &s);
- void sub108670(int arg1);
- void sub108732(int arg1);
+ void handleHorzButton(int direction);
+ void turnShuttle(bool arg1);
virtual void signal();
virtual void dispatch();
};
class Action2: public Action {
public:
- int _field1E;
+ int _direction;
Action2();
virtual void synchronize(Serializer &s);
- void sub10831F(int arg1);
+ void handleVertButton(int direction);
virtual void signal();
};
- class Item4 : public NamedHotspot {
+ class DirectionButton : public NamedHotspot {
public:
- int _field34;
+ int _movementId;
- Item4();
+ DirectionButton();
virtual void synchronize(Serializer &s);
virtual bool startAction(CursorType action, Event &event);
};
- class Actor7 : public SceneActor {
+ class Throttle : public SceneActor {
public:
- int _fieldA4;
- int _fieldA6;
- int _fieldA8;
- int _fieldAA;
- int _fieldAC;
- int _fieldAE;
+ Common::Point _pos;
+ int _deltaX;
+ int _deltaY;
+ int _slideDeltaY;
+ int _deltaMouseY;
- Actor7();
+ Throttle();
virtual void synchronize(Serializer &s);
- void sub109466(int arg1, int arg2, int arg3, int arg4, int arg5);
- void sub1094ED();
- void sub109663(int arg1);
- void sub109693(Common::Point Pt);
+ void init(int xp, int yp, int dx, int dy, int speed);
+ void updateSpeed();
+ void setSpeed(int arg1);
+ void changePosition(const Common::Point &pt);
virtual void process(Event &event);
virtual bool startAction(CursorType action, Event &event);
};
- class Actor8 : public SceneActor {
- public:
- // TODO: double check if nothing specific is present, then remove this class
- };
-
class MazeUI3500 : public MazeUI {
public:
- int cellFromX(int arg1);
- int cellFromY(int arg1);
+ int16 cellFromX(int arg1);
+ int16 cellFromY(int arg1);
int getCellFromMapXY(Common::Point pt);
bool setMazePosition2(Common::Point &p);
};
public:
Action1 _action1;
Action2 _action2;
- NamedHotspot _item1;
- NamedHotspot _item2;
- NamedHotspot _item3;
- Item4 _item4;
- Item4 _item5;
- Item4 _item6;
- Item4 _item7;
+ NamedHotspot _background;
+ NamedHotspot _outsideView;
+ NamedHotspot _mapScreen;
+ DirectionButton _pitchDown;
+ DirectionButton _turnLeft;
+ DirectionButton _pitchUp;
+ DirectionButton _turnRight;
// Glyph of vessel on top of the maze ui
- SceneActor _actor1;
- SceneActor _actor2;
- SceneActor _actor3;
- SceneActor _actor4;
- SceneActor _actor5;
- SceneActor _actor6;
- Actor7 _actor7;
- Actor8 _actor8;
- Actor8 _actor9;
+ SceneActor _shuttle;
+ SceneActor _verticalSpeedDisplay;
+ SceneActor _horizontalSpeedDisplay;
+ SceneActor _symbolVertical;
+ SceneActor _symbolLeft;
+ SceneActor _symbolRight;
+ Throttle _throttle;
+ SceneActor _tunnelVertCircle;
+ SceneActor _tunnelHorzCircle;
ASoundExt _aSound1;
MazeUI3500 _mazeUI;
SequenceManager _sequenceManager;
- int _fieldAF8;
- int _fieldB9E;
+ int _moverVertX;
+ int _moverHorzX;
PaletteRotation *_rotation;
int _mazeChangeAmount;
- int _field1270;
- int _field1272;
- int _field1274;
+ int _speed;
+ bool _updateIdxChangeFl;
int _mazeDirection;
- int _field1278;
+ int _nextMove;
Common::Point _mazePosition;
- int _field127E;
- int _field1280;
- int _field1282;
- int _field1284;
- int _field1286;
+ bool _postFixupFl;
+ int _exitCounter;
+ bool _directionChangesEnabled;
Scene3500();
- void sub107F71(int arg1);
+ void doMovement(int id);
virtual void postInit(SceneObjectList *OwnerList = NULL);
virtual void remove();
@@ -688,7 +674,8 @@ public:
class Scene3600 : public SceneExt {
class Action3600: public ActionExt {
public:
- int _field1E, _field20;
+ bool _part2Fl;
+ int _fadePct;
Action3600();
virtual void synchronize(Serializer &s);
@@ -699,12 +686,12 @@ class Scene3600 : public SceneExt {
virtual void signal();
};
- class Item5 : public NamedHotspot {
+ class LightShaft : public NamedHotspot {
public:
virtual bool startAction(CursorType action, Event &event);
};
- class Actor13 : public SceneActorExt {
+ class Protector : public SceneActorExt {
virtual bool startAction(CursorType action, Event &event);
};
public:
@@ -715,35 +702,30 @@ public:
SpeakerMiranda3600 _mirandaSpeaker;
SpeakerTeal3600 _tealSpeaker;
SpeakerProtector3600 _protectorSpeaker;
- NamedHotspot _item1;
- NamedHotspot _item2;
- NamedHotspot _item3;
- NamedHotspot _item4;
- Item5 _item5;
- SceneActor _actor1;
- SceneActor _actor2;
- SceneActor _actor3;
- SceneActor _actor4;
- SceneActor _actor5;
- SceneActor _actor6;
- SceneActor _actor7;
- SceneActor _actor8;
- SceneActor _actor9;
- SceneActor _actor10;
- SceneActor _actor11;
- SceneActor _actor12;
- Actor13 _actor13;
+ NamedHotspot _background;
+ NamedHotspot _console;
+ NamedHotspot _tapestry1;
+ NamedHotspot _tapestry2;
+ LightShaft _lightShaft;
+ SceneActor _protector3400;
+ SceneActor _steppingDisk;
+ SceneActor _consoleLights;
+ SceneActor _webbster;
+ SceneActor _teal;
+ SceneActor _door3400;
+ SceneActor _quinn;
+ SceneActor _seeker;
+ SceneActor _miranda;
+ Protector _protector;
SequenceManager _sequenceManager1;
SequenceManager _sequenceManager2;
SequenceManager _sequenceManager3;
SequenceManager _sequenceManager4;
ScenePalette _palette1;
- int _field2548;
- int _field254A;
- int _field254C;
- int _field254E;
- bool _field2550;
+ bool _tealDead;
+ bool _lightEntered;
+ bool _ghoulTeleported;
Scene3600();
virtual void postInit(SceneObjectList *OwnerList = NULL);
@@ -759,11 +741,11 @@ public:
SpeakerQuinn3700 _quinnSpeaker;
SpeakerSeeker3700 _seekerSpeaker;
SpeakerMiranda3700 _mirandaSpeaker;
- SceneActor _actor1;
- SceneActor _actor2;
- SceneActor _actor3;
- SceneActor _actor4;
- SceneActor _actor5;
+ SceneActor _quinn;
+ SceneActor _seeker;
+ SceneActor _miranda;
+ SceneActor _webbster;
+ SceneActor _teleportPad;
SequenceManager _sequenceManager;
virtual void postInit(SceneObjectList *OwnerList = NULL);
@@ -793,15 +775,15 @@ class Scene3800 : public SceneExt {
};
public:
- SceneObject _object1;
- SceneObject _object2;
- SceneActor _actor1;
+ SceneObject _balloon;
+ SceneObject _harness;
+ SceneActor _quinnShadow;
NamedHotspot _background;
NorthExit _northExit;
EastExit _eastExit;
SouthExit _southExit;
WestExit _westExit;
- Rect _rect1;
+ Rect _skylineRect;
SequenceManager _sequenceManager1;
int _desertDirection;
@@ -842,14 +824,14 @@ class Scene3900 : public SceneExt {
virtual void changeScene();
};
public:
- SceneActor _actor1;
- NamedHotspot _item1;
+ SceneActor _quinnShadow;
+ NamedHotspot _background;
NorthExit _northExit;
EastExit _eastExit;
SouthExit _southExit;
WestExit _westExit;
- Exit5 _exit5;
- Rect _rect1;
+ Exit5 _westEnterForest;
+ Rect _skylineRect;
virtual void postInit(SceneObjectList *OwnerList = NULL);
virtual void signal();
diff --git a/engines/tsage/ringworld2/ringworld2_speakers.cpp b/engines/tsage/ringworld2/ringworld2_speakers.cpp
index 93f428547e..494a31a829 100644
--- a/engines/tsage/ringworld2/ringworld2_speakers.cpp
+++ b/engines/tsage/ringworld2/ringworld2_speakers.cpp
@@ -36,14 +36,26 @@ namespace Ringworld2 {
VisualSpeaker::VisualSpeaker(): Speaker() {
_delayAmount = 0;
+ _voiceDelayAmount = 0;
_frameNumber = R2_GLOBALS._events.getFrameNumber();
_color1 = 8;
_color2 = 0;
_displayMode = 0;
_speakerMode = 0;
+
+ _object2 = nullptr;
+ _fieldF8 = 0;
+ _soundId = 0;
+ _removeObject = false;
+ _numFrames = 0;
+ _voiceFrameNumber = 0;
}
void VisualSpeaker::remove() {
+ _numFrames = 0;
+ _delayAmount = 0;
+ R2_GLOBALS._playStream.stop();
+
if (_object2) {
if (_fieldF8) {
_fieldF8 = 0;
@@ -59,9 +71,10 @@ void VisualSpeaker::remove() {
}
void VisualSpeaker::signal() {
- // TODO: _action->_field18 = 1;
+ // TODO: Handle _field18 if used in Action. It looks only used in the original in remove()
+ // _action->_field18 = 1;
if (_speakerMode == 0xff)
- proc16();
+ stopSpeaking();
_speakerMode = 0;
if (_numFrames) {
@@ -71,12 +84,11 @@ void VisualSpeaker::signal() {
_fieldF8 = 1;
}
- if ((R2_GLOBALS._speechSubtitles & SPEECH_TEXT) || _soundId)
+ if ((R2_GLOBALS._speechSubtitles & SPEECH_TEXT) || !_soundId)
_sceneText.show();
if ((R2_GLOBALS._speechSubtitles & SPEECH_VOICE) && _soundId) {
- // TODO: Check global that is passed
- setFrame2(/* word_55F90 */ 1);
+ setVoiceFrame(1);
}
} else if (_action && _object2) {
_action->setDelay(1);
@@ -88,6 +100,7 @@ void VisualSpeaker::signal() {
void VisualSpeaker::dispatch() {
uint32 frameNumber = R2_GLOBALS._events.getFrameNumber();
+ assert(_action);
// Delay check for character animation
if (_delayAmount) {
@@ -104,14 +117,14 @@ void VisualSpeaker::dispatch() {
}
// Delay check for voice
- if (_delayAmount2) {
- if (frameNumber >= _frameNumber2) {
- _delayAmount2 = _delayAmount2 - (_frameNumber2 - frameNumber);
- _frameNumber2 = frameNumber;
-
- if (_delayAmount2 <= 0) {
- _delayAmount2 = 0;
- if (R2_GLOBALS._playStream.play(0, NULL)) {
+ if (_voiceDelayAmount) {
+ if (frameNumber >= _voiceFrameNumber) {
+ _voiceDelayAmount = _voiceDelayAmount - (frameNumber - _voiceFrameNumber);
+ _voiceFrameNumber = frameNumber;
+
+ if (_voiceDelayAmount <= 0) {
+ _voiceDelayAmount = 0;
+ if (R2_GLOBALS._playStream.play(_soundId, NULL)) {
_numFrames = 2;
_soundId = 0;
} else {
@@ -128,6 +141,7 @@ void VisualSpeaker::dispatch() {
_object1.setFrame(1);
if (!(R2_GLOBALS._speechSubtitles & SPEECH_TEXT)) {
+ // Don't bother waiting for a mouse click to start the next speech segment
_action->setDelay(1);
}
}
@@ -145,8 +159,8 @@ void VisualSpeaker::synchronize(Serializer &s) {
s.syncAsSint16LE(_numFrames);
s.syncAsSint16LE(_delayAmount);
s.syncAsUint32LE(_frameNumber);
- s.syncAsSint16LE(_delayAmount2);
- s.syncAsUint32LE(_frameNumber2);
+ s.syncAsSint16LE(_voiceDelayAmount);
+ s.syncAsUint32LE(_voiceFrameNumber);
}
void VisualSpeaker::setText(const Common::String &msg) {
@@ -208,7 +222,7 @@ void VisualSpeaker::setText(const Common::String &msg) {
_sceneText.fixPriority(256);
// If subtitles are turned off, don't show the text
- if ((R2_GLOBALS._speechSubtitles & SPEECH_VOICE) &&
+ if ((R2_GLOBALS._speechSubtitles & SPEECH_VOICE) &&
!(R2_GLOBALS._speechSubtitles & SPEECH_TEXT)) {
_sceneText.hide();
}
@@ -240,13 +254,18 @@ void VisualSpeaker::setText(const Common::String &msg) {
_sceneText.hide();
} else {
if ((R2_GLOBALS._speechSubtitles & SPEECH_VOICE) && _soundId) {
- if (!R2_GLOBALS._playStream.play(_soundId, NULL))
+ if (!R2_GLOBALS._playStream.play(_soundId, NULL)) {
+ // Couldn't play voice, so fall back on showing text
_sceneText.show();
+ } else {
+ _numFrames = 2;
+ _soundId = 0;
+ }
}
}
}
-void VisualSpeaker::proc16() {
+void VisualSpeaker::stopSpeaking() {
R2_GLOBALS._playStream.stop();
_speakerMode = 0;
_object1.remove();
@@ -262,9 +281,9 @@ void VisualSpeaker::setFrame(int numFrames) {
_frameNumber = R2_GLOBALS._events.getFrameNumber();
}
-void VisualSpeaker::setFrame2(int numFrames) {
- _delayAmount2 = numFrames;
- _frameNumber2 = R2_GLOBALS._events.getFrameNumber();
+void VisualSpeaker::setVoiceFrame(int numFrames) {
+ _voiceDelayAmount = numFrames;
+ _voiceFrameNumber = R2_GLOBALS._events.getFrameNumber();
}
void VisualSpeaker::setDelay(int delay) {
@@ -299,12 +318,12 @@ SpeakerCaptain3210::SpeakerCaptain3210() {
_numFrames = 0;
}
-void SpeakerCaptain3210::proc15() {
+void SpeakerCaptain3210::animateSpeaker() {
int v = _speakerMode;
Scene3210 *scene = (Scene3210 *)R2_GLOBALS._sceneManager._scene;
if (!_object2) {
- _object2 = &scene->_actor1;
+ _object2 = &scene->_captain;
_object2->hide();
_object1.postInit();
_object1.setPosition(_object2->_position);
@@ -316,7 +335,8 @@ void SpeakerCaptain3210::proc15() {
if (v == 0) {
_object1.animate(ANIM_MODE_2, NULL);
} else {
- ((SceneItem *)_action)->_sceneRegionId = 0;
+ ((StripManager *)_action)->_useless = 0;
+
_object1.setup(4060, (_object2->_strip * 2) - 1, 1);
_object1.animate(ANIM_MODE_5, this);
}
@@ -354,7 +374,7 @@ SpeakerChief1100::SpeakerChief1100() {
_numFrames = 0;
}
-void SpeakerChief1100::proc15() {
+void SpeakerChief1100::animateSpeaker() {
int v = _speakerMode;
Scene1100 *scene = (Scene1100 *)R2_GLOBALS._sceneManager._scene;
@@ -374,18 +394,21 @@ void SpeakerChief1100::proc15() {
_object1.animate(ANIM_MODE_2, NULL);
break;
case 1:
- ((SceneItem *)_action)->_sceneRegionId = 0;
+ ((StripManager *)_action)->_useless = 0;
+
_object1.setup(4080, 1, 1);
_object1.animate(ANIM_MODE_5, this);
break;
case 2:
- ((SceneItem *)_action)->_sceneRegionId = 0;
+ ((StripManager *)_action)->_useless = 0;
+
_object1.setup(4080, 3, 1);
_object1.animate(ANIM_MODE_5, this);
break;
case 100:
_numFrames = 0;
- ((SceneItem *)_action)->_sceneRegionId = 0;
+ ((StripManager *)_action)->_useless = 0;
+
_object1.setStrip(_object1._strip - 1);
_object1.setFrame(_object1.getFrameCount());
_object1.animate(ANIM_MODE_6, this);
@@ -412,7 +435,7 @@ SpeakerGuard::SpeakerGuard() {
_numFrames = 0;
}
-void SpeakerGuard2800::proc15() {
+void SpeakerGuard2800::animateSpeaker() {
int v = _speakerMode;
Scene2800 *scene = (Scene2800 *)R2_GLOBALS._sceneManager._scene;
@@ -429,7 +452,8 @@ void SpeakerGuard2800::proc15() {
if (v == 0) {
_object1.animate(ANIM_MODE_2, NULL);
} else {
- ((SceneItem *)_action)->_sceneRegionId = 0;
+ ((StripManager *)_action)->_useless = 0;
+
_object1.setZoom(75);
_object1.setup(4060, 3, 1);
_object1.animate(ANIM_MODE_5, this);
@@ -452,12 +476,12 @@ SpeakerJocko::SpeakerJocko() {
_numFrames = 0;
}
-void SpeakerJocko3200::proc15() {
+void SpeakerJocko3200::animateSpeaker() {
int v = _speakerMode;
Scene3200 *scene = (Scene3200 *)R2_GLOBALS._sceneManager._scene;
if (!_object2) {
- _object2 = &scene->_actor2;
+ _object2 = &scene->_jocko;
_object2->hide();
_object1.postInit();
_object1.setPosition(_object2->_position);
@@ -469,18 +493,19 @@ void SpeakerJocko3200::proc15() {
if (v == 0) {
_object1.animate(ANIM_MODE_2, NULL);
} else {
- ((SceneItem *)_action)->_sceneRegionId = 0;
+ ((StripManager *)_action)->_useless = 0;
+
_object1.setup(4060, (_object2->_strip * 2) - 1, 1);
_object1.animate(ANIM_MODE_5, this);
}
}
-void SpeakerJocko3220::proc15() {
+void SpeakerJocko3220::animateSpeaker() {
int v = _speakerMode;
Scene3220 *scene = (Scene3220 *)R2_GLOBALS._sceneManager._scene;
if (!_object2) {
- _object2 = &scene->_actor2;
+ _object2 = &scene->_jocko;
_object2->hide();
_object1.postInit();
_object1.setPosition(_object2->_position);
@@ -492,18 +517,19 @@ void SpeakerJocko3220::proc15() {
if (v == 0) {
_object1.animate(ANIM_MODE_2, NULL);
} else {
- ((SceneItem *)_action)->_sceneRegionId = 0;
+ ((StripManager *)_action)->_useless = 0;
+
_object1.setup(4060, (_object2->_strip * 2) - 1, 1);
_object1.animate(ANIM_MODE_5, this);
}
}
-void SpeakerJocko3230::proc15() {
+void SpeakerJocko3230::animateSpeaker() {
int v = _speakerMode;
Scene3230 *scene = (Scene3230 *)R2_GLOBALS._sceneManager._scene;
if (!_object2) {
- _object2 = &scene->_actor2;
+ _object2 = &scene->_jocko;
_object2->hide();
_object1.postInit();
_object1.setPosition(_object2->_position);
@@ -515,7 +541,8 @@ void SpeakerJocko3230::proc15() {
if (v == 0) {
_object1.animate(ANIM_MODE_2, NULL);
} else {
- ((SceneItem *)_action)->_sceneRegionId = 0;
+ ((StripManager *)_action)->_useless = 0;
+
_object1.setup(4060, (_object2->_strip * 2) - 1, 1);
_object1.animate(ANIM_MODE_5, this);
}
@@ -537,7 +564,7 @@ SpeakerMiranda::SpeakerMiranda(): VisualSpeaker() {
_numFrames = 0;
}
-void SpeakerMiranda300::proc15() {
+void SpeakerMiranda300::animateSpeaker() {
int v = _speakerMode;
if (!_object2) {
@@ -560,13 +587,13 @@ void SpeakerMiranda300::proc15() {
_object1.animate(ANIM_MODE_2, NULL);
} else if (v == 100) {
_numFrames = 0;
- ((SceneItem *)_action)->_sceneRegionId = 0;
+ ((StripManager *)_action)->_useless = 0;
_object1.setStrip(_object1._strip - 1);
_object1.setFrame(_object1.getFrameCount());
_object1.animate(ANIM_MODE_6, this);
} else {
- ((SceneItem *)_action)->_sceneRegionId = 0;
+ ((StripManager *)_action)->_useless = 0;
if (v == 4) {
_object1.setup(304, 5, 1);
@@ -577,12 +604,12 @@ void SpeakerMiranda300::proc15() {
}
}
-void SpeakerMiranda1625::proc15() {
+void SpeakerMiranda1625::animateSpeaker() {
int v = _speakerMode;
if (!_object2) {
Scene1625 *scene = (Scene1625 *)R2_GLOBALS._sceneManager._scene;
- _object2 = &scene->_actor3;
+ _object2 = &scene->_mirandaMouth;
_object2->hide();
_object1.postInit();
_object1.setPosition(Common::Point(196, 65));
@@ -594,13 +621,14 @@ void SpeakerMiranda1625::proc15() {
if (v == 0) {
_object1.animate(ANIM_MODE_2, NULL);
} else {
- ((SceneItem *)_action)->_sceneRegionId = 0;
+ ((StripManager *)_action)->_useless = 0;
+
_object1.setup(1627, 3, 1);
_object1.animate(ANIM_MODE_5, this);
}
}
-void SpeakerMiranda3255::proc15() {
+void SpeakerMiranda3255::animateSpeaker() {
int v = _speakerMode;
if (!_object2) {
@@ -615,13 +643,14 @@ void SpeakerMiranda3255::proc15() {
if (v == 0) {
_object1.animate(ANIM_MODE_2, NULL);
} else {
- ((SceneItem *)_action)->_sceneRegionId = 0;
+ ((StripManager *)_action)->_useless = 0;
+
_object1.setup(3257, 5, 1);
_object1.animate(ANIM_MODE_5, this);
}
}
-void SpeakerMiranda3375::proc15() {
+void SpeakerMiranda3375::animateSpeaker() {
Scene3375 *scene = (Scene3375 *)R2_GLOBALS._sceneManager._scene;
int v = _speakerMode;
@@ -636,7 +665,7 @@ void SpeakerMiranda3375::proc15() {
_object1.postInit();
_object1.setPosition(_object2->_position);
_object1._numFrames = 7;
- _object1._effect = 1;
+ _object1._effect = EFFECT_SHADED;
_object1.changeZoom(-1);
if (scene->_companion1._position.y != 163)
@@ -661,7 +690,8 @@ void SpeakerMiranda3375::proc15() {
_object1.animate(ANIM_MODE_2, NULL);
break;
case 1:
- ((SceneItem *)_action)->_sceneRegionId = 0;
+ ((StripManager *)_action)->_useless = 0;
+
_object1.setup(4051, 5, 1);
_object1.animate(ANIM_MODE_5, this);
break;
@@ -671,7 +701,7 @@ void SpeakerMiranda3375::proc15() {
}
}
-void SpeakerMiranda3385::proc15() {
+void SpeakerMiranda3385::animateSpeaker() {
Scene3385 *scene = (Scene3385 *)R2_GLOBALS._sceneManager._scene;
int v = _speakerMode;
@@ -686,7 +716,7 @@ void SpeakerMiranda3385::proc15() {
_object1.postInit();
_object1.setPosition(_object2->_position);
_object1._numFrames = 7;
- _object1._effect = 1;
+ _object1._effect = EFFECT_SHADED;
_object1.changeZoom(-1);
if (R2_GLOBALS._sceneManager._previousScene == 3375)
@@ -710,7 +740,8 @@ void SpeakerMiranda3385::proc15() {
_object1.animate(ANIM_MODE_2, NULL);
break;
case 1:
- ((SceneItem *)_action)->_sceneRegionId = 0;
+ ((StripManager *)_action)->_useless = 0;
+
_object1.setup(4051, 5, 1);
_object1.animate(ANIM_MODE_5, this);
break;
@@ -720,7 +751,7 @@ void SpeakerMiranda3385::proc15() {
}
}
-void SpeakerMiranda3395::proc15() {
+void SpeakerMiranda3395::animateSpeaker() {
Scene3395 *scene = (Scene3395 *)R2_GLOBALS._sceneManager._scene;
int v = _speakerMode;
@@ -735,7 +766,7 @@ void SpeakerMiranda3395::proc15() {
_object1.postInit();
_object1.setPosition(_object2->_position);
_object1._numFrames = 7;
- _object1._effect = 1;
+ _object1._effect = EFFECT_SHADED;
_object1.changeZoom(-1);
if (R2_GLOBALS._sceneManager._previousScene == 3385)
@@ -760,7 +791,8 @@ void SpeakerMiranda3395::proc15() {
_object1.animate(ANIM_MODE_2, NULL);
break;
case 1:
- ((SceneItem *)_action)->_sceneRegionId = 0;
+ ((StripManager *)_action)->_useless = 0;
+
_object1.setup(4051, 5, 1);
_object1.animate(ANIM_MODE_5, this);
break;
@@ -770,7 +802,7 @@ void SpeakerMiranda3395::proc15() {
}
}
-void SpeakerMiranda3400::proc15() {
+void SpeakerMiranda3400::animateSpeaker() {
Scene3400 *scene = (Scene3400 *)R2_GLOBALS._sceneManager._scene;
int v = _speakerMode;
@@ -785,7 +817,7 @@ void SpeakerMiranda3400::proc15() {
_object1.postInit();
_object1.setPosition(_object2->_position);
_object1._numFrames = 7;
- _object1._effect = 1;
+ _object1._effect = EFFECT_SHADED;
_object1.changeZoom(-1);
R2_GLOBALS._player.disableControl();
R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
@@ -799,12 +831,14 @@ void SpeakerMiranda3400::proc15() {
_object1.animate(ANIM_MODE_2, NULL);
break;
case 1:
- ((SceneItem *)_action)->_sceneRegionId = 0;
+ ((StripManager *)_action)->_useless = 0;
+
_object1.setup(4051, 5, 1);
_object1.animate(ANIM_MODE_5, this);
break;
case 2:
- ((SceneItem *)_action)->_sceneRegionId = 0;
+ ((StripManager *)_action)->_useless = 0;
+
_object1.setup(4050, 3, 1);
_object1.animate(ANIM_MODE_5, this);
break;
@@ -814,7 +848,7 @@ void SpeakerMiranda3400::proc15() {
}
}
-void SpeakerMiranda3600::proc15() {
+void SpeakerMiranda3600::animateSpeaker() {
Scene3600 *scene = (Scene3600 *)R2_GLOBALS._sceneManager._scene;
int v = _speakerMode;
@@ -823,13 +857,13 @@ void SpeakerMiranda3600::proc15() {
if (R2_GLOBALS._player._characterIndex == R2_MIRANDA)
_object2 = &R2_GLOBALS._player;
else
- _object2 = &scene->_actor12;
+ _object2 = &scene->_miranda;
_object2->hide();
_object1.postInit();
_object1.setPosition(_object2->_position);
_object1._numFrames = 7;
- _object1._effect = 1;
+ _object1._effect = EFFECT_SHADED;
_object1.changeZoom(-1);
R2_GLOBALS._player.disableControl();
R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
@@ -845,12 +879,14 @@ void SpeakerMiranda3600::proc15() {
_object1.animate(ANIM_MODE_2, NULL);
break;
case 1:
- ((SceneItem *)_action)->_sceneRegionId = 0;
+ ((StripManager *)_action)->_useless = 0;
+
_object1.setup(4051, 1, 1);
_object1.animate(ANIM_MODE_5, this);
break;
case 2:
- ((SceneItem *)_action)->_sceneRegionId = 0;
+ ((StripManager *)_action)->_useless = 0;
+
_object1.setup(4050, 1, 1);
_object1.animate(ANIM_MODE_5, this);
break;
@@ -860,13 +896,13 @@ void SpeakerMiranda3600::proc15() {
}
}
-void SpeakerMiranda3700::proc15() {
+void SpeakerMiranda3700::animateSpeaker() {
Scene3700 *scene = (Scene3700 *)R2_GLOBALS._sceneManager._scene;
int v = _speakerMode;
if (!_object2) {
- _object2 = &scene->_actor3;
+ _object2 = &scene->_miranda;
_object2->hide();
_object1.postInit();
_object1.setPosition(_object2->_position);
@@ -885,26 +921,29 @@ void SpeakerMiranda3700::proc15() {
_object1.animate(ANIM_MODE_2, NULL);
break;
case 1:
- ((SceneItem *)_action)->_sceneRegionId = 0;
- scene->_actor1.setup(10, 6, 1);
- scene->_actor2.setup(20, 5, 1);
+ ((StripManager *)_action)->_useless = 0;
+
+ scene->_quinn.setup(10, 6, 1);
+ scene->_seeker.setup(20, 5, 1);
_object2->setup(30, 1, 1);
- scene->_actor4.setup(40, 1, 1);
+ scene->_webbster.setup(40, 1, 1);
_object1.setup(4050, 5, 1);
- _object1.animate(ANIM_MODE_5, NULL);
+ _object1.animate(ANIM_MODE_5, this);
break;
case 2:
- ((SceneItem *)_action)->_sceneRegionId = 0;
- scene->_actor3.setup(30, 8, 1);
+ ((StripManager *)_action)->_useless = 0;
+
+ scene->_miranda.setup(30, 8, 1);
_object1.setup(4052, 3, 1);
- _object1.animate(ANIM_MODE_5, NULL);
+ _object1.animate(ANIM_MODE_5, this);
break;
case 3:
- ((SceneItem *)_action)->_sceneRegionId = 0;
- scene->_actor2.setup(20, 1, 1);
- scene->_actor3.setup(30, 1, 1);
+ ((StripManager *)_action)->_useless = 0;
+
+ scene->_seeker.setup(20, 1, 1);
+ scene->_miranda.setup(30, 1, 1);
_object1.setup(4051, 7, 1);
- _object1.animate(ANIM_MODE_5, NULL);
+ _object1.animate(ANIM_MODE_5, this);
break;
default:
signal();
@@ -928,7 +967,7 @@ SpeakerNej::SpeakerNej() {
_numFrames = 0;
}
-void SpeakerNej2700::proc15() {
+void SpeakerNej2700::animateSpeaker() {
int v = _speakerMode;
Scene2700 *scene = (Scene2700 *)R2_GLOBALS._sceneManager._scene;
@@ -945,7 +984,8 @@ void SpeakerNej2700::proc15() {
if (v == 0) {
_object1.animate(ANIM_MODE_2, NULL);
} else {
- ((SceneItem *)_action)->_sceneRegionId = 0;
+ ((StripManager *)_action)->_useless = 0;
+
switch (_object2->_visage) {
case 2701:
_object1.setup(4022, 3, 1);
@@ -963,7 +1003,7 @@ void SpeakerNej2700::proc15() {
}
}
-void SpeakerNej2750::proc15() {
+void SpeakerNej2750::animateSpeaker() {
int v = _speakerMode;
Scene2750 *scene = (Scene2750 *)R2_GLOBALS._sceneManager._scene;
@@ -980,7 +1020,8 @@ void SpeakerNej2750::proc15() {
if (v == 0) {
_object1.animate(ANIM_MODE_2, NULL);
} else {
- ((SceneItem *)_action)->_sceneRegionId = 0;
+ ((StripManager *)_action)->_useless = 0;
+
switch (_object2->_visage) {
case 2705:
_object1.setup(4022, 7, 1);
@@ -995,12 +1036,12 @@ void SpeakerNej2750::proc15() {
}
}
-void SpeakerNej2800::proc15() {
+void SpeakerNej2800::animateSpeaker() {
int v = _speakerMode;
- Scene2750 *scene = (Scene2750 *)R2_GLOBALS._sceneManager._scene;
+ Scene2800 *scene = (Scene2800 *)R2_GLOBALS._sceneManager._scene;
if (!_object2) {
- _object2 = &scene->_actor2;
+ _object2 = &scene->_nej;
_object2->hide();
_object1.postInit();
_object1.setPosition(_object2->_position);
@@ -1012,7 +1053,8 @@ void SpeakerNej2800::proc15() {
if (v == 0) {
_object1.animate(ANIM_MODE_2, NULL);
} else {
- ((SceneItem *)_action)->_sceneRegionId = 0;
+ ((StripManager *)_action)->_useless = 0;
+
_object1.setup(4023, 3, 1);
if (_object2->_visage == 2801)
_object1.setPosition(Common::Point(R2_GLOBALS._player._position.x - 12, R2_GLOBALS._player._position.y));
@@ -1036,7 +1078,7 @@ SpeakerPharisha::SpeakerPharisha(): VisualSpeaker() {
_numFrames = 0;
}
-void SpeakerPharisha2435::proc15() {
+void SpeakerPharisha2435::animateSpeaker() {
int v = _speakerMode;
Scene2435 *scene = (Scene2435 *)R2_GLOBALS._sceneManager._scene;
@@ -1050,7 +1092,8 @@ void SpeakerPharisha2435::proc15() {
if (v == 0) {
_object1.animate(ANIM_MODE_2, NULL);
} else {
- ((SceneItem *)_action)->_sceneRegionId = 0;
+ ((StripManager *)_action)->_useless = 0;
+
_object1.setup(4098, 5, 1);
_object1.animate(ANIM_MODE_5, this);
}
@@ -1072,12 +1115,12 @@ SpeakerPrivate3210::SpeakerPrivate3210() {
_numFrames = 0;
}
-void SpeakerPrivate3210::proc15() {
+void SpeakerPrivate3210::animateSpeaker() {
int v = _speakerMode;
Scene3210 *scene = (Scene3210 *)R2_GLOBALS._sceneManager._scene;
if (!_object2) {
- _object2 = &scene->_actor2;
+ _object2 = &scene->_private;
_object2->hide();
_object1.postInit();
_object1.setPosition(_object2->_position);
@@ -1089,7 +1132,8 @@ void SpeakerPrivate3210::proc15() {
if (v == 0) {
_object1.animate(ANIM_MODE_2, NULL);
} else {
- ((SceneItem *)_action)->_sceneRegionId = 0;
+ ((StripManager *)_action)->_useless = 0;
+
_object1.setup(4060, (_object2->_strip * 2) - 1, 1);
_object1.animate(ANIM_MODE_5, this);
}
@@ -1111,17 +1155,17 @@ SpeakerProtector3600::SpeakerProtector3600() {
_numFrames = 0;
}
-void SpeakerProtector3600::proc15() {
+void SpeakerProtector3600::animateSpeaker() {
int v = _speakerMode;
Scene3600 *scene = (Scene3600 *)R2_GLOBALS._sceneManager._scene;
if (!_object2) {
- _object2 = &scene->_actor13;
+ _object2 = &scene->_protector;
_object2->hide();
_object1.postInit();
_object1.setPosition(_object2->_position);
_object1._numFrames = 7;
- _object1._effect = 1;
+ _object1._effect = EFFECT_SHADED;
_object1.changeZoom(-1);
R2_GLOBALS._player.disableControl();
@@ -1138,7 +1182,8 @@ void SpeakerProtector3600::proc15() {
_object1.animate(ANIM_MODE_2, NULL);
break;
case 1:
- ((SceneItem *)_action)->_sceneRegionId = 0;
+ ((StripManager *)_action)->_useless = 0;
+
if (scene->_sceneMode != 3324) {
_object1.setup(4125, 3, 1);
_object1.animate(ANIM_MODE_5, this);
@@ -1172,11 +1217,11 @@ SpeakerQuinn::SpeakerQuinn(): VisualSpeaker() {
_numFrames = 0;
}
-void SpeakerQuinn300::proc15() {
+void SpeakerQuinn300::animateSpeaker() {
int v = _speakerMode;
if (!_object2) {
- if (R2_GLOBALS._player._characterIndex == R2_MIRANDA) {
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
_object2 = &R2_GLOBALS._player;
} else {
assert(R2_GLOBALS._sceneManager._sceneNumber == 300);
@@ -1187,22 +1232,19 @@ void SpeakerQuinn300::proc15() {
_object2->hide();
_object1.postInit();
_object1.setPosition(_object2->_position);
-
- if (_object2->_mover)
- _object2->addMover(NULL);
}
if (v == 0) {
_object1.animate(ANIM_MODE_2, NULL);
} else if (v == 100) {
_numFrames = 0;
- ((SceneItem *)_action)->_sceneRegionId = 0;
+ ((StripManager *)_action)->_useless = 0;
_object1.setStrip(_object1._strip - 1);
_object1.setFrame(_object1.getFrameCount());
_object1.animate(ANIM_MODE_6, this);
} else {
- ((SceneItem *)_action)->_sceneRegionId = 0;
+ ((StripManager *)_action)->_useless = 0;
switch (_object2->_visage) {
case 10:
@@ -1214,13 +1256,15 @@ void SpeakerQuinn300::proc15() {
case 308:
_object1.setup(308, 5, 1);
break;
+ default:
+ break;
}
_object1.animate(ANIM_MODE_5, this);
}
}
-void SpeakerQuinn500::proc15() {
+void SpeakerQuinn500::animateSpeaker() {
int v = _speakerMode;
if (!_object2) {
@@ -1246,7 +1290,7 @@ void SpeakerQuinn500::proc15() {
if (v == 0) {
_object1.animate(ANIM_MODE_2, NULL);
} else {
- ((SceneItem *)_action)->_sceneRegionId = 0;
+ ((StripManager *)_action)->_useless = 0;
switch (_object2->_visage) {
case 10:
@@ -1265,7 +1309,7 @@ void SpeakerQuinn500::proc15() {
}
}
-void SpeakerQuinn1100::proc15() {
+void SpeakerQuinn1100::animateSpeaker() {
int v = _speakerMode;
if (!_object2) {
@@ -1294,17 +1338,20 @@ void SpeakerQuinn1100::proc15() {
_object1.animate(ANIM_MODE_2, NULL);
break;
case 1:
- ((SceneItem *)_action)->_sceneRegionId = 0;
+ ((StripManager *)_action)->_useless = 0;
+
_object1.setup(1108, 7, 1);
_object1.animate(ANIM_MODE_5, this);
break;
case 2:
- ((SceneItem *)_action)->_sceneRegionId = 0;
+ ((StripManager *)_action)->_useless = 0;
+
_object1.setup(1109, 1, 1);
_object1.animate(ANIM_MODE_5, this);
break;
case 3:
- ((SceneItem *)_action)->_sceneRegionId = 0;
+ ((StripManager *)_action)->_useless = 0;
+
_object1.setup(1109, 5, 1);
_object1.animate(ANIM_MODE_5, this);
break;
@@ -1314,7 +1361,7 @@ void SpeakerQuinn1100::proc15() {
}
}
-void SpeakerQuinn2435::proc15() {
+void SpeakerQuinn2435::animateSpeaker() {
int v = _speakerMode;
if (!_object2) {
@@ -1334,14 +1381,15 @@ void SpeakerQuinn2435::proc15() {
if (v == 0) {
_object1.animate(ANIM_MODE_2, NULL);
} else {
- ((SceneItem *)_action)->_sceneRegionId = 0;
+ ((StripManager *)_action)->_useless = 0;
+
_object2->setStrip(7);
_object1.setup(2020, 5, 1);
_object1.animate(ANIM_MODE_5, this);
}
}
-void SpeakerQuinn2450::proc15() {
+void SpeakerQuinn2450::animateSpeaker() {
int v = _speakerMode;
if (!_object2) {
@@ -1361,7 +1409,8 @@ void SpeakerQuinn2450::proc15() {
if (v == 0) {
_object1.animate(ANIM_MODE_2, NULL);
} else {
- ((SceneItem *)_action)->_sceneRegionId = 0;
+ ((StripManager *)_action)->_useless = 0;
+
if (R2_GLOBALS.getFlag(61))
_object1.setup(2020, 3, 1);
else
@@ -1370,7 +1419,7 @@ void SpeakerQuinn2450::proc15() {
}
}
-void SpeakerQuinn2700::proc15() {
+void SpeakerQuinn2700::animateSpeaker() {
int v = _speakerMode;
if (!_object2) {
@@ -1386,7 +1435,8 @@ void SpeakerQuinn2700::proc15() {
if (v == 0) {
_object1.animate(ANIM_MODE_2, NULL);
} else {
- ((SceneItem *)_action)->_sceneRegionId = 0;
+ ((StripManager *)_action)->_useless = 0;
+
switch (_object2->_visage) {
case 19:
_object1.setup(4022, 5, 1);
@@ -1401,7 +1451,7 @@ void SpeakerQuinn2700::proc15() {
}
}
-void SpeakerQuinn2750::proc15() {
+void SpeakerQuinn2750::animateSpeaker() {
int v = _speakerMode;
if (!_object2) {
@@ -1417,13 +1467,14 @@ void SpeakerQuinn2750::proc15() {
if (v == 0) {
_object1.animate(ANIM_MODE_2, NULL);
} else {
- ((SceneItem *)_action)->_sceneRegionId = 0;
+ ((StripManager *)_action)->_useless = 0;
+
switch (_object2->_visage) {
case 19:
_object1.setup(4022, 5, 1);
break;
case 2752:
- _object1.setup(2752, 1, 1);
+ _object1.setup(2752, 3, 1);
break;
default:
break;
@@ -1432,7 +1483,7 @@ void SpeakerQuinn2750::proc15() {
}
}
-void SpeakerQuinn2800::proc15() {
+void SpeakerQuinn2800::animateSpeaker() {
int v = _speakerMode;
if (!_object2) {
@@ -1448,7 +1499,8 @@ void SpeakerQuinn2800::proc15() {
if (v == 0) {
_object1.animate(ANIM_MODE_2, NULL);
} else {
- ((SceneItem *)_action)->_sceneRegionId = 0;
+ ((StripManager *)_action)->_useless = 0;
+
switch (_object2->_visage) {
case 16:
_object1.setZoom(75);
@@ -1471,7 +1523,7 @@ void SpeakerQuinn2800::proc15() {
}
}
-void SpeakerQuinn3255::proc15() {
+void SpeakerQuinn3255::animateSpeaker() {
Scene3255 *scene = (Scene3255 *)R2_GLOBALS._sceneManager._scene;
int v = _speakerMode;
@@ -1488,13 +1540,14 @@ void SpeakerQuinn3255::proc15() {
if (v == 0) {
_object1.animate(ANIM_MODE_2, NULL);
} else {
- ((SceneItem *)_action)->_sceneRegionId = 0;
+ ((StripManager *)_action)->_useless = 0;
+
_object1.setup(3257, 3, 1);
_object1.animate(ANIM_MODE_5, this);
}
}
-void SpeakerQuinn3375::proc15() {
+void SpeakerQuinn3375::animateSpeaker() {
Scene3375 *scene = (Scene3375 *)R2_GLOBALS._sceneManager._scene;
int v = _speakerMode;
@@ -1511,7 +1564,7 @@ void SpeakerQuinn3375::proc15() {
_object1.postInit();
_object1.setPosition(_object2->_position);
_object1._numFrames = 7;
- _object1._effect = 1;
+ _object1._effect = EFFECT_SHADED;
_object1.changeZoom(-1);
if (scene->_companion1._position.y != 163)
@@ -1529,13 +1582,13 @@ void SpeakerQuinn3375::proc15() {
_object2->addMover(NULL);
}
-
switch (v) {
case 0:
_object1.animate(ANIM_MODE_2, NULL);
break;
case 1:
- ((SceneItem *)_action)->_sceneRegionId = 0;
+ ((StripManager *)_action)->_useless = 0;
+
_object1.setup(4010, 5, 1);
_object1.animate(ANIM_MODE_5, this);
break;
@@ -1545,7 +1598,7 @@ void SpeakerQuinn3375::proc15() {
}
}
-void SpeakerQuinn3385::proc15() {
+void SpeakerQuinn3385::animateSpeaker() {
Scene3385 *scene = (Scene3385 *)R2_GLOBALS._sceneManager._scene;
int v = _speakerMode;
@@ -1562,7 +1615,7 @@ void SpeakerQuinn3385::proc15() {
_object1.postInit();
_object1.setPosition(_object2->_position);
_object1._numFrames = 7;
- _object1._effect = 1;
+ _object1._effect = EFFECT_SHADED;
_object1.changeZoom(-1);
if (R2_GLOBALS._sceneManager._previousScene == 3375)
@@ -1580,13 +1633,13 @@ void SpeakerQuinn3385::proc15() {
_object2->addMover(NULL);
}
-
switch (v) {
case 0:
_object1.animate(ANIM_MODE_2, NULL);
break;
case 1:
- ((SceneItem *)_action)->_sceneRegionId = 0;
+ ((StripManager *)_action)->_useless = 0;
+
if (R2_GLOBALS._player._characterIndex == R2_SEEKER)
_object1.setup(4010, 3, 1);
else
@@ -1600,7 +1653,7 @@ void SpeakerQuinn3385::proc15() {
}
}
-void SpeakerQuinn3395::proc15() {
+void SpeakerQuinn3395::animateSpeaker() {
Scene3395 *scene = (Scene3395 *)R2_GLOBALS._sceneManager._scene;
int v = _speakerMode;
@@ -1617,7 +1670,7 @@ void SpeakerQuinn3395::proc15() {
_object1.postInit();
_object1.setPosition(_object2->_position);
_object1._numFrames = 7;
- _object1._effect = 1;
+ _object1._effect = EFFECT_SHADED;
_object1.changeZoom(-1);
if (R2_GLOBALS._sceneManager._previousScene == 3385)
@@ -1635,13 +1688,13 @@ void SpeakerQuinn3395::proc15() {
_object2->addMover(NULL);
}
-
switch (v) {
case 0:
_object1.animate(ANIM_MODE_2, NULL);
break;
case 1:
- ((SceneItem *)_action)->_sceneRegionId = 0;
+ ((StripManager *)_action)->_useless = 0;
+
if (R2_GLOBALS._player._characterIndex == R2_SEEKER)
_object1.setup(4010, 3, 1);
else
@@ -1655,7 +1708,7 @@ void SpeakerQuinn3395::proc15() {
}
}
-void SpeakerQuinn3400::proc15() {
+void SpeakerQuinn3400::animateSpeaker() {
Scene3400 *scene = (Scene3400 *)R2_GLOBALS._sceneManager._scene;
int v = _speakerMode;
@@ -1672,7 +1725,7 @@ void SpeakerQuinn3400::proc15() {
_object1.postInit();
_object1.setPosition(_object2->_position);
_object1._numFrames = 7;
- _object1._effect = 1;
+ _object1._effect = EFFECT_SHADED;
_object1.changeZoom(-1);
R2_GLOBALS._player.disableControl();
if (_object2->_mover)
@@ -1684,17 +1737,20 @@ void SpeakerQuinn3400::proc15() {
_object1.animate(ANIM_MODE_2, NULL);
break;
case 1:
- ((SceneItem *)_action)->_sceneRegionId = 0;
+ ((StripManager *)_action)->_useless = 0;
+
_object1.setup(4010, 5, 1);
_object1.animate(ANIM_MODE_5, NULL);
break;
case 2:
- ((SceneItem *)_action)->_sceneRegionId = 0;
+ ((StripManager *)_action)->_useless = 0;
+
_object1.setup(4010, 3, 1);
_object1.animate(ANIM_MODE_5, this);
break;
case 3:
- ((SceneItem *)_action)->_sceneRegionId = 0;
+ ((StripManager *)_action)->_useless = 0;
+
_object1.setup(4012, 3, 1);
_object1.animate(ANIM_MODE_5, this);
break;
@@ -1704,7 +1760,7 @@ void SpeakerQuinn3400::proc15() {
}
}
-void SpeakerQuinn3600::proc15() {
+void SpeakerQuinn3600::animateSpeaker() {
Scene3600 *scene = (Scene3600 *)R2_GLOBALS._sceneManager._scene;
int v = _speakerMode;
@@ -1713,12 +1769,12 @@ void SpeakerQuinn3600::proc15() {
if (R2_GLOBALS._player._characterIndex == R2_QUINN)
_object2 = &R2_GLOBALS._player;
else
- _object2 = &scene->_actor10;
+ _object2 = &scene->_quinn;
_object2->hide();
_object1.postInit();
_object1.setPosition(_object2->_position);
_object1._numFrames = 7;
- _object1._effect = 1;
+ _object1._effect = EFFECT_SHADED;
_object1.changeZoom(-1);
R2_GLOBALS._player.disableControl();
R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
@@ -1732,17 +1788,20 @@ void SpeakerQuinn3600::proc15() {
_object1.animate(ANIM_MODE_2, NULL);
break;
case 1:
- ((SceneItem *)_action)->_sceneRegionId = 0;
+ ((StripManager *)_action)->_useless = 0;
+
_object1.setup(4021, 7, 1);
_object1.animate(ANIM_MODE_5, this);
break;
case 2:
- ((SceneItem *)_action)->_sceneRegionId = 0;
+ ((StripManager *)_action)->_useless = 0;
+
_object1.setup(4010, 1, 1);
_object1.animate(ANIM_MODE_5, this);
break;
case 3:
- ((SceneItem *)_action)->_sceneRegionId = 0;
+ ((StripManager *)_action)->_useless = 0;
+
_object1.setup(4012, 1, 1);
_object1.animate(ANIM_MODE_5, this);
break;
@@ -1757,26 +1816,26 @@ void SpeakerQuinn3700::setText(const Common::String &msg) {
switch (_speakerMode) {
case 2:
- scene->_actor3.setup(30, 1, 1);
+ scene->_miranda.setup(30, 1, 1);
R2_GLOBALS._sound2.play(44);
break;
case 3:
- scene->_actor3.setup(30, 1, 1);
+ scene->_miranda.setup(30, 1, 1);
break;
default:
- scene->_actor3.setup(30, 7, 1);
+ scene->_miranda.setup(30, 7, 1);
break;
}
VisualSpeaker::setText(msg);
}
-void SpeakerQuinn3700::proc15() {
+void SpeakerQuinn3700::animateSpeaker() {
Scene3700 *scene = (Scene3700 *)R2_GLOBALS._sceneManager._scene;
int v = _speakerMode;
if (!_object2) {
- _object2 = &scene->_actor1;
+ _object2 = &scene->_quinn;
_object2->hide();
_object1.postInit();
_object1.setPosition(_object2->_position);
@@ -1795,26 +1854,29 @@ void SpeakerQuinn3700::proc15() {
_object1.animate(ANIM_MODE_2, NULL);
break;
case 1:
- ((SceneItem *)_action)->_sceneRegionId = 0;
+ ((StripManager *)_action)->_useless = 0;
+
R2_GLOBALS._sound2.stop();
- scene->_actor1.setup(10, 4, 1);
- scene->_actor3.setup(30, 7, 1);
+ scene->_quinn.setup(10, 4, 1);
+ scene->_miranda.setup(30, 7, 1);
_object1.setup(3701, 1, 1);
- _object1.animate(ANIM_MODE_5, NULL);
+ _object1.animate(ANIM_MODE_5, this);
break;
case 2:
- ((SceneItem *)_action)->_sceneRegionId = 0;
- scene->_actor2.setup(20, 1, 1);
- scene->_actor3.setup(30, 1, 1);
- _object1.setup(3701, 2, 1);
- _object1.animate(ANIM_MODE_5, NULL);
+ ((StripManager *)_action)->_useless = 0;
+
+ scene->_seeker.setup(20, 1, 1);
+ scene->_miranda.setup(30, 1, 1);
+ _object1.setup(3702, 1, 1);
+ _object1.animate(ANIM_MODE_5, this);
break;
case 3:
- ((SceneItem *)_action)->_sceneRegionId = 0;
- scene->_actor1.setup(10, 2, 1);
- scene->_actor3.setup(30, 1, 1);
+ ((StripManager *)_action)->_useless = 0;
+
+ scene->_quinn.setup(10, 2, 1);
+ scene->_miranda.setup(30, 1, 1);
_object1.setup(4011, 1, 1);
- _object1.animate(ANIM_MODE_5, NULL);
+ _object1.animate(ANIM_MODE_5, this);
break;
default:
signal();
@@ -1826,17 +1888,8 @@ void SpeakerQuinn3700::proc15() {
// Classes related to QUINNL
//----------------------------------------------------------------------------
-SpeakerQuinnL::SpeakerQuinnL(): VisualSpeaker() {
+SpeakerQuinnL::SpeakerQuinnL(): SpeakerQuinn() {
_speakerName = "QUINNL";
- _color1 = 35;
- _color2 = 0;
- _speakerMode = 0;
- _textWidth = 300;
- _hideObjects = false;
- _object2 = NULL;
- _displayMode = 1;
- _numFrames = 0;
- _fontNumber = 10;
}
//----------------------------------------------------------------------------
@@ -1855,12 +1908,12 @@ SpeakerRalf3245::SpeakerRalf3245() {
_numFrames = 0;
}
-void SpeakerRalf3245::proc15() {
+void SpeakerRalf3245::animateSpeaker() {
int v = _speakerMode;
Scene3245 *scene = (Scene3245 *)R2_GLOBALS._sceneManager._scene;
if (!_object2) {
- _object2 = &scene->_actor1;
+ _object2 = &scene->_ralf;
_object2->hide();
_object1.postInit();
_object1.setPosition(_object2->_position);
@@ -1872,7 +1925,8 @@ void SpeakerRalf3245::proc15() {
if (v == 0) {
_object1.animate(ANIM_MODE_2, NULL);
} else {
- ((SceneItem *)_action)->_sceneRegionId = 0;
+ ((StripManager *)_action)->_useless = 0;
+
switch (_object2->_visage) {
case 3100:
_object1.setup(4105, (_object2->_strip * 2) - 1, 1);
@@ -1907,12 +1961,12 @@ SpeakerRocko::SpeakerRocko() {
_numFrames = 0;
}
-void SpeakerRocko3200::proc15() {
+void SpeakerRocko3200::animateSpeaker() {
int v = _speakerMode;
Scene3200 *scene = (Scene3200 *)R2_GLOBALS._sceneManager._scene;
if (!_object2) {
- _object2 = &scene->_actor1;
+ _object2 = &scene->_rocko;
_object2->hide();
_object1.postInit();
_object1.setPosition(_object2->_position);
@@ -1924,18 +1978,19 @@ void SpeakerRocko3200::proc15() {
if (v == 0) {
_object1.animate(ANIM_MODE_2, NULL);
} else {
- ((SceneItem *)_action)->_sceneRegionId = 0;
+ ((StripManager *)_action)->_useless = 0;
+
_object1.setup(4060, (_object2->_strip * 2) - 1, 1);
_object1.animate(ANIM_MODE_5, this);
}
}
-void SpeakerRocko3220::proc15() {
+void SpeakerRocko3220::animateSpeaker() {
int v = _speakerMode;
Scene3220 *scene = (Scene3220 *)R2_GLOBALS._sceneManager._scene;
if (!_object2) {
- _object2 = &scene->_actor1;
+ _object2 = &scene->_rocko;
_object2->hide();
_object1.postInit();
_object1.setPosition(_object2->_position);
@@ -1947,18 +2002,19 @@ void SpeakerRocko3220::proc15() {
if (v == 0) {
_object1.animate(ANIM_MODE_2, NULL);
} else {
- ((SceneItem *)_action)->_sceneRegionId = 0;
+ ((StripManager *)_action)->_useless = 0;
+
_object1.setup(4060, (_object2->_strip * 2) - 1, 1);
_object1.animate(ANIM_MODE_5, this);
}
}
-void SpeakerRocko3230::proc15() {
+void SpeakerRocko3230::animateSpeaker() {
int v = _speakerMode;
Scene3230 *scene = (Scene3230 *)R2_GLOBALS._sceneManager._scene;
if (!_object2) {
- _object2 = &scene->_actor1;
+ _object2 = &scene->_rocko;
_object2->hide();
_object1.postInit();
_object1.setPosition(_object2->_position);
@@ -1970,7 +2026,8 @@ void SpeakerRocko3230::proc15() {
if (v == 0) {
_object1.animate(ANIM_MODE_2, NULL);
} else {
- ((SceneItem *)_action)->_sceneRegionId = 0;
+ ((StripManager *)_action)->_useless = 0;
+
_object1.setup(4111, (_object2->_strip * 2) - 1, 1);
_object1.animate(ANIM_MODE_5, this);
}
@@ -1992,7 +2049,7 @@ SpeakerSeeker::SpeakerSeeker(): VisualSpeaker() {
_numFrames = 0;
}
-void SpeakerSeeker300::proc15() {
+void SpeakerSeeker300::animateSpeaker() {
int v = _speakerMode;
if (!_object2) {
@@ -2016,19 +2073,20 @@ void SpeakerSeeker300::proc15() {
_object1.animate(ANIM_MODE_2, NULL);
} else if (v == 100) {
_numFrames = 0;
- ((SceneItem *)_action)->_sceneRegionId = 0;
+ ((StripManager *)_action)->_useless = 0;
_object1.setStrip(_object1._strip - 1);
_object1.setFrame(_object1.getFrameCount());
_object1.animate(ANIM_MODE_6, this);
} else {
- ((SceneItem *)_action)->_sceneRegionId = 0;
+ ((StripManager *)_action)->_useless = 0;
+
_object1.setup(306, v * 2 - 1, 1);
_object1.animate(ANIM_MODE_5, this);
}
}
-void SpeakerSeeker500::proc15() {
+void SpeakerSeeker500::animateSpeaker() {
int v = _speakerMode;
if (!_object2) {
@@ -2054,7 +2112,7 @@ void SpeakerSeeker500::proc15() {
if (v == 0) {
_object1.animate(ANIM_MODE_2, NULL);
} else {
- ((SceneItem *)_action)->_sceneRegionId = 0;
+ ((StripManager *)_action)->_useless = 0;
if (v == 1)
_object1.setup(4041, 3, 1);
@@ -2065,7 +2123,7 @@ void SpeakerSeeker500::proc15() {
}
}
-void SpeakerSeeker1100::proc15() {
+void SpeakerSeeker1100::animateSpeaker() {
int v = _speakerMode;
if (!_object2) {
@@ -2094,28 +2152,33 @@ void SpeakerSeeker1100::proc15() {
_object1.animate(ANIM_MODE_2, NULL);
break;
case 1:
- ((SceneItem *)_action)->_sceneRegionId = 0;
+ ((StripManager *)_action)->_useless = 0;
+
_object1.setup(1108, 1, 1);
_object1.animate(ANIM_MODE_5, this);
break;
case 2:
- ((SceneItem *)_action)->_sceneRegionId = 0;
+ ((StripManager *)_action)->_useless = 0;
+
_object1.setup(1108, 3, 1);
_object1.animate(ANIM_MODE_5, this);
break;
case 3:
_object1.setPosition(Common::Point(197, 134));
- ((SceneItem *)_action)->_sceneRegionId = 0;
+ ((StripManager *)_action)->_useless = 0;
+
_object1.setup(1108, 5, 1);
_object1.animate(ANIM_MODE_5, this);
break;
case 4:
- ((SceneItem *)_action)->_sceneRegionId = 0;
+ ((StripManager *)_action)->_useless = 0;
+
_object1.setup(1109, 7, 1);
_object1.animate(ANIM_MODE_5, this);
break;
case 5:
- ((SceneItem *)_action)->_sceneRegionId = 0;
+ ((StripManager *)_action)->_useless = 0;
+
_object1.setup(1109, 3, 1);
_object1.animate(ANIM_MODE_5, this);
break;
@@ -2125,7 +2188,7 @@ void SpeakerSeeker1100::proc15() {
}
}
-void SpeakerSeeker1900::proc15() {
+void SpeakerSeeker1900::animateSpeaker() {
int v = _speakerMode;
if (!_object2) {
@@ -2134,7 +2197,7 @@ void SpeakerSeeker1900::proc15() {
} else {
assert(R2_GLOBALS._sceneManager._sceneNumber == 1900);
Scene1900 *scene = (Scene1900 *)R2_GLOBALS._sceneManager._scene;
- _object2 = &scene->_actor1;
+ _object2 = &scene->_companion;
}
_object2->hide();
@@ -2156,7 +2219,7 @@ void SpeakerSeeker1900::proc15() {
}
}
-void SpeakerSeeker2435::proc15() {
+void SpeakerSeeker2435::animateSpeaker() {
int v = _speakerMode;
if (!_object2) {
@@ -2176,14 +2239,15 @@ void SpeakerSeeker2435::proc15() {
if (v == 0) {
_object1.animate(ANIM_MODE_2, NULL);
} else {
- ((SceneItem *)_action)->_sceneRegionId = 0;
+ ((StripManager *)_action)->_useless = 0;
+
_object2->setStrip(7);
_object1.setup(4099, 1, 1);
_object1.animate(ANIM_MODE_5, this);
}
}
-void SpeakerSeeker2450::proc15() {
+void SpeakerSeeker2450::animateSpeaker() {
int v = _speakerMode;
if (!_object2) {
@@ -2203,13 +2267,14 @@ void SpeakerSeeker2450::proc15() {
if (v == 0) {
_object1.animate(ANIM_MODE_2, NULL);
} else {
- ((SceneItem *)_action)->_sceneRegionId = 0;
+ ((StripManager *)_action)->_useless = 0;
+
_object1.setup(4099, 3, 1);
_object1.animate(ANIM_MODE_5, this);
}
}
-void SpeakerSeeker3375::proc15() {
+void SpeakerSeeker3375::animateSpeaker() {
Scene3375 *scene = (Scene3375 *)R2_GLOBALS._sceneManager._scene;
int v = _speakerMode;
@@ -2224,7 +2289,7 @@ void SpeakerSeeker3375::proc15() {
_object1.postInit();
_object1.setPosition(_object2->_position);
_object1._numFrames = 7;
- _object1._effect = 1;
+ _object1._effect = EFFECT_SHADED;
_object1.changeZoom(-1);
if (scene->_companion1._position.y != 163)
@@ -2242,13 +2307,13 @@ void SpeakerSeeker3375::proc15() {
_object2->addMover(NULL);
}
-
switch (v) {
case 0:
_object1.animate(ANIM_MODE_2, NULL);
break;
case 1:
- ((SceneItem *)_action)->_sceneRegionId = 0;
+ ((StripManager *)_action)->_useless = 0;
+
_object1.setup(4031, 1, 1);
_object1.animate(ANIM_MODE_5, this);
break;
@@ -2258,7 +2323,7 @@ void SpeakerSeeker3375::proc15() {
}
}
-void SpeakerSeeker3385::proc15() {
+void SpeakerSeeker3385::animateSpeaker() {
Scene3385 *scene = (Scene3385 *)R2_GLOBALS._sceneManager._scene;
int v = _speakerMode;
@@ -2273,7 +2338,7 @@ void SpeakerSeeker3385::proc15() {
_object1.postInit();
_object1.setPosition(_object2->_position);
_object1._numFrames = 7;
- _object1._effect = 1;
+ _object1._effect = EFFECT_SHADED;
_object1.changeZoom(-1);
if (R2_GLOBALS._sceneManager._previousScene == 3375)
@@ -2297,7 +2362,8 @@ void SpeakerSeeker3385::proc15() {
_object1.animate(ANIM_MODE_2, NULL);
break;
case 1:
- ((SceneItem *)_action)->_sceneRegionId = 0;
+ ((StripManager *)_action)->_useless = 0;
+
_object1.setup(4031, 3, 1);
_object1.animate(ANIM_MODE_5, this);
break;
@@ -2307,7 +2373,7 @@ void SpeakerSeeker3385::proc15() {
}
}
-void SpeakerSeeker3395::proc15() {
+void SpeakerSeeker3395::animateSpeaker() {
Scene3395 *scene = (Scene3395 *)R2_GLOBALS._sceneManager._scene;
int v = _speakerMode;
@@ -2322,7 +2388,7 @@ void SpeakerSeeker3395::proc15() {
_object1.postInit();
_object1.setPosition(_object2->_position);
_object1._numFrames = 7;
- _object1._effect = 1;
+ _object1._effect = EFFECT_SHADED;
_object1.changeZoom(-1);
if (R2_GLOBALS._sceneManager._previousScene == 3385)
@@ -2340,13 +2406,13 @@ void SpeakerSeeker3395::proc15() {
_object2->addMover(NULL);
}
-
switch (v) {
case 0:
_object1.animate(ANIM_MODE_2, NULL);
break;
case 1:
- ((SceneItem *)_action)->_sceneRegionId = 0;
+ ((StripManager *)_action)->_useless = 0;
+
_object1.setup(4031, 3, 1);
_object1.animate(ANIM_MODE_5, this);
break;
@@ -2356,7 +2422,7 @@ void SpeakerSeeker3395::proc15() {
}
}
-void SpeakerSeeker3400::proc15() {
+void SpeakerSeeker3400::animateSpeaker() {
Scene3400 *scene = (Scene3400 *)R2_GLOBALS._sceneManager._scene;
int v = _speakerMode;
@@ -2371,7 +2437,7 @@ void SpeakerSeeker3400::proc15() {
_object1.postInit();
_object1.setPosition(_object2->_position);
_object1._numFrames = 7;
- _object1._effect = 1;
+ _object1._effect = EFFECT_SHADED;
_object1.changeZoom(-1);
R2_GLOBALS._player.disableControl();
R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
@@ -2385,27 +2451,32 @@ void SpeakerSeeker3400::proc15() {
_object1.animate(ANIM_MODE_2, NULL);
break;
case 1:
- ((SceneItem *)_action)->_sceneRegionId = 0;
+ ((StripManager *)_action)->_useless = 0;
+
_object1.setup(4031, 1, 1);
_object1.animate(ANIM_MODE_5, this);
break;
case 2:
- ((SceneItem *)_action)->_sceneRegionId = 0;
+ ((StripManager *)_action)->_useless = 0;
+
_object1.setup(4031, 3, 1);
_object1.animate(ANIM_MODE_5, this);
break;
case 3:
- ((SceneItem *)_action)->_sceneRegionId = 0;
+ ((StripManager *)_action)->_useless = 0;
+
_object1.setup(4030, 3, 1);
_object1.animate(ANIM_MODE_5, this);
break;
case 4:
- ((SceneItem *)_action)->_sceneRegionId = 0;
+ ((StripManager *)_action)->_useless = 0;
+
_object1.setup(4031, 7, 1);
_object1.animate(ANIM_MODE_5, this);
break;
case 5:
- ((SceneItem *)_action)->_sceneRegionId = 0;
+ ((StripManager *)_action)->_useless = 0;
+
_object1.setup(4033, 1, 1);
_object1.animate(ANIM_MODE_5, this);
break;
@@ -2415,7 +2486,7 @@ void SpeakerSeeker3400::proc15() {
}
}
-void SpeakerSeeker3600::proc15() {
+void SpeakerSeeker3600::animateSpeaker() {
Scene3600 *scene = (Scene3600 *)R2_GLOBALS._sceneManager._scene;
int v = _speakerMode;
@@ -2424,13 +2495,13 @@ void SpeakerSeeker3600::proc15() {
if (R2_GLOBALS._player._characterIndex == R2_SEEKER)
_object2 = &R2_GLOBALS._player;
else
- _object2 = &scene->_actor11;
+ _object2 = &scene->_seeker;
_object2->hide();
_object1.postInit();
_object1.setPosition(_object2->_position);
_object1._numFrames = 7;
- _object1._effect = 1;
+ _object1._effect = EFFECT_SHADED;
_object1.changeZoom(-1);
R2_GLOBALS._player.disableControl();
R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
@@ -2447,12 +2518,14 @@ void SpeakerSeeker3600::proc15() {
_object1.animate(ANIM_MODE_2, NULL);
break;
case 1:
- ((SceneItem *)_action)->_sceneRegionId = 0;
+ ((StripManager *)_action)->_useless = 0;
+
_object1.setup(4031, 5, 1);
_object1.animate(ANIM_MODE_5, this);
break;
case 2:
- ((SceneItem *)_action)->_sceneRegionId = 0;
+ ((StripManager *)_action)->_useless = 0;
+
_object1.setup(4030, 1, 1);
_object1.animate(ANIM_MODE_5, this);
break;
@@ -2467,20 +2540,21 @@ void SpeakerSeeker3700::setText(const Common::String &msg) {
if (_speakerMode == 1) {
R2_GLOBALS._sound2.play(44);
- scene->_actor3.setup(30, 8, 1);
+ scene->_miranda.setup(30, 8, 1);
} else {
- scene->_actor3.setup(30, 2, 1);
+ scene->_miranda.setup(30, 2, 1);
}
+
VisualSpeaker::setText(msg);
}
-void SpeakerSeeker3700::proc15() {
+void SpeakerSeeker3700::animateSpeaker() {
Scene3700 *scene = (Scene3700 *)R2_GLOBALS._sceneManager._scene;
int v = _speakerMode;
if (!_object2) {
- _object2 = &scene->_actor2;
+ _object2 = &scene->_seeker;
_object2->hide();
_object1.postInit();
_object1.setPosition(_object2->_position);
@@ -2499,21 +2573,23 @@ void SpeakerSeeker3700::proc15() {
_object1.animate(ANIM_MODE_2, NULL);
break;
case 1:
- ((SceneItem *)_action)->_sceneRegionId = 0;
+ ((StripManager *)_action)->_useless = 0;
+
R2_GLOBALS._sound2.stop();
- scene->_actor1.setup(10, 8, 1);
- scene->_actor2.setup(20, 7, 1);
- scene->_actor3.setup(30, 8, 1);
+ scene->_quinn.setup(10, 8, 1);
+ scene->_seeker.setup(20, 7, 1);
+ scene->_miranda.setup(30, 8, 1);
_object1.setup(3701, 3, 1);
- _object1.animate(ANIM_MODE_5, NULL);
+ _object1.animate(ANIM_MODE_5, this);
break;
case 2:
- ((SceneItem *)_action)->_sceneRegionId = 0;
- scene->_actor1.setup(10, 2, 1);
- scene->_actor2.setup(20, 1, 1);
- scene->_actor3.setup(30, 1, 1);
+ ((StripManager *)_action)->_useless = 0;
+
+ scene->_quinn.setup(10, 2, 1);
+ scene->_seeker.setup(20, 1, 1);
+ scene->_miranda.setup(30, 1, 1);
_object1.setup(4031, 1, 1);
- _object1.animate(ANIM_MODE_5, NULL);
+ _object1.animate(ANIM_MODE_5, this);
break;
default:
signal();
@@ -2525,17 +2601,8 @@ void SpeakerSeeker3700::proc15() {
// Classes related to SEEKERL
//----------------------------------------------------------------------------
-SpeakerSeekerL::SpeakerSeekerL(): VisualSpeaker() {
+SpeakerSeekerL::SpeakerSeekerL(): SpeakerSeeker() {
_speakerName = "SEEKERL";
- _color1 = 35;
- _color2 = 0;
- _speakerMode = 0;
- _textWidth = 300;
- _hideObjects = false;
- _object2 = NULL;
- _displayMode = 1;
- _numFrames = 0;
- _fontNumber = 10;
}
//----------------------------------------------------------------------------
@@ -2554,12 +2621,12 @@ SpeakerSocko3200::SpeakerSocko3200() {
_numFrames = 0;
}
-void SpeakerSocko3200::proc15() {
+void SpeakerSocko3200::animateSpeaker() {
int v = _speakerMode;
Scene3200 *scene = (Scene3200 *)R2_GLOBALS._sceneManager._scene;
if (!_object2) {
- _object2 = &scene->_actor3;
+ _object2 = &scene->_socko;
_object2->hide();
_object1.postInit();
_object1.setPosition(_object2->_position);
@@ -2571,7 +2638,8 @@ void SpeakerSocko3200::proc15() {
if (v == 0) {
_object1.animate(ANIM_MODE_2, NULL);
} else {
- ((SceneItem *)_action)->_sceneRegionId = 0;
+ ((StripManager *)_action)->_useless = 0;
+
_object1.setup(4060, (_object2->_strip * 2) - 1, 1);
_object1.animate(ANIM_MODE_5, this);
}
@@ -2593,7 +2661,7 @@ SpeakerSoldier::SpeakerSoldier(int color) {
_numFrames = 0;
}
-void SpeakerSoldier300::proc15() {
+void SpeakerSoldier300::animateSpeaker() {
int v = _speakerMode;
if (!_object2) {
@@ -2611,7 +2679,8 @@ void SpeakerSoldier300::proc15() {
if (v == 0) {
_object1.animate(ANIM_MODE_2, NULL);
} else {
- ((SceneItem *)_action)->_sceneRegionId = 0;
+ ((StripManager *)_action)->_useless = 0;
+
_object1.setup(303, 3, 1);
_object1.animate(ANIM_MODE_5, this);
}
@@ -2637,7 +2706,44 @@ SpeakerTealMode7::SpeakerTealMode7(): SpeakerTeal() {
_displayMode = 7;
}
-void SpeakerTeal300::proc15() {
+void SpeakerTeal180::animateSpeaker() {
+ int v = _speakerMode;
+
+ if (!_object2) {
+ Scene180 *scene = (Scene180 *)R2_GLOBALS._sceneManager._scene;
+ _object2 = &scene->_teal;
+ _object2->hide();
+
+ _object1.postInit();
+ _object1.setPosition(_object2->_position);
+
+ if (_object2->_mover)
+ _object2->addMover(NULL);
+ }
+
+ switch (v) {
+ case 0:
+ _object1.animate(ANIM_MODE_2, NULL);
+ break;
+ case 1:
+ ((StripManager *)_action)->_useless = 0;
+
+ _object1.setup(75, 5, 1);
+ _object1.animate(ANIM_MODE_5, this);
+ break;
+ case 2:
+ ((StripManager *)_action)->_useless = 0;
+
+ _object1.setup(77, 1, 1);
+ _object1.animate(ANIM_MODE_5, this);
+ break;
+ default:
+ signal();
+ break;
+ }
+}
+
+void SpeakerTeal300::animateSpeaker() {
int v = _speakerMode;
if (!_object2) {
@@ -2655,13 +2761,14 @@ void SpeakerTeal300::proc15() {
if (v == 0) {
_object1.animate(ANIM_MODE_2, NULL);
} else {
- ((SceneItem *)_action)->_sceneRegionId = 0;
+ ((StripManager *)_action)->_useless = 0;
+
_object1.setup(303, 1, 1);
_object1.animate(ANIM_MODE_5, this);
}
}
-void SpeakerTeal1625::proc15() {
+void SpeakerTeal1625::animateSpeaker() {
int v = _speakerMode;
if (!_object2) {
@@ -2679,18 +2786,19 @@ void SpeakerTeal1625::proc15() {
if (v == 0) {
_object1.animate(ANIM_MODE_2, NULL);
} else {
- ((SceneItem *)_action)->_sceneRegionId = 0;
+ ((StripManager *)_action)->_useless = 0;
+
_object1.setup(1627, 1, 1);
_object1.animate(ANIM_MODE_5, this);
}
}
-void SpeakerTeal3240::proc15() {
+void SpeakerTeal3240::animateSpeaker() {
int v = _speakerMode;
Scene3240 *scene = (Scene3240 *)R2_GLOBALS._sceneManager._scene;
if (!_object2) {
- _object2 = &scene->_actor1;
+ _object2 = &scene->_teal;
_object2->hide();
_object1.postInit();
_object1.setPosition(_object2->_position);
@@ -2702,13 +2810,14 @@ void SpeakerTeal3240::proc15() {
if (v == 0) {
_object1.animate(ANIM_MODE_2, NULL);
} else {
- ((SceneItem *)_action)->_sceneRegionId = 0;
+ ((StripManager *)_action)->_useless = 0;
+
_object1.setup(4070, (_object2->_strip * 2) - 1, 1);
_object1.animate(ANIM_MODE_5, this);
}
}
-void SpeakerTeal3400::proc15() {
+void SpeakerTeal3400::animateSpeaker() {
Scene3400 *scene = (Scene3400 *)R2_GLOBALS._sceneManager._scene;
int v = _speakerMode;
@@ -2718,7 +2827,7 @@ void SpeakerTeal3400::proc15() {
_object2->hide();
_object1.postInit();
_object1._numFrames = 7;
- _object1._effect = 1;
+ _object1._effect = EFFECT_SHADED;
_object1.changeZoom(-1);
R2_GLOBALS._player.disableControl();
R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
@@ -2740,22 +2849,26 @@ void SpeakerTeal3400::proc15() {
_object1.animate(ANIM_MODE_2, NULL);
break;
case 1:
- ((SceneItem *)_action)->_sceneRegionId = 0;
+ ((StripManager *)_action)->_useless = 0;
+
_object1.setup(4107, 5, 1);
_object1.animate(ANIM_MODE_5, this);
break;
case 2:
- ((SceneItem *)_action)->_sceneRegionId = 0;
+ ((StripManager *)_action)->_useless = 0;
+
_object1.setup(4107, 1, 1);
_object1.animate(ANIM_MODE_5, this);
break;
case 3:
- ((SceneItem *)_action)->_sceneRegionId = 0;
+ ((StripManager *)_action)->_useless = 0;
+
_object1.setup(4107, 7, 1);
_object1.animate(ANIM_MODE_5, this);
break;
case 4:
- ((SceneItem *)_action)->_sceneRegionId = 0;
+ ((StripManager *)_action)->_useless = 0;
+
_object1.setup(4107, 3, 1);
_object1.animate(ANIM_MODE_5, this);
break;
@@ -2765,18 +2878,18 @@ void SpeakerTeal3400::proc15() {
}
}
-void SpeakerTeal3600::proc15() {
+void SpeakerTeal3600::animateSpeaker() {
Scene3600 *scene = (Scene3600 *)R2_GLOBALS._sceneManager._scene;
int v = _speakerMode;
if (!_object2) {
- _object2 = &scene->_actor5;
+ _object2 = &scene->_teal;
_object2->hide();
_object1.postInit();
_object1.setPosition(_object2->_position);
_object1._numFrames = 7;
- _object1._effect = 1;
+ _object1._effect = EFFECT_SHADED;
_object1.changeZoom(-1);
R2_GLOBALS._player.disableControl();
R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
@@ -2796,22 +2909,26 @@ void SpeakerTeal3600::proc15() {
_object1.animate(ANIM_MODE_2, NULL);
break;
case 1:
- ((SceneItem *)_action)->_sceneRegionId = 0;
+ ((StripManager *)_action)->_useless = 0;
+
_object1.setup(4107, 5, 1);
_object1.animate(ANIM_MODE_5, this);
break;
case 2:
- ((SceneItem *)_action)->_sceneRegionId = 0;
+ ((StripManager *)_action)->_useless = 0;
+
_object1.setup(4107, 1, 1);
_object1.animate(ANIM_MODE_5, this);
break;
case 3:
- ((SceneItem *)_action)->_sceneRegionId = 0;
+ ((StripManager *)_action)->_useless = 0;
+
_object1.setup(4107, 7, 1);
_object1.animate(ANIM_MODE_5, this);
break;
case 4:
- ((SceneItem *)_action)->_sceneRegionId = 0;
+ ((StripManager *)_action)->_useless = 0;
+
_object1.setup(4107, 3, 1);
_object1.animate(ANIM_MODE_5, this);
break;
@@ -2837,12 +2954,12 @@ SpeakerTomko3245::SpeakerTomko3245() {
_numFrames = 0;
}
-void SpeakerTomko3245::proc15() {
+void SpeakerTomko3245::animateSpeaker() {
int v = _speakerMode;
Scene3245 *scene = (Scene3245 *)R2_GLOBALS._sceneManager._scene;
if (!_object2) {
- _object2 = &scene->_actor2;
+ _object2 = &scene->_tomko;
_object2->hide();
_object1.postInit();
_object1.setPosition(_object2->_position);
@@ -2854,7 +2971,8 @@ void SpeakerTomko3245::proc15() {
if (v == 0) {
_object1.animate(ANIM_MODE_2, NULL);
} else {
- ((SceneItem *)_action)->_sceneRegionId = 0;
+ ((StripManager *)_action)->_useless = 0;
+
switch (_object2->_visage) {
case 3100:
_object1.setup(4105, (_object2->_strip * 2) - 1, 1);
@@ -2889,12 +3007,56 @@ SpeakerWebbster::SpeakerWebbster(int color) {
_numFrames = 0;
}
-void SpeakerWebbster3240::proc15() {
+void SpeakerWebbster180::animateSpeaker() {
+ Scene180 *scene = (Scene180 *)R2_GLOBALS._sceneManager._scene;
+
+ int v = _speakerMode;
+
+ if (!_object2) {
+ _object2 = &scene->_webbster;
+ _object2->hide();
+ _object1.postInit();
+ _object1.setPosition(_object2->_position);
+ _object1._numFrames = 6;
+
+ if (_object2->_mover)
+ _object2->addMover(NULL);
+ }
+
+ switch (v) {
+ case 0:
+ _object1.animate(ANIM_MODE_2, NULL);
+ break;
+ case 1:
+ ((StripManager *)_action)->_useless = 0;
+
+ _object1.setup(75, 7, 1);
+ _object1.animate(ANIM_MODE_5, this);
+ break;
+ case 2:
+ ((StripManager *)_action)->_useless = 0;
+
+ _object1.setup(76, 4, 1);
+ _object1.animate(ANIM_MODE_5, this);
+ break;
+ case 3:
+ ((StripManager *)_action)->_useless = 0;
+
+ _object1.setup(76, 6, 1);
+ _object1.animate(ANIM_MODE_5, this);
+ break;
+ default:
+ signal();
+ break;
+ }
+}
+
+void SpeakerWebbster3240::animateSpeaker() {
int v = _speakerMode;
Scene3240 *scene = (Scene3240 *)R2_GLOBALS._sceneManager._scene;
if (!_object2) {
- _object2 = &scene->_actor2;
+ _object2 = &scene->_webbster;
_object2->hide();
_object1.postInit();
_object1.setPosition(_object2->_position);
@@ -2906,13 +3068,14 @@ void SpeakerWebbster3240::proc15() {
if (v == 0) {
_object1.animate(ANIM_MODE_2, NULL);
} else {
- ((SceneItem *)_action)->_sceneRegionId = 0;
+ ((StripManager *)_action)->_useless = 0;
+
_object1.setup(4110, 5, 1);
_object1.animate(ANIM_MODE_5, this);
}
}
-void SpeakerWebbster3375::proc15() {
+void SpeakerWebbster3375::animateSpeaker() {
Scene3375 *scene = (Scene3375 *)R2_GLOBALS._sceneManager._scene;
int v = _speakerMode;
@@ -2923,7 +3086,7 @@ void SpeakerWebbster3375::proc15() {
_object1.postInit();
_object1.setPosition(_object2->_position);
_object1._numFrames = 7;
- _object1._effect = 1;
+ _object1._effect = EFFECT_SHADED;
_object1.changeZoom(-1);
if (scene->_companion1._position.y != 163)
@@ -2946,7 +3109,8 @@ void SpeakerWebbster3375::proc15() {
_object1.animate(ANIM_MODE_2, NULL);
break;
case 1:
- ((SceneItem *)_action)->_sceneRegionId = 0;
+ ((StripManager *)_action)->_useless = 0;
+
_object1.setup(4110, 5, 1);
_object1.animate(ANIM_MODE_5, this);
break;
@@ -2956,7 +3120,7 @@ void SpeakerWebbster3375::proc15() {
}
}
-void SpeakerWebbster3385::proc15() {
+void SpeakerWebbster3385::animateSpeaker() {
Scene3385 *scene = (Scene3385 *)R2_GLOBALS._sceneManager._scene;
int v = _speakerMode;
@@ -2967,7 +3131,7 @@ void SpeakerWebbster3385::proc15() {
_object1.postInit();
_object1.setPosition(_object2->_position);
_object1._numFrames = 7;
- _object1._effect = 1;
+ _object1._effect = EFFECT_SHADED;
_object1.changeZoom(-1);
if (R2_GLOBALS._sceneManager._previousScene == 3375)
@@ -2990,7 +3154,8 @@ void SpeakerWebbster3385::proc15() {
_object1.animate(ANIM_MODE_2, NULL);
break;
case 1:
- ((SceneItem *)_action)->_sceneRegionId = 0;
+ ((StripManager *)_action)->_useless = 0;
+
_object1.setup(4110, 5, 1);
_object1.animate(ANIM_MODE_5, this);
break;
@@ -3000,7 +3165,7 @@ void SpeakerWebbster3385::proc15() {
}
}
-void SpeakerWebbster3395::proc15() {
+void SpeakerWebbster3395::animateSpeaker() {
Scene3395 *scene = (Scene3395 *)R2_GLOBALS._sceneManager._scene;
int v = _speakerMode;
@@ -3011,7 +3176,7 @@ void SpeakerWebbster3395::proc15() {
_object1.postInit();
_object1.setPosition(_object2->_position);
_object1._numFrames = 7;
- _object1._effect = 1;
+ _object1._effect = EFFECT_SHADED;
_object1.changeZoom(-1);
if (R2_GLOBALS._sceneManager._previousScene == 3385)
@@ -3034,7 +3199,8 @@ void SpeakerWebbster3395::proc15() {
_object1.animate(ANIM_MODE_2, NULL);
break;
case 1:
- ((SceneItem *)_action)->_sceneRegionId = 0;
+ ((StripManager *)_action)->_useless = 0;
+
_object1.setup(4110, 5, 1);
_object1.animate(ANIM_MODE_5, this);
break;
@@ -3044,7 +3210,7 @@ void SpeakerWebbster3395::proc15() {
}
}
-void SpeakerWebbster3400::proc15() {
+void SpeakerWebbster3400::animateSpeaker() {
Scene3400 *scene = (Scene3400 *)R2_GLOBALS._sceneManager._scene;
int v = _speakerMode;
@@ -3055,7 +3221,7 @@ void SpeakerWebbster3400::proc15() {
_object1.postInit();
_object1.setPosition(_object2->_position);
_object1._numFrames = 7;
- _object1._effect = 1;
+ _object1._effect = EFFECT_SHADED;
_object1.changeZoom(-1);
R2_GLOBALS._player.disableControl();
R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
@@ -3069,17 +3235,20 @@ void SpeakerWebbster3400::proc15() {
_object1.animate(ANIM_MODE_2, NULL);
break;
case 1:
- ((SceneItem *)_action)->_sceneRegionId = 0;
+ ((StripManager *)_action)->_useless = 0;
+
_object1.setup(4110, 5, 1);
_object1.animate(ANIM_MODE_5, this);
break;
case 2:
- ((SceneItem *)_action)->_sceneRegionId = 0;
+ ((StripManager *)_action)->_useless = 0;
+
_object1.setup(4110, 7, 1);
_object1.animate(ANIM_MODE_5, this);
break;
case 3:
- ((SceneItem *)_action)->_sceneRegionId = 0;
+ ((StripManager *)_action)->_useless = 0;
+
_object1.setup(4110, 3, 1);
_object1.animate(ANIM_MODE_5, this);
break;
@@ -3091,7 +3260,7 @@ void SpeakerWebbster3400::proc15() {
//----------------------------------------------------------------------------
-SpeakerDutyOfficer::SpeakerDutyOfficer(): VisualSpeaker() {
+SpeakerDutyOfficer180::SpeakerDutyOfficer180(): VisualSpeaker() {
_speakerName = "DUTYOFFICER";
_color1 = 5;
_color2 = 0;
@@ -3103,13 +3272,13 @@ SpeakerDutyOfficer::SpeakerDutyOfficer(): VisualSpeaker() {
_numFrames = 0;
}
-void SpeakerDutyOfficer::proc15() {
+void SpeakerDutyOfficer180::animateSpeaker() {
Scene180 *scene = (Scene180 *)R2_GLOBALS._sceneManager._scene;
int v = _speakerMode;
if (!_object2) {
- _object2 = &scene->_object2;
+ _object2 = &scene->_dutyOfficer;
_object2->hide();
_object1.postInit();
_object1.setPosition(_object2->_position);
@@ -3123,7 +3292,7 @@ void SpeakerDutyOfficer::proc15() {
_object1.animate(ANIM_MODE_2, NULL);
break;
case 1:
- _action = NULL;
+ _action->_action = NULL;
_object1.setup(76, 2, 1);
_object1.animate(ANIM_MODE_5, this);
break;
@@ -3133,6 +3302,5 @@ void SpeakerDutyOfficer::proc15() {
}
}
-
} // End of namespace Ringworld2
} // End of namespace TsAGE
diff --git a/engines/tsage/ringworld2/ringworld2_speakers.h b/engines/tsage/ringworld2/ringworld2_speakers.h
index 4dfb500f2d..d70652ff97 100644
--- a/engines/tsage/ringworld2/ringworld2_speakers.h
+++ b/engines/tsage/ringworld2/ringworld2_speakers.h
@@ -49,11 +49,11 @@ public:
bool _removeObject;
uint32 _frameNumber;
int _numFrames;
- int _delayAmount2;
- uint32 _frameNumber2;
+ int _voiceDelayAmount;
+ uint32 _voiceFrameNumber;
private:
void setFrame(int numFrames);
- void setFrame2(int numFrames);
+ void setVoiceFrame(int numFrames);
public:
VisualSpeaker();
@@ -63,8 +63,8 @@ public:
virtual void signal();
virtual void dispatch();
virtual void setText(const Common::String &msg);
- virtual void proc15() {}
- virtual void proc16();
+ virtual void animateSpeaker() {}
+ virtual void stopSpeaking();
void setDelay(int delay);
};
@@ -83,7 +83,7 @@ public:
SpeakerCaptain3210();
virtual Common::String getClassName() { return "SpeakerCaptain3210"; }
- virtual void proc15();
+ virtual void animateSpeaker();
};
// Classes related to Caretaker
@@ -102,7 +102,7 @@ public:
SpeakerChief1100();
virtual Common::String getClassName() { return "SpeakerChief1100"; }
- virtual void proc15();
+ virtual void animateSpeaker();
};
// Classes related to Guard
@@ -116,7 +116,7 @@ public:
class SpeakerGuard2800 : public SpeakerGuard {
public:
virtual Common::String getClassName() { return "SpeakerGuard2800"; }
- virtual void proc15();
+ virtual void animateSpeaker();
};
// Classes related to Jocko
@@ -130,19 +130,19 @@ public:
class SpeakerJocko3200 : public SpeakerJocko {
public:
virtual Common::String getClassName() { return "SpeakerJocko3200"; }
- virtual void proc15();
+ virtual void animateSpeaker();
};
class SpeakerJocko3220 : public SpeakerJocko {
public:
virtual Common::String getClassName() { return "SpeakerJocko3220"; }
- virtual void proc15();
+ virtual void animateSpeaker();
};
class SpeakerJocko3230 : public SpeakerJocko {
public:
virtual Common::String getClassName() { return "SpeakerJocko3230"; }
- virtual void proc15();
+ virtual void animateSpeaker();
};
// Classes related to Miranda
@@ -156,55 +156,55 @@ public:
class SpeakerMiranda300 : public SpeakerMiranda {
public:
virtual Common::String getClassName() { return "SpeakerMiranda300"; }
- virtual void proc15();
+ virtual void animateSpeaker();
};
class SpeakerMiranda1625 : public SpeakerMiranda {
public:
virtual Common::String getClassName() { return "SpeakerMiranda1625"; }
- virtual void proc15();
+ virtual void animateSpeaker();
};
class SpeakerMiranda3255 : public SpeakerMiranda {
public:
virtual Common::String getClassName() { return "SpeakerMiranda3255"; }
- virtual void proc15();
+ virtual void animateSpeaker();
};
class SpeakerMiranda3375 : public SpeakerMiranda {
public:
virtual Common::String getClassName() { return "SpeakerMiranda3375"; }
- virtual void proc15();
+ virtual void animateSpeaker();
};
class SpeakerMiranda3385 : public SpeakerMiranda {
public:
virtual Common::String getClassName() { return "SpeakerMiranda3385"; }
- virtual void proc15();
+ virtual void animateSpeaker();
};
class SpeakerMiranda3395 : public SpeakerMiranda {
public:
virtual Common::String getClassName() { return "SpeakerMiranda3395"; }
- virtual void proc15();
+ virtual void animateSpeaker();
};
class SpeakerMiranda3400 : public SpeakerMiranda {
public:
virtual Common::String getClassName() { return "SpeakerMiranda3400"; }
- virtual void proc15();
+ virtual void animateSpeaker();
};
class SpeakerMiranda3600 : public SpeakerMiranda {
public:
virtual Common::String getClassName() { return "SpeakerMiranda3600"; }
- virtual void proc15();
+ virtual void animateSpeaker();
};
class SpeakerMiranda3700 : public SpeakerMiranda {
public:
virtual Common::String getClassName() { return "SpeakerMiranda3700"; }
- virtual void proc15();
+ virtual void animateSpeaker();
};
// Classes related to Nej
@@ -218,19 +218,19 @@ public:
class SpeakerNej2700 : public SpeakerNej {
public:
virtual Common::String getClassName() { return "SpeakerNej2700"; }
- virtual void proc15();
+ virtual void animateSpeaker();
};
class SpeakerNej2750 : public SpeakerNej {
public:
virtual Common::String getClassName() { return "SpeakerNej2750"; }
- virtual void proc15();
+ virtual void animateSpeaker();
};
class SpeakerNej2800 : public SpeakerNej {
public:
virtual Common::String getClassName() { return "SpeakerNej2800"; }
- virtual void proc15();
+ virtual void animateSpeaker();
};
// Classes related to Pharisha
@@ -245,7 +245,7 @@ public:
class SpeakerPharisha2435 : public SpeakerPharisha {
public:
virtual Common::String getClassName() { return "SpeakerPharisha2435"; }
- virtual void proc15();
+ virtual void animateSpeaker();
};
// Classes related to Private
@@ -255,7 +255,7 @@ public:
SpeakerPrivate3210();
virtual Common::String getClassName() { return "SpeakerPrivate3210"; }
- virtual void proc15();
+ virtual void animateSpeaker();
};
// Classes related to Protector
@@ -265,7 +265,7 @@ public:
SpeakerProtector3600();
virtual Common::String getClassName() { return "SpeakerProtector3600"; }
- virtual void proc15();
+ virtual void animateSpeaker();
};
// Classes related to Quinn
@@ -279,97 +279,97 @@ public:
class SpeakerQuinn300 : public SpeakerQuinn {
public:
virtual Common::String getClassName() { return "SpeakerQuinn300"; }
- virtual void proc15();
+ virtual void animateSpeaker();
};
class SpeakerQuinn500 : public SpeakerQuinn {
public:
virtual Common::String getClassName() { return "SpeakerQuinn500"; }
- virtual void proc15();
+ virtual void animateSpeaker();
};
class SpeakerQuinn1100 : public SpeakerQuinn {
public:
virtual Common::String getClassName() { return "SpeakerQuinn1100"; }
- virtual void proc15();
+ virtual void animateSpeaker();
};
class SpeakerQuinn2435 : public SpeakerQuinn {
public:
virtual Common::String getClassName() { return "SpeakerQuinn2435"; }
- virtual void proc15();
+ virtual void animateSpeaker();
};
class SpeakerQuinn2450 : public SpeakerQuinn {
public:
virtual Common::String getClassName() { return "SpeakerQuinn2450"; }
- virtual void proc15();
+ virtual void animateSpeaker();
};
class SpeakerQuinn2700 : public SpeakerQuinn {
public:
virtual Common::String getClassName() { return "SpeakerQuinn2700"; }
- virtual void proc15();
+ virtual void animateSpeaker();
};
class SpeakerQuinn2750 : public SpeakerQuinn {
public:
virtual Common::String getClassName() { return "SpeakerQuinn2750"; }
- virtual void proc15();
+ virtual void animateSpeaker();
};
class SpeakerQuinn2800 : public SpeakerQuinn {
public:
virtual Common::String getClassName() { return "SpeakerQuinn2800"; }
- virtual void proc15();
+ virtual void animateSpeaker();
};
class SpeakerQuinn3255 : public SpeakerQuinn {
public:
virtual Common::String getClassName() { return "SpeakerQuinn3255"; }
- virtual void proc15();
+ virtual void animateSpeaker();
};
class SpeakerQuinn3375 : public SpeakerQuinn {
public:
virtual Common::String getClassName() { return "SpeakerQuinn3375"; }
- virtual void proc15();
+ virtual void animateSpeaker();
};
class SpeakerQuinn3385 : public SpeakerQuinn {
public:
virtual Common::String getClassName() { return "SpeakerQuinn3385"; }
- virtual void proc15();
+ virtual void animateSpeaker();
};
class SpeakerQuinn3395 : public SpeakerQuinn {
public:
virtual Common::String getClassName() { return "SpeakerQuinn3395"; }
- virtual void proc15();
+ virtual void animateSpeaker();
};
class SpeakerQuinn3400 : public SpeakerQuinn {
public:
virtual Common::String getClassName() { return "SpeakerQuinn3400"; }
- virtual void proc15();
+ virtual void animateSpeaker();
};
class SpeakerQuinn3600 : public SpeakerQuinn {
public:
virtual Common::String getClassName() { return "SpeakerQuinn3600"; }
- virtual void proc15();
+ virtual void animateSpeaker();
};
class SpeakerQuinn3700 : public SpeakerQuinn {
public:
virtual Common::String getClassName() { return "SpeakerQuinn3700"; }
virtual void setText(const Common::String &msg);
- virtual void proc15();
+ virtual void animateSpeaker();
};
// Classes related to QuinnL
-class SpeakerQuinnL : public VisualSpeaker {
+class SpeakerQuinnL : public SpeakerQuinn {
public:
SpeakerQuinnL();
@@ -383,7 +383,7 @@ public:
SpeakerRalf3245();
virtual Common::String getClassName() { return "SpeakerRalf3245"; }
- virtual void proc15();
+ virtual void animateSpeaker();
};
// Classes related to Rocko
@@ -397,19 +397,19 @@ public:
class SpeakerRocko3200 : public SpeakerRocko {
public:
virtual Common::String getClassName() { return "SpeakerRocko3200"; }
- virtual void proc15();
+ virtual void animateSpeaker();
};
class SpeakerRocko3220 : public SpeakerRocko {
public:
virtual Common::String getClassName() { return "SpeakerRocko3220"; }
- virtual void proc15();
+ virtual void animateSpeaker();
};
class SpeakerRocko3230 : public SpeakerRocko {
public:
virtual Common::String getClassName() { return "SpeakerRocko3230"; }
- virtual void proc15();
+ virtual void animateSpeaker();
};
// Classes related to Seeker
@@ -423,79 +423,79 @@ public:
class SpeakerSeeker300 : public SpeakerSeeker {
public:
virtual Common::String getClassName() { return "SpeakerSeeker300"; }
- virtual void proc15();
+ virtual void animateSpeaker();
};
class SpeakerSeeker500 : public SpeakerSeeker {
public:
virtual Common::String getClassName() { return "SpeakerSeeker500"; }
- virtual void proc15();
+ virtual void animateSpeaker();
};
class SpeakerSeeker1100 : public SpeakerSeeker {
public:
virtual Common::String getClassName() { return "SpeakerSeeker1100"; }
- virtual void proc15();
+ virtual void animateSpeaker();
};
class SpeakerSeeker1900 : public SpeakerSeeker {
public:
virtual Common::String getClassName() { return "SpeakerSeeker1900"; }
- virtual void proc15();
+ virtual void animateSpeaker();
};
class SpeakerSeeker2435 : public SpeakerSeeker {
public:
virtual Common::String getClassName() { return "SpeakerSeeker2435"; }
- virtual void proc15();
+ virtual void animateSpeaker();
};
class SpeakerSeeker2450 : public SpeakerSeeker {
public:
virtual Common::String getClassName() { return "SpeakerSeeker2450"; }
- virtual void proc15();
+ virtual void animateSpeaker();
};
class SpeakerSeeker3375 : public SpeakerSeeker {
public:
virtual Common::String getClassName() { return "SpeakerSeeker3375"; }
- virtual void proc15();
+ virtual void animateSpeaker();
};
class SpeakerSeeker3385 : public SpeakerSeeker {
public:
virtual Common::String getClassName() { return "SpeakerSeeker3385"; }
- virtual void proc15();
+ virtual void animateSpeaker();
};
class SpeakerSeeker3395 : public SpeakerSeeker {
public:
virtual Common::String getClassName() { return "SpeakerSeeker3395"; }
- virtual void proc15();
+ virtual void animateSpeaker();
};
class SpeakerSeeker3400 : public SpeakerSeeker {
public:
virtual Common::String getClassName() { return "SpeakerSeeker3400"; }
- virtual void proc15();
+ virtual void animateSpeaker();
};
class SpeakerSeeker3600 : public SpeakerSeeker {
public:
virtual Common::String getClassName() { return "SpeakerSeeker3600"; }
- virtual void proc15();
+ virtual void animateSpeaker();
};
class SpeakerSeeker3700 : public SpeakerSeeker {
public:
virtual Common::String getClassName() { return "SpeakerSeeker3700"; }
virtual void setText(const Common::String &msg);
- virtual void proc15();
+ virtual void animateSpeaker();
};
// Classes related to SeekerL
-class SpeakerSeekerL : public VisualSpeaker {
+class SpeakerSeekerL : public SpeakerSeeker {
public:
SpeakerSeekerL();
@@ -509,7 +509,7 @@ public:
SpeakerSocko3200();
virtual Common::String getClassName() { return "SpeakerSocko3200"; }
- virtual void proc15();
+ virtual void animateSpeaker();
};
// Classes related to Soldier
@@ -524,7 +524,7 @@ class SpeakerSoldier300 : public SpeakerSoldier {
public:
SpeakerSoldier300() : SpeakerSoldier(60) {}
virtual Common::String getClassName() { return "SpeakerSoldier300"; }
- virtual void proc15();
+ virtual void animateSpeaker();
};
class SpeakerSoldier1625 : public SpeakerSoldier {
@@ -547,34 +547,40 @@ public:
virtual Common::String getClassName() { return "SpeakerTealMode7"; }
};
+class SpeakerTeal180 : public SpeakerTeal {
+public:
+ virtual Common::String getClassName() { return "SpeakerTeal180"; }
+ virtual void animateSpeaker();
+};
+
class SpeakerTeal300 : public SpeakerTeal {
public:
virtual Common::String getClassName() { return "SpeakerTeal300"; }
- virtual void proc15();
+ virtual void animateSpeaker();
};
class SpeakerTeal1625 : public SpeakerTeal {
public:
virtual Common::String getClassName() { return "SpeakerTeal1625"; }
- virtual void proc15();
+ virtual void animateSpeaker();
};
class SpeakerTeal3240 : public SpeakerTeal {
public:
virtual Common::String getClassName() { return "SpeakerTeal3240"; }
- virtual void proc15();
+ virtual void animateSpeaker();
};
class SpeakerTeal3400 : public SpeakerTeal {
public:
virtual Common::String getClassName() { return "SpeakerTeal3400"; }
- virtual void proc15();
+ virtual void animateSpeaker();
};
class SpeakerTeal3600 : public SpeakerTealMode7 {
public:
virtual Common::String getClassName() { return "SpeakerTeal3600"; }
- virtual void proc15();
+ virtual void animateSpeaker();
};
// Classes related to Tomko
@@ -584,7 +590,7 @@ public:
SpeakerTomko3245();
virtual Common::String getClassName() { return "SpeakerTomko3245"; }
- virtual void proc15();
+ virtual void animateSpeaker();
};
// Classes related to Webbster
@@ -595,6 +601,13 @@ public:
virtual Common::String getClassName() { return "SpeakerWebbster"; }
};
+class SpeakerWebbster180 : public SpeakerWebbster {
+public:
+ SpeakerWebbster180() : SpeakerWebbster(27) {}
+ virtual Common::String getClassName() { return "SpeakerWebbster180"; }
+ virtual void animateSpeaker();
+};
+
class SpeakerWebbster2500 : public SpeakerWebbster {
public:
SpeakerWebbster2500() : SpeakerWebbster(27) {}
@@ -606,7 +619,7 @@ public:
SpeakerWebbster3240() : SpeakerWebbster(10) {}
virtual Common::String getClassName() { return "SpeakerWebbster3240"; }
- virtual void proc15();
+ virtual void animateSpeaker();
};
class SpeakerWebbster3375 : public SpeakerWebbster {
@@ -614,7 +627,7 @@ public:
SpeakerWebbster3375() : SpeakerWebbster(60) {}
virtual Common::String getClassName() { return "SpeakerWebbster3375"; }
- virtual void proc15();
+ virtual void animateSpeaker();
};
class SpeakerWebbster3385 : public SpeakerWebbster {
@@ -622,7 +635,7 @@ public:
SpeakerWebbster3385() : SpeakerWebbster(60) {}
virtual Common::String getClassName() { return "SpeakerWebbster3385"; }
- virtual void proc15();
+ virtual void animateSpeaker();
};
class SpeakerWebbster3395 : public SpeakerWebbster {
@@ -630,7 +643,7 @@ public:
SpeakerWebbster3395() : SpeakerWebbster(60) {}
virtual Common::String getClassName() { return "SpeakerWebbster3395"; }
- virtual void proc15();
+ virtual void animateSpeaker();
};
class SpeakerWebbster3400 : public SpeakerWebbster {
@@ -638,15 +651,15 @@ public:
SpeakerWebbster3400() : SpeakerWebbster(27) {}
virtual Common::String getClassName() { return "SpeakerWebbster3400"; }
- virtual void proc15();
+ virtual void animateSpeaker();
};
-class SpeakerDutyOfficer: public VisualSpeaker {
+class SpeakerDutyOfficer180: public VisualSpeaker {
public:
- SpeakerDutyOfficer();
+ SpeakerDutyOfficer180();
virtual Common::String getClassName() { return "SpeakerDutyOfficer"; }
- virtual void proc15();
+ virtual void animateSpeaker();
};
} // End of namespace Ringworld2
diff --git a/engines/tsage/saveload.cpp b/engines/tsage/saveload.cpp
index 7143305586..f9e84e8913 100644
--- a/engines/tsage/saveload.cpp
+++ b/engines/tsage/saveload.cpp
@@ -47,6 +47,8 @@ SavedObject::~SavedObject() {
Saver::Saver() {
_macroSaveFlag = false;
_macroRestoreFlag = false;
+
+ _factoryPtr = nullptr;
}
Saver::~Saver() {
@@ -127,7 +129,6 @@ Common::Error Saver::save(int slot, const Common::String &saveName) {
// Set fields
_macroSaveFlag = true;
- _saveSlot = slot;
// Try and create the save file
Common::OutSaveFile *saveFile = g_system->getSavefileManager()->openForSaving(g_vm->generateSaveName(slot));
@@ -151,8 +152,9 @@ Common::Error Saver::save(int slot, const Common::String &saveName) {
// Save each registered SaveObject descendant object into the savegame file
for (SynchronizedList<SavedObject *>::iterator i = _objList.begin(); i != _objList.end(); ++i) {
- serializer.validate((*i)->getClassName());
- (*i)->synchronize(serializer);
+ SavedObject *so = *i;
+ serializer.validate(so->getClassName());
+ so->synchronize(serializer);
}
// Save file complete
@@ -176,7 +178,6 @@ Common::Error Saver::restore(int slot) {
// Set fields
_macroRestoreFlag = true;
- _saveSlot = slot;
_unresolvedPtrs.clear();
// Set up the serializer
diff --git a/engines/tsage/saveload.h b/engines/tsage/saveload.h
index d43ef792bc..42fd4f3282 100644
--- a/engines/tsage/saveload.h
+++ b/engines/tsage/saveload.h
@@ -33,7 +33,7 @@ namespace TsAGE {
typedef void (*SaveNotifierFn)(bool postFlag);
-#define TSAGE_SAVEGAME_VERSION 10
+#define TSAGE_SAVEGAME_VERSION 15
class SavedObject;
@@ -48,7 +48,7 @@ struct tSageSavegameHeader {
/*--------------------------------------------------------------------------*/
-// FIXME: workaround to supress spurious strict-alias warnings on older GCC
+// FIXME: workaround to suppress spurious strict-alias warnings on older GCC
// versions. this should be resolved with the savegame rewrite
#define SYNC_POINTER(x) do { \
SavedObject **y = (SavedObject **)((void *)&x); \
@@ -59,7 +59,7 @@ struct tSageSavegameHeader {
if (s.isLoading()) FIELD = (TYPE)v_##FIELD;
/**
- * Derived serializer class with extra synchronisation types
+ * Derived serializer class with extra synchronization types
*/
class Serializer : public Common::Serializer {
public:
@@ -212,7 +212,6 @@ private:
bool _macroSaveFlag;
bool _macroRestoreFlag;
- int _saveSlot;
void resolveLoadPointers();
public:
diff --git a/engines/tsage/scenes.cpp b/engines/tsage/scenes.cpp
index 58bb8c4a44..b41e8175c6 100644
--- a/engines/tsage/scenes.cpp
+++ b/engines/tsage/scenes.cpp
@@ -43,6 +43,7 @@ SceneManager::SceneManager() {
g_saver->addListener(this);
_objectCount = 0;
_loadMode = 0;
+ _sceneLoadCount = 0;
}
SceneManager::~SceneManager() {
@@ -273,6 +274,8 @@ Scene::Scene() : _sceneBounds(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT),
_activeScreenNumber = 0;
_oldSceneBounds = Rect(4000, 4000, 4100, 4100);
Common::fill(&_zoomPercents[0], &_zoomPercents[256], 0);
+
+ _screenNumber = 0;
}
Scene::~Scene() {
@@ -282,15 +285,23 @@ void Scene::synchronize(Serializer &s) {
if (s.getVersion() >= 2)
StripCallback::synchronize(s);
- s.syncAsSint32LE(_field12);
+ if (s.getVersion() < 14) {
+ int useless = 0;
+ s.syncAsSint32LE(useless);
+ }
+
s.syncAsSint32LE(_screenNumber);
s.syncAsSint32LE(_activeScreenNumber);
s.syncAsSint32LE(_sceneMode);
_backgroundBounds.synchronize(s);
_sceneBounds.synchronize(s);
_oldSceneBounds.synchronize(s);
- s.syncAsSint16LE(_fieldA);
- s.syncAsSint16LE(_fieldE);
+
+ if (s.getVersion() < 14) {
+ int useless = 0;
+ s.syncAsSint16LE(useless);
+ s.syncAsSint16LE(useless);
+ }
for (int i = 0; i < 256; ++i)
s.syncAsUint16LE(_enabledSections[i]);
@@ -303,7 +314,6 @@ void Scene::synchronize(Serializer &s) {
void Scene::postInit(SceneObjectList *OwnerList) {
_action = NULL;
- _field12 = 0;
_sceneMode = 0;
}
diff --git a/engines/tsage/scenes.h b/engines/tsage/scenes.h
index d5ac88c692..4d36192cec 100644
--- a/engines/tsage/scenes.h
+++ b/engines/tsage/scenes.h
@@ -35,7 +35,6 @@ class Scene : public StripCallback {
private:
void drawBackgroundObjects();
public:
- int _field12;
int _screenNumber;
int _activeScreenNumber;
int _sceneMode;
@@ -49,9 +48,6 @@ public:
int _zoomPercents[256];
ScenePriorities _priorities;
SceneObjectList _bgSceneObjects;
-
- int _fieldA;
- int _fieldE;
public:
Scene();
virtual ~Scene();
diff --git a/engines/tsage/sound.cpp b/engines/tsage/sound.cpp
index b9567cece2..6633d15c26 100644
--- a/engines/tsage/sound.cpp
+++ b/engines/tsage/sound.cpp
@@ -22,6 +22,8 @@
#include "audio/decoders/raw.h"
#include "common/config-manager.h"
+#include "audio/decoders/raw.h"
+#include "audio/audiostream.h"
#include "tsage/core.h"
#include "tsage/globals.h"
#include "tsage/debugger.h"
@@ -118,17 +120,31 @@ void SoundManager::syncSounds() {
bool mute = false;
if (ConfMan.hasKey("mute"))
mute = ConfMan.getBool("mute");
+ bool subtitles = ConfMan.hasKey("subtitles") ? ConfMan.getBool("subtitles") : true;
bool music_mute = mute;
+ bool voice_mute = mute;
if (!mute) {
music_mute = ConfMan.getBool("music_mute");
+ voice_mute = ConfMan.getBool("speech_mute");
}
// Get the new music volume
int musicVolume = music_mute ? 0 : MIN(255, ConfMan.getInt("music_volume"));
this->setMasterVol(musicVolume / 2);
+
+ // Return to Ringworld voice settings
+ if (g_vm->getGameID() == GType_Ringworld2) {
+ // If we don't have voice, then ensure that text is turned on
+ if (voice_mute)
+ subtitles = true;
+
+ R2_GLOBALS._speechSubtitles =
+ (voice_mute ? 0 : SPEECH_VOICE) |
+ (!subtitles ? 0 : SPEECH_TEXT);
+ }
}
void SoundManager::update() {
@@ -953,7 +969,7 @@ void SoundManager::sfRethinkVoiceTypes() {
int entryIndex = -1;
for (uint idx = 0; idx < vtStruct->_entries.size(); ++idx) {
if (vtStruct->_entries[idx]._voiceNum == foundIndex) {
- foundIndex = true;
+ foundMatch = true;
if (!vtStruct->_entries[idx]._type0._sound2) {
entryIndex = idx;
break;
@@ -992,7 +1008,7 @@ void SoundManager::sfRethinkVoiceTypes() {
if (vtStruct->_entries[idx]._type0._priority2 > maxPriority) {
maxPriority = vtStruct->_entries[idx]._type0._priority2;
- entryIndex = -1;
+ entryIndex = idx;
}
}
@@ -1720,7 +1736,7 @@ uint32 Sound::getTimeIndex() const {
}
int Sound::getCueValue() const {
- return _cueValue;
+ return _cueValue == 0xff ? -1 : _cueValue;
}
void Sound::setCueValue(int cueValue) {
@@ -2395,7 +2411,7 @@ int Sound::soFindSound(VoiceTypeStruct *vtStruct, int channelNum) {
/*--------------------------------------------------------------------------*/
ASound::ASound(): EventHandler() {
- _action = NULL;
+ _endAction = NULL;
_cueValue = -1;
if (g_globals)
g_globals->_sounds.push_back(this);
@@ -2422,23 +2438,23 @@ void ASound::dispatch() {
_cueValue = cueValue;
_sound.setCueValue(-1);
- if (_action)
- _action->signal();
+ if (_endAction)
+ _endAction->signal();
}
if (_cueValue != -1) {
if (!_sound.isPrimed()) {
_cueValue = -1;
- if (_action) {
- _action->signal();
- _action = NULL;
+ if (_endAction) {
+ _endAction->signal();
+ _endAction = NULL;
}
}
}
}
-void ASound::play(int soundNum, EventHandler *action, int volume) {
- _action = action;
+void ASound::play(int soundNum, EventHandler *endAction, int volume) {
+ _endAction = endAction;
_cueValue = 0;
setVol(volume);
@@ -2461,9 +2477,9 @@ void ASound::unPrime() {
_action = NULL;
}
-void ASound::fade(int fadeDest, int fadeSteps, int fadeTicks, bool stopAfterFadeFlag, EventHandler *action) {
- if (action)
- _action = action;
+void ASound::fade(int fadeDest, int fadeSteps, int fadeTicks, bool stopAfterFadeFlag, EventHandler *endAction) {
+ if (endAction)
+ _endAction = endAction;
_sound.fade(fadeDest, fadeSteps, fadeTicks, stopAfterFadeFlag);
}
@@ -2490,8 +2506,8 @@ void ASoundExt::signal() {
}
}
-void ASoundExt::fadeOut2(EventHandler *action) {
- fade(0, 10, 10, true, action);
+void ASoundExt::fadeOut2(EventHandler *endAction) {
+ fade(0, 10, 10, true, endAction);
}
void ASoundExt::changeSound(int soundNum) {
@@ -2505,6 +2521,183 @@ void ASoundExt::changeSound(int soundNum) {
/*--------------------------------------------------------------------------*/
+void PlayStream::ResFileData::load(Common::SeekableReadStream &stream) {
+ // Validate that it's the correct data file
+ char header[4];
+ stream.read(&header[0], 4);
+ if (strncmp(header, "SPAM", 4))
+ error("Invalid voice resource data");
+
+ _fileChunkSize = stream.readUint32LE();
+ stream.skip(2);
+ _indexSize = stream.readUint16LE();
+ _chunkSize = stream.readUint16LE();
+
+ stream.skip(18);
+}
+
+PlayStream::PlayStream(): EventHandler() {
+ _index = NULL;
+ _endAction = NULL;
+ _audioStream = NULL;
+
+ _resData._fileChunkSize = 0;
+ _resData._indexSize = 0;
+ _resData._chunkSize = 0;
+ _voiceNum = 0;
+}
+
+PlayStream::~PlayStream() {
+ remove();
+}
+
+bool PlayStream::setFile(const Common::String &filename) {
+ remove();
+
+ // Open the resource file for access
+ if (!_file.open(filename))
+ return false;
+
+ // Load header
+ _resData.load(_file);
+
+ // Load the index
+ _index = new uint16[_resData._indexSize / 2];
+ for (uint i = 0; i < (_resData._indexSize / 2); ++i)
+ _index[i] = _file.readUint16LE();
+
+ return true;
+}
+
+bool PlayStream::play(int voiceNum, EventHandler *endAction) {
+ uint32 offset = getFileOffset(_index, _resData._fileChunkSize, voiceNum);
+ if (offset) {
+ stop();
+ _voiceNum = 0;
+
+ // Move to the offset for the start of the voice
+ _file.seek(offset);
+
+ // Read in the header and validate it
+ char header[4];
+ _file.read(&header[0], 4);
+ if (strncmp(header, "FEED", 4))
+ error("Invalid stream data");
+
+ // Get basic details of first sound chunk
+ uint chunkSize = _file.readUint16LE() - 16;
+ _file.skip(4);
+ int rate = _file.readUint16LE();
+ _file.skip(4);
+
+ // Create the stream
+ _audioStream = Audio::makeQueuingAudioStream(rate, false);
+
+ // Load in the first chunk
+ byte *data = (byte *)malloc(chunkSize);
+ _file.read(data, chunkSize);
+ _audioStream->queueBuffer(data, chunkSize, DisposeAfterUse::YES, Audio::FLAG_UNSIGNED);
+
+ // If necessary, load further chunks of the voice in
+ while (chunkSize == (_resData._chunkSize - 16)) {
+ // Ensure the next chunk has the 'MORE' header
+ _file.read(&header[0], 4);
+ if (!strncmp(header, "FEED", 4))
+ // Reached start of next voice sample, so stop
+ break;
+ if (strncmp(header, "MORE", 4))
+ // Not more remaining, so break
+ break;
+
+ // Get the size of the chunk
+ chunkSize = _file.readUint16LE() - 16;
+ _file.skip(10);
+
+ // Read in the data for this next chunk and queue it
+ data = (byte *)malloc(chunkSize);
+ _file.read(data, chunkSize);
+ _audioStream->queueBuffer(data, chunkSize, DisposeAfterUse::YES, Audio::FLAG_UNSIGNED);
+ }
+
+ g_vm->_mixer->playStream(Audio::Mixer::kSpeechSoundType, &_soundHandle,
+ _audioStream, DisposeAfterUse::YES);
+ _voiceNum = voiceNum;
+ _endAction = endAction;
+ return true;
+ }
+
+ // If it reaches this point, no valid voice data found
+ return false;
+}
+
+void PlayStream::stop() {
+ if (_audioStream) {
+ g_vm->_mixer->stopHandle(_soundHandle);
+ }
+
+ _audioStream = NULL;
+ _voiceNum = 0;
+ _endAction = NULL;
+}
+
+bool PlayStream::isPlaying() const {
+ return _audioStream != NULL && !_audioStream->endOfData();
+}
+
+void PlayStream::remove() {
+ stop();
+ _file.close();
+
+ // Free index
+ delete[] _index;
+ _index = NULL;
+
+ _endAction = NULL;
+ _voiceNum = 0;
+}
+
+void PlayStream::dispatch() {
+ if (_voiceNum != 0 && !isPlaying()) {
+ // If voice has finished playing, reset fields
+ EventHandler *endAction = _endAction;
+ _endAction = NULL;
+ _voiceNum = 0;
+
+ if (endAction)
+ // Signal given end action
+ endAction->signal();
+ }
+}
+
+uint32 PlayStream::getFileOffset(const uint16 *data, int count, int voiceNum) {
+ if (!data)
+ return 0; // no valid voice data found
+
+ int bitsIndex = voiceNum & 7;
+ int byteIndex = voiceNum >> 3;
+ int shiftAmount = bitsIndex * 2;
+ int bitMask = 3 << shiftAmount;
+ int v = (data[byteIndex] & bitMask) >> shiftAmount;
+ uint32 offset = 0;
+
+ if (!v)
+ return 0;
+
+ // Loop to figure out offsets from index words skipped over
+ for (int i = 0; i < (voiceNum >> 3); ++i) {
+ for (int bit = 0; bit < 16; bit += 2)
+ offset += ((data[i] >> bit) & 3) * count;
+ }
+
+ // Bit index loop
+ for (int i = 0; i < bitsIndex; ++i)
+ offset += ((data[byteIndex] >> (i * 2)) & 3) * count;
+
+ return offset;
+}
+
+/*--------------------------------------------------------------------------*/
+
SoundDriver::SoundDriver() {
_driverResID = 0;
_minVersion = _maxVersion = 0;
@@ -2516,13 +2709,8 @@ SoundDriver::SoundDriver() {
const byte adlib_group_data[] = { 1, 1, 9, 1, 0xff };
-const byte v440B0[9] = { 0, 1, 2, 6, 7, 8, 12, 13, 14 };
-
-const byte v440B9[9] = { 3, 4, 5, 9, 10, 11, 15, 16, 17 };
-
-const byte v440C2[18] = {
- 0, 1, 2, 3, 4, 5, 8, 9, 10, 11, 12, 13, 16, 17, 18, 19, 20, 21
-};
+const byte adlib_operator1_offset[] = { 0, 1, 2, 8, 9, 10, 16, 17, 18 };
+const byte adlib_operator2_offset[] = { 3, 4, 5, 11, 12, 13, 19, 20, 21 };
const byte v44134[64] = {
0, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
@@ -2546,8 +2734,6 @@ AdlibSoundDriver::AdlibSoundDriver(): SoundDriver() {
_masterVolume = 0;
_groupData._groupMask = 9;
- _groupData._v1 = 0x46;
- _groupData._v2 = 0;
_groupData._pData = &adlib_group_data[0];
_mixer = g_vm->_mixer;
@@ -2653,10 +2839,10 @@ void AdlibSoundDriver::playSound(const byte *channelData, int dataOffset, int pr
_v4409E[channel] = dataP + offset - _patchData;
// Set sustain/release
- int portNum = v440C2[v440B0[channel]] + 0x80;
+ int portNum = adlib_operator1_offset[channel] + 0x80;
write(portNum, (_portContents[portNum] & 0xF0) | 0xF);
- portNum = v440C2[v440B9[channel]] + 0x80;
+ portNum = adlib_operator2_offset[channel] + 0x80;
write(portNum, (_portContents[portNum] & 0xF0) | 0xF);
if (_channelVoiced[channel])
@@ -2713,10 +2899,10 @@ void AdlibSoundDriver::updateChannelVolume(int channelNum) {
int level1 = !_v44082[channelNum] ? 63 - _v44070[channelNum] :
63 - v44134[volume * _v44070[channelNum] / 63];
- int portNum = v440C2[v440B0[channelNum]] + 0x40;
+ int portNum = adlib_operator1_offset[channelNum] + 0x40;
write(portNum, (_portContents[portNum] & 0x80) | level1);
- portNum = v440C2[v440B9[channelNum]] + 0x40;
+ portNum = adlib_operator2_offset[channelNum] + 0x40;
write(portNum, (_portContents[portNum] & 0x80) | level2);
}
@@ -2733,7 +2919,7 @@ void AdlibSoundDriver::clearVoice(int channel) {
void AdlibSoundDriver::updateChannel(int channel) {
const byte *dataP = _patchData + _v4409E[channel];
- int portOffset = v440C2[v440B0[channel]];
+ int portOffset = adlib_operator1_offset[channel];
int portNum = portOffset + 0x20;
int portValue = 0;
@@ -2756,7 +2942,7 @@ void AdlibSoundDriver::updateChannel(int channel) {
write(0x80 + portOffset, *(dataP + 14) | (*(dataP + 13) << 4));
write(0xE0 + portOffset, (_portContents[0xE0 + portOffset] & 0xFC) | *(dataP + 15));
- portOffset = v440C2[v440B9[channel]];
+ portOffset = adlib_operator2_offset[channel];
portNum = portOffset + 0x20;
portValue = 0;
if (*(dataP + 17))
@@ -2865,8 +3051,6 @@ SoundBlasterDriver::SoundBlasterDriver(): SoundDriver() {
_masterVolume = 0;
_groupData._groupMask = 1;
- _groupData._v1 = 0x3E;
- _groupData._v2 = 0;
static byte const group_data[] = { 3, 1, 1, 0, 0xff };
_groupData._pData = group_data;
@@ -2914,10 +3098,12 @@ void SoundBlasterDriver::playSound(const byte *channelData, int dataOffset, int
updateVoice(channel);
// Set the new channel data
- _channelData = channelData + dataOffset;
+ _channelData = channelData + dataOffset + 18;
// Make a copy of the buffer
int dataSize = g_vm->_memoryManager.getSize(channelData);
+ dataSize -= 18;
+
byte *soundData = (byte *)malloc(dataSize - dataOffset);
Common::copy(_channelData, _channelData + (dataSize - dataOffset), soundData);
diff --git a/engines/tsage/sound.h b/engines/tsage/sound.h
index 2f59afb49b..fefe8ad101 100644
--- a/engines/tsage/sound.h
+++ b/engines/tsage/sound.h
@@ -63,8 +63,6 @@ public:
struct GroupData {
uint32 _groupMask;
- byte _v1;
- byte _v2;
const byte *_pData;
};
@@ -98,7 +96,7 @@ public:
virtual const GroupData *getGroupData() { return NULL; } // Method #3
virtual void installPatch(const byte *data, int size) {} // Method #4
virtual void poll() {} // Method #5
- virtual void proc12() {} // Method #6
+ virtual void method6() {} // Method #6
virtual int setMasterVolume(int volume) { return 0; } // Method #7
virtual void proc16() {} // Method #8
virtual void proc18(int al, VoiceType voiceType) {} // Method #9
@@ -259,6 +257,7 @@ public:
class Sound: public EventHandler {
private:
void _prime(int soundResID, bool dontQueue);
+ void _primeBuffer(const byte *soundData);
void _unPrime();
public:
bool _stoppedAsynchronously;
@@ -365,7 +364,7 @@ public:
class ASound: public EventHandler {
public:
Sound _sound;
- EventHandler *_action;
+ EventHandler *_endAction;
int _cueValue;
ASound();
@@ -373,7 +372,7 @@ public:
virtual void synchronize(Serializer &s);
virtual void dispatch();
- void play(int soundNum, EventHandler *action = NULL, int volume = 127);
+ void play(int soundNum, EventHandler *endAction = NULL, int volume = 127);
void stop();
void prime(int soundNum, Action *action = NULL);
void unPrime();
@@ -385,7 +384,7 @@ public:
bool isMuted() const { return _sound.isMuted(); }
void pause(bool flag) { _sound.pause(flag); }
void mute(bool flag) { _sound.mute(flag); }
- void fade(int fadeDest, int fadeSteps, int fadeTicks, bool stopAfterFadeFlag, EventHandler *action);
+ void fade(int fadeDest, int fadeSteps, int fadeTicks, bool stopAfterFadeFlag, EventHandler *endAction);
void fadeIn() { fade(127, 5, 10, false, NULL); }
void fadeOut(Action *action) { fade(0, 5, 10, true, action); }
void setTimeIndex(uint32 timeIndex) { _sound.setTimeIndex(timeIndex); }
@@ -406,7 +405,7 @@ public:
int _soundNum;
ASoundExt();
- void fadeOut2(EventHandler *action);
+ void fadeOut2(EventHandler *endAction);
void changeSound(int soundNum);
virtual Common::String getClassName() { return "ASoundExt"; }
@@ -414,15 +413,36 @@ public:
virtual void signal();
};
-class PlayStream {
+class PlayStream: public EventHandler {
+ class ResFileData {
+ public:
+ int _fileChunkSize;
+ uint _indexSize;
+ uint _chunkSize;
+
+ void load(Common::SeekableReadStream &stream);
+ };
+private:
+ Common::File _file;
+ ResFileData _resData;
+ Audio::QueuingAudioStream *_audioStream;
+ Audio::SoundHandle _soundHandle;
+ uint16 *_index;
+ EventHandler *_endAction;
+ int _voiceNum;
+
+ static uint32 getFileOffset(const uint16 *data, int count, int voiceNum);
public:
- Sound _sound;
+ PlayStream();
+ virtual ~PlayStream();
- void setFile(const Common::String &filename) {}
- bool play(int soundNum, EventHandler *endAction) { return false; }
- void stop() {}
- void proc1() {}
- bool isPlaying() const { return false; }
+ bool setFile(const Common::String &filename);
+ bool play(int voiceNum, EventHandler *endAction);
+ void stop();
+ bool isPlaying() const;
+
+ virtual void remove();
+ virtual void dispatch();
};
#define ADLIB_CHANNEL_COUNT 9
diff --git a/engines/tsage/staticres.cpp b/engines/tsage/staticres.cpp
index 2c5e8e57a0..fb08195180 100644
--- a/engines/tsage/staticres.cpp
+++ b/engines/tsage/staticres.cpp
@@ -213,6 +213,14 @@ char const *const ACCESS_CODE_REQUIRED = "access code required";
char const *const INVALID_ACCESS_CODE = "invalid access code";
char const *const FOREIGN_OBJECT_EXTRACTED = "foreign object extracted";
+// Scene 1330/7 Options dialog messages
+char const *const AUTO_PLAY_ON = "Auto-Play is On";
+char const *const AUTO_PLAY_OFF = "Auto-Play is Off";
+char const *const START_NEW_CARD_GAME = "Start a new game";
+char const *const QUIT_CARD_GAME = "Quit Outpost Alpha";
+char const *const CONTINUE_CARD_GAME = "Continue Outpost Alpha";
+
+//
char const *const HELP_MSG = "\x1\rRETURN TO\r RINGWORLD\x14";
char const *const CHAR_TITLE = "\x01Select Character:";
char const *const CHAR_QUINN_MSG = " Quinn ";
@@ -229,6 +237,7 @@ char const *const RESTORE_GAME = "Restore game";
char const *const SHOW_CREDITS = "Show credits";
char const *const PAUSE_GAME = "Pause game";
char const *const RESUME_PLAY = " Resume play ";
+char const *const R2_RESTART_MSG = "Go to the beginning of game?";
char const *const F2 = "F2";
char const *const F3 = "F3";
char const *const F4 = "F4";
@@ -244,6 +253,8 @@ char const *const USE_INTERCEPTOR = "Do you want to use your interceptor card?";
char const *const USE_DOUBLE_AGENT = "Do you want to use your double agent?";
char const *const NEED_INSTRUCTIONS = "Do you want instructions?";
char const *const WRONG_ANSWER_MSG = "Wrong respond value sent.";
+char const *const BUY_FULL_GAME_MSG = "To order the complete game, RETURN TO RINGWORLD, call 1-800-482-3766!";
+
const byte scene1550JunkLocationsDefault[] = {
20, 7, 41, 6,
3, 6, 42, 11,
@@ -397,8 +408,8 @@ const byte scene1550AreaMap[] = {
13, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 14
};
-const byte k5A72E[] = {0, 98, 135, 183, 229, 81, 133, 185, 235, 75, 131, 187, 241, 70, 129, 190, 247};
-const byte k5A73F[] = {0, 42, 42, 42, 42, 67, 67, 67, 67, 92, 92, 92, 92, 116, 116, 116, 116};
+const byte scene1550JunkX[] = {0, 98, 135, 183, 229, 81, 133, 185, 235, 75, 131, 187, 241, 70, 129, 190, 247};
+const byte scene1550JunkY[] = {0, 42, 42, 42, 42, 67, 67, 67, 67, 92, 92, 92, 92, 116, 116, 116, 116};
const byte k5A750[] = {
9, 10, 7, 13, 7, 8, 9, 7, 9, 10,
2, 3, 3, 2, 2, 2, 4, 3, 3, 4,
@@ -410,7 +421,7 @@ const byte k5A76D[] = {
3, 3, 3, 3, 3, 3, 3, 3, 3
};
const byte scene1550JunkRegions[] = {0, 8, 15, 16, 12, 7, 18, 17, 13, 6, 19, 20, 14, 5, 11, 10, 9};
-const byte k5A79B[] = {
+const byte scene1550SpecialAreas[] = {
23, 3, 1,
23, 4, 1,
26, 3, 1,
diff --git a/engines/tsage/staticres.h b/engines/tsage/staticres.h
index b6c5d5e72a..334a240f28 100644
--- a/engines/tsage/staticres.h
+++ b/engines/tsage/staticres.h
@@ -165,6 +165,13 @@ extern char const *const ACCESS_CODE_REQUIRED;
extern char const *const INVALID_ACCESS_CODE;
extern char const *const FOREIGN_OBJECT_EXTRACTED;
+// Scene 1330/7 Options dialog messages
+extern char const *const AUTO_PLAY_ON;
+extern char const *const AUTO_PLAY_OFF;
+extern char const *const START_NEW_CARD_GAME;
+extern char const *const QUIT_CARD_GAME;
+extern char const *const CONTINUE_CARD_GAME;
+
// Dialog messages
extern char const *const HELP_MSG;
extern char const *const CHAR_TITLE;
@@ -182,6 +189,7 @@ extern char const *const RESTORE_GAME;
extern char const *const SHOW_CREDITS;
extern char const *const PAUSE_GAME;
extern char const *const RESUME_PLAY;
+extern char const *const R2_RESTART_MSG;
extern char const *const F2;
extern char const *const F3;
extern char const *const F4;
@@ -198,15 +206,16 @@ extern char const *const USE_DOUBLE_AGENT;
extern char const *const NEED_INSTRUCTIONS;
extern char const *const WRONG_ANSWER_MSG;
+extern char const *const BUY_FULL_GAME_MSG;
// Scene 1550 arrays of constants
extern const byte scene1550JunkLocationsDefault[];
extern const byte scene1550AreaMap[];
-extern const byte k5A72E[];
-extern const byte k5A73F[];
+extern const byte scene1550JunkX[];
+extern const byte scene1550JunkY[];
extern const byte k5A750[];
extern const byte k5A76D[];
extern const byte scene1550JunkRegions[];
-extern const byte k5A79B[];
+extern const byte scene1550SpecialAreas[];
extern const byte k5A7F6[];
// Scene 2900 balloon data
diff --git a/engines/tsage/tsage.cpp b/engines/tsage/tsage.cpp
index 87697f950b..36708e373e 100644
--- a/engines/tsage/tsage.cpp
+++ b/engines/tsage/tsage.cpp
@@ -38,10 +38,13 @@ TSageEngine::TSageEngine(OSystem *system, const tSageGameDescription *gameDesc)
_gameDescription(gameDesc) {
g_vm = this;
DebugMan.addDebugChannel(kRingDebugScripts, "scripts", "Scripts debugging");
- if (g_vm->getFeatures() & GF_DEMO)
- _debugger = new DemoDebugger();
- else if (g_vm->getGameID() == GType_Ringworld)
- _debugger = new RingworldDebugger();
+ _debugger = nullptr;
+ if (g_vm->getGameID() == GType_Ringworld) {
+ if (g_vm->getFeatures() & GF_DEMO)
+ _debugger = new DemoDebugger();
+ else
+ _debugger = new RingworldDebugger();
+ }
else if (g_vm->getGameID() == GType_BlueForce)
_debugger = new BlueForceDebugger();
else if (g_vm->getGameID() == GType_Ringworld2)
@@ -75,16 +78,16 @@ void TSageEngine::initialize() {
// Set up the resource manager
g_resourceManager = new ResourceManager();
- if (g_vm->getFeatures() & GF_DEMO) {
- // Add the single library file associated with the demo
- g_resourceManager->addLib(getPrimaryFilename());
- g_globals = new Globals();
-
- } else if (g_vm->getGameID() == GType_Ringworld) {
- g_resourceManager->addLib("RING.RLB");
- g_resourceManager->addLib("TSAGE.RLB");
- g_globals = new Globals();
-
+ if (g_vm->getGameID() == GType_Ringworld) {
+ if (g_vm->getFeatures() & GF_DEMO) {
+ // Add the single library file associated with the demo
+ g_resourceManager->addLib(getPrimaryFilename());
+ g_globals = new Globals();
+ } else {
+ g_resourceManager->addLib("RING.RLB");
+ g_resourceManager->addLib("TSAGE.RLB");
+ g_globals = new Globals();
+ }
} else if (g_vm->getGameID() == GType_BlueForce) {
g_resourceManager->addLib("BLUE.RLB");
if (g_vm->getFeatures() & GF_FLOPPY) {
@@ -103,7 +106,7 @@ void TSageEngine::initialize() {
g_globals = new Ringworld2::Ringworld2Globals();
// Setup the user interface
- T2_GLOBALS._uiElements.setup(Common::Point(0, UI_INTERFACE_Y - 2));
+ T2_GLOBALS._uiElements.setup(Common::Point(0, UI_INTERFACE_Y));
// Reset all global variables
R2_GLOBALS.reset();
@@ -124,7 +127,7 @@ void TSageEngine::deinitialize() {
}
Common::Error TSageEngine::run() {
- // Basic initialisation
+ // Basic initialization
initialize();
g_globals->_sceneHandler->registerHandler();
@@ -176,8 +179,4 @@ void TSageEngine::syncSoundSettings() {
g_globals->_soundManager.syncSounds();
}
-bool TSageEngine::shouldQuit() {
- return getEventManager()->shouldQuit() || getEventManager()->shouldRTL();
-}
-
} // End of namespace TsAGE
diff --git a/engines/tsage/tsage.h b/engines/tsage/tsage.h
index 41179c4915..e69fe0612a 100644
--- a/engines/tsage/tsage.h
+++ b/engines/tsage/tsage.h
@@ -27,6 +27,7 @@
#include "common/rect.h"
#include "audio/mixer.h"
#include "common/file.h"
+#include "gui/debugger.h"
#include "tsage/core.h"
#include "tsage/resources.h"
@@ -76,12 +77,12 @@ public:
MemoryManager _memoryManager;
Debugger *_debugger;
+ GUI::Debugger *getDebugger() { return _debugger; }
const char *getGameId() const;
uint32 getGameID() const;
uint32 getFeatures() const;
Common::String getPrimaryFilename() const;
- bool shouldQuit();
virtual Common::Error init();
virtual Common::Error run();
diff --git a/engines/tsage/user_interface.cpp b/engines/tsage/user_interface.cpp
index 09cc2fd56d..ae5c6c8cee 100644
--- a/engines/tsage/user_interface.cpp
+++ b/engines/tsage/user_interface.cpp
@@ -38,13 +38,15 @@ void StripProxy::process(Event &event) {
void UIElement::synchronize(Serializer &s) {
BackgroundSceneObject::synchronize(s);
- s.syncAsSint16LE(_field88);
+ if (s.getVersion() < 15) {
+ int useless = 0;
+ s.syncAsSint16LE(useless);
+ }
s.syncAsSint16LE(_enabled);
s.syncAsSint16LE(_frameNum);
}
void UIElement::setup(int visage, int stripNum, int frameNum, int posX, int posY, int priority) {
- _field88 = 0;
_frameNum = frameNum;
_enabled = true;
@@ -87,7 +89,7 @@ void UIQuestion::showDescription(CursorType cursor) {
Ringworld2::SceneExt *scene = static_cast<Ringworld2::SceneExt *>
(R2_GLOBALS._sceneManager._scene);
if (!scene->_sceneAreas.contains(R2_GLOBALS._scannerDialog))
- R2_GLOBALS._scannerDialog->proc12(4, 1, 1, 160, 125);
+ R2_GLOBALS._scannerDialog->setup2(4, 1, 1, 160, 125);
} else {
// Show object description
SceneItem::display2(3, (int)cursor);
@@ -276,11 +278,29 @@ void UICollection::draw() {
Rect(0, UI_INTERFACE_Y, SCREEN_WIDTH, SCREEN_HEIGHT),
Rect(0, UI_INTERFACE_Y, SCREEN_WIDTH, SCREEN_HEIGHT));
+ if (g_vm->getGameID() == GType_Ringworld2)
+ r2rDrawFrame();
+
_clearScreen = 1;
g_globals->_sceneManager._scene->_sceneBounds = savedBounds;
}
}
+void UICollection::r2rDrawFrame() {
+ Visage visage;
+ visage.setVisage(2, 1);
+ GfxSurface vertLine = visage.getFrame(1);
+ GfxSurface horizLine = visage.getFrame(2);
+
+ GLOBALS._screenSurface.copyFrom(horizLine, 0, 0);
+ GLOBALS._screenSurface.copyFrom(vertLine, 0, 3);
+ GLOBALS._screenSurface.copyFrom(vertLine, SCREEN_WIDTH - 4, 3);
+
+ // Restrict drawing area to exclude the borders at the edge of the screen
+ R2_GLOBALS._screenSurface._clipRect = Rect(4, 4, SCREEN_WIDTH - 4,
+ SCREEN_HEIGHT - 4);
+}
+
/*--------------------------------------------------------------------------*/
UIElements::UIElements(): UICollection() {
@@ -289,6 +309,10 @@ UIElements::UIElements(): UICollection() {
else
_cursorVisage.setVisage(1, 5);
g_saver->addLoadNotifier(&UIElements::loadNotifierProc);
+
+ _slotStart = 0;
+ _scoreValue = 0;
+ _active = false;
}
void UIElements::synchronize(Serializer &s) {
diff --git a/engines/tsage/user_interface.h b/engines/tsage/user_interface.h
index d06dccd9a4..bc2398bf05 100644
--- a/engines/tsage/user_interface.h
+++ b/engines/tsage/user_interface.h
@@ -37,7 +37,6 @@ public:
class UIElement: public BackgroundSceneObject {
public:
- int _field88;
bool _enabled;
int _frameNum;
@@ -95,6 +94,8 @@ public:
};
class UICollection: public EventHandler {
+private:
+ void r2rDrawFrame();
protected:
void erase();
public:
diff --git a/engines/tucker/configure.engine b/engines/tucker/configure.engine
new file mode 100644
index 0000000000..06676cf0a4
--- /dev/null
+++ b/engines/tucker/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 tucker "Bud Tucker in Double Trouble" yes
diff --git a/engines/wintermute/ad/ad_actor.cpp b/engines/wintermute/ad/ad_actor.cpp
index 94df17c543..33ad39b411 100644
--- a/engines/wintermute/ad/ad_actor.cpp
+++ b/engines/wintermute/ad/ad_actor.cpp
@@ -119,7 +119,7 @@ AdActor::~AdActor() {
//////////////////////////////////////////////////////////////////////////
bool AdActor::loadFile(const char *filename) {
- byte *buffer = BaseFileManager::getEngineInstance()->readWholeFile(filename);
+ char *buffer = (char *)BaseFileManager::getEngineInstance()->readWholeFile(filename);
if (buffer == nullptr) {
_gameRef->LOG(0, "AdActor::LoadFile failed for file '%s'", filename);
return STATUS_FAILED;
@@ -179,7 +179,7 @@ TOKEN_DEF(EDITOR_PROPERTY)
TOKEN_DEF(ANIMATION)
TOKEN_DEF_END
//////////////////////////////////////////////////////////////////////////
-bool AdActor::loadBuffer(byte *buffer, bool complete) {
+bool AdActor::loadBuffer(char *buffer, bool complete) {
TOKEN_TABLE_START(commands)
TOKEN_TABLE(ACTOR)
TOKEN_TABLE(X)
@@ -219,12 +219,12 @@ bool AdActor::loadBuffer(byte *buffer, bool complete) {
TOKEN_TABLE(ANIMATION)
TOKEN_TABLE_END
- byte *params;
+ char *params;
int cmd;
BaseParser parser;
if (complete) {
- if (parser.getCommand((char **)&buffer, commands, (char **)&params) != TOKEN_ACTOR) {
+ if (parser.getCommand(&buffer, commands, &params) != TOKEN_ACTOR) {
_gameRef->LOG(0, "'ACTOR' keyword expected.");
return STATUS_FAILED;
}
@@ -234,55 +234,55 @@ bool AdActor::loadBuffer(byte *buffer, bool complete) {
AdGame *adGame = (AdGame *)_gameRef;
AdSpriteSet *spr = nullptr;
int ar = 0, ag = 0, ab = 0, alpha = 0;
- while ((cmd = parser.getCommand((char **)&buffer, commands, (char **)&params)) > 0) {
+ while ((cmd = parser.getCommand(&buffer, commands, &params)) > 0) {
switch (cmd) {
case TOKEN_TEMPLATE:
- if (DID_FAIL(loadFile((char *)params))) {
+ if (DID_FAIL(loadFile(params))) {
cmd = PARSERR_GENERIC;
}
break;
case TOKEN_X:
- parser.scanStr((char *)params, "%d", &_posX);
+ parser.scanStr(params, "%d", &_posX);
break;
case TOKEN_Y:
- parser.scanStr((char *)params, "%d", &_posY);
+ parser.scanStr(params, "%d", &_posY);
break;
case TOKEN_NAME:
- setName((char *)params);
+ setName(params);
break;
case TOKEN_CAPTION:
- setCaption((char *)params);
+ setCaption(params);
break;
case TOKEN_FONT:
- setFont((char *)params);
+ setFont(params);
break;
case TOKEN_SCALABLE:
- parser.scanStr((char *)params, "%b", &_zoomable);
+ parser.scanStr(params, "%b", &_zoomable);
break;
case TOKEN_ROTABLE:
case TOKEN_ROTATABLE:
- parser.scanStr((char *)params, "%b", &_rotatable);
+ parser.scanStr(params, "%b", &_rotatable);
break;
case TOKEN_REGISTRABLE:
case TOKEN_INTERACTIVE:
- parser.scanStr((char *)params, "%b", &_registrable);
+ parser.scanStr(params, "%b", &_registrable);
break;
case TOKEN_SHADOWABLE:
case TOKEN_COLORABLE:
- parser.scanStr((char *)params, "%b", &_shadowable);
+ parser.scanStr(params, "%b", &_shadowable);
break;
case TOKEN_ACTIVE:
- parser.scanStr((char *)params, "%b", &_active);
+ parser.scanStr(params, "%b", &_active);
break;
case TOKEN_WALK:
@@ -348,7 +348,7 @@ bool AdActor::loadBuffer(byte *buffer, bool complete) {
break;
case TOKEN_SCRIPT:
- addScript((char *)params);
+ addScript(params);
break;
case TOKEN_CURSOR:
@@ -362,12 +362,12 @@ bool AdActor::loadBuffer(byte *buffer, bool complete) {
break;
case TOKEN_SOUND_VOLUME:
- parser.scanStr((char *)params, "%d", &_sFXVolume);
+ parser.scanStr(params, "%d", &_sFXVolume);
break;
case TOKEN_SCALE: {
int s;
- parser.scanStr((char *)params, "%d", &s);
+ parser.scanStr(params, "%d", &s);
_scale = (float)s;
}
@@ -375,14 +375,14 @@ bool AdActor::loadBuffer(byte *buffer, bool complete) {
case TOKEN_RELATIVE_SCALE: {
int s;
- parser.scanStr((char *)params, "%d", &s);
+ parser.scanStr(params, "%d", &s);
_relativeScale = (float)s;
}
break;
case TOKEN_SOUND_PANNING:
- parser.scanStr((char *)params, "%b", &_autoSoundPanning);
+ parser.scanStr(params, "%b", &_autoSoundPanning);
break;
case TOKEN_PROPERTY:
@@ -432,15 +432,15 @@ bool AdActor::loadBuffer(byte *buffer, bool complete) {
break;
case TOKEN_IGNORE_ITEMS:
- parser.scanStr((char *)params, "%b", &_ignoreItems);
+ parser.scanStr(params, "%b", &_ignoreItems);
break;
case TOKEN_ALPHA_COLOR:
- parser.scanStr((char *)params, "%d,%d,%d", &ar, &ag, &ab);
+ parser.scanStr(params, "%d,%d,%d", &ar, &ag, &ab);
break;
case TOKEN_ALPHA:
- parser.scanStr((char *)params, "%d", &alpha);
+ parser.scanStr(params, "%d", &alpha);
break;
case TOKEN_EDITOR_PROPERTY:
@@ -1319,29 +1319,29 @@ BaseSprite *AdActor::getTalkStanceOld(const char *stance) {
bool AdActor::persist(BasePersistenceManager *persistMgr) {
AdTalkHolder::persist(persistMgr);
- persistMgr->transfer(TMEMBER_INT(_dir));
+ persistMgr->transferSint32(TMEMBER_INT(_dir));
persistMgr->transferPtr(TMEMBER_PTR(_path));
- persistMgr->transfer(TMEMBER(_pFCount));
- persistMgr->transfer(TMEMBER(_pFStepX));
- persistMgr->transfer(TMEMBER(_pFStepY));
- persistMgr->transfer(TMEMBER(_pFX));
- persistMgr->transfer(TMEMBER(_pFY));
+ persistMgr->transferSint32(TMEMBER(_pFCount));
+ persistMgr->transferDouble(TMEMBER(_pFStepX));
+ persistMgr->transferDouble(TMEMBER(_pFStepY));
+ persistMgr->transferDouble(TMEMBER(_pFX));
+ persistMgr->transferDouble(TMEMBER(_pFY));
persistMgr->transferPtr(TMEMBER_PTR(_standSprite));
_talkSprites.persist(persistMgr);
_talkSpritesEx.persist(persistMgr);
- persistMgr->transfer(TMEMBER_INT(_targetDir));
- persistMgr->transfer(TMEMBER_INT(_afterWalkDir));
+ persistMgr->transferSint32(TMEMBER_INT(_targetDir));
+ persistMgr->transferSint32(TMEMBER_INT(_afterWalkDir));
persistMgr->transferPtr(TMEMBER_PTR(_targetPoint));
persistMgr->transferPtr(TMEMBER_PTR(_turnLeftSprite));
persistMgr->transferPtr(TMEMBER_PTR(_turnRightSprite));
persistMgr->transferPtr(TMEMBER_PTR(_walkSprite));
persistMgr->transferPtr(TMEMBER_PTR(_animSprite2));
- persistMgr->transfer(TMEMBER(_talkAnimName));
- persistMgr->transfer(TMEMBER(_idleAnimName));
- persistMgr->transfer(TMEMBER(_walkAnimName));
- persistMgr->transfer(TMEMBER(_turnLeftAnimName));
- persistMgr->transfer(TMEMBER(_turnRightAnimName));
+ persistMgr->transferString(TMEMBER(_talkAnimName));
+ persistMgr->transferString(TMEMBER(_idleAnimName));
+ persistMgr->transferString(TMEMBER(_walkAnimName));
+ persistMgr->transferString(TMEMBER(_turnLeftAnimName));
+ persistMgr->transferString(TMEMBER(_turnRightAnimName));
_anims.persist(persistMgr);
@@ -1376,7 +1376,7 @@ TDirection AdActor::angleToDirection(int angle) {
//////////////////////////////////////////////////////////////////////////
-int AdActor::getHeight() {
+int32 AdActor::getHeight() {
// if no current sprite is set, set some
if (_currentSprite == nullptr) {
if (_standSprite) {
@@ -1410,20 +1410,20 @@ bool AdActor::mergeAnims(const char *animsFilename) {
TOKEN_TABLE_END
- byte *fileBuffer = BaseFileManager::getEngineInstance()->readWholeFile(animsFilename);
+ char *fileBuffer = (char *)BaseFileManager::getEngineInstance()->readWholeFile(animsFilename);
if (fileBuffer == nullptr) {
_gameRef->LOG(0, "AdActor::MergeAnims failed for file '%s'", animsFilename);
return STATUS_FAILED;
}
- byte *buffer = fileBuffer;
- byte *params;
+ char *buffer = fileBuffer;
+ char *params;
int cmd;
BaseParser parser;
bool ret = STATUS_OK;
- while ((cmd = parser.getCommand((char **)&buffer, commands, (char **)&params)) > 0) {
+ while ((cmd = parser.getCommand(&buffer, commands, &params)) > 0) {
switch (cmd) {
case TOKEN_ANIMATION: {
AdSpriteSet *anim = new AdSpriteSet(_gameRef, this);
diff --git a/engines/wintermute/ad/ad_actor.h b/engines/wintermute/ad/ad_actor.h
index 582b41b8b0..3225eb44ec 100644
--- a/engines/wintermute/ad/ad_actor.h
+++ b/engines/wintermute/ad/ad_actor.h
@@ -47,7 +47,7 @@ class AdActor : public AdTalkHolder {
public:
TDirection angleToDirection(int angle);
DECLARE_PERSISTENT(AdActor, AdTalkHolder)
- virtual int getHeight();
+ virtual int32 getHeight() override;
BaseSprite *getTalkStance(const char *stance);
virtual void goTo(int x, int y, TDirection afterWalkDir = DI_NONE);
BasePoint *_targetPoint;
@@ -57,7 +57,7 @@ public:
AdActor(BaseGame *inGame/*=nullptr*/);
virtual ~AdActor();
bool loadFile(const char *filename);
- bool loadBuffer(byte *buffer, bool complete = true);
+ bool loadBuffer(char *buffer, bool complete = true);
private:
diff --git a/engines/wintermute/ad/ad_entity.cpp b/engines/wintermute/ad/ad_entity.cpp
index 388accf34f..098da49750 100644
--- a/engines/wintermute/ad/ad_entity.cpp
+++ b/engines/wintermute/ad/ad_entity.cpp
@@ -100,7 +100,7 @@ const char *AdEntity::getItemName() const {
//////////////////////////////////////////////////////////////////////////
bool AdEntity::loadFile(const char *filename) {
- byte *buffer = BaseFileManager::getEngineInstance()->readWholeFile(filename);
+ char *buffer = (char *)BaseFileManager::getEngineInstance()->readWholeFile(filename);
if (buffer == nullptr) {
_gameRef->LOG(0, "AdEntity::LoadFile failed for file '%s'", filename);
return STATUS_FAILED;
@@ -166,7 +166,7 @@ TOKEN_DEF(WALK_TO_DIR)
TOKEN_DEF(SAVE_STATE)
TOKEN_DEF_END
//////////////////////////////////////////////////////////////////////////
-bool AdEntity::loadBuffer(byte *buffer, bool complete) {
+bool AdEntity::loadBuffer(char *buffer, bool complete) {
TOKEN_TABLE_START(commands)
TOKEN_TABLE(ENTITY)
TOKEN_TABLE(SPRITE)
@@ -212,12 +212,12 @@ bool AdEntity::loadBuffer(byte *buffer, bool complete) {
TOKEN_TABLE(SAVE_STATE)
TOKEN_TABLE_END
- byte *params;
+ char *params;
int cmd;
BaseParser parser;
if (complete) {
- if (parser.getCommand((char **)&buffer, commands, (char **)&params) != TOKEN_ENTITY) {
+ if (parser.getCommand(&buffer, commands, &params) != TOKEN_ENTITY) {
_gameRef->LOG(0, "'ENTITY' keyword expected.");
return STATUS_FAILED;
}
@@ -227,27 +227,27 @@ bool AdEntity::loadBuffer(byte *buffer, bool complete) {
AdGame *adGame = (AdGame *)_gameRef;
BaseSprite *spr = nullptr;
int ar = 0, ag = 0, ab = 0, alpha = 0;
- while ((cmd = parser.getCommand((char **)&buffer, commands, (char **)&params)) > 0) {
+ while ((cmd = parser.getCommand(&buffer, commands, &params)) > 0) {
switch (cmd) {
case TOKEN_TEMPLATE:
- if (DID_FAIL(loadFile((char *)params))) {
+ if (DID_FAIL(loadFile(params))) {
cmd = PARSERR_GENERIC;
}
break;
case TOKEN_X:
- parser.scanStr((char *)params, "%d", &_posX);
+ parser.scanStr(params, "%d", &_posX);
break;
case TOKEN_Y:
- parser.scanStr((char *)params, "%d", &_posY);
+ parser.scanStr(params, "%d", &_posY);
break;
case TOKEN_SPRITE: {
delete _sprite;
_sprite = nullptr;
spr = new BaseSprite(_gameRef, this);
- if (!spr || DID_FAIL(spr->loadFile((char *)params))) {
+ if (!spr || DID_FAIL(spr->loadFile(params))) {
cmd = PARSERR_GENERIC;
} else {
_sprite = spr;
@@ -257,7 +257,7 @@ bool AdEntity::loadBuffer(byte *buffer, bool complete) {
case TOKEN_TALK: {
spr = new BaseSprite(_gameRef, this);
- if (!spr || DID_FAIL(spr->loadFile((char *)params, adGame->_texTalkLifeTime))) {
+ if (!spr || DID_FAIL(spr->loadFile(params, adGame->_texTalkLifeTime))) {
cmd = PARSERR_GENERIC;
} else {
_talkSprites.add(spr);
@@ -267,7 +267,7 @@ bool AdEntity::loadBuffer(byte *buffer, bool complete) {
case TOKEN_TALK_SPECIAL: {
spr = new BaseSprite(_gameRef, this);
- if (!spr || DID_FAIL(spr->loadFile((char *)params, adGame->_texTalkLifeTime))) {
+ if (!spr || DID_FAIL(spr->loadFile(params, adGame->_texTalkLifeTime))) {
cmd = PARSERR_GENERIC;
} else {
_talkSpritesEx.add(spr);
@@ -276,28 +276,28 @@ bool AdEntity::loadBuffer(byte *buffer, bool complete) {
break;
case TOKEN_NAME:
- setName((char *)params);
+ setName(params);
break;
case TOKEN_ITEM:
- setItem((char *)params);
+ setItem(params);
break;
case TOKEN_CAPTION:
- setCaption((char *)params);
+ setCaption(params);
break;
case TOKEN_FONT:
- setFont((char *)params);
+ setFont(params);
break;
case TOKEN_SCALABLE:
- parser.scanStr((char *)params, "%b", &_zoomable);
+ parser.scanStr(params, "%b", &_zoomable);
break;
case TOKEN_SCALE: {
int s;
- parser.scanStr((char *)params, "%d", &s);
+ parser.scanStr(params, "%d", &s);
_scale = (float)s;
}
@@ -305,7 +305,7 @@ bool AdEntity::loadBuffer(byte *buffer, bool complete) {
case TOKEN_RELATIVE_SCALE: {
int s;
- parser.scanStr((char *)params, "%d", &s);
+ parser.scanStr(params, "%d", &s);
_relativeScale = (float)s;
}
@@ -313,27 +313,27 @@ bool AdEntity::loadBuffer(byte *buffer, bool complete) {
case TOKEN_ROTABLE:
case TOKEN_ROTATABLE:
- parser.scanStr((char *)params, "%b", &_rotatable);
+ parser.scanStr(params, "%b", &_rotatable);
break;
case TOKEN_REGISTRABLE:
case TOKEN_INTERACTIVE:
- parser.scanStr((char *)params, "%b", &_registrable);
+ parser.scanStr(params, "%b", &_registrable);
break;
case TOKEN_SHADOWABLE:
case TOKEN_COLORABLE:
- parser.scanStr((char *)params, "%b", &_shadowable);
+ parser.scanStr(params, "%b", &_shadowable);
break;
case TOKEN_ACTIVE:
- parser.scanStr((char *)params, "%b", &_active);
+ parser.scanStr(params, "%b", &_active);
break;
case TOKEN_CURSOR:
delete _cursor;
_cursor = new BaseSprite(_gameRef);
- if (!_cursor || DID_FAIL(_cursor->loadFile((char *)params))) {
+ if (!_cursor || DID_FAIL(_cursor->loadFile(params))) {
delete _cursor;
_cursor = nullptr;
cmd = PARSERR_GENERIC;
@@ -341,7 +341,7 @@ bool AdEntity::loadBuffer(byte *buffer, bool complete) {
break;
case TOKEN_EDITOR_SELECTED:
- parser.scanStr((char *)params, "%b", &_editorSelected);
+ parser.scanStr(params, "%b", &_editorSelected);
break;
case TOKEN_REGION: {
@@ -402,11 +402,11 @@ bool AdEntity::loadBuffer(byte *buffer, bool complete) {
break;
case TOKEN_SCRIPT:
- addScript((char *)params);
+ addScript(params);
break;
case TOKEN_SUBTYPE: {
- if (scumm_stricmp((char *)params, "sound") == 0) {
+ if (scumm_stricmp(params, "sound") == 0) {
delete _sprite;
_sprite = nullptr;
if (_gameRef->_editorMode) {
@@ -430,23 +430,23 @@ bool AdEntity::loadBuffer(byte *buffer, bool complete) {
break;
case TOKEN_SOUND:
- playSFX((char *)params, false, false);
+ playSFX(params, false, false);
break;
case TOKEN_SOUND_START_TIME:
- parser.scanStr((char *)params, "%d", &_sFXStart);
+ parser.scanStr(params, "%d", &_sFXStart);
break;
case TOKEN_SOUND_VOLUME:
- parser.scanStr((char *)params, "%d", &_sFXVolume);
+ parser.scanStr(params, "%d", &_sFXVolume);
break;
case TOKEN_SOUND_PANNING:
- parser.scanStr((char *)params, "%b", &_autoSoundPanning);
+ parser.scanStr(params, "%b", &_autoSoundPanning);
break;
case TOKEN_SAVE_STATE:
- parser.scanStr((char *)params, "%b", &_saveState);
+ parser.scanStr(params, "%b", &_saveState);
break;
case TOKEN_PROPERTY:
@@ -454,15 +454,15 @@ bool AdEntity::loadBuffer(byte *buffer, bool complete) {
break;
case TOKEN_IGNORE_ITEMS:
- parser.scanStr((char *)params, "%b", &_ignoreItems);
+ parser.scanStr(params, "%b", &_ignoreItems);
break;
case TOKEN_ALPHA_COLOR:
- parser.scanStr((char *)params, "%d,%d,%d", &ar, &ag, &ab);
+ parser.scanStr(params, "%d,%d,%d", &ar, &ag, &ab);
break;
case TOKEN_ALPHA:
- parser.scanStr((char *)params, "%d", &alpha);
+ parser.scanStr(params, "%d", &alpha);
break;
case TOKEN_EDITOR_PROPERTY:
@@ -470,16 +470,16 @@ bool AdEntity::loadBuffer(byte *buffer, bool complete) {
break;
case TOKEN_WALK_TO_X:
- parser.scanStr((char *)params, "%d", &_walkToX);
+ parser.scanStr(params, "%d", &_walkToX);
break;
case TOKEN_WALK_TO_Y:
- parser.scanStr((char *)params, "%d", &_walkToY);
+ parser.scanStr(params, "%d", &_walkToY);
break;
case TOKEN_WALK_TO_DIR: {
int i;
- parser.scanStr((char *)params, "%d", &i);
+ parser.scanStr(params, "%d", &i);
if (i < 0) {
i = 0;
}
@@ -1067,7 +1067,7 @@ bool AdEntity::saveAsText(BaseDynamicBuffer *buffer, int indent) {
//////////////////////////////////////////////////////////////////////////
-int AdEntity::getHeight() {
+int32 AdEntity::getHeight() {
if (_region && !_sprite) {
return _region->_rect.bottom - _region->_rect.top;
} else {
@@ -1092,16 +1092,16 @@ void AdEntity::updatePosition() {
bool AdEntity::persist(BasePersistenceManager *persistMgr) {
AdTalkHolder::persist(persistMgr);
- persistMgr->transfer(TMEMBER(_item));
+ persistMgr->transferCharPtr(TMEMBER(_item));
persistMgr->transferPtr(TMEMBER_PTR(_region));
//persistMgr->transfer(TMEMBER(_sprite));
- persistMgr->transfer(TMEMBER_INT(_subtype));
+ persistMgr->transferSint32(TMEMBER_INT(_subtype));
_talkSprites.persist(persistMgr);
_talkSpritesEx.persist(persistMgr);
- persistMgr->transfer(TMEMBER(_walkToX));
- persistMgr->transfer(TMEMBER(_walkToY));
- persistMgr->transfer(TMEMBER_INT(_walkToDir));
+ persistMgr->transferSint32(TMEMBER(_walkToX));
+ persistMgr->transferSint32(TMEMBER(_walkToY));
+ persistMgr->transferSint32(TMEMBER_INT(_walkToDir));
persistMgr->transferPtr(TMEMBER_PTR(_theora));
diff --git a/engines/wintermute/ad/ad_entity.h b/engines/wintermute/ad/ad_entity.h
index bdbd271667..c3ed5622e5 100644
--- a/engines/wintermute/ad/ad_entity.h
+++ b/engines/wintermute/ad/ad_entity.h
@@ -40,7 +40,7 @@ public:
void setItem(const char *itemName);
DECLARE_PERSISTENT(AdEntity, AdTalkHolder)
void updatePosition();
- virtual int getHeight();
+ virtual int32 getHeight() override;
BaseRegion *_region;
virtual bool saveAsText(BaseDynamicBuffer *buffer, int indent) override;
virtual bool update();
@@ -48,7 +48,7 @@ public:
AdEntity(BaseGame *inGame);
virtual ~AdEntity();
bool loadFile(const char *filename);
- bool loadBuffer(byte *buffer, bool complete = true);
+ bool loadBuffer(char *buffer, bool complete = true);
int32 getWalkToX() const;
int32 getWalkToY() const;
diff --git a/engines/wintermute/ad/ad_game.cpp b/engines/wintermute/ad/ad_game.cpp
index d5799e851b..904b8a541c 100644
--- a/engines/wintermute/ad/ad_game.cpp
+++ b/engines/wintermute/ad/ad_game.cpp
@@ -1245,7 +1245,7 @@ bool AdGame::showCursor() {
//////////////////////////////////////////////////////////////////////////
bool AdGame::loadFile(const char *filename) {
- byte *buffer = BaseFileManager::getEngineInstance()->readWholeFile(filename);
+ char *buffer = (char *)BaseFileManager::getEngineInstance()->readWholeFile(filename);
if (buffer == nullptr) {
_gameRef->LOG(0, "AdGame::LoadFile failed for file '%s'", filename);
return STATUS_FAILED;
@@ -1281,7 +1281,7 @@ TOKEN_DEF(STARTUP_SCENE)
TOKEN_DEF(DEBUG_STARTUP_SCENE)
TOKEN_DEF_END
//////////////////////////////////////////////////////////////////////////
-bool AdGame::loadBuffer(byte *buffer, bool complete) {
+bool AdGame::loadBuffer(char *buffer, bool complete) {
TOKEN_TABLE_START(commands)
TOKEN_TABLE(GAME)
TOKEN_TABLE(AD_GAME)
@@ -1295,14 +1295,14 @@ bool AdGame::loadBuffer(byte *buffer, bool complete) {
TOKEN_TABLE(DEBUG_STARTUP_SCENE)
TOKEN_TABLE_END
- byte *params;
- byte *params2;
+ char *params;
+ char *params2;
int cmd = 1;
BaseParser parser;
bool itemFound = false, itemsFound = false;
- while (cmd > 0 && (cmd = parser.getCommand((char **)&buffer, commands, (char **)&params)) > 0) {
+ while (cmd > 0 && (cmd = parser.getCommand(&buffer, commands, &params)) > 0) {
switch (cmd) {
case TOKEN_GAME:
if (DID_FAIL(BaseGame::loadBuffer(params, false))) {
@@ -1311,12 +1311,12 @@ bool AdGame::loadBuffer(byte *buffer, bool complete) {
break;
case TOKEN_AD_GAME:
- while (cmd > 0 && (cmd = parser.getCommand((char **)&params, commands, (char **)&params2)) > 0) {
+ while (cmd > 0 && (cmd = parser.getCommand(&params, commands, &params2)) > 0) {
switch (cmd) {
case TOKEN_RESPONSE_BOX:
delete _responseBox;
_responseBox = new AdResponseBox(_gameRef);
- if (_responseBox && !DID_FAIL(_responseBox->loadFile((char *)params2))) {
+ if (_responseBox && !DID_FAIL(_responseBox->loadFile(params2))) {
registerObject(_responseBox);
} else {
delete _responseBox;
@@ -1328,7 +1328,7 @@ bool AdGame::loadBuffer(byte *buffer, bool complete) {
case TOKEN_INVENTORY_BOX:
delete _inventoryBox;
_inventoryBox = new AdInventoryBox(_gameRef);
- if (_inventoryBox && !DID_FAIL(_inventoryBox->loadFile((char *)params2))) {
+ if (_inventoryBox && !DID_FAIL(_inventoryBox->loadFile(params2))) {
registerObject(_inventoryBox);
} else {
delete _inventoryBox;
@@ -1339,7 +1339,7 @@ bool AdGame::loadBuffer(byte *buffer, bool complete) {
case TOKEN_ITEMS:
itemsFound = true;
- BaseUtils::setString(&_itemsFile, (char *)params2);
+ BaseUtils::setString(&_itemsFile, params2);
if (DID_FAIL(loadItemsFile(_itemsFile))) {
delete[] _itemsFile;
_itemsFile = nullptr;
@@ -1348,9 +1348,9 @@ bool AdGame::loadBuffer(byte *buffer, bool complete) {
break;
case TOKEN_TALK_SKIP_BUTTON:
- if (scumm_stricmp((char *)params2, "right") == 0) {
+ if (scumm_stricmp(params2, "right") == 0) {
_talkSkipButton = TALK_SKIP_RIGHT;
- } else if (scumm_stricmp((char *)params2, "both") == 0) {
+ } else if (scumm_stricmp(params2, "both") == 0) {
_talkSkipButton = TALK_SKIP_BOTH;
} else {
_talkSkipButton = TALK_SKIP_LEFT;
@@ -1359,7 +1359,7 @@ bool AdGame::loadBuffer(byte *buffer, bool complete) {
case TOKEN_SCENE_VIEWPORT: {
Rect32 rc;
- parser.scanStr((char *)params2, "%d,%d,%d,%d", &rc.left, &rc.top, &rc.right, &rc.bottom);
+ parser.scanStr(params2, "%d,%d,%d,%d", &rc.left, &rc.top, &rc.right, &rc.bottom);
if (!_sceneViewport) {
_sceneViewport = new BaseViewport(_gameRef);
}
@@ -1374,11 +1374,11 @@ bool AdGame::loadBuffer(byte *buffer, bool complete) {
break;
case TOKEN_STARTUP_SCENE:
- BaseUtils::setString(&_startupScene, (char *)params2);
+ BaseUtils::setString(&_startupScene, params2);
break;
case TOKEN_DEBUG_STARTUP_SCENE:
- BaseUtils::setString(&_debugStartupScene, (char *)params2);
+ BaseUtils::setString(&_debugStartupScene, params2);
break;
}
}
@@ -1417,41 +1417,41 @@ bool AdGame::persist(BasePersistenceManager *persistMgr) {
_objects.persist(persistMgr);
- persistMgr->transfer(TMEMBER(_prevSceneName));
- persistMgr->transfer(TMEMBER(_prevSceneFilename));
+ persistMgr->transferCharPtr(TMEMBER(_prevSceneName));
+ persistMgr->transferCharPtr(TMEMBER(_prevSceneFilename));
persistMgr->transferPtr(TMEMBER_PTR(_responseBox));
_responsesBranch.persist(persistMgr);
_responsesGame.persist(persistMgr);
persistMgr->transferPtr(TMEMBER_PTR(_scene));
_sceneStates.persist(persistMgr);
- persistMgr->transfer(TMEMBER(_scheduledFadeIn));
- persistMgr->transfer(TMEMBER(_scheduledScene));
+ persistMgr->transferBool(TMEMBER(_scheduledFadeIn));
+ persistMgr->transferCharPtr(TMEMBER(_scheduledScene));
persistMgr->transferPtr(TMEMBER_PTR(_selectedItem));
- persistMgr->transfer(TMEMBER_INT(_talkSkipButton));
+ persistMgr->transferSint32(TMEMBER_INT(_talkSkipButton));
_sentences.persist(persistMgr);
persistMgr->transferPtr(TMEMBER_PTR(_sceneViewport));
- persistMgr->transfer(TMEMBER_INT(_stateEx));
- persistMgr->transfer(TMEMBER(_initialScene));
- persistMgr->transfer(TMEMBER(_debugStartupScene));
+ persistMgr->transferSint32(TMEMBER_INT(_stateEx));
+ persistMgr->transferBool(TMEMBER(_initialScene));
+ persistMgr->transferCharPtr(TMEMBER(_debugStartupScene));
persistMgr->transferPtr(TMEMBER_PTR(_invObject));
persistMgr->transferPtr(TMEMBER_PTR(_inventoryOwner));
- persistMgr->transfer(TMEMBER(_tempDisableSaveState));
+ persistMgr->transferBool(TMEMBER(_tempDisableSaveState));
_items.persist(persistMgr);
- persistMgr->transfer(TMEMBER(_itemsFile));
+ persistMgr->transferCharPtr(TMEMBER(_itemsFile));
_speechDirs.persist(persistMgr);
- persistMgr->transfer(TMEMBER(_smartItemCursor));
+ persistMgr->transferBool(TMEMBER(_smartItemCursor));
if (!persistMgr->getIsSaving()) {
_initialScene = false;
}
- persistMgr->transfer(TMEMBER(_startupScene));
+ persistMgr->transferCharPtr(TMEMBER(_startupScene));
return STATUS_OK;
@@ -1518,7 +1518,7 @@ bool AdGame::getVersion(byte *verMajor, byte *verMinor, byte *extMajor, byte *ex
//////////////////////////////////////////////////////////////////////////
bool AdGame::loadItemsFile(const char *filename, bool merge) {
- byte *buffer = BaseFileManager::getEngineInstance()->readWholeFile(filename);
+ char *buffer = (char *)BaseFileManager::getEngineInstance()->readWholeFile(filename);
if (buffer == nullptr) {
_gameRef->LOG(0, "AdGame::LoadItemsFile failed for file '%s'", filename);
return STATUS_FAILED;
@@ -1541,12 +1541,12 @@ bool AdGame::loadItemsFile(const char *filename, bool merge) {
//////////////////////////////////////////////////////////////////////////
-bool AdGame::loadItemsBuffer(byte *buffer, bool merge) {
+bool AdGame::loadItemsBuffer(char *buffer, bool merge) {
TOKEN_TABLE_START(commands)
TOKEN_TABLE(ITEM)
TOKEN_TABLE_END
- byte *params;
+ char *params;
int cmd;
BaseParser parser;
@@ -1556,7 +1556,7 @@ bool AdGame::loadItemsBuffer(byte *buffer, bool merge) {
}
}
- while ((cmd = parser.getCommand((char **)&buffer, commands, (char **)&params)) > 0) {
+ while ((cmd = parser.getCommand(&buffer, commands, &params)) > 0) {
switch (cmd) {
case TOKEN_ITEM: {
AdItem *item = new AdItem(_gameRef);
@@ -1637,7 +1637,7 @@ bool AdGame::windowLoadHook(UIWindow *win, char **buffer, char **params) {
switch (cmd) {
case TOKEN_ENTITY_CONTAINER: {
UIEntity *ent = new UIEntity(_gameRef);
- if (!ent || DID_FAIL(ent->loadBuffer((byte *)*params, false))) {
+ if (!ent || DID_FAIL(ent->loadBuffer(*params, false))) {
delete ent;
ent = nullptr;
cmd = PARSERR_GENERIC;
@@ -2160,7 +2160,6 @@ bool AdGame::onMouseLeftDown() {
_gameRef->_capturedObject = _gameRef->_activeObject;
}
_mouseLeftDown = true;
- BasePlatform::setCapture(/*_renderer->_window*/);
return STATUS_OK;
}
@@ -2171,7 +2170,6 @@ bool AdGame::onMouseLeftUp() {
_activeObject->handleMouse(MOUSE_RELEASE, MOUSE_BUTTON_LEFT);
}
- BasePlatform::releaseCapture();
_capturedObject = nullptr;
_mouseLeftDown = false;
diff --git a/engines/wintermute/ad/ad_game.h b/engines/wintermute/ad/ad_game.h
index cb5147501d..019f2e6478 100644
--- a/engines/wintermute/ad/ad_game.h
+++ b/engines/wintermute/ad/ad_game.h
@@ -120,10 +120,10 @@ public:
BaseArray<AdObject *> _objects;
virtual bool loadFile(const char *filename);
- virtual bool loadBuffer(byte *buffer, bool complete = true);
+ virtual bool loadBuffer(char *buffer, bool complete = true);
bool loadItemsFile(const char *filename, bool merge = false);
- bool loadItemsBuffer(byte *buffer, bool merge = false);
+ bool loadItemsBuffer(char *buffer, bool merge = false);
// scripting interface
virtual ScValue *scGetProperty(const Common::String &name) override;
diff --git a/engines/wintermute/ad/ad_inventory.cpp b/engines/wintermute/ad/ad_inventory.cpp
index 544d8310d0..f9352c77c6 100644
--- a/engines/wintermute/ad/ad_inventory.cpp
+++ b/engines/wintermute/ad/ad_inventory.cpp
@@ -128,7 +128,7 @@ bool AdInventory::persist(BasePersistenceManager *persistMgr) {
BaseObject::persist(persistMgr);
_takenItems.persist(persistMgr);
- persistMgr->transfer(TMEMBER(_scrollOffset));
+ persistMgr->transferSint32(TMEMBER(_scrollOffset));
return STATUS_OK;
}
diff --git a/engines/wintermute/ad/ad_inventory_box.cpp b/engines/wintermute/ad/ad_inventory_box.cpp
index d703de1714..5d7f053bb5 100644
--- a/engines/wintermute/ad/ad_inventory_box.cpp
+++ b/engines/wintermute/ad/ad_inventory_box.cpp
@@ -120,8 +120,8 @@ bool AdInventoryBox::display() {
if (_closeButton) {
_closeButton->_posX = _closeButton->_posY = 0;
- _closeButton->_width = _gameRef->_renderer->getWidth();
- _closeButton->_height = _gameRef->_renderer->getHeight();
+ _closeButton->setWidth(_gameRef->_renderer->getWidth());
+ _closeButton->setHeight(_gameRef->_renderer->getHeight());
_closeButton->display();
}
@@ -165,7 +165,7 @@ bool AdInventoryBox::display() {
//////////////////////////////////////////////////////////////////////////
bool AdInventoryBox::loadFile(const char *filename) {
- byte *buffer = BaseFileManager::getEngineInstance()->readWholeFile(filename);
+ char *buffer = (char *)BaseFileManager::getEngineInstance()->readWholeFile(filename);
if (buffer == nullptr) {
_gameRef->LOG(0, "AdInventoryBox::LoadFile failed for file '%s'", filename);
return STATUS_FAILED;
@@ -203,7 +203,7 @@ TOKEN_DEF(HIDE_SELECTED)
TOKEN_DEF(EDITOR_PROPERTY)
TOKEN_DEF_END
//////////////////////////////////////////////////////////////////////////
-bool AdInventoryBox::loadBuffer(byte *buffer, bool complete) {
+bool AdInventoryBox::loadBuffer(char *buffer, bool complete) {
TOKEN_TABLE_START(commands)
TOKEN_TABLE(INVENTORY_BOX)
TOKEN_TABLE(TEMPLATE)
@@ -221,34 +221,34 @@ bool AdInventoryBox::loadBuffer(byte *buffer, bool complete) {
TOKEN_TABLE(EDITOR_PROPERTY)
TOKEN_TABLE_END
- byte *params;
+ char *params;
int cmd = 2;
BaseParser parser;
bool alwaysVisible = false;
_exclusive = false;
if (complete) {
- if (parser.getCommand((char **)&buffer, commands, (char **)&params) != TOKEN_INVENTORY_BOX) {
+ if (parser.getCommand(&buffer, commands, &params) != TOKEN_INVENTORY_BOX) {
_gameRef->LOG(0, "'INVENTORY_BOX' keyword expected.");
return STATUS_FAILED;
}
buffer = params;
}
- while (cmd > 0 && (cmd = parser.getCommand((char **)&buffer, commands, (char **)&params)) > 0) {
+ while (cmd > 0 && (cmd = parser.getCommand(&buffer, commands, &params)) > 0) {
switch (cmd) {
case TOKEN_TEMPLATE:
- if (DID_FAIL(loadFile((char *)params))) {
+ if (DID_FAIL(loadFile(params))) {
cmd = PARSERR_GENERIC;
}
break;
case TOKEN_NAME:
- setName((char *)params);
+ setName(params);
break;
case TOKEN_CAPTION:
- setCaption((char *)params);
+ setCaption(params);
break;
case TOKEN_WINDOW:
@@ -264,35 +264,35 @@ bool AdInventoryBox::loadBuffer(byte *buffer, bool complete) {
break;
case TOKEN_AREA:
- parser.scanStr((char *)params, "%d,%d,%d,%d", &_itemsArea.left, &_itemsArea.top, &_itemsArea.right, &_itemsArea.bottom);
+ parser.scanStr(params, "%d,%d,%d,%d", &_itemsArea.left, &_itemsArea.top, &_itemsArea.right, &_itemsArea.bottom);
break;
case TOKEN_EXCLUSIVE:
- parser.scanStr((char *)params, "%b", &_exclusive);
+ parser.scanStr(params, "%b", &_exclusive);
break;
case TOKEN_HIDE_SELECTED:
- parser.scanStr((char *)params, "%b", &_hideSelected);
+ parser.scanStr(params, "%b", &_hideSelected);
break;
case TOKEN_ALWAYS_VISIBLE:
- parser.scanStr((char *)params, "%b", &alwaysVisible);
+ parser.scanStr(params, "%b", &alwaysVisible);
break;
case TOKEN_SPACING:
- parser.scanStr((char *)params, "%d", &_spacing);
+ parser.scanStr(params, "%d", &_spacing);
break;
case TOKEN_ITEM_WIDTH:
- parser.scanStr((char *)params, "%d", &_itemWidth);
+ parser.scanStr(params, "%d", &_itemWidth);
break;
case TOKEN_ITEM_HEIGHT:
- parser.scanStr((char *)params, "%d", &_itemHeight);
+ parser.scanStr(params, "%d", &_itemHeight);
break;
case TOKEN_SCROLL_BY:
- parser.scanStr((char *)params, "%d", &_scrollBy);
+ parser.scanStr(params, "%d", &_scrollBy);
break;
case TOKEN_EDITOR_PROPERTY:
@@ -323,7 +323,7 @@ bool AdInventoryBox::loadBuffer(byte *buffer, bool complete) {
if (_window) {
for (uint32 i = 0; i < _window->_widgets.size(); i++) {
- if (!_window->_widgets[i]->_listenerObject) {
+ if (!_window->_widgets[i]->getListener()) {
_window->_widgets[i]->setListener(this, _window->_widgets[i], 0);
}
}
@@ -372,16 +372,16 @@ bool AdInventoryBox::persist(BasePersistenceManager *persistMgr) {
BaseObject::persist(persistMgr);
persistMgr->transferPtr(TMEMBER_PTR(_closeButton));
- persistMgr->transfer(TMEMBER(_hideSelected));
- persistMgr->transfer(TMEMBER(_itemHeight));
- persistMgr->transfer(TMEMBER(_itemsArea));
- persistMgr->transfer(TMEMBER(_itemWidth));
- persistMgr->transfer(TMEMBER(_scrollBy));
- persistMgr->transfer(TMEMBER(_scrollOffset));
- persistMgr->transfer(TMEMBER(_spacing));
- persistMgr->transfer(TMEMBER(_visible));
+ persistMgr->transferBool(TMEMBER(_hideSelected));
+ persistMgr->transferSint32(TMEMBER(_itemHeight));
+ persistMgr->transferRect32(TMEMBER(_itemsArea));
+ persistMgr->transferSint32(TMEMBER(_itemWidth));
+ persistMgr->transferSint32(TMEMBER(_scrollBy));
+ persistMgr->transferSint32(TMEMBER(_scrollOffset));
+ persistMgr->transferSint32(TMEMBER(_spacing));
+ persistMgr->transferBool(TMEMBER(_visible));
persistMgr->transferPtr(TMEMBER_PTR(_window));
- persistMgr->transfer(TMEMBER(_exclusive));
+ persistMgr->transferBool(TMEMBER(_exclusive));
return STATUS_OK;
}
diff --git a/engines/wintermute/ad/ad_inventory_box.h b/engines/wintermute/ad/ad_inventory_box.h
index f65bd8d8f0..4d576625b2 100644
--- a/engines/wintermute/ad/ad_inventory_box.h
+++ b/engines/wintermute/ad/ad_inventory_box.h
@@ -51,7 +51,7 @@ public:
AdInventoryBox(BaseGame *inGame);
virtual ~AdInventoryBox();
bool loadFile(const char *filename);
- bool loadBuffer(byte *buffer, bool complete = true);
+ bool loadBuffer(char *buffer, bool complete = true);
virtual bool saveAsText(BaseDynamicBuffer *buffer, int indent) override;
private:
bool _exclusive;
diff --git a/engines/wintermute/ad/ad_item.cpp b/engines/wintermute/ad/ad_item.cpp
index 7d05461169..1f19a3eeae 100644
--- a/engines/wintermute/ad/ad_item.cpp
+++ b/engines/wintermute/ad/ad_item.cpp
@@ -84,7 +84,7 @@ AdItem::~AdItem() {
//////////////////////////////////////////////////////////////////////////
bool AdItem::loadFile(const char *filename) {
- byte *buffer = BaseFileManager::getEngineInstance()->readWholeFile(filename);
+ char *buffer = (char *)BaseFileManager::getEngineInstance()->readWholeFile(filename);
if (buffer == nullptr) {
_gameRef->LOG(0, "AdItem::LoadFile failed for file '%s'", filename);
return STATUS_FAILED;
@@ -134,7 +134,7 @@ TOKEN_DEF(AMOUNT_STRING)
TOKEN_DEF(AMOUNT)
TOKEN_DEF_END
//////////////////////////////////////////////////////////////////////////
-bool AdItem::loadBuffer(byte *buffer, bool complete) {
+bool AdItem::loadBuffer(char *buffer, bool complete) {
TOKEN_TABLE_START(commands)
TOKEN_TABLE(ITEM)
TOKEN_TABLE(TEMPLATE)
@@ -164,12 +164,12 @@ bool AdItem::loadBuffer(byte *buffer, bool complete) {
TOKEN_TABLE(AMOUNT)
TOKEN_TABLE_END
- byte *params;
+ char *params;
int cmd = 2;
BaseParser parser;
if (complete) {
- if (parser.getCommand((char **)&buffer, commands, (char **)&params) != TOKEN_ITEM) {
+ if (parser.getCommand(&buffer, commands, &params) != TOKEN_ITEM) {
_gameRef->LOG(0, "'ITEM' keyword expected.");
return STATUS_FAILED;
}
@@ -177,31 +177,31 @@ bool AdItem::loadBuffer(byte *buffer, bool complete) {
}
int ar = 0, ag = 0, ab = 0, alpha = 255;
- while (cmd > 0 && (cmd = parser.getCommand((char **)&buffer, commands, (char **)&params)) > 0) {
+ while (cmd > 0 && (cmd = parser.getCommand(&buffer, commands, &params)) > 0) {
switch (cmd) {
case TOKEN_TEMPLATE:
- if (DID_FAIL(loadFile((char *)params))) {
+ if (DID_FAIL(loadFile(params))) {
cmd = PARSERR_GENERIC;
}
break;
case TOKEN_NAME:
- setName((char *)params);
+ setName(params);
break;
case TOKEN_FONT:
- setFont((char *)params);
+ setFont(params);
break;
case TOKEN_CAPTION:
- setCaption((char *)params);
+ setCaption(params);
break;
case TOKEN_IMAGE:
case TOKEN_SPRITE:
delete _sprite;
_sprite = new BaseSprite(_gameRef, this);
- if (!_sprite || DID_FAIL(_sprite->loadFile((char *)params, ((AdGame *)_gameRef)->_texItemLifeTime))) {
+ if (!_sprite || DID_FAIL(_sprite->loadFile(params, ((AdGame *)_gameRef)->_texItemLifeTime))) {
delete _sprite;
cmd = PARSERR_GENERIC;
}
@@ -211,32 +211,32 @@ bool AdItem::loadBuffer(byte *buffer, bool complete) {
case TOKEN_SPRITE_HOVER:
delete _spriteHover;
_spriteHover = new BaseSprite(_gameRef, this);
- if (!_spriteHover || DID_FAIL(_spriteHover->loadFile((char *)params, ((AdGame *)_gameRef)->_texItemLifeTime))) {
+ if (!_spriteHover || DID_FAIL(_spriteHover->loadFile(params, ((AdGame *)_gameRef)->_texItemLifeTime))) {
delete _spriteHover;
cmd = PARSERR_GENERIC;
}
break;
case TOKEN_AMOUNT:
- parser.scanStr((char *)params, "%d", &_amount);
+ parser.scanStr(params, "%d", &_amount);
break;
case TOKEN_DISPLAY_AMOUNT:
- parser.scanStr((char *)params, "%b", &_displayAmount);
+ parser.scanStr(params, "%b", &_displayAmount);
break;
case TOKEN_AMOUNT_OFFSET_X:
- parser.scanStr((char *)params, "%d", &_amountOffsetX);
+ parser.scanStr(params, "%d", &_amountOffsetX);
break;
case TOKEN_AMOUNT_OFFSET_Y:
- parser.scanStr((char *)params, "%d", &_amountOffsetY);
+ parser.scanStr(params, "%d", &_amountOffsetY);
break;
case TOKEN_AMOUNT_ALIGN:
- if (scumm_stricmp((char *)params, "left") == 0) {
+ if (scumm_stricmp(params, "left") == 0) {
_amountAlign = TAL_LEFT;
- } else if (scumm_stricmp((char *)params, "right") == 0) {
+ } else if (scumm_stricmp(params, "right") == 0) {
_amountAlign = TAL_RIGHT;
} else {
_amountAlign = TAL_CENTER;
@@ -244,12 +244,12 @@ bool AdItem::loadBuffer(byte *buffer, bool complete) {
break;
case TOKEN_AMOUNT_STRING:
- BaseUtils::setString(&_amountString, (char *)params);
+ BaseUtils::setString(&_amountString, params);
break;
case TOKEN_TALK: {
BaseSprite *spr = new BaseSprite(_gameRef, this);
- if (!spr || DID_FAIL(spr->loadFile((char *)params, ((AdGame *)_gameRef)->_texTalkLifeTime))) {
+ if (!spr || DID_FAIL(spr->loadFile(params, ((AdGame *)_gameRef)->_texTalkLifeTime))) {
cmd = PARSERR_GENERIC;
} else {
_talkSprites.add(spr);
@@ -259,7 +259,7 @@ bool AdItem::loadBuffer(byte *buffer, bool complete) {
case TOKEN_TALK_SPECIAL: {
BaseSprite *spr = new BaseSprite(_gameRef, this);
- if (!spr || DID_FAIL(spr->loadFile((char *)params, ((AdGame *)_gameRef)->_texTalkLifeTime))) {
+ if (!spr || DID_FAIL(spr->loadFile(params, ((AdGame *)_gameRef)->_texTalkLifeTime))) {
cmd = PARSERR_GENERIC;
} else {
_talkSpritesEx.add(spr);
@@ -270,7 +270,7 @@ bool AdItem::loadBuffer(byte *buffer, bool complete) {
case TOKEN_CURSOR:
delete _cursorNormal;
_cursorNormal = new BaseSprite(_gameRef);
- if (!_cursorNormal || DID_FAIL(_cursorNormal->loadFile((char *)params, ((AdGame *)_gameRef)->_texItemLifeTime))) {
+ if (!_cursorNormal || DID_FAIL(_cursorNormal->loadFile(params, ((AdGame *)_gameRef)->_texItemLifeTime))) {
delete _cursorNormal;
_cursorNormal = nullptr;
cmd = PARSERR_GENERIC;
@@ -280,7 +280,7 @@ bool AdItem::loadBuffer(byte *buffer, bool complete) {
case TOKEN_CURSOR_HOVER:
delete _cursorHover;
_cursorHover = new BaseSprite(_gameRef);
- if (!_cursorHover || DID_FAIL(_cursorHover->loadFile((char *)params, ((AdGame *)_gameRef)->_texItemLifeTime))) {
+ if (!_cursorHover || DID_FAIL(_cursorHover->loadFile(params, ((AdGame *)_gameRef)->_texItemLifeTime))) {
delete _cursorHover;
_cursorHover = nullptr;
cmd = PARSERR_GENERIC;
@@ -288,11 +288,11 @@ bool AdItem::loadBuffer(byte *buffer, bool complete) {
break;
case TOKEN_CURSOR_COMBINED:
- parser.scanStr((char *)params, "%b", &_cursorCombined);
+ parser.scanStr(params, "%b", &_cursorCombined);
break;
case TOKEN_SCRIPT:
- addScript((char *)params);
+ addScript(params);
break;
case TOKEN_PROPERTY:
@@ -300,11 +300,11 @@ bool AdItem::loadBuffer(byte *buffer, bool complete) {
break;
case TOKEN_ALPHA_COLOR:
- parser.scanStr((char *)params, "%d,%d,%d", &ar, &ag, &ab);
+ parser.scanStr(params, "%d,%d,%d", &ar, &ag, &ab);
break;
case TOKEN_ALPHA:
- parser.scanStr((char *)params, "%d", &alpha);
+ parser.scanStr(params, "%d", &alpha);
break;
case TOKEN_EDITOR_PROPERTY:
@@ -783,17 +783,17 @@ bool AdItem::persist(BasePersistenceManager *persistMgr) {
AdTalkHolder::persist(persistMgr);
- persistMgr->transfer(TMEMBER(_cursorCombined));
+ persistMgr->transferBool(TMEMBER(_cursorCombined));
persistMgr->transferPtr(TMEMBER_PTR(_cursorHover));
persistMgr->transferPtr(TMEMBER_PTR(_cursorNormal));
persistMgr->transferPtr(TMEMBER_PTR(_spriteHover));
- persistMgr->transfer(TMEMBER(_inInventory));
- persistMgr->transfer(TMEMBER(_displayAmount));
- persistMgr->transfer(TMEMBER(_amount));
- persistMgr->transfer(TMEMBER(_amountOffsetX));
- persistMgr->transfer(TMEMBER(_amountOffsetY));
- persistMgr->transfer(TMEMBER_INT(_amountAlign));
- persistMgr->transfer(TMEMBER(_amountString));
+ persistMgr->transferBool(TMEMBER(_inInventory));
+ persistMgr->transferBool(TMEMBER(_displayAmount));
+ persistMgr->transferSint32(TMEMBER(_amount));
+ persistMgr->transferSint32(TMEMBER(_amountOffsetX));
+ persistMgr->transferSint32(TMEMBER(_amountOffsetY));
+ persistMgr->transferSint32(TMEMBER_INT(_amountAlign));
+ persistMgr->transferCharPtr(TMEMBER(_amountString));
return STATUS_OK;
}
diff --git a/engines/wintermute/ad/ad_item.h b/engines/wintermute/ad/ad_item.h
index dd7039db43..935ea5d73d 100644
--- a/engines/wintermute/ad/ad_item.h
+++ b/engines/wintermute/ad/ad_item.h
@@ -35,6 +35,8 @@
namespace Wintermute {
class AdItem : public AdTalkHolder {
+ using Wintermute::AdObject::display;
+
public:
bool update();
DECLARE_PERSISTENT(AdItem, AdTalkHolder)
@@ -48,7 +50,7 @@ public:
AdItem(BaseGame *inGame);
virtual ~AdItem();
bool loadFile(const char *filename);
- bool loadBuffer(byte *buffer, bool complete = true);
+ bool loadBuffer(char *buffer, bool complete = true);
// scripting interface
virtual ScValue *scGetProperty(const Common::String &name) override;
diff --git a/engines/wintermute/ad/ad_layer.cpp b/engines/wintermute/ad/ad_layer.cpp
index c833b59163..17dd83a8b7 100644
--- a/engines/wintermute/ad/ad_layer.cpp
+++ b/engines/wintermute/ad/ad_layer.cpp
@@ -62,7 +62,7 @@ AdLayer::~AdLayer() {
//////////////////////////////////////////////////////////////////////////
bool AdLayer::loadFile(const char *filename) {
- byte *buffer = BaseFileManager::getEngineInstance()->readWholeFile(filename);
+ char *buffer = (char *)BaseFileManager::getEngineInstance()->readWholeFile(filename);
if (buffer == nullptr) {
_gameRef->LOG(0, "AdLayer::LoadFile failed for file '%s'", filename);
return STATUS_FAILED;
@@ -100,7 +100,7 @@ TOKEN_DEF(CLOSE_UP)
TOKEN_DEF(EDITOR_PROPERTY)
TOKEN_DEF_END
//////////////////////////////////////////////////////////////////////////
-bool AdLayer::loadBuffer(byte *buffer, bool complete) {
+bool AdLayer::loadBuffer(char *buffer, bool complete) {
TOKEN_TABLE_START(commands)
TOKEN_TABLE(LAYER)
TOKEN_TABLE(TEMPLATE)
@@ -119,52 +119,52 @@ bool AdLayer::loadBuffer(byte *buffer, bool complete) {
TOKEN_TABLE(EDITOR_PROPERTY)
TOKEN_TABLE_END
- byte *params;
+ char *params;
int cmd;
BaseParser parser;
if (complete) {
- if (parser.getCommand((char **)&buffer, commands, (char **)&params) != TOKEN_LAYER) {
+ if (parser.getCommand(&buffer, commands, &params) != TOKEN_LAYER) {
_gameRef->LOG(0, "'LAYER' keyword expected.");
return STATUS_FAILED;
}
buffer = params;
}
- while ((cmd = parser.getCommand((char **)&buffer, commands, (char **)&params)) > 0) {
+ while ((cmd = parser.getCommand(&buffer, commands, &params)) > 0) {
switch (cmd) {
case TOKEN_TEMPLATE:
- if (DID_FAIL(loadFile((char *)params))) {
+ if (DID_FAIL(loadFile(params))) {
cmd = PARSERR_GENERIC;
}
break;
case TOKEN_NAME:
- setName((char *)params);
+ setName(params);
break;
case TOKEN_CAPTION:
- setCaption((char *)params);
+ setCaption(params);
break;
case TOKEN_MAIN:
- parser.scanStr((char *)params, "%b", &_main);
+ parser.scanStr(params, "%b", &_main);
break;
case TOKEN_CLOSE_UP:
- parser.scanStr((char *)params, "%b", &_closeUp);
+ parser.scanStr(params, "%b", &_closeUp);
break;
case TOKEN_WIDTH:
- parser.scanStr((char *)params, "%d", &_width);
+ parser.scanStr(params, "%d", &_width);
break;
case TOKEN_HEIGHT:
- parser.scanStr((char *)params, "%d", &_height);
+ parser.scanStr(params, "%d", &_height);
break;
case TOKEN_ACTIVE:
- parser.scanStr((char *)params, "%b", &_active);
+ parser.scanStr(params, "%b", &_active);
break;
case TOKEN_REGION: {
@@ -203,11 +203,11 @@ bool AdLayer::loadBuffer(byte *buffer, bool complete) {
break;
case TOKEN_EDITOR_SELECTED:
- parser.scanStr((char *)params, "%b", &_editorSelected);
+ parser.scanStr(params, "%b", &_editorSelected);
break;
case TOKEN_SCRIPT:
- addScript((char *)params);
+ addScript(params);
break;
case TOKEN_PROPERTY:
@@ -551,12 +551,12 @@ bool AdLayer::persist(BasePersistenceManager *persistMgr) {
BaseObject::persist(persistMgr);
- persistMgr->transfer(TMEMBER(_active));
- persistMgr->transfer(TMEMBER(_closeUp));
- persistMgr->transfer(TMEMBER(_height));
- persistMgr->transfer(TMEMBER(_main));
+ persistMgr->transferBool(TMEMBER(_active));
+ persistMgr->transferBool(TMEMBER(_closeUp));
+ persistMgr->transferSint32(TMEMBER(_height));
+ persistMgr->transferBool(TMEMBER(_main));
_nodes.persist(persistMgr);
- persistMgr->transfer(TMEMBER(_width));
+ persistMgr->transferSint32(TMEMBER(_width));
return STATUS_OK;
}
diff --git a/engines/wintermute/ad/ad_layer.h b/engines/wintermute/ad/ad_layer.h
index b260b919fd..af7c3a364c 100644
--- a/engines/wintermute/ad/ad_layer.h
+++ b/engines/wintermute/ad/ad_layer.h
@@ -43,7 +43,7 @@ public:
virtual ~AdLayer();
BaseArray<AdSceneNode *> _nodes;
bool loadFile(const char *filename);
- bool loadBuffer(byte *buffer, bool complete = true);
+ bool loadBuffer(char *buffer, bool complete = true);
virtual bool saveAsText(BaseDynamicBuffer *buffer, int indent) override;
// scripting interface
diff --git a/engines/wintermute/ad/ad_node_state.cpp b/engines/wintermute/ad/ad_node_state.cpp
index 876c5a8bb4..dd07f23762 100644
--- a/engines/wintermute/ad/ad_node_state.cpp
+++ b/engines/wintermute/ad/ad_node_state.cpp
@@ -95,13 +95,13 @@ void AdNodeState::setCursor(const char *filename) {
bool AdNodeState::persist(BasePersistenceManager *persistMgr) {
persistMgr->transferPtr(TMEMBER_PTR(_gameRef));
- persistMgr->transfer(TMEMBER(_active));
- persistMgr->transfer(TMEMBER(_name));
- persistMgr->transfer(TMEMBER(_filename));
- persistMgr->transfer(TMEMBER(_cursor));
- persistMgr->transfer(TMEMBER(_alphaColor));
+ persistMgr->transferBool(TMEMBER(_active));
+ persistMgr->transferCharPtr(TMEMBER(_name));
+ persistMgr->transferCharPtr(TMEMBER(_filename));
+ persistMgr->transferCharPtr(TMEMBER(_cursor));
+ persistMgr->transferUint32(TMEMBER(_alphaColor));
for (int i = 0; i < 7; i++) {
- persistMgr->transfer(TMEMBER(_caption[i]));
+ persistMgr->transferCharPtr(TMEMBER(_caption[i]));
}
return STATUS_OK;
diff --git a/engines/wintermute/ad/ad_object.cpp b/engines/wintermute/ad/ad_object.cpp
index 0d5011f92d..3664e0fd8a 100644
--- a/engines/wintermute/ad/ad_object.cpp
+++ b/engines/wintermute/ad/ad_object.cpp
@@ -859,7 +859,7 @@ bool AdObject::setFont(const char *filename) {
//////////////////////////////////////////////////////////////////////////
-int AdObject::getHeight() {
+int32 AdObject::getHeight() {
if (!_currentSprite) {
return 0;
} else {
@@ -1030,30 +1030,30 @@ bool AdObject::reset() {
bool AdObject::persist(BasePersistenceManager *persistMgr) {
BaseObject::persist(persistMgr);
- persistMgr->transfer(TMEMBER(_active));
+ persistMgr->transferBool(TMEMBER(_active));
persistMgr->transferPtr(TMEMBER_PTR(_blockRegion));
persistMgr->transferPtr(TMEMBER_PTR(_currentBlockRegion));
persistMgr->transferPtr(TMEMBER_PTR(_currentWptGroup));
persistMgr->transferPtr(TMEMBER_PTR(_currentSprite));
- persistMgr->transfer(TMEMBER(_drawn));
+ persistMgr->transferBool(TMEMBER(_drawn));
persistMgr->transferPtr(TMEMBER_PTR(_font));
- persistMgr->transfer(TMEMBER(_ignoreItems));
- persistMgr->transfer(TMEMBER_INT(_nextState));
+ persistMgr->transferBool(TMEMBER(_ignoreItems));
+ persistMgr->transferSint32(TMEMBER_INT(_nextState));
persistMgr->transferPtr(TMEMBER_PTR(_sentence));
- persistMgr->transfer(TMEMBER_INT(_state));
+ persistMgr->transferSint32(TMEMBER_INT(_state));
persistMgr->transferPtr(TMEMBER_PTR(_animSprite));
- persistMgr->transfer(TMEMBER(_sceneIndependent));
- persistMgr->transfer(TMEMBER(_forcedTalkAnimName));
- persistMgr->transfer(TMEMBER(_forcedTalkAnimUsed));
+ persistMgr->transferBool(TMEMBER(_sceneIndependent));
+ persistMgr->transferCharPtr(TMEMBER(_forcedTalkAnimName));
+ persistMgr->transferBool(TMEMBER(_forcedTalkAnimUsed));
persistMgr->transferPtr(TMEMBER_PTR(_tempSprite2));
- persistMgr->transfer(TMEMBER_INT(_type));
+ persistMgr->transferSint32(TMEMBER_INT(_type));
persistMgr->transferPtr(TMEMBER_PTR(_wptGroup));
persistMgr->transferPtr(TMEMBER_PTR(_stickRegion));
- persistMgr->transfer(TMEMBER(_subtitlesModRelative));
- persistMgr->transfer(TMEMBER(_subtitlesModX));
- persistMgr->transfer(TMEMBER(_subtitlesModY));
- persistMgr->transfer(TMEMBER(_subtitlesModXCenter));
- persistMgr->transfer(TMEMBER(_subtitlesWidth));
+ persistMgr->transferBool(TMEMBER(_subtitlesModRelative));
+ persistMgr->transferSint32(TMEMBER(_subtitlesModX));
+ persistMgr->transferSint32(TMEMBER(_subtitlesModY));
+ persistMgr->transferBool(TMEMBER(_subtitlesModXCenter));
+ persistMgr->transferSint32(TMEMBER(_subtitlesWidth));
persistMgr->transferPtr(TMEMBER_PTR(_inventory));
persistMgr->transferPtr(TMEMBER_PTR(_partEmitter));
@@ -1065,9 +1065,9 @@ bool AdObject::persist(BasePersistenceManager *persistMgr) {
_attachmentsPost.persist(persistMgr);
persistMgr->transferPtr(TMEMBER_PTR(_registerAlias));
- persistMgr->transfer(TMEMBER(_partFollowParent));
- persistMgr->transfer(TMEMBER(_partOffsetX));
- persistMgr->transfer(TMEMBER(_partOffsetY));
+ persistMgr->transferBool(TMEMBER(_partFollowParent));
+ persistMgr->transferSint32(TMEMBER(_partOffsetX));
+ persistMgr->transferSint32(TMEMBER(_partOffsetY));
return STATUS_OK;
}
diff --git a/engines/wintermute/ad/ad_object.h b/engines/wintermute/ad/ad_object.h
index 9e30f69855..ba984ef8d1 100644
--- a/engines/wintermute/ad/ad_object.h
+++ b/engines/wintermute/ad/ad_object.h
@@ -61,7 +61,7 @@ public:
bool reset();
DECLARE_PERSISTENT(AdObject, BaseObject)
virtual void talk(const char *text, const char *sound = nullptr, uint32 duration = 0, const char *stances = nullptr, TTextAlign align = TAL_CENTER);
- virtual int getHeight() override;
+ virtual int32 getHeight() override;
bool setFont(const char *filename);
virtual bool update() override;
diff --git a/engines/wintermute/ad/ad_path.cpp b/engines/wintermute/ad/ad_path.cpp
index 91a24cbf7d..156fc80958 100644
--- a/engines/wintermute/ad/ad_path.cpp
+++ b/engines/wintermute/ad/ad_path.cpp
@@ -110,9 +110,9 @@ bool AdPath::persist(BasePersistenceManager *persistMgr) {
persistMgr->transferPtr(TMEMBER_PTR(_gameRef));
- persistMgr->transfer(TMEMBER(_currIndex));
+ persistMgr->transferSint32(TMEMBER(_currIndex));
_points.persist(persistMgr);
- persistMgr->transfer(TMEMBER(_ready));
+ persistMgr->transferBool(TMEMBER(_ready));
return STATUS_OK;
}
diff --git a/engines/wintermute/ad/ad_path_point.cpp b/engines/wintermute/ad/ad_path_point.cpp
index d5108ad8c1..5ee9568608 100644
--- a/engines/wintermute/ad/ad_path_point.cpp
+++ b/engines/wintermute/ad/ad_path_point.cpp
@@ -65,8 +65,8 @@ bool AdPathPoint::persist(BasePersistenceManager *persistMgr) {
BasePoint::persist(persistMgr);
- persistMgr->transfer(TMEMBER(_distance));
- persistMgr->transfer(TMEMBER(_marked));
+ persistMgr->transferSint32(TMEMBER(_distance));
+ persistMgr->transferBool(TMEMBER(_marked));
persistMgr->transferPtr(TMEMBER_PTR(_origin));
return STATUS_OK;
diff --git a/engines/wintermute/ad/ad_region.cpp b/engines/wintermute/ad/ad_region.cpp
index bc9ac903c6..2e8e73a1cf 100644
--- a/engines/wintermute/ad/ad_region.cpp
+++ b/engines/wintermute/ad/ad_region.cpp
@@ -69,7 +69,7 @@ bool AdRegion::hasDecoration() const {
//////////////////////////////////////////////////////////////////////////
bool AdRegion::loadFile(const char *filename) {
- byte *buffer = BaseFileManager::getEngineInstance()->readWholeFile(filename);
+ char *buffer = (char *)BaseFileManager::getEngineInstance()->readWholeFile(filename);
if (buffer == nullptr) {
_gameRef->LOG(0, "AdRegion::LoadFile failed for file '%s'", filename);
return STATUS_FAILED;
@@ -110,7 +110,7 @@ TOKEN_DEF(PROPERTY)
TOKEN_DEF(EDITOR_PROPERTY)
TOKEN_DEF_END
//////////////////////////////////////////////////////////////////////////
-bool AdRegion::loadBuffer(byte *buffer, bool complete) {
+bool AdRegion::loadBuffer(char *buffer, bool complete) {
TOKEN_TABLE_START(commands)
TOKEN_TABLE(REGION)
TOKEN_TABLE(TEMPLATE)
@@ -131,12 +131,12 @@ bool AdRegion::loadBuffer(byte *buffer, bool complete) {
TOKEN_TABLE(EDITOR_PROPERTY)
TOKEN_TABLE_END
- byte *params;
+ char *params;
int cmd;
BaseParser parser;
if (complete) {
- if (parser.getCommand((char **)&buffer, commands, (char **)&params) != TOKEN_REGION) {
+ if (parser.getCommand(&buffer, commands, &params) != TOKEN_REGION) {
_gameRef->LOG(0, "'REGION' keyword expected.");
return STATUS_FAILED;
}
@@ -150,67 +150,67 @@ bool AdRegion::loadBuffer(byte *buffer, bool complete) {
int ar = 255, ag = 255, ab = 255, alpha = 255;
- while ((cmd = parser.getCommand((char **)&buffer, commands, (char **)&params)) > 0) {
+ while ((cmd = parser.getCommand(&buffer, commands, &params)) > 0) {
switch (cmd) {
case TOKEN_TEMPLATE:
- if (DID_FAIL(loadFile((char *)params))) {
+ if (DID_FAIL(loadFile(params))) {
cmd = PARSERR_GENERIC;
}
break;
case TOKEN_NAME:
- setName((char *)params);
+ setName(params);
break;
case TOKEN_CAPTION:
- setCaption((char *)params);
+ setCaption(params);
break;
case TOKEN_ACTIVE:
- parser.scanStr((char *)params, "%b", &_active);
+ parser.scanStr(params, "%b", &_active);
break;
case TOKEN_BLOCKED:
- parser.scanStr((char *)params, "%b", &_blocked);
+ parser.scanStr(params, "%b", &_blocked);
break;
case TOKEN_DECORATION:
- parser.scanStr((char *)params, "%b", &_decoration);
+ parser.scanStr(params, "%b", &_decoration);
break;
case TOKEN_ZOOM:
case TOKEN_SCALE: {
int j;
- parser.scanStr((char *)params, "%d", &j);
+ parser.scanStr(params, "%d", &j);
_zoom = (float)j;
}
break;
case TOKEN_POINT: {
int x, y;
- parser.scanStr((char *)params, "%d,%d", &x, &y);
+ parser.scanStr(params, "%d,%d", &x, &y);
_points.add(new BasePoint(x, y));
}
break;
case TOKEN_ALPHA_COLOR:
- parser.scanStr((char *)params, "%d,%d,%d", &ar, &ag, &ab);
+ parser.scanStr(params, "%d,%d,%d", &ar, &ag, &ab);
break;
case TOKEN_ALPHA:
- parser.scanStr((char *)params, "%d", &alpha);
+ parser.scanStr(params, "%d", &alpha);
break;
case TOKEN_EDITOR_SELECTED:
- parser.scanStr((char *)params, "%b", &_editorSelected);
+ parser.scanStr(params, "%b", &_editorSelected);
break;
case TOKEN_EDITOR_SELECTED_POINT:
- parser.scanStr((char *)params, "%d", &_editorSelectedPoint);
+ parser.scanStr(params, "%d", &_editorSelectedPoint);
break;
case TOKEN_SCRIPT:
- addScript((char *)params);
+ addScript(params);
break;
case TOKEN_PROPERTY:
@@ -401,9 +401,9 @@ bool AdRegion::saveAsText(BaseDynamicBuffer *buffer, int indent) {
bool AdRegion::persist(BasePersistenceManager *persistMgr) {
BaseRegion::persist(persistMgr);
- persistMgr->transfer(TMEMBER(_alpha));
- persistMgr->transfer(TMEMBER(_blocked));
- persistMgr->transfer(TMEMBER(_decoration));
+ persistMgr->transferUint32(TMEMBER(_alpha));
+ persistMgr->transferBool(TMEMBER(_blocked));
+ persistMgr->transferBool(TMEMBER(_decoration));
persistMgr->transferFloat(TMEMBER(_zoom));
return STATUS_OK;
diff --git a/engines/wintermute/ad/ad_region.h b/engines/wintermute/ad/ad_region.h
index 637c742c9c..f3674dcbfb 100644
--- a/engines/wintermute/ad/ad_region.h
+++ b/engines/wintermute/ad/ad_region.h
@@ -40,7 +40,7 @@ public:
AdRegion(BaseGame *inGame);
virtual ~AdRegion();
bool loadFile(const char *filename);
- bool loadBuffer(byte *buffer, bool complete = true);
+ bool loadBuffer(char *buffer, bool complete = true);
virtual bool saveAsText(BaseDynamicBuffer *buffer, int indent) override;
bool hasDecoration() const;
diff --git a/engines/wintermute/ad/ad_response.cpp b/engines/wintermute/ad/ad_response.cpp
index fa05224b06..e7b4188de6 100644
--- a/engines/wintermute/ad/ad_response.cpp
+++ b/engines/wintermute/ad/ad_response.cpp
@@ -134,10 +134,10 @@ bool AdResponse::persist(BasePersistenceManager *persistMgr) {
persistMgr->transferPtr(TMEMBER_PTR(_icon));
persistMgr->transferPtr(TMEMBER_PTR(_iconHover));
persistMgr->transferPtr(TMEMBER_PTR(_iconPressed));
- persistMgr->transfer(TMEMBER(_iD));
- persistMgr->transfer(TMEMBER(_text));
- persistMgr->transfer(TMEMBER(_textOrig));
- persistMgr->transfer(TMEMBER_INT(_responseType));
+ persistMgr->transferSint32(TMEMBER(_iD));
+ persistMgr->transferCharPtr(TMEMBER(_text));
+ persistMgr->transferCharPtr(TMEMBER(_textOrig));
+ persistMgr->transferSint32(TMEMBER_INT(_responseType));
persistMgr->transferPtr(TMEMBER_PTR(_font));
return STATUS_OK;
diff --git a/engines/wintermute/ad/ad_response_box.cpp b/engines/wintermute/ad/ad_response_box.cpp
index 9d7c17ac74..f2e986cbdc 100644
--- a/engines/wintermute/ad/ad_response_box.cpp
+++ b/engines/wintermute/ad/ad_response_box.cpp
@@ -58,7 +58,7 @@ AdResponseBox::AdResponseBox(BaseGame *inGame) : BaseObject(inGame) {
_shieldWindow = new UIWindow(_gameRef);
_horizontal = false;
- BasePlatform::setRectEmpty(&_responseArea);
+ _responseArea.setEmpty();
_scrollOffset = 0;
_spacing = 0;
@@ -121,12 +121,12 @@ void AdResponseBox::clearButtons() {
//////////////////////////////////////////////////////////////////////////
bool AdResponseBox::invalidateButtons() {
for (uint32 i = 0; i < _respButtons.size(); i++) {
- _respButtons[i]->_image = nullptr;
- _respButtons[i]->_cursor = nullptr;
- _respButtons[i]->_font = nullptr;
- _respButtons[i]->_fontHover = nullptr;
- _respButtons[i]->_fontPress = nullptr;
+ _respButtons[i]->setImage(nullptr);
+ _respButtons[i]->setFont(nullptr);
_respButtons[i]->setText("");
+ _respButtons[i]->_cursor = nullptr;
+ _respButtons[i]->setFontHover(nullptr);
+ _respButtons[i]->setFontPress(nullptr);
}
return STATUS_OK;
}
@@ -141,16 +141,17 @@ bool AdResponseBox::createButtons() {
UIButton *btn = new UIButton(_gameRef);
if (btn) {
btn->_parent = _window;
- btn->_sharedFonts = btn->_sharedImages = true;
+ btn->setSharedFonts(true);
+ btn->setSharedImages(true);
btn->_sharedCursors = true;
// iconic
if (_responses[i]->getIcon()) {
- btn->_image = _responses[i]->getIcon();
+ btn->setImage(_responses[i]->getIcon());
if (_responses[i]->getIconHover()) {
- btn->_imageHover = _responses[i]->getIconHover();
+ btn->setImageHover(_responses[i]->getIconHover());
}
if (_responses[i]->getIconPressed()) {
- btn->_imagePress = _responses[i]->getIconPressed();
+ btn->setImagePress(_responses[i]->getIconPressed());
}
btn->setCaption(_responses[i]->getText());
@@ -163,23 +164,30 @@ bool AdResponseBox::createButtons() {
// textual
else {
btn->setText(_responses[i]->getText());
- btn->_font = (_font == nullptr) ? _gameRef->getSystemFont() : _font;
- btn->_fontHover = (_fontHover == nullptr) ? _gameRef->getSystemFont() : _fontHover;
- btn->_fontPress = btn->_fontHover;
- btn->_align = _align;
+ if (_font == nullptr) {
+ btn->setFont(_gameRef->getSystemFont());
+ } else {
+ btn->setFont(_font);
+ }
+ btn->setFontHover((_fontHover == nullptr) ? _gameRef->getSystemFont() : _fontHover);
+ btn->setFontPress(btn->getFontHover());
+ btn->setTextAlign(_align);
if (_gameRef->_touchInterface) {
- btn->_fontHover = btn->_font;
+ btn->setFontHover(btn->getFont());
}
if (_responses[i]->getFont()) {
- btn->_font = _responses[i]->getFont();
+ btn->setFont(_responses[i]->getFont());
}
- btn->_width = _responseArea.right - _responseArea.left;
- if (btn->_width <= 0) {
- btn->_width = _gameRef->_renderer->getWidth();
+ int width = _responseArea.right - _responseArea.left;
+
+ if (width <= 0) {
+ btn->setWidth(_gameRef->_renderer->getWidth());
+ } else {
+ btn->setWidth(width);
}
}
btn->setName("response");
@@ -187,17 +195,17 @@ bool AdResponseBox::createButtons() {
// make the responses touchable
if (_gameRef->_touchInterface) {
- btn->_height = MAX<int32>(btn->_height, 50);
+ btn->setHeight(MAX<int32>(btn->getHeight(), 50));
}
//btn->SetListener(this, btn, _responses[i]->_iD);
btn->setListener(this, btn, i);
- btn->_visible = false;
+ btn->setVisible(false);
_respButtons.add(btn);
- if (_responseArea.bottom - _responseArea.top < btn->_height) {
+ if (_responseArea.bottom - _responseArea.top < btn->getHeight()) {
_gameRef->LOG(0, "Warning: Response '%s' is too high to be displayed within response box. Correcting.", _responses[i]->getText());
- _responseArea.bottom += (btn->_height - (_responseArea.bottom - _responseArea.top));
+ _responseArea.bottom += (btn->getHeight() - (_responseArea.bottom - _responseArea.top));
}
}
}
@@ -209,7 +217,7 @@ bool AdResponseBox::createButtons() {
//////////////////////////////////////////////////////////////////////////
bool AdResponseBox::loadFile(const char *filename) {
- byte *buffer = BaseFileManager::getEngineInstance()->readWholeFile(filename);
+ char *buffer = (char *)BaseFileManager::getEngineInstance()->readWholeFile(filename);
if (buffer == nullptr) {
_gameRef->LOG(0, "AdResponseBox::LoadFile failed for file '%s'", filename);
return STATUS_FAILED;
@@ -245,7 +253,7 @@ TOKEN_DEF(VERTICAL_ALIGN)
TOKEN_DEF(EDITOR_PROPERTY)
TOKEN_DEF_END
//////////////////////////////////////////////////////////////////////////
-bool AdResponseBox::loadBuffer(byte *buffer, bool complete) {
+bool AdResponseBox::loadBuffer(char *buffer, bool complete) {
TOKEN_TABLE_START(commands)
TOKEN_TABLE(RESPONSE_BOX)
TOKEN_TABLE(TEMPLATE)
@@ -262,22 +270,22 @@ bool AdResponseBox::loadBuffer(byte *buffer, bool complete) {
TOKEN_TABLE_END
- byte *params;
+ char *params;
int cmd;
BaseParser parser;
if (complete) {
- if (parser.getCommand((char **)&buffer, commands, (char **)&params) != TOKEN_RESPONSE_BOX) {
+ if (parser.getCommand(&buffer, commands, &params) != TOKEN_RESPONSE_BOX) {
_gameRef->LOG(0, "'RESPONSE_BOX' keyword expected.");
return STATUS_FAILED;
}
buffer = params;
}
- while ((cmd = parser.getCommand((char **)&buffer, commands, (char **)&params)) > 0) {
+ while ((cmd = parser.getCommand(&buffer, commands, &params)) > 0) {
switch (cmd) {
case TOKEN_TEMPLATE:
- if (DID_FAIL(loadFile((char *)params))) {
+ if (DID_FAIL(loadFile(params))) {
cmd = PARSERR_GENERIC;
}
break;
@@ -298,7 +306,7 @@ bool AdResponseBox::loadBuffer(byte *buffer, bool complete) {
if (_font) {
_gameRef->_fontStorage->removeFont(_font);
}
- _font = _gameRef->_fontStorage->addFont((char *)params);
+ _font = _gameRef->_fontStorage->addFont(params);
if (!_font) {
cmd = PARSERR_GENERIC;
}
@@ -308,24 +316,24 @@ bool AdResponseBox::loadBuffer(byte *buffer, bool complete) {
if (_fontHover) {
_gameRef->_fontStorage->removeFont(_fontHover);
}
- _fontHover = _gameRef->_fontStorage->addFont((char *)params);
+ _fontHover = _gameRef->_fontStorage->addFont(params);
if (!_fontHover) {
cmd = PARSERR_GENERIC;
}
break;
case TOKEN_AREA:
- parser.scanStr((char *)params, "%d,%d,%d,%d", &_responseArea.left, &_responseArea.top, &_responseArea.right, &_responseArea.bottom);
+ parser.scanStr(params, "%d,%d,%d,%d", &_responseArea.left, &_responseArea.top, &_responseArea.right, &_responseArea.bottom);
break;
case TOKEN_HORIZONTAL:
- parser.scanStr((char *)params, "%b", &_horizontal);
+ parser.scanStr(params, "%b", &_horizontal);
break;
case TOKEN_TEXT_ALIGN:
- if (scumm_stricmp((char *)params, "center") == 0) {
+ if (scumm_stricmp(params, "center") == 0) {
_align = TAL_CENTER;
- } else if (scumm_stricmp((char *)params, "right") == 0) {
+ } else if (scumm_stricmp(params, "right") == 0) {
_align = TAL_RIGHT;
} else {
_align = TAL_LEFT;
@@ -333,9 +341,9 @@ bool AdResponseBox::loadBuffer(byte *buffer, bool complete) {
break;
case TOKEN_VERTICAL_ALIGN:
- if (scumm_stricmp((char *)params, "top") == 0) {
+ if (scumm_stricmp(params, "top") == 0) {
_verticalAlign = VAL_TOP;
- } else if (scumm_stricmp((char *)params, "center") == 0) {
+ } else if (scumm_stricmp(params, "center") == 0) {
_verticalAlign = VAL_CENTER;
} else {
_verticalAlign = VAL_BOTTOM;
@@ -343,7 +351,7 @@ bool AdResponseBox::loadBuffer(byte *buffer, bool complete) {
break;
case TOKEN_SPACING:
- parser.scanStr((char *)params, "%d", &_spacing);
+ parser.scanStr(params, "%d", &_spacing);
break;
case TOKEN_EDITOR_PROPERTY:
@@ -353,7 +361,7 @@ bool AdResponseBox::loadBuffer(byte *buffer, bool complete) {
case TOKEN_CURSOR:
delete _cursor;
_cursor = new BaseSprite(_gameRef);
- if (!_cursor || DID_FAIL(_cursor->loadFile((char *)params))) {
+ if (!_cursor || DID_FAIL(_cursor->loadFile(params))) {
delete _cursor;
_cursor = nullptr;
cmd = PARSERR_GENERIC;
@@ -368,7 +376,7 @@ bool AdResponseBox::loadBuffer(byte *buffer, bool complete) {
if (_window) {
for (uint32 i = 0; i < _window->_widgets.size(); i++) {
- if (!_window->_widgets[i]->_listenerObject) {
+ if (!_window->_widgets[i]->getListener()) {
_window->_widgets[i]->setListener(this, _window->_widgets[i], 0);
}
}
@@ -461,7 +469,7 @@ bool AdResponseBox::display() {
if (!_horizontal) {
int totalHeight = 0;
for (i = 0; i < _respButtons.size(); i++) {
- totalHeight += (_respButtons[i]->_height + _spacing);
+ totalHeight += (_respButtons[i]->getHeight() + _spacing);
}
totalHeight -= _spacing;
@@ -487,22 +495,22 @@ bool AdResponseBox::display() {
// prepare response buttons
bool scrollNeeded = false;
for (i = _scrollOffset; i < _respButtons.size(); i++) {
- if ((_horizontal && xxx + _respButtons[i]->_width > rect.right)
- || (!_horizontal && yyy + _respButtons[i]->_height > rect.bottom)) {
+ if ((_horizontal && xxx + _respButtons[i]->getWidth() > rect.right)
+ || (!_horizontal && yyy + _respButtons[i]->getHeight() > rect.bottom)) {
scrollNeeded = true;
- _respButtons[i]->_visible = false;
+ _respButtons[i]->setVisible(false);
break;
}
- _respButtons[i]->_visible = true;
+ _respButtons[i]->setVisible(true);
_respButtons[i]->_posX = xxx;
_respButtons[i]->_posY = yyy;
if (_horizontal) {
- xxx += (_respButtons[i]->_width + _spacing);
+ xxx += (_respButtons[i]->getWidth() + _spacing);
} else {
- yyy += (_respButtons[i]->_height + _spacing);
+ yyy += (_respButtons[i]->getHeight() + _spacing);
}
}
@@ -515,8 +523,8 @@ bool AdResponseBox::display() {
// go exclusive
if (_shieldWindow) {
_shieldWindow->_posX = _shieldWindow->_posY = 0;
- _shieldWindow->_width = _gameRef->_renderer->getWidth();
- _shieldWindow->_height = _gameRef->_renderer->getHeight();
+ _shieldWindow->setWidth(_gameRef->_renderer->getWidth());
+ _shieldWindow->setHeight(_gameRef->_renderer->getHeight());
_shieldWindow->display();
}
@@ -575,20 +583,20 @@ bool AdResponseBox::persist(BasePersistenceManager *persistMgr) {
persistMgr->transferPtr(TMEMBER_PTR(_font));
persistMgr->transferPtr(TMEMBER_PTR(_fontHover));
- persistMgr->transfer(TMEMBER(_horizontal));
- persistMgr->transfer(TMEMBER(_lastResponseText));
- persistMgr->transfer(TMEMBER(_lastResponseTextOrig));
+ persistMgr->transferBool(TMEMBER(_horizontal));
+ persistMgr->transferCharPtr(TMEMBER(_lastResponseText));
+ persistMgr->transferCharPtr(TMEMBER(_lastResponseTextOrig));
_respButtons.persist(persistMgr);
- persistMgr->transfer(TMEMBER(_responseArea));
+ persistMgr->transferRect32(TMEMBER(_responseArea));
_responses.persist(persistMgr);
- persistMgr->transfer(TMEMBER(_scrollOffset));
+ persistMgr->transferSint32(TMEMBER(_scrollOffset));
persistMgr->transferPtr(TMEMBER_PTR(_shieldWindow));
- persistMgr->transfer(TMEMBER(_spacing));
+ persistMgr->transferSint32(TMEMBER(_spacing));
persistMgr->transferPtr(TMEMBER_PTR(_waitingScript));
persistMgr->transferPtr(TMEMBER_PTR(_window));
- persistMgr->transfer(TMEMBER_INT(_verticalAlign));
- persistMgr->transfer(TMEMBER_INT(_align));
+ persistMgr->transferSint32(TMEMBER_INT(_verticalAlign));
+ persistMgr->transferSint32(TMEMBER_INT(_align));
return STATUS_OK;
}
diff --git a/engines/wintermute/ad/ad_response_box.h b/engines/wintermute/ad/ad_response_box.h
index 7598e8b569..9469bfda43 100644
--- a/engines/wintermute/ad/ad_response_box.h
+++ b/engines/wintermute/ad/ad_response_box.h
@@ -72,7 +72,7 @@ public:
virtual ~AdResponseBox();
bool loadFile(const char *filename);
- bool loadBuffer(byte *buffer, bool complete = true);
+ bool loadBuffer(char *buffer, bool complete = true);
virtual bool saveAsText(BaseDynamicBuffer *buffer, int indent) override;
UIWindow *getResponseWindow();
diff --git a/engines/wintermute/ad/ad_response_context.cpp b/engines/wintermute/ad/ad_response_context.cpp
index 0b58f5ba0c..44b43a6077 100644
--- a/engines/wintermute/ad/ad_response_context.cpp
+++ b/engines/wintermute/ad/ad_response_context.cpp
@@ -50,8 +50,8 @@ AdResponseContext::~AdResponseContext() {
//////////////////////////////////////////////////////////////////////////
bool AdResponseContext::persist(BasePersistenceManager *persistMgr) {
persistMgr->transferPtr(TMEMBER_PTR(_gameRef));
- persistMgr->transfer(TMEMBER(_context));
- persistMgr->transfer(TMEMBER(_id));
+ persistMgr->transferCharPtr(TMEMBER(_context));
+ persistMgr->transferSint32(TMEMBER(_id));
return STATUS_OK;
}
diff --git a/engines/wintermute/ad/ad_rot_level.cpp b/engines/wintermute/ad/ad_rot_level.cpp
index d925b0d57a..b5bdc8ebe9 100644
--- a/engines/wintermute/ad/ad_rot_level.cpp
+++ b/engines/wintermute/ad/ad_rot_level.cpp
@@ -53,7 +53,7 @@ AdRotLevel::~AdRotLevel() {
//////////////////////////////////////////////////////////////////////////
bool AdRotLevel::loadFile(const char *filename) {
- byte *buffer = BaseFileManager::getEngineInstance()->readWholeFile(filename);
+ char *buffer = (char *)BaseFileManager::getEngineInstance()->readWholeFile(filename);
if (buffer == nullptr) {
_gameRef->LOG(0, "AdRotLevel::LoadFile failed for file '%s'", filename);
return STATUS_FAILED;
@@ -82,7 +82,7 @@ TOKEN_DEF(ROTATION)
TOKEN_DEF(EDITOR_PROPERTY)
TOKEN_DEF_END
//////////////////////////////////////////////////////////////////////////
-bool AdRotLevel::loadBuffer(byte *buffer, bool complete) {
+bool AdRotLevel::loadBuffer(char *buffer, bool complete) {
TOKEN_TABLE_START(commands)
TOKEN_TABLE(ROTATION_LEVEL)
TOKEN_TABLE(TEMPLATE)
@@ -91,33 +91,33 @@ bool AdRotLevel::loadBuffer(byte *buffer, bool complete) {
TOKEN_TABLE(EDITOR_PROPERTY)
TOKEN_TABLE_END
- byte *params;
+ char *params;
int cmd;
BaseParser parser;
if (complete) {
- if (parser.getCommand((char **)&buffer, commands, (char **)&params) != TOKEN_ROTATION_LEVEL) {
+ if (parser.getCommand(&buffer, commands, &params) != TOKEN_ROTATION_LEVEL) {
_gameRef->LOG(0, "'ROTATION_LEVEL' keyword expected.");
return STATUS_FAILED;
}
buffer = params;
}
- while ((cmd = parser.getCommand((char **)&buffer, commands, (char **)&params)) > 0) {
+ while ((cmd = parser.getCommand(&buffer, commands, &params)) > 0) {
switch (cmd) {
case TOKEN_TEMPLATE:
- if (DID_FAIL(loadFile((char *)params))) {
+ if (DID_FAIL(loadFile(params))) {
cmd = PARSERR_GENERIC;
}
break;
case TOKEN_X:
- parser.scanStr((char *)params, "%d", &_posX);
+ parser.scanStr(params, "%d", &_posX);
break;
case TOKEN_ROTATION: {
int i;
- parser.scanStr((char *)params, "%d", &i);
+ parser.scanStr(params, "%d", &i);
_rotation = (float)i;
}
break;
diff --git a/engines/wintermute/ad/ad_rot_level.h b/engines/wintermute/ad/ad_rot_level.h
index fe2d1691cd..47c621845a 100644
--- a/engines/wintermute/ad/ad_rot_level.h
+++ b/engines/wintermute/ad/ad_rot_level.h
@@ -42,7 +42,7 @@ public:
float getRotation() const { return _rotation; }
virtual bool saveAsText(BaseDynamicBuffer *buffer, int indent) override;
bool loadFile(const char *filename);
- bool loadBuffer(byte *buffer, bool complete = true);
+ bool loadBuffer(char *buffer, bool complete = true);
};
} // End of namespace Wintermute
diff --git a/engines/wintermute/ad/ad_scale_level.cpp b/engines/wintermute/ad/ad_scale_level.cpp
index 59e6d57787..aa7f6f89cf 100644
--- a/engines/wintermute/ad/ad_scale_level.cpp
+++ b/engines/wintermute/ad/ad_scale_level.cpp
@@ -54,7 +54,7 @@ float AdScaleLevel::getScale() const {
//////////////////////////////////////////////////////////////////////////
bool AdScaleLevel::loadFile(const char *filename) {
- byte *buffer = BaseFileManager::getEngineInstance()->readWholeFile(filename);
+ char *buffer = (char *)BaseFileManager::getEngineInstance()->readWholeFile(filename);
if (buffer == nullptr) {
_gameRef->LOG(0, "AdScaleLevel::LoadFile failed for file '%s'", filename);
return STATUS_FAILED;
@@ -83,7 +83,7 @@ TOKEN_DEF(SCALE)
TOKEN_DEF(EDITOR_PROPERTY)
TOKEN_DEF_END
//////////////////////////////////////////////////////////////////////////
-bool AdScaleLevel::loadBuffer(byte *buffer, bool complete) {
+bool AdScaleLevel::loadBuffer(char *buffer, bool complete) {
TOKEN_TABLE_START(commands)
TOKEN_TABLE(SCALE_LEVEL)
TOKEN_TABLE(TEMPLATE)
@@ -92,33 +92,33 @@ bool AdScaleLevel::loadBuffer(byte *buffer, bool complete) {
TOKEN_TABLE(EDITOR_PROPERTY)
TOKEN_TABLE_END
- byte *params;
+ char *params;
int cmd;
BaseParser parser;
if (complete) {
- if (parser.getCommand((char **)&buffer, commands, (char **)&params) != TOKEN_SCALE_LEVEL) {
+ if (parser.getCommand(&buffer, commands, &params) != TOKEN_SCALE_LEVEL) {
_gameRef->LOG(0, "'SCALE_LEVEL' keyword expected.");
return STATUS_FAILED;
}
buffer = params;
}
- while ((cmd = parser.getCommand((char **)&buffer, commands, (char **)&params)) > 0) {
+ while ((cmd = parser.getCommand(&buffer, commands, &params)) > 0) {
switch (cmd) {
case TOKEN_TEMPLATE:
- if (DID_FAIL(loadFile((char *)params))) {
+ if (DID_FAIL(loadFile(params))) {
cmd = PARSERR_GENERIC;
}
break;
case TOKEN_Y:
- parser.scanStr((char *)params, "%d", &_posY);
+ parser.scanStr(params, "%d", &_posY);
break;
case TOKEN_SCALE: {
int i;
- parser.scanStr((char *)params, "%d", &i);
+ parser.scanStr(params, "%d", &i);
_scale = (float)i;
}
break;
diff --git a/engines/wintermute/ad/ad_scale_level.h b/engines/wintermute/ad/ad_scale_level.h
index b2dd7aa91f..768e79bbf7 100644
--- a/engines/wintermute/ad/ad_scale_level.h
+++ b/engines/wintermute/ad/ad_scale_level.h
@@ -41,7 +41,7 @@ public:
virtual ~AdScaleLevel();
virtual bool saveAsText(BaseDynamicBuffer *buffer, int indent) override;
bool loadFile(const char *filename);
- bool loadBuffer(byte *buffer, bool complete = true);
+ bool loadBuffer(char *buffer, bool complete = true);
float getScale() const;
private:
float _scale;
diff --git a/engines/wintermute/ad/ad_scene.cpp b/engines/wintermute/ad/ad_scene.cpp
index 668b39853b..ab7ab51f30 100644
--- a/engines/wintermute/ad/ad_scene.cpp
+++ b/engines/wintermute/ad/ad_scene.cpp
@@ -538,7 +538,7 @@ bool AdScene::initLoop() {
//////////////////////////////////////////////////////////////////////////
bool AdScene::loadFile(const char *filename) {
- byte *buffer = BaseFileManager::getEngineInstance()->readWholeFile(filename);
+ char *buffer = (char *)BaseFileManager::getEngineInstance()->readWholeFile(filename);
if (buffer == nullptr) {
_gameRef->LOG(0, "AdScene::LoadFile failed for file '%s'", filename);
return STATUS_FAILED;
@@ -600,7 +600,7 @@ TOKEN_DEF(PERSISTENT_STATE)
TOKEN_DEF(EDITOR_PROPERTY)
TOKEN_DEF_END
//////////////////////////////////////////////////////////////////////////
-bool AdScene::loadBuffer(byte *buffer, bool complete) {
+bool AdScene::loadBuffer(char *buffer, bool complete) {
TOKEN_TABLE_START(commands)
TOKEN_TABLE(SCENE)
TOKEN_TABLE(TEMPLATE)
@@ -643,12 +643,12 @@ bool AdScene::loadBuffer(byte *buffer, bool complete) {
cleanup();
- byte *params;
+ char *params;
int cmd;
BaseParser parser;
if (complete) {
- if (parser.getCommand((char **)&buffer, commands, (char **)&params) != TOKEN_SCENE) {
+ if (parser.getCommand(&buffer, commands, &params) != TOKEN_SCENE) {
_gameRef->LOG(0, "'SCENE' keyword expected.");
return STATUS_FAILED;
}
@@ -659,20 +659,20 @@ bool AdScene::loadBuffer(byte *buffer, bool complete) {
char camera[MAX_PATH_LENGTH] = "";
/* float waypointHeight = -1.0f; */
- while ((cmd = parser.getCommand((char **)&buffer, commands, (char **)&params)) > 0) {
+ while ((cmd = parser.getCommand(&buffer, commands, &params)) > 0) {
switch (cmd) {
case TOKEN_TEMPLATE:
- if (DID_FAIL(loadFile((char *)params))) {
+ if (DID_FAIL(loadFile(params))) {
cmd = PARSERR_GENERIC;
}
break;
case TOKEN_NAME:
- setName((char *)params);
+ setName(params);
break;
case TOKEN_CAPTION:
- setCaption((char *)params);
+ setCaption(params);
break;
case TOKEN_LAYER: {
@@ -747,7 +747,7 @@ bool AdScene::loadBuffer(byte *buffer, bool complete) {
case TOKEN_CURSOR:
delete _cursor;
_cursor = new BaseSprite(_gameRef);
- if (!_cursor || DID_FAIL(_cursor->loadFile((char *)params))) {
+ if (!_cursor || DID_FAIL(_cursor->loadFile(params))) {
delete _cursor;
_cursor = nullptr;
cmd = PARSERR_GENERIC;
@@ -755,99 +755,99 @@ bool AdScene::loadBuffer(byte *buffer, bool complete) {
break;
case TOKEN_CAMERA:
- Common::strlcpy(camera, (char *)params, MAX_PATH_LENGTH);
+ Common::strlcpy(camera, params, MAX_PATH_LENGTH);
break;
case TOKEN_EDITOR_MARGIN_H:
- parser.scanStr((char *)params, "%d", &_editorMarginH);
+ parser.scanStr(params, "%d", &_editorMarginH);
break;
case TOKEN_EDITOR_MARGIN_V:
- parser.scanStr((char *)params, "%d", &_editorMarginV);
+ parser.scanStr(params, "%d", &_editorMarginV);
break;
case TOKEN_EDITOR_COLOR_FRAME:
- parser.scanStr((char *)params, "%d,%d,%d,%d", &ar, &ag, &ab, &aa);
+ parser.scanStr(params, "%d,%d,%d,%d", &ar, &ag, &ab, &aa);
_editorColFrame = BYTETORGBA(ar, ag, ab, aa);
break;
case TOKEN_EDITOR_COLOR_ENTITY:
- parser.scanStr((char *)params, "%d,%d,%d,%d", &ar, &ag, &ab, &aa);
+ parser.scanStr(params, "%d,%d,%d,%d", &ar, &ag, &ab, &aa);
_editorColEntity = BYTETORGBA(ar, ag, ab, aa);
break;
case TOKEN_EDITOR_COLOR_ENTITY_SEL:
- parser.scanStr((char *)params, "%d,%d,%d,%d", &ar, &ag, &ab, &aa);
+ parser.scanStr(params, "%d,%d,%d,%d", &ar, &ag, &ab, &aa);
_editorColEntitySel = BYTETORGBA(ar, ag, ab, aa);
break;
case TOKEN_EDITOR_COLOR_REGION_SEL:
- parser.scanStr((char *)params, "%d,%d,%d,%d", &ar, &ag, &ab, &aa);
+ parser.scanStr(params, "%d,%d,%d,%d", &ar, &ag, &ab, &aa);
_editorColRegionSel = BYTETORGBA(ar, ag, ab, aa);
break;
case TOKEN_EDITOR_COLOR_DECORATION_SEL:
- parser.scanStr((char *)params, "%d,%d,%d,%d", &ar, &ag, &ab, &aa);
+ parser.scanStr(params, "%d,%d,%d,%d", &ar, &ag, &ab, &aa);
_editorColDecorSel = BYTETORGBA(ar, ag, ab, aa);
break;
case TOKEN_EDITOR_COLOR_BLOCKED_SEL:
- parser.scanStr((char *)params, "%d,%d,%d,%d", &ar, &ag, &ab, &aa);
+ parser.scanStr(params, "%d,%d,%d,%d", &ar, &ag, &ab, &aa);
_editorColBlockedSel = BYTETORGBA(ar, ag, ab, aa);
break;
case TOKEN_EDITOR_COLOR_WAYPOINTS_SEL:
- parser.scanStr((char *)params, "%d,%d,%d,%d", &ar, &ag, &ab, &aa);
+ parser.scanStr(params, "%d,%d,%d,%d", &ar, &ag, &ab, &aa);
_editorColWaypointsSel = BYTETORGBA(ar, ag, ab, aa);
break;
case TOKEN_EDITOR_COLOR_REGION:
- parser.scanStr((char *)params, "%d,%d,%d,%d", &ar, &ag, &ab, &aa);
+ parser.scanStr(params, "%d,%d,%d,%d", &ar, &ag, &ab, &aa);
_editorColRegion = BYTETORGBA(ar, ag, ab, aa);
break;
case TOKEN_EDITOR_COLOR_DECORATION:
- parser.scanStr((char *)params, "%d,%d,%d,%d", &ar, &ag, &ab, &aa);
+ parser.scanStr(params, "%d,%d,%d,%d", &ar, &ag, &ab, &aa);
_editorColDecor = BYTETORGBA(ar, ag, ab, aa);
break;
case TOKEN_EDITOR_COLOR_BLOCKED:
- parser.scanStr((char *)params, "%d,%d,%d,%d", &ar, &ag, &ab, &aa);
+ parser.scanStr(params, "%d,%d,%d,%d", &ar, &ag, &ab, &aa);
_editorColBlocked = BYTETORGBA(ar, ag, ab, aa);
break;
case TOKEN_EDITOR_COLOR_WAYPOINTS:
- parser.scanStr((char *)params, "%d,%d,%d,%d", &ar, &ag, &ab, &aa);
+ parser.scanStr(params, "%d,%d,%d,%d", &ar, &ag, &ab, &aa);
_editorColWaypoints = BYTETORGBA(ar, ag, ab, aa);
break;
case TOKEN_EDITOR_COLOR_SCALE:
- parser.scanStr((char *)params, "%d,%d,%d,%d", &ar, &ag, &ab, &aa);
+ parser.scanStr(params, "%d,%d,%d,%d", &ar, &ag, &ab, &aa);
_editorColScale = BYTETORGBA(ar, ag, ab, aa);
break;
case TOKEN_EDITOR_SHOW_REGIONS:
- parser.scanStr((char *)params, "%b", &_editorShowRegions);
+ parser.scanStr(params, "%b", &_editorShowRegions);
break;
case TOKEN_EDITOR_SHOW_BLOCKED:
- parser.scanStr((char *)params, "%b", &_editorShowBlocked);
+ parser.scanStr(params, "%b", &_editorShowBlocked);
break;
case TOKEN_EDITOR_SHOW_DECORATION:
- parser.scanStr((char *)params, "%b", &_editorShowDecor);
+ parser.scanStr(params, "%b", &_editorShowDecor);
break;
case TOKEN_EDITOR_SHOW_ENTITIES:
- parser.scanStr((char *)params, "%b", &_editorShowEntities);
+ parser.scanStr(params, "%b", &_editorShowEntities);
break;
case TOKEN_EDITOR_SHOW_SCALE:
- parser.scanStr((char *)params, "%b", &_editorShowScale);
+ parser.scanStr(params, "%b", &_editorShowScale);
break;
case TOKEN_SCRIPT:
- addScript((char *)params);
+ addScript(params);
break;
case TOKEN_PROPERTY:
@@ -856,7 +856,7 @@ bool AdScene::loadBuffer(byte *buffer, bool complete) {
case TOKEN_VIEWPORT: {
Rect32 rc;
- parser.scanStr((char *)params, "%d,%d,%d,%d", &rc.left, &rc.top, &rc.right, &rc.bottom);
+ parser.scanStr(params, "%d,%d,%d,%d", &rc.left, &rc.top, &rc.right, &rc.bottom);
if (!_viewport) {
_viewport = new BaseViewport(_gameRef);
}
@@ -864,13 +864,14 @@ bool AdScene::loadBuffer(byte *buffer, bool complete) {
_viewport->setRect(rc.left, rc.top, rc.right, rc.bottom, true);
}
}
+ break;
case TOKEN_PERSISTENT_STATE:
- parser.scanStr((char *)params, "%b", &_persistentState);
+ parser.scanStr(params, "%b", &_persistentState);
break;
case TOKEN_PERSISTENT_STATE_SPRITES:
- parser.scanStr((char *)params, "%b", &_persistentStateSprites);
+ parser.scanStr(params, "%b", &_persistentStateSprites);
break;
case TOKEN_EDITOR_PROPERTY:
@@ -1014,8 +1015,8 @@ bool AdScene::traverseNodes(bool doUpdate) {
}
if (_shieldWindow) {
_shieldWindow->_posX = _shieldWindow->_posY = 0;
- _shieldWindow->_width = _gameRef->_renderer->getWidth();
- _shieldWindow->_height = _gameRef->_renderer->getHeight();
+ _shieldWindow->setWidth(_gameRef->_renderer->getWidth());
+ _shieldWindow->setHeight(_gameRef->_renderer->getHeight());
_shieldWindow->display();
}
}
@@ -2299,58 +2300,58 @@ float AdScene::getScaleAt(int Y) {
bool AdScene::persist(BasePersistenceManager *persistMgr) {
BaseObject::persist(persistMgr);
- persistMgr->transfer(TMEMBER(_autoScroll));
- persistMgr->transfer(TMEMBER(_editorColBlocked));
- persistMgr->transfer(TMEMBER(_editorColBlockedSel));
- persistMgr->transfer(TMEMBER(_editorColDecor));
- persistMgr->transfer(TMEMBER(_editorColDecorSel));
- persistMgr->transfer(TMEMBER(_editorColEntity));
- persistMgr->transfer(TMEMBER(_editorColEntitySel));
- persistMgr->transfer(TMEMBER(_editorColFrame));
- persistMgr->transfer(TMEMBER(_editorColRegion));
- persistMgr->transfer(TMEMBER(_editorColRegionSel));
- persistMgr->transfer(TMEMBER(_editorColScale));
- persistMgr->transfer(TMEMBER(_editorColWaypoints));
- persistMgr->transfer(TMEMBER(_editorColWaypointsSel));
- persistMgr->transfer(TMEMBER(_editorMarginH));
- persistMgr->transfer(TMEMBER(_editorMarginV));
- persistMgr->transfer(TMEMBER(_editorShowBlocked));
- persistMgr->transfer(TMEMBER(_editorShowDecor));
- persistMgr->transfer(TMEMBER(_editorShowEntities));
- persistMgr->transfer(TMEMBER(_editorShowRegions));
- persistMgr->transfer(TMEMBER(_editorShowScale));
+ persistMgr->transferBool(TMEMBER(_autoScroll));
+ persistMgr->transferUint32(TMEMBER(_editorColBlocked));
+ persistMgr->transferUint32(TMEMBER(_editorColBlockedSel));
+ persistMgr->transferUint32(TMEMBER(_editorColDecor));
+ persistMgr->transferUint32(TMEMBER(_editorColDecorSel));
+ persistMgr->transferUint32(TMEMBER(_editorColEntity));
+ persistMgr->transferUint32(TMEMBER(_editorColEntitySel));
+ persistMgr->transferUint32(TMEMBER(_editorColFrame));
+ persistMgr->transferUint32(TMEMBER(_editorColRegion));
+ persistMgr->transferUint32(TMEMBER(_editorColRegionSel));
+ persistMgr->transferUint32(TMEMBER(_editorColScale));
+ persistMgr->transferUint32(TMEMBER(_editorColWaypoints));
+ persistMgr->transferUint32(TMEMBER(_editorColWaypointsSel));
+ persistMgr->transferSint32(TMEMBER(_editorMarginH));
+ persistMgr->transferSint32(TMEMBER(_editorMarginV));
+ persistMgr->transferBool(TMEMBER(_editorShowBlocked));
+ persistMgr->transferBool(TMEMBER(_editorShowDecor));
+ persistMgr->transferBool(TMEMBER(_editorShowEntities));
+ persistMgr->transferBool(TMEMBER(_editorShowRegions));
+ persistMgr->transferBool(TMEMBER(_editorShowScale));
persistMgr->transferPtr(TMEMBER_PTR(_fader));
- persistMgr->transfer(TMEMBER(_height));
- persistMgr->transfer(TMEMBER(_initialized));
- persistMgr->transfer(TMEMBER(_lastTimeH));
- persistMgr->transfer(TMEMBER(_lastTimeV));
+ persistMgr->transferSint32(TMEMBER(_height));
+ persistMgr->transferBool(TMEMBER(_initialized));
+ persistMgr->transferUint32(TMEMBER(_lastTimeH));
+ persistMgr->transferUint32(TMEMBER(_lastTimeV));
_layers.persist(persistMgr);
persistMgr->transferPtr(TMEMBER_PTR(_mainLayer));
_objects.persist(persistMgr);
- persistMgr->transfer(TMEMBER(_offsetLeft));
- persistMgr->transfer(TMEMBER(_offsetTop));
- persistMgr->transfer(TMEMBER(_paralaxScrolling));
- persistMgr->transfer(TMEMBER(_persistentState));
- persistMgr->transfer(TMEMBER(_persistentStateSprites));
- persistMgr->transfer(TMEMBER(_pfMaxTime));
+ persistMgr->transferSint32(TMEMBER(_offsetLeft));
+ persistMgr->transferSint32(TMEMBER(_offsetTop));
+ persistMgr->transferBool(TMEMBER(_paralaxScrolling));
+ persistMgr->transferBool(TMEMBER(_persistentState));
+ persistMgr->transferBool(TMEMBER(_persistentStateSprites));
+ persistMgr->transferUint32(TMEMBER(_pfMaxTime));
_pfPath.persist(persistMgr);
- persistMgr->transfer(TMEMBER(_pfPointsNum));
- persistMgr->transfer(TMEMBER(_pfReady));
+ persistMgr->transferSint32(TMEMBER(_pfPointsNum));
+ persistMgr->transferBool(TMEMBER(_pfReady));
persistMgr->transferPtr(TMEMBER_PTR(_pfRequester));
persistMgr->transferPtr(TMEMBER_PTR(_pfTarget));
persistMgr->transferPtr(TMEMBER_PTR(_pfTargetPath));
_rotLevels.persist(persistMgr);
_scaleLevels.persist(persistMgr);
- persistMgr->transfer(TMEMBER(_scrollPixelsH));
- persistMgr->transfer(TMEMBER(_scrollPixelsV));
- persistMgr->transfer(TMEMBER(_scrollTimeH));
- persistMgr->transfer(TMEMBER(_scrollTimeV));
+ persistMgr->transferSint32(TMEMBER(_scrollPixelsH));
+ persistMgr->transferSint32(TMEMBER(_scrollPixelsV));
+ persistMgr->transferUint32(TMEMBER(_scrollTimeH));
+ persistMgr->transferUint32(TMEMBER(_scrollTimeV));
persistMgr->transferPtr(TMEMBER_PTR(_shieldWindow));
- persistMgr->transfer(TMEMBER(_targetOffsetLeft));
- persistMgr->transfer(TMEMBER(_targetOffsetTop));
+ persistMgr->transferSint32(TMEMBER(_targetOffsetLeft));
+ persistMgr->transferSint32(TMEMBER(_targetOffsetTop));
_waypointGroups.persist(persistMgr);
persistMgr->transferPtr(TMEMBER_PTR(_viewport));
- persistMgr->transfer(TMEMBER(_width));
+ persistMgr->transferSint32(TMEMBER(_width));
return STATUS_OK;
}
diff --git a/engines/wintermute/ad/ad_scene.h b/engines/wintermute/ad/ad_scene.h
index 5beb10e546..1f35a776b5 100644
--- a/engines/wintermute/ad/ad_scene.h
+++ b/engines/wintermute/ad/ad_scene.h
@@ -124,7 +124,7 @@ public:
BaseArray<AdObject *> _objects;
BaseArray<AdWaypointGroup *> _waypointGroups;
bool loadFile(const char *filename);
- bool loadBuffer(byte *buffer, bool complete = true);
+ bool loadBuffer(char *buffer, bool complete = true);
int32 _width;
int32 _height;
bool addObject(AdObject *Object);
diff --git a/engines/wintermute/ad/ad_scene_node.cpp b/engines/wintermute/ad/ad_scene_node.cpp
index 8548da91db..5f6207c23a 100644
--- a/engines/wintermute/ad/ad_scene_node.cpp
+++ b/engines/wintermute/ad/ad_scene_node.cpp
@@ -74,7 +74,7 @@ bool AdSceneNode::persist(BasePersistenceManager *persistMgr) {
persistMgr->transferPtr(TMEMBER_PTR(_entity));
persistMgr->transferPtr(TMEMBER_PTR(_region));
- persistMgr->transfer(TMEMBER_INT(_type));
+ persistMgr->transferSint32(TMEMBER_INT(_type));
return STATUS_OK;
}
diff --git a/engines/wintermute/ad/ad_scene_state.cpp b/engines/wintermute/ad/ad_scene_state.cpp
index 58cb5f514a..a4218751c3 100644
--- a/engines/wintermute/ad/ad_scene_state.cpp
+++ b/engines/wintermute/ad/ad_scene_state.cpp
@@ -56,7 +56,7 @@ AdSceneState::~AdSceneState() {
//////////////////////////////////////////////////////////////////////////
bool AdSceneState::persist(BasePersistenceManager *persistMgr) {
- persistMgr->transfer(TMEMBER(_filename));
+ persistMgr->transferCharPtr(TMEMBER(_filename));
_nodeStates.persist(persistMgr);
return STATUS_OK;
diff --git a/engines/wintermute/ad/ad_sentence.cpp b/engines/wintermute/ad/ad_sentence.cpp
index d5baa8291f..21ffac5aaf 100644
--- a/engines/wintermute/ad/ad_sentence.cpp
+++ b/engines/wintermute/ad/ad_sentence.cpp
@@ -249,23 +249,23 @@ bool AdSentence::persist(BasePersistenceManager *persistMgr) {
persistMgr->transferPtr(TMEMBER_PTR(_gameRef));
- persistMgr->transfer(TMEMBER_INT(_align));
- persistMgr->transfer(TMEMBER(_currentStance));
+ persistMgr->transferSint32(TMEMBER_INT(_align));
+ persistMgr->transferSint32(TMEMBER(_currentStance));
persistMgr->transferPtr(TMEMBER_PTR(_currentSprite));
- persistMgr->transfer(TMEMBER(_currentSkelAnim));
- persistMgr->transfer(TMEMBER(_duration));
+ persistMgr->transferCharPtr(TMEMBER(_currentSkelAnim));
+ persistMgr->transferUint32(TMEMBER(_duration));
persistMgr->transferPtr(TMEMBER_PTR(_font));
- persistMgr->transfer(TMEMBER(_pos));
+ persistMgr->transferPoint32(TMEMBER(_pos));
persistMgr->transferPtr(TMEMBER_PTR(_sound));
- persistMgr->transfer(TMEMBER(_soundStarted));
- persistMgr->transfer(TMEMBER(_stances));
- persistMgr->transfer(TMEMBER(_startTime));
+ persistMgr->transferBool(TMEMBER(_soundStarted));
+ persistMgr->transferCharPtr(TMEMBER(_stances));
+ persistMgr->transferUint32(TMEMBER(_startTime));
persistMgr->transferPtr(TMEMBER_PTR(_talkDef));
- persistMgr->transfer(TMEMBER(_tempStance));
- persistMgr->transfer(TMEMBER(_text));
- persistMgr->transfer(TMEMBER(_width));
- persistMgr->transfer(TMEMBER(_fixedPos));
- persistMgr->transfer(TMEMBER(_freezable));
+ persistMgr->transferCharPtr(TMEMBER(_tempStance));
+ persistMgr->transferCharPtr(TMEMBER(_text));
+ persistMgr->transferSint32(TMEMBER(_width));
+ persistMgr->transferBool(TMEMBER(_fixedPos));
+ persistMgr->transferBool(TMEMBER(_freezable));
return STATUS_OK;
}
diff --git a/engines/wintermute/ad/ad_sprite_set.cpp b/engines/wintermute/ad/ad_sprite_set.cpp
index 9eb3bd0686..dd920492de 100644
--- a/engines/wintermute/ad/ad_sprite_set.cpp
+++ b/engines/wintermute/ad/ad_sprite_set.cpp
@@ -60,7 +60,7 @@ AdSpriteSet::~AdSpriteSet() {
//////////////////////////////////////////////////////////////////////////
bool AdSpriteSet::loadFile(const char *filename, int lifeTime, TSpriteCacheType cacheType) {
- byte *buffer = BaseFileManager::getEngineInstance()->readWholeFile(filename);
+ char *buffer = (char *)BaseFileManager::getEngineInstance()->readWholeFile(filename);
if (buffer == nullptr) {
_gameRef->LOG(0, "AdSpriteSet::LoadFile failed for file '%s'", filename);
return STATUS_FAILED;
@@ -93,7 +93,7 @@ TOKEN_DEF(TEMPLATE)
TOKEN_DEF(EDITOR_PROPERTY)
TOKEN_DEF_END
//////////////////////////////////////////////////////////////////////////
-bool AdSpriteSet::loadBuffer(byte *buffer, bool complete, int lifeTime, TSpriteCacheType cacheType) {
+bool AdSpriteSet::loadBuffer(char *buffer, bool complete, int lifeTime, TSpriteCacheType cacheType) {
TOKEN_TABLE_START(commands)
TOKEN_TABLE(SPRITESET)
TOKEN_TABLE(NAME)
@@ -109,12 +109,12 @@ bool AdSpriteSet::loadBuffer(byte *buffer, bool complete, int lifeTime, TSpriteC
TOKEN_TABLE(EDITOR_PROPERTY)
TOKEN_TABLE_END
- byte *params;
+ char *params;
int cmd;
BaseParser parser;
if (complete) {
- if (parser.getCommand((char **)&buffer, commands, (char **)&params) != TOKEN_SPRITESET) {
+ if (parser.getCommand(&buffer, commands, &params) != TOKEN_SPRITESET) {
_gameRef->LOG(0, "'SPRITESET' keyword expected.");
return STATUS_FAILED;
}
@@ -122,23 +122,23 @@ bool AdSpriteSet::loadBuffer(byte *buffer, bool complete, int lifeTime, TSpriteC
}
BaseSprite *spr = nullptr;
- while ((cmd = parser.getCommand((char **)&buffer, commands, (char **)&params)) > 0) {
+ while ((cmd = parser.getCommand(&buffer, commands, &params)) > 0) {
switch (cmd) {
case TOKEN_TEMPLATE:
- if (DID_FAIL(loadFile((char *)params, lifeTime, cacheType))) {
+ if (DID_FAIL(loadFile(params, lifeTime, cacheType))) {
cmd = PARSERR_GENERIC;
}
break;
case TOKEN_NAME:
- setName((char *)params);
+ setName(params);
break;
case TOKEN_LEFT:
delete _sprites[DI_LEFT];
_sprites[DI_LEFT] = nullptr;
spr = new BaseSprite(_gameRef, _owner);
- if (!spr || DID_FAIL(spr->loadFile((char *)params, lifeTime, cacheType))) {
+ if (!spr || DID_FAIL(spr->loadFile(params, lifeTime, cacheType))) {
cmd = PARSERR_GENERIC;
} else {
_sprites[DI_LEFT] = spr;
@@ -149,7 +149,7 @@ bool AdSpriteSet::loadBuffer(byte *buffer, bool complete, int lifeTime, TSpriteC
delete _sprites[DI_RIGHT];
_sprites[DI_RIGHT] = nullptr;
spr = new BaseSprite(_gameRef, _owner);
- if (!spr || DID_FAIL(spr->loadFile((char *)params, lifeTime, cacheType))) {
+ if (!spr || DID_FAIL(spr->loadFile(params, lifeTime, cacheType))) {
cmd = PARSERR_GENERIC;
} else {
_sprites[DI_RIGHT] = spr;
@@ -160,7 +160,7 @@ bool AdSpriteSet::loadBuffer(byte *buffer, bool complete, int lifeTime, TSpriteC
delete _sprites[DI_UP];
_sprites[DI_UP] = nullptr;
spr = new BaseSprite(_gameRef, _owner);
- if (!spr || DID_FAIL(spr->loadFile((char *)params, lifeTime, cacheType))) {
+ if (!spr || DID_FAIL(spr->loadFile(params, lifeTime, cacheType))) {
cmd = PARSERR_GENERIC;
} else {
_sprites[DI_UP] = spr;
@@ -171,7 +171,7 @@ bool AdSpriteSet::loadBuffer(byte *buffer, bool complete, int lifeTime, TSpriteC
delete _sprites[DI_DOWN];
_sprites[DI_DOWN] = nullptr;
spr = new BaseSprite(_gameRef, _owner);
- if (!spr || DID_FAIL(spr->loadFile((char *)params, lifeTime, cacheType))) {
+ if (!spr || DID_FAIL(spr->loadFile(params, lifeTime, cacheType))) {
cmd = PARSERR_GENERIC;
} else {
_sprites[DI_DOWN] = spr;
@@ -182,7 +182,7 @@ bool AdSpriteSet::loadBuffer(byte *buffer, bool complete, int lifeTime, TSpriteC
delete _sprites[DI_UPLEFT];
_sprites[DI_UPLEFT] = nullptr;
spr = new BaseSprite(_gameRef, _owner);
- if (!spr || DID_FAIL(spr->loadFile((char *)params, lifeTime, cacheType))) {
+ if (!spr || DID_FAIL(spr->loadFile(params, lifeTime, cacheType))) {
cmd = PARSERR_GENERIC;
} else {
_sprites[DI_UPLEFT] = spr;
@@ -193,7 +193,7 @@ bool AdSpriteSet::loadBuffer(byte *buffer, bool complete, int lifeTime, TSpriteC
delete _sprites[DI_UPRIGHT];
_sprites[DI_UPRIGHT] = nullptr;
spr = new BaseSprite(_gameRef, _owner);
- if (!spr || DID_FAIL(spr->loadFile((char *)params, lifeTime, cacheType))) {
+ if (!spr || DID_FAIL(spr->loadFile(params, lifeTime, cacheType))) {
cmd = PARSERR_GENERIC;
} else {
_sprites[DI_UPRIGHT] = spr;
@@ -204,7 +204,7 @@ bool AdSpriteSet::loadBuffer(byte *buffer, bool complete, int lifeTime, TSpriteC
delete _sprites[DI_DOWNLEFT];
_sprites[DI_DOWNLEFT] = nullptr;
spr = new BaseSprite(_gameRef, _owner);
- if (!spr || DID_FAIL(spr->loadFile((char *)params, lifeTime, cacheType))) {
+ if (!spr || DID_FAIL(spr->loadFile(params, lifeTime, cacheType))) {
cmd = PARSERR_GENERIC;
} else {
_sprites[DI_DOWNLEFT] = spr;
@@ -215,7 +215,7 @@ bool AdSpriteSet::loadBuffer(byte *buffer, bool complete, int lifeTime, TSpriteC
delete _sprites[DI_DOWNRIGHT];
_sprites[DI_DOWNRIGHT] = nullptr;
spr = new BaseSprite(_gameRef, _owner);
- if (!spr || DID_FAIL(spr->loadFile((char *)params, lifeTime, cacheType))) {
+ if (!spr || DID_FAIL(spr->loadFile(params, lifeTime, cacheType))) {
cmd = PARSERR_GENERIC;
} else {
_sprites[DI_DOWNRIGHT] = spr;
diff --git a/engines/wintermute/ad/ad_sprite_set.h b/engines/wintermute/ad/ad_sprite_set.h
index ef5ef3a94f..ece71f7adb 100644
--- a/engines/wintermute/ad/ad_sprite_set.h
+++ b/engines/wintermute/ad/ad_sprite_set.h
@@ -44,7 +44,7 @@ public:
AdSpriteSet(BaseGame *inGame, BaseObject *owner = nullptr);
virtual ~AdSpriteSet();
bool loadFile(const char *filename, int lifeTime = -1, TSpriteCacheType cacheType = CACHE_ALL);
- bool loadBuffer(byte *buffer, bool complete = true, int lifeTime = -1, TSpriteCacheType cacheType = CACHE_ALL);
+ bool loadBuffer(char *buffer, bool complete = true, int lifeTime = -1, TSpriteCacheType cacheType = CACHE_ALL);
BaseSprite *_sprites[NUM_DIRECTIONS];
};
diff --git a/engines/wintermute/ad/ad_talk_def.cpp b/engines/wintermute/ad/ad_talk_def.cpp
index f10a0e2fb9..22e3d7b4cc 100644
--- a/engines/wintermute/ad/ad_talk_def.cpp
+++ b/engines/wintermute/ad/ad_talk_def.cpp
@@ -71,7 +71,7 @@ AdTalkDef::~AdTalkDef() {
//////////////////////////////////////////////////////////////////////////
bool AdTalkDef::loadFile(const char *filename) {
- byte *buffer = BaseFileManager::getEngineInstance()->readWholeFile(filename);
+ char *buffer = (char *)BaseFileManager::getEngineInstance()->readWholeFile(filename);
if (buffer == nullptr) {
_gameRef->LOG(0, "AdTalkDef::LoadFile failed for file '%s'", filename);
return STATUS_FAILED;
@@ -101,7 +101,7 @@ TOKEN_DEF(DEFAULT_SPRITE)
TOKEN_DEF(EDITOR_PROPERTY)
TOKEN_DEF_END
//////////////////////////////////////////////////////////////////////////
-bool AdTalkDef::loadBuffer(byte *buffer, bool complete) {
+bool AdTalkDef::loadBuffer(char *buffer, bool complete) {
TOKEN_TABLE_START(commands)
TOKEN_TABLE(TALK)
TOKEN_TABLE(TEMPLATE)
@@ -112,22 +112,22 @@ bool AdTalkDef::loadBuffer(byte *buffer, bool complete) {
TOKEN_TABLE(EDITOR_PROPERTY)
TOKEN_TABLE_END
- byte *params;
+ char *params;
int cmd;
BaseParser parser;
if (complete) {
- if (parser.getCommand((char **)&buffer, commands, (char **)&params) != TOKEN_TALK) {
+ if (parser.getCommand(&buffer, commands, &params) != TOKEN_TALK) {
_gameRef->LOG(0, "'TALK' keyword expected.");
return STATUS_FAILED;
}
buffer = params;
}
- while ((cmd = parser.getCommand((char **)&buffer, commands, (char **)&params)) > 0) {
+ while ((cmd = parser.getCommand(&buffer, commands, &params)) > 0) {
switch (cmd) {
case TOKEN_TEMPLATE:
- if (DID_FAIL(loadFile((char *)params))) {
+ if (DID_FAIL(loadFile(params))) {
cmd = PARSERR_GENERIC;
}
break;
@@ -145,11 +145,11 @@ bool AdTalkDef::loadBuffer(byte *buffer, bool complete) {
break;
case TOKEN_DEFAULT_SPRITE:
- BaseUtils::setString(&_defaultSpriteFilename, (char *)params);
+ BaseUtils::setString(&_defaultSpriteFilename, params);
break;
case TOKEN_DEFAULT_SPRITESET_FILE:
- BaseUtils::setString(&_defaultSpriteSetFilename, (char *)params);
+ BaseUtils::setString(&_defaultSpriteSetFilename, params);
break;
case TOKEN_DEFAULT_SPRITESET: {
@@ -209,9 +209,9 @@ bool AdTalkDef::persist(BasePersistenceManager *persistMgr) {
BaseObject::persist(persistMgr);
persistMgr->transferPtr(TMEMBER_PTR(_defaultSprite));
- persistMgr->transfer(TMEMBER(_defaultSpriteFilename));
+ persistMgr->transferCharPtr(TMEMBER(_defaultSpriteFilename));
persistMgr->transferPtr(TMEMBER_PTR(_defaultSpriteSet));
- persistMgr->transfer(TMEMBER(_defaultSpriteSetFilename));
+ persistMgr->transferCharPtr(TMEMBER(_defaultSpriteSetFilename));
_nodes.persist(persistMgr);
diff --git a/engines/wintermute/ad/ad_talk_def.h b/engines/wintermute/ad/ad_talk_def.h
index 726eefbe4c..5711906b4b 100644
--- a/engines/wintermute/ad/ad_talk_def.h
+++ b/engines/wintermute/ad/ad_talk_def.h
@@ -46,7 +46,7 @@ public:
AdTalkDef(BaseGame *inGame);
virtual ~AdTalkDef();
bool loadFile(const char *filename);
- bool loadBuffer(byte *buffer, bool complete = true);
+ bool loadBuffer(char *buffer, bool complete = true);
BaseArray<AdTalkNode *> _nodes;
char *_defaultSpriteFilename;
BaseSprite *_defaultSprite;
diff --git a/engines/wintermute/ad/ad_talk_node.cpp b/engines/wintermute/ad/ad_talk_node.cpp
index ce86dccd8e..6c0d2e1f06 100644
--- a/engines/wintermute/ad/ad_talk_node.cpp
+++ b/engines/wintermute/ad/ad_talk_node.cpp
@@ -79,7 +79,7 @@ TOKEN_DEF(PRECACHE)
TOKEN_DEF(EDITOR_PROPERTY)
TOKEN_DEF_END
//////////////////////////////////////////////////////////////////////////
-bool AdTalkNode::loadBuffer(byte *buffer, bool complete) {
+bool AdTalkNode::loadBuffer(char *buffer, bool complete) {
TOKEN_TABLE_START(commands)
TOKEN_TABLE(ACTION)
TOKEN_TABLE(SPRITESET_FILE)
@@ -92,12 +92,12 @@ bool AdTalkNode::loadBuffer(byte *buffer, bool complete) {
TOKEN_TABLE(EDITOR_PROPERTY)
TOKEN_TABLE_END
- byte *params;
+ char *params;
int cmd;
BaseParser parser;
if (complete) {
- if (parser.getCommand((char **)&buffer, commands, (char **)&params) != TOKEN_ACTION) {
+ if (parser.getCommand(&buffer, commands, &params) != TOKEN_ACTION) {
_gameRef->LOG(0, "'ACTION' keyword expected.");
return STATUS_FAILED;
}
@@ -108,14 +108,14 @@ bool AdTalkNode::loadBuffer(byte *buffer, bool complete) {
_playToEnd = false;
_preCache = false;
- while ((cmd = parser.getCommand((char **)&buffer, commands, (char **)&params)) > 0) {
+ while ((cmd = parser.getCommand(&buffer, commands, &params)) > 0) {
switch (cmd) {
case TOKEN_SPRITE:
- BaseUtils::setString(&_spriteFilename, (char *)params);
+ BaseUtils::setString(&_spriteFilename, params);
break;
case TOKEN_SPRITESET_FILE:
- BaseUtils::setString(&_spriteSetFilename, (char *)params);
+ BaseUtils::setString(&_spriteSetFilename, params);
break;
case TOKEN_SPRITESET: {
@@ -130,20 +130,20 @@ bool AdTalkNode::loadBuffer(byte *buffer, bool complete) {
break;
case TOKEN_START_TIME:
- parser.scanStr((char *)params, "%d", &_startTime);
+ parser.scanStr(params, "%d", &_startTime);
break;
case TOKEN_END_TIME:
- parser.scanStr((char *)params, "%d", &_endTime);
+ parser.scanStr(params, "%d", &_endTime);
break;
case TOKEN_PRECACHE:
- parser.scanStr((char *)params, "%b", &_preCache);
+ parser.scanStr(params, "%b", &_preCache);
break;
case TOKEN_COMMENT:
if (_gameRef->_editorMode) {
- BaseUtils::setString(&_comment, (char *)params);
+ BaseUtils::setString(&_comment, params);
}
break;
@@ -191,14 +191,14 @@ bool AdTalkNode::loadBuffer(byte *buffer, bool complete) {
//////////////////////////////////////////////////////////////////////////
bool AdTalkNode::persist(BasePersistenceManager *persistMgr) {
- persistMgr->transfer(TMEMBER(_comment));
- persistMgr->transfer(TMEMBER(_startTime));
- persistMgr->transfer(TMEMBER(_endTime));
- persistMgr->transfer(TMEMBER(_playToEnd));
+ persistMgr->transferCharPtr(TMEMBER(_comment));
+ persistMgr->transferUint32(TMEMBER(_startTime));
+ persistMgr->transferUint32(TMEMBER(_endTime));
+ persistMgr->transferBool(TMEMBER(_playToEnd));
persistMgr->transferPtr(TMEMBER_PTR(_sprite));
- persistMgr->transfer(TMEMBER(_spriteFilename));
+ persistMgr->transferCharPtr(TMEMBER(_spriteFilename));
persistMgr->transferPtr(TMEMBER_PTR(_spriteSet));
- persistMgr->transfer(TMEMBER(_spriteSetFilename));
+ persistMgr->transferCharPtr(TMEMBER(_spriteSetFilename));
return STATUS_OK;
}
diff --git a/engines/wintermute/ad/ad_talk_node.h b/engines/wintermute/ad/ad_talk_node.h
index 01dfb6b4ff..7a014b2d9f 100644
--- a/engines/wintermute/ad/ad_talk_node.h
+++ b/engines/wintermute/ad/ad_talk_node.h
@@ -46,7 +46,7 @@ public:
AdTalkNode(BaseGame *inGame);
virtual ~AdTalkNode();
- bool loadBuffer(byte *buffer, bool complete = true);
+ bool loadBuffer(char *buffer, bool complete = true);
virtual bool saveAsText(BaseDynamicBuffer *buffer, int indent = 0) override;
char *_spriteFilename;
BaseSprite *_sprite;
diff --git a/engines/wintermute/ad/ad_waypoint_group.cpp b/engines/wintermute/ad/ad_waypoint_group.cpp
index cc7982cb9d..ae6b18e266 100644
--- a/engines/wintermute/ad/ad_waypoint_group.cpp
+++ b/engines/wintermute/ad/ad_waypoint_group.cpp
@@ -66,7 +66,7 @@ void AdWaypointGroup::cleanup() {
//////////////////////////////////////////////////////////////////////////
bool AdWaypointGroup::loadFile(const char *filename) {
- byte *buffer = BaseFileManager::getEngineInstance()->readWholeFile(filename);
+ char *buffer = (char *)BaseFileManager::getEngineInstance()->readWholeFile(filename);
if (buffer == nullptr) {
_gameRef->LOG(0, "AdWaypointGroup::LoadFile failed for file '%s'", filename);
return STATUS_FAILED;
@@ -98,7 +98,7 @@ TOKEN_DEF(PROPERTY)
TOKEN_DEF(EDITOR_PROPERTY)
TOKEN_DEF_END
//////////////////////////////////////////////////////////////////////////
-bool AdWaypointGroup::loadBuffer(byte *buffer, bool complete) {
+bool AdWaypointGroup::loadBuffer(char *buffer, bool complete) {
TOKEN_TABLE_START(commands)
TOKEN_TABLE(WAYPOINTS)
TOKEN_TABLE(TEMPLATE)
@@ -110,43 +110,43 @@ bool AdWaypointGroup::loadBuffer(byte *buffer, bool complete) {
TOKEN_TABLE(EDITOR_PROPERTY)
TOKEN_TABLE_END
- byte *params;
+ char *params;
int cmd;
BaseParser parser;
if (complete) {
- if (parser.getCommand((char **)&buffer, commands, (char **)&params) != TOKEN_WAYPOINTS) {
+ if (parser.getCommand(&buffer, commands, &params) != TOKEN_WAYPOINTS) {
_gameRef->LOG(0, "'WAYPOINTS' keyword expected.");
return STATUS_FAILED;
}
buffer = params;
}
- while ((cmd = parser.getCommand((char **)&buffer, commands, (char **)&params)) > 0) {
+ while ((cmd = parser.getCommand(&buffer, commands, &params)) > 0) {
switch (cmd) {
case TOKEN_TEMPLATE:
- if (DID_FAIL(loadFile((char *)params))) {
+ if (DID_FAIL(loadFile(params))) {
cmd = PARSERR_GENERIC;
}
break;
case TOKEN_NAME:
- setName((char *)params);
+ setName(params);
break;
case TOKEN_POINT: {
int x, y;
- parser.scanStr((char *)params, "%d,%d", &x, &y);
+ parser.scanStr(params, "%d,%d", &x, &y);
_points.add(new BasePoint(x, y));
}
break;
case TOKEN_EDITOR_SELECTED:
- parser.scanStr((char *)params, "%b", &_editorSelected);
+ parser.scanStr(params, "%b", &_editorSelected);
break;
case TOKEN_EDITOR_SELECTED_POINT:
- parser.scanStr((char *)params, "%d", &_editorSelectedPoint);
+ parser.scanStr(params, "%d", &_editorSelectedPoint);
break;
case TOKEN_PROPERTY:
@@ -194,11 +194,11 @@ bool AdWaypointGroup::persist(BasePersistenceManager *persistMgr) {
BaseObject::persist(persistMgr);
- persistMgr->transfer(TMEMBER(_active));
- persistMgr->transfer(TMEMBER(_editorSelectedPoint));
+ persistMgr->transferBool(TMEMBER(_active));
+ persistMgr->transferSint32(TMEMBER(_editorSelectedPoint));
persistMgr->transferFloat(TMEMBER(_lastMimicScale));
- persistMgr->transfer(TMEMBER(_lastMimicX));
- persistMgr->transfer(TMEMBER(_lastMimicY));
+ persistMgr->transferSint32(TMEMBER(_lastMimicX));
+ persistMgr->transferSint32(TMEMBER(_lastMimicY));
_points.persist(persistMgr);
return STATUS_OK;
diff --git a/engines/wintermute/ad/ad_waypoint_group.h b/engines/wintermute/ad/ad_waypoint_group.h
index af97a21290..47fd611be6 100644
--- a/engines/wintermute/ad/ad_waypoint_group.h
+++ b/engines/wintermute/ad/ad_waypoint_group.h
@@ -41,7 +41,7 @@ public:
virtual bool saveAsText(BaseDynamicBuffer *buffer, int indent) override;
AdWaypointGroup(BaseGame *inGame);
bool loadFile(const char *filename);
- bool loadBuffer(byte *buffer, bool complete = true);
+ bool loadBuffer(char *buffer, bool complete = true);
virtual ~AdWaypointGroup();
bool _active;
diff --git a/engines/wintermute/base/base.cpp b/engines/wintermute/base/base.cpp
index a64770c577..6a0666b36e 100644
--- a/engines/wintermute/base/base.cpp
+++ b/engines/wintermute/base/base.cpp
@@ -60,7 +60,7 @@ Common::String BaseClass::getEditorProp(const Common::String &propName, const Co
if (_editorPropsIter != _editorProps.end()) {
return _editorPropsIter->_value.c_str();
} else {
- return initVal;
+ return initVal; // Used to be NULL
}
}
@@ -87,7 +87,7 @@ TOKEN_DEF(NAME)
TOKEN_DEF(VALUE)
TOKEN_DEF_END
//////////////////////////////////////////////////////////////////////////
-bool BaseClass::parseEditorProperty(byte *buffer, bool complete) {
+bool BaseClass::parseEditorProperty(char *buffer, bool complete) {
TOKEN_TABLE_START(commands)
TOKEN_TABLE(EDITOR_PROPERTY)
TOKEN_TABLE(NAME)
@@ -100,12 +100,12 @@ bool BaseClass::parseEditorProperty(byte *buffer, bool complete) {
}
- byte *params;
+ char *params;
int cmd;
BaseParser parser;
if (complete) {
- if (parser.getCommand((char **)&buffer, commands, (char **)&params) != TOKEN_EDITOR_PROPERTY) {
+ if (parser.getCommand(&buffer, commands, &params) != TOKEN_EDITOR_PROPERTY) {
BaseEngine::LOG(0, "'EDITOR_PROPERTY' keyword expected.");
return STATUS_FAILED;
}
@@ -115,13 +115,13 @@ bool BaseClass::parseEditorProperty(byte *buffer, bool complete) {
char *propName = nullptr;
char *propValue = nullptr;
- while ((cmd = parser.getCommand((char **)&buffer, commands, (char **)&params)) > 0) {
+ while ((cmd = parser.getCommand(&buffer, commands, &params)) > 0) {
switch (cmd) {
case TOKEN_NAME:
delete[] propName;
- propName = new char[strlen((char *)params) + 1];
+ propName = new char[strlen(params) + 1];
if (propName) {
- strcpy(propName, (char *)params);
+ strcpy(propName, params);
} else {
cmd = PARSERR_GENERIC;
}
@@ -129,9 +129,9 @@ bool BaseClass::parseEditorProperty(byte *buffer, bool complete) {
case TOKEN_VALUE:
delete[] propValue;
- propValue = new char[strlen((char *)params) + 1];
+ propValue = new char[strlen(params) + 1];
if (propValue) {
- strcpy(propValue, (char *)params);
+ strcpy(propValue, params);
} else {
cmd = PARSERR_GENERIC;
}
diff --git a/engines/wintermute/base/base.h b/engines/wintermute/base/base.h
index 48ebe49a97..8767cc9bdd 100644
--- a/engines/wintermute/base/base.h
+++ b/engines/wintermute/base/base.h
@@ -44,9 +44,9 @@ class BaseClass {
public:
bool _persistable;
bool setEditorProp(const Common::String &propName, const Common::String &propValue);
- Common::String getEditorProp(const Common::String &propName, const Common::String &initVal = nullptr);
+ Common::String getEditorProp(const Common::String &propName, const Common::String &initVal = Common::String());
BaseClass(TDynamicConstructor, TDynamicConstructor) {}
- bool parseEditorProperty(byte *buffer, bool complete = true);
+ bool parseEditorProperty(char *buffer, bool complete = true);
virtual bool saveAsText(BaseDynamicBuffer *buffer, int indent = 0);
BaseClass();
BaseClass(BaseGame *GameOwner);
diff --git a/engines/wintermute/base/base_active_rect.cpp b/engines/wintermute/base/base_active_rect.cpp
index abeaa18d54..69cc7b02b6 100644
--- a/engines/wintermute/base/base_active_rect.cpp
+++ b/engines/wintermute/base/base_active_rect.cpp
@@ -37,7 +37,7 @@ namespace Wintermute {
//////////////////////////////////////////////////////////////////////
BaseActiveRect::BaseActiveRect(BaseGame *inGame) : BaseClass(inGame) {
- BasePlatform::setRectEmpty(&_rect);
+ _rect.setEmpty();
_owner = nullptr;
_frame = nullptr;
_region = nullptr;
@@ -52,7 +52,7 @@ BaseActiveRect::BaseActiveRect(BaseGame *inGame) : BaseClass(inGame) {
BaseActiveRect::BaseActiveRect(BaseGame *inGame, BaseObject *owner, BaseSubFrame *frame, int x, int y, int width, int height, float zoomX, float zoomY, bool precise) : BaseClass(inGame) {
_owner = owner;
_frame = frame;
- BasePlatform::setRect(&_rect, x, y, x + width, y + height);
+ _rect.setRect(x, y, x + width, y + height);
_zoomX = zoomX;
_zoomY = zoomY;
_precise = precise;
diff --git a/engines/wintermute/base/base_fader.cpp b/engines/wintermute/base/base_fader.cpp
index 7978230964..c7dac8be27 100644
--- a/engines/wintermute/base/base_fader.cpp
+++ b/engines/wintermute/base/base_fader.cpp
@@ -175,16 +175,16 @@ uint32 BaseFader::getCurrentColor() const {
bool BaseFader::persist(BasePersistenceManager *persistMgr) {
BaseObject::persist(persistMgr);
- persistMgr->transfer(TMEMBER(_active));
- persistMgr->transfer(TMEMBER(_blue));
- persistMgr->transfer(TMEMBER(_currentAlpha));
- persistMgr->transfer(TMEMBER(_duration));
- persistMgr->transfer(TMEMBER(_green));
- persistMgr->transfer(TMEMBER(_red));
- persistMgr->transfer(TMEMBER(_sourceAlpha));
- persistMgr->transfer(TMEMBER(_startTime));
- persistMgr->transfer(TMEMBER(_targetAlpha));
- persistMgr->transfer(TMEMBER(_system));
+ persistMgr->transferBool(TMEMBER(_active));
+ persistMgr->transferByte(TMEMBER(_blue));
+ persistMgr->transferByte(TMEMBER(_currentAlpha));
+ persistMgr->transferUint32(TMEMBER(_duration));
+ persistMgr->transferByte(TMEMBER(_green));
+ persistMgr->transferByte(TMEMBER(_red));
+ persistMgr->transferByte(TMEMBER(_sourceAlpha));
+ persistMgr->transferUint32(TMEMBER(_startTime));
+ persistMgr->transferByte(TMEMBER(_targetAlpha));
+ persistMgr->transferBool(TMEMBER(_system));
if (_system && !persistMgr->getIsSaving()) {
_startTime = 0;
diff --git a/engines/wintermute/base/base_file_manager.cpp b/engines/wintermute/base/base_file_manager.cpp
index bea7e53445..e39a15f469 100644
--- a/engines/wintermute/base/base_file_manager.cpp
+++ b/engines/wintermute/base/base_file_manager.cpp
@@ -168,15 +168,20 @@ bool BaseFileManager::initPaths() {
if (languageSubFolder.exists()) {
addPath(PATH_PACKAGE, languageSubFolder);
}
+ // Also add languages/ for Reversion1.
+ languageSubFolder = gameData.getChild("languages");
+ if (languageSubFolder.exists()) {
+ addPath(PATH_PACKAGE, languageSubFolder);
+ }
return STATUS_OK;
}
bool BaseFileManager::registerPackages(const Common::FSList &fslist) {
for (Common::FSList::const_iterator it = fslist.begin(); it != fslist.end(); ++it) {
- debugC(kWintermuteDebugFileAccess, "Adding %s", (*it).getName().c_str());
- if ((*it).getName().contains(".dcp")) {
- if (registerPackage((*it))) {
- addPath(PATH_PACKAGE, (*it));
+ debugC(kWintermuteDebugFileAccess, "Adding %s", it->getName().c_str());
+ if (it->getName().contains(".dcp")) {
+ if (registerPackage(*it)) {
+ addPath(PATH_PACKAGE, *it);
}
}
}
@@ -187,36 +192,77 @@ bool BaseFileManager::registerPackages(const Common::FSList &fslist) {
bool BaseFileManager::registerPackages() {
debugC(kWintermuteDebugFileAccess | kWintermuteDebugLog, "Scanning packages");
+ // We need the target name as a Common::String to perform some game-specific hacks.
+ Common::String targetName = BaseEngine::instance().getGameTargetName();
+
// Register without using SearchMan, as otherwise the FSNode-based lookup in openPackage will fail
// and that has to be like that to support the detection-scheme.
Common::FSList files;
- for (Common::FSList::iterator it = _packagePaths.begin(); it != _packagePaths.end(); ++it) {
- debugC(kWintermuteDebugFileAccess, "Should register folder: %s %s", (*it).getPath().c_str(), (*it).getName().c_str());
- if (!(*it).getChildren(files, Common::FSNode::kListFilesOnly)) {
- warning("getChildren() failed for path: %s", (*it).getDisplayName().c_str());
+ for (Common::FSList::const_iterator it = _packagePaths.begin(); it != _packagePaths.end(); ++it) {
+ debugC(kWintermuteDebugFileAccess, "Should register folder: %s %s", it->getPath().c_str(), it->getName().c_str());
+ if (!it->getChildren(files, Common::FSNode::kListFilesOnly)) {
+ warning("getChildren() failed for path: %s", it->getDisplayName().c_str());
}
- for (Common::FSList::iterator fileIt = files.begin(); fileIt != files.end(); ++fileIt) {
- if (!fileIt->getName().hasSuffix(".dcp")) {
+ for (Common::FSList::const_iterator fileIt = files.begin(); fileIt != files.end(); ++fileIt) {
+ // To prevent any case sensitivity issues we make the filename
+ // all lowercase here. This makes the code slightly prettier
+ // than the equivalent of using equalsIgnoreCase.
+ Common::String fileName = fileIt->getName();
+ fileName.toLowercase();
+
+ if (!fileName.hasSuffix(".dcp")) {
continue;
}
+ // HACK: for Reversion1, avoid loading xlanguage_pt.dcp from the main folder:
+ if (_language != Common::PT_BRA && targetName.hasPrefix("reversion1")) {
+ if (fileName == "xlanguage_pt.dcp") {
+ continue;
+ }
+ }
+
+ // Again, make the parent's name all lowercase to avoid any case
+ // issues.
+ Common::String parentName = fileIt->getParent().getName();
+ parentName.toLowercase();
+
// Avoid registering all the language files
// TODO: Select based on the gameDesc.
- if (_language != Common::UNK_LANG && fileIt->getParent().getName() == "language") {
- Common::String parentName = fileIt->getParent().getName();
- Common::String dcpName = fileIt->getName();
- if (_language == Common::EN_ANY && fileIt->getName() != "english.dcp") {
+ if (_language != Common::UNK_LANG && (parentName == "language" || parentName == "languages")) {
+ // English
+ if (_language == Common::EN_ANY && (fileName != "english.dcp" && fileName != "xlanguage_en.dcp")) {
+ continue;
+ // Chinese
+ } else if (_language == Common::ZH_CNA && (fileName != "chinese.dcp" && fileName != "xlanguage_nz.dcp")) {
+ continue;
+ // Czech
+ } else if (_language == Common::CZ_CZE && (fileName != "czech.dcp" && fileName != "xlanguage_cz.dcp")) {
+ continue;
+ // French
+ } else if (_language == Common::FR_FRA && (fileName != "french.dcp" && fileName != "xlanguage_fr.dcp")) {
+ continue;
+ // German
+ } else if (_language == Common::DE_DEU && (fileName != "german.dcp" && fileName != "xlanguage_de.dcp")) {
+ continue;
+ // Italian
+ } else if (_language == Common::IT_ITA && (fileName != "italian.dcp" && fileName != "xlanguage_it.dcp")) {
continue;
- } else if (_language == Common::CZ_CZE && fileIt->getName() != "czech.dcp") {
+ // Latvian
+ } else if (_language == Common::LV_LAT && (fileName != "latvian.dcp" && fileName != "xlanguage_lv.dcp")) {
+ // TODO: 'latvian.dcp' is just guesswork. Is there any
+ // game using Latvian and using this filename?
continue;
- } else if (_language == Common::IT_ITA && fileIt->getName() != "italian.dcp") {
+ // Polish
+ } else if (_language == Common::PL_POL && (fileName != "polish.dcp" && fileName != "xlanguage_pl.dcp")) {
continue;
- } else if (_language == Common::PL_POL && fileIt->getName() != "polish.dcp") {
+ // Portuguese
+ } else if (_language == Common::PT_BRA && (fileName != "portuguese.dcp" && fileName != "xlanguage_pt.dcp")) {
continue;
- } else if (_language == Common::RU_RUS && fileIt->getName() != "russian.dcp") {
+ // Russian
+ } else if (_language == Common::RU_RUS && (fileName != "russian.dcp" && fileName != "xlanguage_ru.dcp")) {
continue;
}
}
- debugC(kWintermuteDebugFileAccess, "Registering %s %s", (*fileIt).getPath().c_str(), (*fileIt).getName().c_str());
+ debugC(kWintermuteDebugFileAccess, "Registering %s %s", fileIt->getPath().c_str(), fileIt->getName().c_str());
registerPackage((*fileIt));
}
}
@@ -250,8 +296,6 @@ Common::SeekableReadStream *BaseFileManager::openPkgFile(const Common::String &f
Common::String upcName = filename;
upcName.toUppercase();
Common::SeekableReadStream *file = nullptr;
- char fileName[MAX_PATH_LENGTH];
- Common::strlcpy(fileName, upcName.c_str(), MAX_PATH_LENGTH);
// correct slashes
for (uint32 i = 0; i < upcName.size(); i++) {
diff --git a/engines/wintermute/base/base_frame.cpp b/engines/wintermute/base/base_frame.cpp
index eaad024120..1455733461 100644
--- a/engines/wintermute/base/base_frame.cpp
+++ b/engines/wintermute/base/base_frame.cpp
@@ -142,7 +142,7 @@ TOKEN_DEF(EDITOR_PROPERTY)
TOKEN_DEF(KILL_SOUND)
TOKEN_DEF_END
//////////////////////////////////////////////////////////////////////
-bool BaseFrame::loadBuffer(byte *buffer, int lifeTime, bool keepLoaded) {
+bool BaseFrame::loadBuffer(char *buffer, int lifeTime, bool keepLoaded) {
TOKEN_TABLE_START(commands)
TOKEN_TABLE(DELAY)
TOKEN_TABLE(IMAGE)
@@ -181,10 +181,10 @@ bool BaseFrame::loadBuffer(byte *buffer, int lifeTime, bool keepLoaded) {
bool decoration = false;
bool mirrorX = false;
bool mirrorY = false;
- BasePlatform::setRectEmpty(&rect);
+ rect.setEmpty();
char *surface_file = nullptr;
- while ((cmd = parser.getCommand((char **)&buffer, commands, &params)) > 0) {
+ while ((cmd = parser.getCommand(&buffer, commands, &params)) > 0) {
switch (cmd) {
case TOKEN_DELAY:
parser.scanStr(params, "%d", &_delay);
@@ -249,7 +249,7 @@ bool BaseFrame::loadBuffer(byte *buffer, int lifeTime, bool keepLoaded) {
case TOKEN_SUBFRAME: {
BaseSubFrame *subframe = new BaseSubFrame(_gameRef);
- if (!subframe || DID_FAIL(subframe->loadBuffer((byte *)params, lifeTime, keepLoaded))) {
+ if (!subframe || DID_FAIL(subframe->loadBuffer(params, lifeTime, keepLoaded))) {
delete subframe;
cmd = PARSERR_GENERIC;
} else {
@@ -290,7 +290,7 @@ bool BaseFrame::loadBuffer(byte *buffer, int lifeTime, bool keepLoaded) {
break;
case TOKEN_EDITOR_PROPERTY:
- parseEditorProperty((byte *)params, false);
+ parseEditorProperty(params, false);
break;
}
}
@@ -325,7 +325,7 @@ bool BaseFrame::loadBuffer(byte *buffer, int lifeTime, bool keepLoaded) {
}
}
- if (BasePlatform::isRectEmpty(&rect)) {
+ if (rect.isRectEmpty()) {
sub->setDefaultRect();
} else {
sub->setRect(rect);
@@ -352,7 +352,7 @@ bool BaseFrame::getBoundingRect(Rect32 *rect, int x, int y, float scaleX, float
if (!rect) {
return false;
}
- BasePlatform::setRectEmpty(rect);
+ rect->setEmpty();
Rect32 subRect;
@@ -414,12 +414,12 @@ bool BaseFrame::persist(BasePersistenceManager *persistMgr) {
BaseScriptable::persist(persistMgr);
_applyEvent.persist(persistMgr);
- persistMgr->transfer(TMEMBER(_delay));
- persistMgr->transfer(TMEMBER(_editorExpanded));
- persistMgr->transfer(TMEMBER(_keyframe));
- persistMgr->transfer(TMEMBER(_killSound));
- persistMgr->transfer(TMEMBER(_moveX));
- persistMgr->transfer(TMEMBER(_moveY));
+ persistMgr->transferUint32(TMEMBER(_delay));
+ persistMgr->transferBool(TMEMBER(_editorExpanded));
+ persistMgr->transferBool(TMEMBER(_keyframe));
+ persistMgr->transferBool(TMEMBER(_killSound));
+ persistMgr->transferSint32(TMEMBER(_moveX));
+ persistMgr->transferSint32(TMEMBER(_moveY));
persistMgr->transferPtr(TMEMBER_PTR(_sound));
_subframes.persist(persistMgr);
diff --git a/engines/wintermute/base/base_frame.h b/engines/wintermute/base/base_frame.h
index bf1e40daa1..c4cfc443fa 100644
--- a/engines/wintermute/base/base_frame.h
+++ b/engines/wintermute/base/base_frame.h
@@ -52,7 +52,7 @@ public:
uint32 _delay;
BaseArray<BaseSubFrame *> _subframes;
bool draw(int x, int y, BaseObject *registerOwner = nullptr, float zoomX = 100, float zoomY = 100, bool precise = true, uint32 alpha = 0xFFFFFFFF, bool allFrames = false, float rotate = 0.0f, TSpriteBlendMode blendMode = BLEND_NORMAL);
- bool loadBuffer(byte *buffer, int lifeTime, bool keepLoaded);
+ bool loadBuffer(char *buffer, int lifeTime, bool keepLoaded);
BaseFrame(BaseGame *inGame);
virtual ~BaseFrame();
diff --git a/engines/wintermute/base/base_game.cpp b/engines/wintermute/base/base_game.cpp
index b2c05d271d..6b7e1cf803 100644
--- a/engines/wintermute/base/base_game.cpp
+++ b/engines/wintermute/base/base_game.cpp
@@ -185,7 +185,7 @@ BaseGame::BaseGame(const Common::String &targetName) : BaseObject(this), _target
_lastCursor = nullptr;
- BasePlatform::setRectEmpty(&_mouseLockRect);
+ _mouseLockRect.setEmpty();
_suppressScriptErrors = false;
_lastMiniUpdate = 0;
@@ -573,7 +573,7 @@ bool BaseGame::initLoop() {
_focusedWindow = nullptr;
for (int i = _windows.size() - 1; i >= 0; i--) {
- if (_windows[i]->_visible) {
+ if (_windows[i]->isVisible()) {
_focusedWindow = _windows[i];
break;
}
@@ -620,7 +620,7 @@ void BaseGame::getOffset(int *offsetX, int *offsetY) const {
//////////////////////////////////////////////////////////////////////////
bool BaseGame::loadFile(const char *filename) {
- byte *buffer = BaseFileManager::getEngineInstance()->readWholeFile(filename);
+ char *buffer = (char *)BaseFileManager::getEngineInstance()->readWholeFile(filename);
if (buffer == nullptr) {
_gameRef->LOG(0, "BaseGame::LoadFile failed for file '%s'", filename);
return STATUS_FAILED;
@@ -690,7 +690,7 @@ TOKEN_DEF(GUID)
TOKEN_DEF(COMPAT_KILL_METHOD_THREADS)
TOKEN_DEF_END
//////////////////////////////////////////////////////////////////////////
-bool BaseGame::loadBuffer(byte *buffer, bool complete) {
+bool BaseGame::loadBuffer(char *buffer, bool complete) {
TOKEN_TABLE_START(commands)
TOKEN_TABLE(GAME)
TOKEN_TABLE(TEMPLATE)
@@ -740,32 +740,32 @@ bool BaseGame::loadBuffer(byte *buffer, bool complete) {
Common::String loadImageName = "";
Common::String saveImageName = "";
- byte *params;
+ char *params;
int cmd;
BaseParser parser;
if (complete) {
- if (parser.getCommand((char **)&buffer, commands, (char **)&params) != TOKEN_GAME) {
+ if (parser.getCommand(&buffer, commands, &params) != TOKEN_GAME) {
_gameRef->LOG(0, "'GAME' keyword expected.");
return STATUS_FAILED;
}
buffer = params;
}
- while ((cmd = parser.getCommand((char **)&buffer, commands, (char **)&params)) > 0) {
+ while ((cmd = parser.getCommand(&buffer, commands, &params)) > 0) {
switch (cmd) {
case TOKEN_TEMPLATE:
- if (DID_FAIL(loadFile((char *)params))) {
+ if (DID_FAIL(loadFile(params))) {
cmd = PARSERR_GENERIC;
}
break;
case TOKEN_NAME:
- setName((char *)params);
+ setName(params);
break;
case TOKEN_CAPTION:
- setCaption((char *)params);
+ setCaption(params);
break;
case TOKEN_SYSTEM_FONT:
@@ -774,7 +774,7 @@ bool BaseGame::loadBuffer(byte *buffer, bool complete) {
}
_systemFont = nullptr;
- _systemFont = _gameRef->_fontStorage->addFont((char *)params);
+ _systemFont = _gameRef->_fontStorage->addFont(params);
break;
case TOKEN_VIDEO_FONT:
@@ -783,14 +783,14 @@ bool BaseGame::loadBuffer(byte *buffer, bool complete) {
}
_videoFont = nullptr;
- _videoFont = _gameRef->_fontStorage->addFont((char *)params);
+ _videoFont = _gameRef->_fontStorage->addFont(params);
break;
case TOKEN_CURSOR:
delete _cursor;
_cursor = new BaseSprite(_gameRef);
- if (!_cursor || DID_FAIL(_cursor->loadFile((char *)params))) {
+ if (!_cursor || DID_FAIL(_cursor->loadFile(params))) {
delete _cursor;
_cursor = nullptr;
cmd = PARSERR_GENERIC;
@@ -801,7 +801,7 @@ bool BaseGame::loadBuffer(byte *buffer, bool complete) {
delete _activeCursor;
_activeCursor = nullptr;
_activeCursor = new BaseSprite(_gameRef);
- if (!_activeCursor || DID_FAIL(_activeCursor->loadFile((char *)params))) {
+ if (!_activeCursor || DID_FAIL(_activeCursor->loadFile(params))) {
delete _activeCursor;
_activeCursor = nullptr;
cmd = PARSERR_GENERIC;
@@ -811,7 +811,7 @@ bool BaseGame::loadBuffer(byte *buffer, bool complete) {
case TOKEN_NONINTERACTIVE_CURSOR:
delete _cursorNoninteractive;
_cursorNoninteractive = new BaseSprite(_gameRef);
- if (!_cursorNoninteractive || DID_FAIL(_cursorNoninteractive->loadFile((char *)params))) {
+ if (!_cursorNoninteractive || DID_FAIL(_cursorNoninteractive->loadFile(params))) {
delete _cursorNoninteractive;
_cursorNoninteractive = nullptr;
cmd = PARSERR_GENERIC;
@@ -819,23 +819,23 @@ bool BaseGame::loadBuffer(byte *buffer, bool complete) {
break;
case TOKEN_SCRIPT:
- addScript((char *)params);
+ addScript(params);
break;
case TOKEN_PERSONAL_SAVEGAMES:
- parser.scanStr((char *)params, "%b", &_personalizedSave);
+ parser.scanStr(params, "%b", &_personalizedSave);
break;
case TOKEN_SUBTITLES:
- parser.scanStr((char *)params, "%b", &_subtitles);
+ parser.scanStr(params, "%b", &_subtitles);
break;
case TOKEN_SUBTITLES_SPEED:
- parser.scanStr((char *)params, "%d", &_subtitlesSpeed);
+ parser.scanStr(params, "%d", &_subtitlesSpeed);
break;
case TOKEN_VIDEO_SUBTITLES:
- parser.scanStr((char *)params, "%b", &_videoSubtitles);
+ parser.scanStr(params, "%b", &_videoSubtitles);
break;
case TOKEN_PROPERTY:
@@ -847,66 +847,66 @@ bool BaseGame::loadBuffer(byte *buffer, bool complete) {
break;
case TOKEN_THUMBNAIL_WIDTH:
- parser.scanStr((char *)params, "%d", &_thumbnailWidth);
+ parser.scanStr(params, "%d", &_thumbnailWidth);
break;
case TOKEN_THUMBNAIL_HEIGHT:
- parser.scanStr((char *)params, "%d", &_thumbnailHeight);
+ parser.scanStr(params, "%d", &_thumbnailHeight);
break;
case TOKEN_INDICATOR_X:
- parser.scanStr((char *)params, "%d", &indicatorX);
+ parser.scanStr(params, "%d", &indicatorX);
break;
case TOKEN_INDICATOR_Y:
- parser.scanStr((char *)params, "%d", &indicatorY);
+ parser.scanStr(params, "%d", &indicatorY);
break;
case TOKEN_INDICATOR_COLOR: {
int r, g, b, a;
- parser.scanStr((char *)params, "%d,%d,%d,%d", &r, &g, &b, &a);
+ parser.scanStr(params, "%d,%d,%d,%d", &r, &g, &b, &a);
indicatorColor = BYTETORGBA(r, g, b, a);
}
break;
case TOKEN_INDICATOR_WIDTH:
- parser.scanStr((char *)params, "%d", &indicatorWidth);
+ parser.scanStr(params, "%d", &indicatorWidth);
break;
case TOKEN_INDICATOR_HEIGHT:
- parser.scanStr((char *)params, "%d", &indicatorHeight);
+ parser.scanStr(params, "%d", &indicatorHeight);
break;
case TOKEN_SAVE_IMAGE:
- saveImageName = (char *) params;
+ saveImageName = params;
break;
case TOKEN_SAVE_IMAGE_X:
- parser.scanStr((char *)params, "%d", &saveImageX);
+ parser.scanStr(params, "%d", &saveImageX);
break;
case TOKEN_SAVE_IMAGE_Y:
- parser.scanStr((char *)params, "%d", &saveImageY);
+ parser.scanStr(params, "%d", &saveImageY);
break;
case TOKEN_LOAD_IMAGE:
- loadImageName = (char *) params;
+ loadImageName = params;
break;
case TOKEN_LOAD_IMAGE_X:
- parser.scanStr((char *)params, "%d", &loadImageX);
+ parser.scanStr(params, "%d", &loadImageX);
break;
case TOKEN_LOAD_IMAGE_Y:
- parser.scanStr((char *)params, "%d", &loadImageY);
+ parser.scanStr(params, "%d", &loadImageY);
break;
case TOKEN_LOCAL_SAVE_DIR:
- _localSaveDir = (char *)params;
+ _localSaveDir = params;
break;
case TOKEN_COMPAT_KILL_METHOD_THREADS:
- parser.scanStr((char *)params, "%b", &_compatKillMethodThreads);
+ parser.scanStr(params, "%b", &_compatKillMethodThreads);
break;
}
}
@@ -1123,7 +1123,7 @@ bool BaseGame::scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack
BaseUtils::swap(&top, &bottom);
}
- BasePlatform::setRect(&_mouseLockRect, left, top, right, bottom);
+ _mouseLockRect.setRect(left, top, right, bottom);
stack->pushNULL();
return STATUS_OK;
@@ -3019,10 +3019,10 @@ bool BaseGame::displayWindows(bool inGame) {
bool res;
// did we lose focus? focus topmost window
- if (_focusedWindow == nullptr || !_focusedWindow->_visible || _focusedWindow->_disable) {
+ if (_focusedWindow == nullptr || !_focusedWindow->isVisible() || _focusedWindow->isDisabled()) {
_focusedWindow = nullptr;
for (int i = _windows.size() - 1; i >= 0; i--) {
- if (_windows[i]->_visible && !_windows[i]->_disable) {
+ if (_windows[i]->isVisible() && !_windows[i]->isDisabled()) {
_focusedWindow = _windows[i];
break;
}
@@ -3031,7 +3031,7 @@ bool BaseGame::displayWindows(bool inGame) {
// display all windows
for (uint32 i = 0; i < _windows.size(); i++) {
- if (_windows[i]->_visible && _windows[i]->_inGame == inGame) {
+ if (_windows[i]->isVisible() && _windows[i]->getInGame() == inGame) {
res = _windows[i]->display();
if (DID_FAIL(res)) {
@@ -3054,61 +3054,61 @@ bool BaseGame::persist(BasePersistenceManager *persistMgr) {
persistMgr->transferPtr(TMEMBER_PTR(_activeObject));
persistMgr->transferPtr(TMEMBER_PTR(_capturedObject));
persistMgr->transferPtr(TMEMBER_PTR(_cursorNoninteractive));
- persistMgr->transfer(TMEMBER(_editorMode));
+ persistMgr->transferBool(TMEMBER(_editorMode));
persistMgr->transferPtr(TMEMBER_PTR(_fader));
- persistMgr->transfer(TMEMBER(_freezeLevel));
+ persistMgr->transferSint32(TMEMBER(_freezeLevel));
persistMgr->transferPtr(TMEMBER_PTR(_focusedWindow));
persistMgr->transferPtr(TMEMBER_PTR(_fontStorage));
- persistMgr->transfer(TMEMBER(_interactive));
+ persistMgr->transferBool(TMEMBER(_interactive));
persistMgr->transferPtr(TMEMBER_PTR(_keyboardState));
- persistMgr->transfer(TMEMBER(_lastTime));
+ persistMgr->transferUint32(TMEMBER(_lastTime));
persistMgr->transferPtr(TMEMBER_PTR(_mainObject));
_musicSystem->persistChannels(persistMgr);
_musicSystem->persistCrossfadeSettings(persistMgr);
- persistMgr->transfer(TMEMBER(_offsetX));
- persistMgr->transfer(TMEMBER(_offsetY));
+ persistMgr->transferSint32(TMEMBER(_offsetX));
+ persistMgr->transferSint32(TMEMBER(_offsetY));
persistMgr->transferFloat(TMEMBER(_offsetPercentX));
persistMgr->transferFloat(TMEMBER(_offsetPercentY));
- persistMgr->transfer(TMEMBER(_origInteractive));
- persistMgr->transfer(TMEMBER_INT(_origState));
- persistMgr->transfer(TMEMBER(_personalizedSave));
- persistMgr->transfer(TMEMBER(_quitting));
+ persistMgr->transferBool(TMEMBER(_origInteractive));
+ persistMgr->transferSint32(TMEMBER_INT(_origState));
+ persistMgr->transferBool(TMEMBER(_personalizedSave));
+ persistMgr->transferBool(TMEMBER(_quitting));
_regObjects.persist(persistMgr);
persistMgr->transferPtr(TMEMBER_PTR(_scEngine));
//persistMgr->transfer(TMEMBER(_soundMgr));
- persistMgr->transfer(TMEMBER_INT(_state));
+ persistMgr->transferSint32(TMEMBER_INT(_state));
//persistMgr->transfer(TMEMBER(_surfaceStorage));
- persistMgr->transfer(TMEMBER(_subtitles));
- persistMgr->transfer(TMEMBER(_subtitlesSpeed));
+ persistMgr->transferBool(TMEMBER(_subtitles));
+ persistMgr->transferSint32(TMEMBER(_subtitlesSpeed));
persistMgr->transferPtr(TMEMBER_PTR(_systemFont));
persistMgr->transferPtr(TMEMBER_PTR(_videoFont));
- persistMgr->transfer(TMEMBER(_videoSubtitles));
+ persistMgr->transferBool(TMEMBER(_videoSubtitles));
_timerNormal.persist(persistMgr);
_timerLive.persist(persistMgr);
_renderer->persistSaveLoadImages(persistMgr);
- persistMgr->transfer(TMEMBER_INT(_textEncoding));
- persistMgr->transfer(TMEMBER(_textRTL));
+ persistMgr->transferSint32(TMEMBER_INT(_textEncoding));
+ persistMgr->transferBool(TMEMBER(_textRTL));
- persistMgr->transfer(TMEMBER(_soundBufferSizeSec));
- persistMgr->transfer(TMEMBER(_suspendedRendering));
+ persistMgr->transferSint32(TMEMBER(_soundBufferSizeSec));
+ persistMgr->transferBool(TMEMBER(_suspendedRendering));
- persistMgr->transfer(TMEMBER(_mouseLockRect));
+ persistMgr->transferRect32(TMEMBER(_mouseLockRect));
_windows.persist(persistMgr);
- persistMgr->transfer(TMEMBER(_suppressScriptErrors));
- persistMgr->transfer(TMEMBER(_autorunDisabled));
+ persistMgr->transferBool(TMEMBER(_suppressScriptErrors));
+ persistMgr->transferBool(TMEMBER(_autorunDisabled));
- persistMgr->transfer(TMEMBER(_autoSaveOnExit));
- persistMgr->transfer(TMEMBER(_autoSaveSlot));
- persistMgr->transfer(TMEMBER(_cursorHidden));
+ persistMgr->transferBool(TMEMBER(_autoSaveOnExit));
+ persistMgr->transferUint32(TMEMBER(_autoSaveSlot));
+ persistMgr->transferBool(TMEMBER(_cursorHidden));
if (!persistMgr->getIsSaving()) {
_quitting = false;
@@ -3131,7 +3131,7 @@ bool BaseGame::focusWindow(UIWindow *window) {
_gameRef->_focusedWindow = window;
}
- if (window->_mode == WINDOW_NORMAL && prev != window && _gameRef->validObject(prev) && (prev->_mode == WINDOW_EXCLUSIVE || prev->_mode == WINDOW_SYSTEM_EXCLUSIVE)) {
+ if (window->getMode() == WINDOW_NORMAL && prev != window && _gameRef->validObject(prev) && (prev->getMode() == WINDOW_EXCLUSIVE || prev->getMode() == WINDOW_SYSTEM_EXCLUSIVE)) {
return focusWindow(prev);
} else {
return STATUS_OK;
@@ -3361,10 +3361,10 @@ bool BaseGame::getCurrentViewportRect(Rect32 *rect, bool *custom) const {
*custom = true;
}
} else {
- BasePlatform::setRect(rect, _renderer->_drawOffsetX,
- _renderer->_drawOffsetY,
- _renderer->getWidth() + _renderer->_drawOffsetX,
- _renderer->getHeight() + _renderer->_drawOffsetY);
+ rect->setRect(_renderer->_drawOffsetX,
+ _renderer->_drawOffsetY,
+ _renderer->getWidth() + _renderer->_drawOffsetX,
+ _renderer->getHeight() + _renderer->_drawOffsetY);
if (custom) {
*custom = false;
}
@@ -3577,7 +3577,6 @@ bool BaseGame::onMouseLeftDown() {
_capturedObject = _activeObject;
}
_mouseLeftDown = true;
- BasePlatform::setCapture(/*_renderer->_window*/);
return STATUS_OK;
}
@@ -3588,7 +3587,6 @@ bool BaseGame::onMouseLeftUp() {
_activeObject->handleMouse(MOUSE_RELEASE, MOUSE_BUTTON_LEFT);
}
- BasePlatform::releaseCapture();
_capturedObject = nullptr;
_mouseLeftDown = false;
diff --git a/engines/wintermute/base/base_game.h b/engines/wintermute/base/base_game.h
index d295bb6b1a..29d312fe97 100644
--- a/engines/wintermute/base/base_game.h
+++ b/engines/wintermute/base/base_game.h
@@ -157,7 +157,7 @@ public:
int32 _sequence;
virtual bool loadFile(const char *filename);
- virtual bool loadBuffer(byte *buffer, bool complete = true);
+ virtual bool loadBuffer(char *buffer, bool complete = true);
int32 _viewportSP;
@@ -251,6 +251,8 @@ public:
void addMem(int32 bytes);
bool _touchInterface;
bool _constrainedMemory;
+
+ bool stopVideo();
protected:
BaseFont *_systemFont;
BaseFont *_videoFont;
@@ -319,7 +321,6 @@ private:
BaseGameMusic *_musicSystem;
bool isVideoPlaying();
- bool stopVideo();
BaseArray<BaseQuickMsg *> _quickMessages;
BaseArray<UIWindow *> _windows;
diff --git a/engines/wintermute/base/base_game_music.cpp b/engines/wintermute/base/base_game_music.cpp
index c50969df76..8894fb843f 100644
--- a/engines/wintermute/base/base_game_music.cpp
+++ b/engines/wintermute/base/base_game_music.cpp
@@ -215,18 +215,18 @@ bool BaseGameMusic::updateMusicCrossfade() {
bool BaseGameMusic::persistChannels(BasePersistenceManager *persistMgr) {
for (int i = 0; i < NUM_MUSIC_CHANNELS; i++) {
persistMgr->transferPtr(TMEMBER_PTR(_music[i]));
- persistMgr->transfer(TMEMBER(_musicStartTime[i]));
+ persistMgr->transferUint32(TMEMBER(_musicStartTime[i]));
}
return true;
}
bool BaseGameMusic::persistCrossfadeSettings(BasePersistenceManager *persistMgr) {
- persistMgr->transfer(TMEMBER(_musicCrossfadeRunning));
- persistMgr->transfer(TMEMBER(_musicCrossfadeStartTime));
- persistMgr->transfer(TMEMBER(_musicCrossfadeLength));
- persistMgr->transfer(TMEMBER(_musicCrossfadeChannel1));
- persistMgr->transfer(TMEMBER(_musicCrossfadeChannel2));
- persistMgr->transfer(TMEMBER(_musicCrossfadeSwap));
+ persistMgr->transferBool(TMEMBER(_musicCrossfadeRunning));
+ persistMgr->transferUint32(TMEMBER(_musicCrossfadeStartTime));
+ persistMgr->transferUint32(TMEMBER(_musicCrossfadeLength));
+ persistMgr->transferSint32(TMEMBER(_musicCrossfadeChannel1));
+ persistMgr->transferSint32(TMEMBER(_musicCrossfadeChannel2));
+ persistMgr->transferBool(TMEMBER(_musicCrossfadeSwap));
return true;
}
diff --git a/engines/wintermute/base/base_game_settings.cpp b/engines/wintermute/base/base_game_settings.cpp
index 1de8b31ca7..43809b5d1e 100644
--- a/engines/wintermute/base/base_game_settings.cpp
+++ b/engines/wintermute/base/base_game_settings.cpp
@@ -103,7 +103,7 @@ bool BaseGameSettings::loadSettings(const char *filename) {
TOKEN_TABLE_END
- byte *origBuffer = BaseFileManager::getEngineInstance()->readWholeFile(filename);
+ char *origBuffer = (char *)BaseFileManager::getEngineInstance()->readWholeFile(filename);
if (origBuffer == nullptr) {
BaseEngine::LOG(0, "BaseGame::LoadSettings failed for file '%s'", filename);
return STATUS_FAILED;
@@ -111,78 +111,78 @@ bool BaseGameSettings::loadSettings(const char *filename) {
bool ret = STATUS_OK;
- byte *buffer = origBuffer;
- byte *params;
+ char *buffer = origBuffer;
+ char *params;
int cmd;
BaseParser parser;
- if (parser.getCommand((char **)&buffer, commands, (char **)&params) != TOKEN_SETTINGS) {
+ if (parser.getCommand(&buffer, commands, &params) != TOKEN_SETTINGS) {
BaseEngine::LOG(0, "'SETTINGS' keyword expected in game settings file.");
return STATUS_FAILED;
}
buffer = params;
- while ((cmd = parser.getCommand((char **)&buffer, commands, (char **)&params)) > 0) {
+ while ((cmd = parser.getCommand(&buffer, commands, &params)) > 0) {
switch (cmd) {
case TOKEN_GAME:
delete[] _gameFile;
- _gameFile = new char[strlen((char *)params) + 1];
+ _gameFile = new char[strlen(params) + 1];
if (_gameFile) {
- strcpy(_gameFile, (char *)params);
+ strcpy(_gameFile, params);
}
break;
case TOKEN_STRING_TABLE:
- if (DID_FAIL(_stringTable->loadFile((char *)params))) {
+ if (DID_FAIL(_stringTable->loadFile(params))) {
cmd = PARSERR_GENERIC;
}
break;
case TOKEN_RESOLUTION:
- parser.scanStr((char *)params, "%d,%d", &_resWidth, &_resHeight);
+ parser.scanStr(params, "%d,%d", &_resWidth, &_resHeight);
break;
case TOKEN_REQUIRE_3D_ACCELERATION:
- parser.scanStr((char *)params, "%b", &_requireAcceleration);
+ parser.scanStr(params, "%b", &_requireAcceleration);
break;
case TOKEN_REQUIRE_SOUND:
- parser.scanStr((char *)params, "%b", &_requireSound);
+ parser.scanStr(params, "%b", &_requireSound);
break;
case TOKEN_HWTL_MODE:
- parser.scanStr((char *)params, "%d", &_TLMode);
+ parser.scanStr(params, "%d", &_TLMode);
break;
case TOKEN_ALLOW_WINDOWED_MODE:
- parser.scanStr((char *)params, "%b", &_allowWindowed);
+ parser.scanStr(params, "%b", &_allowWindowed);
break;
case TOKEN_ALLOW_DESKTOP_RES:
- parser.scanStr((char *)params, "%b", &_allowDesktopRes);
+ parser.scanStr(params, "%b", &_allowDesktopRes);
break;
case TOKEN_ALLOW_ADVANCED:
- parser.scanStr((char *)params, "%b", &_allowAdvanced);
+ parser.scanStr(params, "%b", &_allowAdvanced);
break;
case TOKEN_ALLOW_ACCESSIBILITY_TAB:
- parser.scanStr((char *)params, "%b", &_allowAccessTab);
+ parser.scanStr(params, "%b", &_allowAccessTab);
break;
case TOKEN_ALLOW_ABOUT_TAB:
- parser.scanStr((char *)params, "%b", &_allowAboutTab);
+ parser.scanStr(params, "%b", &_allowAboutTab);
break;
case TOKEN_REGISTRY_PATH:
- //BaseEngine::instance().getRegistry()->setBasePath((char *)params);
+ //BaseEngine::instance().getRegistry()->setBasePath(params);
break;
case TOKEN_RICH_SAVED_GAMES:
- parser.scanStr((char *)params, "%b", &_richSavedGames);
+ parser.scanStr(params, "%b", &_richSavedGames);
break;
case TOKEN_SAVED_GAME_EXT:
- _savedGameExt = (char *)params;
+ _savedGameExt = params;
break;
case TOKEN_GUID:
diff --git a/engines/wintermute/base/base_keyboard_state.cpp b/engines/wintermute/base/base_keyboard_state.cpp
index aeb56ad282..77469e07a5 100644
--- a/engines/wintermute/base/base_keyboard_state.cpp
+++ b/engines/wintermute/base/base_keyboard_state.cpp
@@ -221,12 +221,12 @@ bool BaseKeyboardState::persist(BasePersistenceManager *persistMgr) {
//if (!persistMgr->getIsSaving()) cleanup();
BaseScriptable::persist(persistMgr);
- persistMgr->transfer(TMEMBER(_currentAlt));
- persistMgr->transfer(TMEMBER(_currentCharCode));
- persistMgr->transfer(TMEMBER(_currentControl));
- persistMgr->transfer(TMEMBER(_currentKeyData));
- persistMgr->transfer(TMEMBER(_currentPrintable));
- persistMgr->transfer(TMEMBER(_currentShift));
+ persistMgr->transferBool(TMEMBER(_currentAlt));
+ persistMgr->transferUint32(TMEMBER(_currentCharCode));
+ persistMgr->transferBool(TMEMBER(_currentControl));
+ persistMgr->transferUint32(TMEMBER(_currentKeyData));
+ persistMgr->transferBool(TMEMBER(_currentPrintable));
+ persistMgr->transferBool(TMEMBER(_currentShift));
if (!persistMgr->getIsSaving()) {
_keyStates = new uint8[323]; // Hardcoded size for the common/keyboard.h enum
@@ -276,17 +276,21 @@ uint32 BaseKeyboardState::keyCodeToVKey(Common::Event *event) {
}
enum VKeyCodes {
- kVkSpace = 32,
- kVkLeft = 37,
- kVkUp = 38,
- kVkRight = 39,
- kVkDown = 40
+ kVkEscape = 27,
+ kVkSpace = 32,
+ kVkLeft = 37,
+ kVkUp = 38,
+ kVkRight = 39,
+ kVkDown = 40
};
//////////////////////////////////////////////////////////////////////////
Common::KeyCode BaseKeyboardState::vKeyToKeyCode(uint32 vkey) {
// todo
switch (vkey) {
+ case kVkEscape:
+ return Common::KEYCODE_ESCAPE;
+ break;
case kVkSpace:
return Common::KEYCODE_SPACE;
break;
diff --git a/engines/wintermute/base/base_object.cpp b/engines/wintermute/base/base_object.cpp
index ea754f8f23..540c7dd164 100644
--- a/engines/wintermute/base/base_object.cpp
+++ b/engines/wintermute/base/base_object.cpp
@@ -63,7 +63,7 @@ BaseObject::BaseObject(BaseGame *inGame) : BaseScriptHolder(inGame) {
_iD = _gameRef->getSequence();
- BasePlatform::setRectEmpty(&_rect);
+ _rect.setEmpty();
_rectSet = false;
_cursor = nullptr;
@@ -953,53 +953,53 @@ bool BaseObject::persist(BasePersistenceManager *persistMgr) {
BaseScriptHolder::persist(persistMgr);
for (int i = 0; i < 7; i++) {
- persistMgr->transfer(TMEMBER(_caption[i]));
+ persistMgr->transferCharPtr(TMEMBER(_caption[i]));
}
persistMgr->transferPtr(TMEMBER_PTR(_activeCursor));
- persistMgr->transfer(TMEMBER(_alphaColor));
- persistMgr->transfer(TMEMBER(_autoSoundPanning));
+ persistMgr->transferUint32(TMEMBER(_alphaColor));
+ persistMgr->transferBool(TMEMBER(_autoSoundPanning));
persistMgr->transferPtr(TMEMBER_PTR(_cursor));
- persistMgr->transfer(TMEMBER(_sharedCursors));
- persistMgr->transfer(TMEMBER(_editorAlwaysRegister));
- persistMgr->transfer(TMEMBER(_editorOnly));
- persistMgr->transfer(TMEMBER(_editorSelected));
- persistMgr->transfer(TMEMBER(_iD));
- persistMgr->transfer(TMEMBER(_is3D));
- persistMgr->transfer(TMEMBER(_movable));
- persistMgr->transfer(TMEMBER(_posX));
- persistMgr->transfer(TMEMBER(_posY));
+ persistMgr->transferBool(TMEMBER(_sharedCursors));
+ persistMgr->transferBool(TMEMBER(_editorAlwaysRegister));
+ persistMgr->transferBool(TMEMBER(_editorOnly));
+ persistMgr->transferBool(TMEMBER(_editorSelected));
+ persistMgr->transferSint32(TMEMBER(_iD));
+ persistMgr->transferBool(TMEMBER(_is3D));
+ persistMgr->transferBool(TMEMBER(_movable));
+ persistMgr->transferSint32(TMEMBER(_posX));
+ persistMgr->transferSint32(TMEMBER(_posY));
persistMgr->transferFloat(TMEMBER(_relativeScale));
- persistMgr->transfer(TMEMBER(_rotatable));
+ persistMgr->transferBool(TMEMBER(_rotatable));
persistMgr->transferFloat(TMEMBER(_scale));
persistMgr->transferPtr(TMEMBER_PTR(_sFX));
- persistMgr->transfer(TMEMBER(_sFXStart));
- persistMgr->transfer(TMEMBER(_sFXVolume));
- persistMgr->transfer(TMEMBER(_ready));
- persistMgr->transfer(TMEMBER(_rect));
- persistMgr->transfer(TMEMBER(_rectSet));
- persistMgr->transfer(TMEMBER(_registrable));
- persistMgr->transfer(TMEMBER(_shadowable));
- persistMgr->transfer(TMEMBER(_soundEvent));
- persistMgr->transfer(TMEMBER(_zoomable));
+ persistMgr->transferUint32(TMEMBER(_sFXStart));
+ persistMgr->transferSint32(TMEMBER(_sFXVolume));
+ persistMgr->transferBool(TMEMBER(_ready));
+ persistMgr->transferRect32(TMEMBER(_rect));
+ persistMgr->transferBool(TMEMBER(_rectSet));
+ persistMgr->transferBool(TMEMBER(_registrable));
+ persistMgr->transferBool(TMEMBER(_shadowable));
+ persistMgr->transferCharPtr(TMEMBER(_soundEvent));
+ persistMgr->transferBool(TMEMBER(_zoomable));
persistMgr->transferFloat(TMEMBER(_scaleX));
persistMgr->transferFloat(TMEMBER(_scaleY));
persistMgr->transferFloat(TMEMBER(_rotate));
- persistMgr->transfer(TMEMBER(_rotateValid));
+ persistMgr->transferBool(TMEMBER(_rotateValid));
persistMgr->transferFloat(TMEMBER(_relativeRotate));
- persistMgr->transfer(TMEMBER(_saveState));
- persistMgr->transfer(TMEMBER(_nonIntMouseEvents));
+ persistMgr->transferBool(TMEMBER(_saveState));
+ persistMgr->transferBool(TMEMBER(_nonIntMouseEvents));
- persistMgr->transfer(TMEMBER_INT(_sFXType));
+ persistMgr->transferSint32(TMEMBER_INT(_sFXType));
persistMgr->transferFloat(TMEMBER(_sFXParam1));
persistMgr->transferFloat(TMEMBER(_sFXParam2));
persistMgr->transferFloat(TMEMBER(_sFXParam3));
persistMgr->transferFloat(TMEMBER(_sFXParam4));
- persistMgr->transfer(TMEMBER_INT(_blendMode));
+ persistMgr->transferSint32(TMEMBER_INT(_blendMode));
return STATUS_OK;
}
@@ -1039,7 +1039,7 @@ bool BaseObject::setActiveCursor(const char *filename) {
//////////////////////////////////////////////////////////////////////////
-int BaseObject::getHeight() {
+int32 BaseObject::getHeight() {
return 0;
}
diff --git a/engines/wintermute/base/base_object.h b/engines/wintermute/base/base_object.h
index 42041c5e3c..a190b1bcb4 100644
--- a/engines/wintermute/base/base_object.h
+++ b/engines/wintermute/base/base_object.h
@@ -89,7 +89,7 @@ public:
virtual bool handleMouseWheel(int delta);
virtual bool handleMouse(TMouseEvent event, TMouseButton button);
virtual bool handleKeypress(Common::Event *event, bool printable = false);
- virtual int getHeight();
+ virtual int32 getHeight();
bool setCursor(const char *filename);
bool setActiveCursor(const char *filename);
bool cleanup();
diff --git a/engines/wintermute/base/base_parser.cpp b/engines/wintermute/base/base_parser.cpp
index 0b677b6cb2..ff9c6c81b0 100644
--- a/engines/wintermute/base/base_parser.cpp
+++ b/engines/wintermute/base/base_parser.cpp
@@ -250,10 +250,10 @@ Common::String BaseParser::getToken(char **buf) {
*t++ = 0;
} else if (*b == 0) {
*buf = b;
- return nullptr;
+ return Common::String();
} else {
// Error.
- return nullptr;
+ return Common::String();
}
*buf = b;
diff --git a/engines/wintermute/base/base_persistence_manager.cpp b/engines/wintermute/base/base_persistence_manager.cpp
index e5542d96b7..3d0fc0e925 100644
--- a/engines/wintermute/base/base_persistence_manager.cpp
+++ b/engines/wintermute/base/base_persistence_manager.cpp
@@ -587,7 +587,7 @@ double BasePersistenceManager::getDouble() {
//////////////////////////////////////////////////////////////////////////
// bool
-bool BasePersistenceManager::transfer(const char *name, bool *val) {
+bool BasePersistenceManager::transferBool(const char *name, bool *val) {
if (_saving) {
_saveStream->writeByte(*val);
if (_saveStream->err()) {
@@ -606,7 +606,7 @@ bool BasePersistenceManager::transfer(const char *name, bool *val) {
//////////////////////////////////////////////////////////////////////////
// int
-bool BasePersistenceManager::transfer(const char *name, int32 *val) {
+bool BasePersistenceManager::transferSint32(const char *name, int32 *val) {
if (_saving) {
_saveStream->writeSint32LE(*val);
if (_saveStream->err()) {
@@ -625,7 +625,7 @@ bool BasePersistenceManager::transfer(const char *name, int32 *val) {
//////////////////////////////////////////////////////////////////////////
// DWORD
-bool BasePersistenceManager::transfer(const char *name, uint32 *val) {
+bool BasePersistenceManager::transferUint32(const char *name, uint32 *val) {
if (_saving) {
_saveStream->writeUint32LE(*val);
if (_saveStream->err()) {
@@ -663,7 +663,7 @@ bool BasePersistenceManager::transferFloat(const char *name, float *val) {
//////////////////////////////////////////////////////////////////////////
// double
-bool BasePersistenceManager::transfer(const char *name, double *val) {
+bool BasePersistenceManager::transferDouble(const char *name, double *val) {
if (_saving) {
putDouble(*val);
if (_saveStream->err()) {
@@ -682,7 +682,7 @@ bool BasePersistenceManager::transfer(const char *name, double *val) {
//////////////////////////////////////////////////////////////////////////
// char*
-bool BasePersistenceManager::transfer(const char *name, char **val) {
+bool BasePersistenceManager::transferCharPtr(const char *name, char **val) {
if (_saving) {
putString(*val);
return STATUS_OK;
@@ -699,7 +699,7 @@ bool BasePersistenceManager::transfer(const char *name, char **val) {
//////////////////////////////////////////////////////////////////////////
// const char*
-bool BasePersistenceManager::transfer(const char *name, const char **val) {
+bool BasePersistenceManager::transferConstChar(const char *name, const char **val) {
if (_saving) {
putString(*val);
return STATUS_OK;
@@ -716,7 +716,7 @@ bool BasePersistenceManager::transfer(const char *name, const char **val) {
//////////////////////////////////////////////////////////////////////////
// Common::String
-bool BasePersistenceManager::transfer(const char *name, Common::String *val) {
+bool BasePersistenceManager::transferString(const char *name, Common::String *val) {
if (_saving) {
putString(val->c_str());
return STATUS_OK;
@@ -737,39 +737,8 @@ bool BasePersistenceManager::transfer(const char *name, Common::String *val) {
}
//////////////////////////////////////////////////////////////////////////
-bool BasePersistenceManager::transfer(const char *name, AnsiStringArray &val) {
- size_t size;
-
- if (_saving) {
- size = val.size();
- _saveStream->writeUint32LE(size);
-
- for (AnsiStringArray::iterator it = val.begin(); it != val.end(); ++it) {
- putString((*it).c_str());
- }
- } else {
- val.clear();
- size = _loadStream->readUint32LE();
-
- for (size_t i = 0; i < size; i++) {
- char *str = getString();
- if (_loadStream->err()) {
- delete[] str;
- return STATUS_FAILED;
- }
- if (str) {
- val.push_back(str);
- }
- delete[] str;
- }
- }
-
- return STATUS_OK;
-}
-
-//////////////////////////////////////////////////////////////////////////
// BYTE
-bool BasePersistenceManager::transfer(const char *name, byte *val) {
+bool BasePersistenceManager::transferByte(const char *name, byte *val) {
if (_saving) {
_saveStream->writeByte(*val);
if (_saveStream->err()) {
@@ -788,7 +757,7 @@ bool BasePersistenceManager::transfer(const char *name, byte *val) {
//////////////////////////////////////////////////////////////////////////
// RECT
-bool BasePersistenceManager::transfer(const char *name, Rect32 *val) {
+bool BasePersistenceManager::transferRect32(const char *name, Rect32 *val) {
if (_saving) {
_saveStream->writeSint32LE(val->left);
_saveStream->writeSint32LE(val->top);
@@ -813,7 +782,7 @@ bool BasePersistenceManager::transfer(const char *name, Rect32 *val) {
//////////////////////////////////////////////////////////////////////////
// POINT
-bool BasePersistenceManager::transfer(const char *name, Point32 *val) {
+bool BasePersistenceManager::transferPoint32(const char *name, Point32 *val) {
if (_saving) {
_saveStream->writeSint32LE(val->x);
_saveStream->writeSint32LE(val->y);
@@ -834,7 +803,7 @@ bool BasePersistenceManager::transfer(const char *name, Point32 *val) {
//////////////////////////////////////////////////////////////////////////
// Vector2
-bool BasePersistenceManager::transfer(const char *name, Vector2 *val) {
+bool BasePersistenceManager::transferVector2(const char *name, Vector2 *val) {
if (_saving) {
putFloat(val->x);
putFloat(val->y);
diff --git a/engines/wintermute/base/base_persistence_manager.h b/engines/wintermute/base/base_persistence_manager.h
index 3c0587b362..43259b26ff 100644
--- a/engines/wintermute/base/base_persistence_manager.h
+++ b/engines/wintermute/base/base_persistence_manager.h
@@ -74,19 +74,18 @@ public:
byte *_richBuffer;
bool transferPtr(const char *name, void *val);
- bool transfer(const char *name, int32 *val);
- bool transfer(const char *name, uint32 *val);
+ bool transferSint32(const char *name, int32 *val);
+ bool transferUint32(const char *name, uint32 *val);
bool transferFloat(const char *name, float *val);
- bool transfer(const char *name, double *val);
- bool transfer(const char *name, bool *val);
- bool transfer(const char *name, byte *val);
- bool transfer(const char *name, Rect32 *val);
- bool transfer(const char *name, Point32 *val);
- bool transfer(const char *name, const char **val);
- bool transfer(const char *name, char **val);
- bool transfer(const char *name, Common::String *val);
- bool transfer(const char *name, Vector2 *val);
- bool transfer(const char *name, AnsiStringArray &Val);
+ bool transferDouble(const char *name, double *val);
+ bool transferBool(const char *name, bool *val);
+ bool transferByte(const char *name, byte *val);
+ bool transferRect32(const char *name, Rect32 *val);
+ bool transferPoint32(const char *name, Point32 *val);
+ bool transferConstChar(const char *name, const char **val);
+ bool transferCharPtr(const char *name, char **val);
+ bool transferString(const char *name, Common::String *val);
+ bool transferVector2(const char *name, Vector2 *val);
BasePersistenceManager(const char *savePrefix = nullptr, bool deleteSingleton = false);
virtual ~BasePersistenceManager();
bool checkVersion(byte verMajor, byte verMinor, byte verBuild);
diff --git a/engines/wintermute/base/base_point.cpp b/engines/wintermute/base/base_point.cpp
index fe6ca941f3..84b6a629c7 100644
--- a/engines/wintermute/base/base_point.cpp
+++ b/engines/wintermute/base/base_point.cpp
@@ -54,8 +54,8 @@ BasePoint::BasePoint(int initX, int initY) {
//////////////////////////////////////////////////////////////////////////
bool BasePoint::persist(BasePersistenceManager *persistMgr) {
- persistMgr->transfer(TMEMBER(x));
- persistMgr->transfer(TMEMBER(y));
+ persistMgr->transferSint32(TMEMBER(x));
+ persistMgr->transferSint32(TMEMBER(y));
return STATUS_OK;
}
diff --git a/engines/wintermute/base/base_region.cpp b/engines/wintermute/base/base_region.cpp
index 36036a1f18..dc17b18ea2 100644
--- a/engines/wintermute/base/base_region.cpp
+++ b/engines/wintermute/base/base_region.cpp
@@ -48,7 +48,7 @@ BaseRegion::BaseRegion(BaseGame *inGame) : BaseObject(inGame) {
_lastMimicScale = -1;
_lastMimicX = _lastMimicY = INT_MIN;
- BasePlatform::setRectEmpty(&_rect);
+ _rect.setEmpty();
}
@@ -65,7 +65,7 @@ void BaseRegion::cleanup() {
}
_points.clear();
- BasePlatform::setRectEmpty(&_rect);
+ _rect.setEmpty();
_editorSelectedPoint = -1;
}
@@ -102,7 +102,7 @@ bool BaseRegion::pointInRegion(int x, int y) {
//////////////////////////////////////////////////////////////////////////
bool BaseRegion::loadFile(const char *filename) {
- byte *buffer = BaseFileManager::getEngineInstance()->readWholeFile(filename);
+ char *buffer = (char *)BaseFileManager::getEngineInstance()->readWholeFile(filename);
if (buffer == nullptr) {
BaseEngine::LOG(0, "BaseRegion::LoadFile failed for file '%s'", filename);
return STATUS_FAILED;
@@ -135,7 +135,7 @@ TOKEN_DEF(EDITOR_SELECTED_POINT)
TOKEN_DEF(PROPERTY)
TOKEN_DEF_END
//////////////////////////////////////////////////////////////////////////
-bool BaseRegion::loadBuffer(byte *buffer, bool complete) {
+bool BaseRegion::loadBuffer(char *buffer, bool complete) {
TOKEN_TABLE_START(commands)
TOKEN_TABLE(REGION)
TOKEN_TABLE(TEMPLATE)
@@ -148,12 +148,12 @@ bool BaseRegion::loadBuffer(byte *buffer, bool complete) {
TOKEN_TABLE(PROPERTY)
TOKEN_TABLE_END
- byte *params;
+ char *params;
int cmd;
BaseParser parser;
if (complete) {
- if (parser.getCommand((char **)&buffer, commands, (char **)&params) != TOKEN_REGION) {
+ if (parser.getCommand(&buffer, commands, &params) != TOKEN_REGION) {
BaseEngine::LOG(0, "'REGION' keyword expected.");
return STATUS_FAILED;
}
@@ -165,39 +165,39 @@ bool BaseRegion::loadBuffer(byte *buffer, bool complete) {
}
_points.clear();
- while ((cmd = parser.getCommand((char **)&buffer, commands, (char **)&params)) > 0) {
+ while ((cmd = parser.getCommand(&buffer, commands, &params)) > 0) {
switch (cmd) {
case TOKEN_TEMPLATE:
- if (DID_FAIL(loadFile((char *)params))) {
+ if (DID_FAIL(loadFile(params))) {
cmd = PARSERR_GENERIC;
}
break;
case TOKEN_NAME:
- setName((char *)params);
+ setName(params);
break;
case TOKEN_CAPTION:
- setCaption((char *)params);
+ setCaption(params);
break;
case TOKEN_ACTIVE:
- parser.scanStr((char *)params, "%b", &_active);
+ parser.scanStr(params, "%b", &_active);
break;
case TOKEN_POINT: {
int x, y;
- parser.scanStr((char *)params, "%d,%d", &x, &y);
+ parser.scanStr(params, "%d,%d", &x, &y);
_points.add(new BasePoint(x, y));
}
break;
case TOKEN_SCRIPT:
- addScript((char *)params);
+ addScript(params);
break;
case TOKEN_EDITOR_SELECTED_POINT:
- parser.scanStr((char *)params, "%d", &_editorSelectedPoint);
+ parser.scanStr(params, "%d", &_editorSelectedPoint);
break;
case TOKEN_PROPERTY:
@@ -430,11 +430,11 @@ bool BaseRegion::persist(BasePersistenceManager *persistMgr) {
BaseObject::persist(persistMgr);
- persistMgr->transfer(TMEMBER(_active));
- persistMgr->transfer(TMEMBER(_editorSelectedPoint));
+ persistMgr->transferBool(TMEMBER(_active));
+ persistMgr->transferSint32(TMEMBER(_editorSelectedPoint));
persistMgr->transferFloat(TMEMBER(_lastMimicScale));
- persistMgr->transfer(TMEMBER(_lastMimicX));
- persistMgr->transfer(TMEMBER(_lastMimicY));
+ persistMgr->transferSint32(TMEMBER(_lastMimicX));
+ persistMgr->transferSint32(TMEMBER(_lastMimicY));
_points.persist(persistMgr);
return STATUS_OK;
@@ -491,7 +491,7 @@ bool BaseRegion::ptInPolygon(int32 x, int32 y) {
//////////////////////////////////////////////////////////////////////////
bool BaseRegion::getBoundingRect(Rect32 *rect) {
if (_points.size() == 0) {
- BasePlatform::setRectEmpty(rect);
+ rect->setEmpty();
} else {
int32 minX = INT_MAX, minY = INT_MAX, maxX = INT_MIN, maxY = INT_MIN;
@@ -502,7 +502,7 @@ bool BaseRegion::getBoundingRect(Rect32 *rect) {
maxX = MAX(maxX, _points[i]->x);
maxY = MAX(maxY, _points[i]->y);
}
- BasePlatform::setRect(rect, minX, minY, maxX, maxY);
+ rect->setRect(minX, minY, maxX, maxY);
}
return STATUS_OK;
}
diff --git a/engines/wintermute/base/base_region.h b/engines/wintermute/base/base_region.h
index 93ad6a6fbe..846dcfc341 100644
--- a/engines/wintermute/base/base_region.h
+++ b/engines/wintermute/base/base_region.h
@@ -48,7 +48,7 @@ public:
bool pointInRegion(int x, int y);
bool createRegion();
bool loadFile(const char *filename);
- bool loadBuffer(byte *buffer, bool complete = true);
+ bool loadBuffer(char *buffer, bool complete = true);
Rect32 _rect;
BaseArray<BasePoint *> _points;
virtual bool saveAsText(BaseDynamicBuffer *buffer, int indent) { return saveAsText(buffer, indent, nullptr); }
diff --git a/engines/wintermute/base/base_script_holder.cpp b/engines/wintermute/base/base_script_holder.cpp
index 25b8775a98..5fb0b62713 100644
--- a/engines/wintermute/base/base_script_holder.cpp
+++ b/engines/wintermute/base/base_script_holder.cpp
@@ -280,14 +280,14 @@ bool BaseScriptHolder::saveAsText(BaseDynamicBuffer *buffer, int indent) {
bool BaseScriptHolder::persist(BasePersistenceManager *persistMgr) {
BaseScriptable::persist(persistMgr);
- persistMgr->transfer(TMEMBER(_filename));
- persistMgr->transfer(TMEMBER(_freezable));
+ persistMgr->transferCharPtr(TMEMBER(_filename));
+ persistMgr->transferBool(TMEMBER(_freezable));
if (persistMgr->getIsSaving()) {
const char *name = getName();
- persistMgr->transfer(TMEMBER(name));
+ persistMgr->transferConstChar(TMEMBER(name));
} else {
char *name;
- persistMgr->transfer(TMEMBER(name));
+ persistMgr->transferCharPtr(TMEMBER(name));
setName(name);
delete[] name;
}
@@ -370,19 +370,19 @@ TOKEN_DEF(NAME)
TOKEN_DEF(VALUE)
TOKEN_DEF_END
//////////////////////////////////////////////////////////////////////////
-bool BaseScriptHolder::parseProperty(byte *buffer, bool complete) {
+bool BaseScriptHolder::parseProperty(char *buffer, bool complete) {
TOKEN_TABLE_START(commands)
TOKEN_TABLE(PROPERTY)
TOKEN_TABLE(NAME)
TOKEN_TABLE(VALUE)
TOKEN_TABLE_END
- byte *params;
+ char *params;
int cmd;
BaseParser parser;
if (complete) {
- if (parser.getCommand((char **)&buffer, commands, (char **)&params) != TOKEN_PROPERTY) {
+ if (parser.getCommand(&buffer, commands, &params) != TOKEN_PROPERTY) {
BaseEngine::LOG(0, "'PROPERTY' keyword expected.");
return STATUS_FAILED;
}
@@ -392,13 +392,13 @@ bool BaseScriptHolder::parseProperty(byte *buffer, bool complete) {
char *propName = nullptr;
char *propValue = nullptr;
- while ((cmd = parser.getCommand((char **)&buffer, commands, (char **)&params)) > 0) {
+ while ((cmd = parser.getCommand(&buffer, commands, &params)) > 0) {
switch (cmd) {
case TOKEN_NAME:
delete[] propName;
- propName = new char[strlen((char *)params) + 1];
+ propName = new char[strlen(params) + 1];
if (propName) {
- strcpy(propName, (char *)params);
+ strcpy(propName, params);
} else {
cmd = PARSERR_GENERIC;
}
@@ -406,9 +406,9 @@ bool BaseScriptHolder::parseProperty(byte *buffer, bool complete) {
case TOKEN_VALUE:
delete[] propValue;
- propValue = new char[strlen((char *)params) + 1];
+ propValue = new char[strlen(params) + 1];
if (propValue) {
- strcpy(propValue, (char *)params);
+ strcpy(propValue, params);
} else {
cmd = PARSERR_GENERIC;
}
diff --git a/engines/wintermute/base/base_script_holder.h b/engines/wintermute/base/base_script_holder.h
index c34b0378a1..b4e22a59ee 100644
--- a/engines/wintermute/base/base_script_holder.h
+++ b/engines/wintermute/base/base_script_holder.h
@@ -53,7 +53,7 @@ public:
bool applyEvent(const char *eventName, bool unbreakable = false);
void setFilename(const char *filename);
const char *getFilename() { return _filename; }
- bool parseProperty(byte *buffer, bool complete = true);
+ bool parseProperty(char *buffer, bool complete = true);
bool _freezable;
bool _ready;
diff --git a/engines/wintermute/base/base_scriptable.cpp b/engines/wintermute/base/base_scriptable.cpp
index be1e18c2c4..d2ff627f0a 100644
--- a/engines/wintermute/base/base_scriptable.cpp
+++ b/engines/wintermute/base/base_scriptable.cpp
@@ -153,7 +153,7 @@ void BaseScriptable::scSetBool(bool val) {
//////////////////////////////////////////////////////////////////////////
bool BaseScriptable::persist(BasePersistenceManager *persistMgr) {
persistMgr->transferPtr(TMEMBER_PTR(_gameRef));
- persistMgr->transfer(TMEMBER(_refCount));
+ persistMgr->transferSint32(TMEMBER(_refCount));
persistMgr->transferPtr(TMEMBER_PTR(_scProp));
persistMgr->transferPtr(TMEMBER_PTR(_scValue));
diff --git a/engines/wintermute/base/base_sprite.cpp b/engines/wintermute/base/base_sprite.cpp
index ab78c5ac7c..b1fcb42dcc 100644
--- a/engines/wintermute/base/base_sprite.cpp
+++ b/engines/wintermute/base/base_sprite.cpp
@@ -168,7 +168,7 @@ bool BaseSprite::loadFile(const Common::String &filename, int lifeTime, TSpriteC
ret = STATUS_OK;
}
} else {
- byte *buffer = BaseFileManager::getEngineInstance()->readWholeFile(filename);
+ char *buffer = (char *)BaseFileManager::getEngineInstance()->readWholeFile(filename);
if (buffer) {
if (DID_FAIL(ret = loadBuffer(buffer, true, lifeTime, cacheType))) {
BaseEngine::LOG(0, "Error parsing SPRITE file '%s'", filename.c_str());
@@ -204,7 +204,7 @@ TOKEN_DEF(EDITOR_BG_ALPHA)
TOKEN_DEF(EDITOR_PROPERTY)
TOKEN_DEF_END
//////////////////////////////////////////////////////////////////////
-bool BaseSprite::loadBuffer(byte *buffer, bool complete, int lifeTime, TSpriteCacheType cacheType) {
+bool BaseSprite::loadBuffer(char *buffer, bool complete, int lifeTime, TSpriteCacheType cacheType) {
TOKEN_TABLE_START(commands)
TOKEN_TABLE(CONTINUOUS)
TOKEN_TABLE(SPRITE)
@@ -223,7 +223,7 @@ bool BaseSprite::loadBuffer(byte *buffer, bool complete, int lifeTime, TSpriteCa
TOKEN_TABLE(EDITOR_PROPERTY)
TOKEN_TABLE_END
- byte *params;
+ char *params;
int cmd;
BaseParser parser;
@@ -231,7 +231,7 @@ bool BaseSprite::loadBuffer(byte *buffer, bool complete, int lifeTime, TSpriteCa
if (complete) {
- if (parser.getCommand((char **)&buffer, commands, (char **)&params) != TOKEN_SPRITE) {
+ if (parser.getCommand(&buffer, commands, &params) != TOKEN_SPRITE) {
BaseEngine::LOG(0, "'SPRITE' keyword expected.");
return STATUS_FAILED;
}
@@ -240,30 +240,30 @@ bool BaseSprite::loadBuffer(byte *buffer, bool complete, int lifeTime, TSpriteCa
int frameCount = 1;
BaseFrame *frame;
- while ((cmd = parser.getCommand((char **)&buffer, commands, (char **)&params)) > 0) {
+ while ((cmd = parser.getCommand(&buffer, commands, &params)) > 0) {
switch (cmd) {
case TOKEN_CONTINUOUS:
- parser.scanStr((char *)params, "%b", &_continuous);
+ parser.scanStr(params, "%b", &_continuous);
break;
case TOKEN_EDITOR_MUTED:
- parser.scanStr((char *)params, "%b", &_editorMuted);
+ parser.scanStr(params, "%b", &_editorMuted);
break;
case TOKEN_SCRIPT:
- addScript((char *)params);
+ addScript(params);
break;
case TOKEN_LOOPING:
- parser.scanStr((char *)params, "%b", &_looping);
+ parser.scanStr(params, "%b", &_looping);
break;
case TOKEN_PRECISE:
- parser.scanStr((char *)params, "%b", &_precise);
+ parser.scanStr(params, "%b", &_precise);
break;
case TOKEN_STREAMED:
- parser.scanStr((char *)params, "%b", &_streamed);
+ parser.scanStr(params, "%b", &_streamed);
if (_streamed && lifeTime == -1) {
lifeTime = 500;
cacheType = CACHE_ALL;
@@ -271,33 +271,33 @@ bool BaseSprite::loadBuffer(byte *buffer, bool complete, int lifeTime, TSpriteCa
break;
case TOKEN_STREAMED_KEEP_LOADED:
- parser.scanStr((char *)params, "%b", &_streamedKeepLoaded);
+ parser.scanStr(params, "%b", &_streamedKeepLoaded);
break;
case TOKEN_NAME:
- setName((char *)params);
+ setName(params);
break;
case TOKEN_EDITOR_BG_FILE:
if (_gameRef->_editorMode) {
delete[] _editorBgFile;
- _editorBgFile = new char[strlen((char *)params) + 1];
+ _editorBgFile = new char[strlen(params) + 1];
if (_editorBgFile) {
- strcpy(_editorBgFile, (char *)params);
+ strcpy(_editorBgFile, params);
}
}
break;
case TOKEN_EDITOR_BG_OFFSET_X:
- parser.scanStr((char *)params, "%d", &_editorBgOffsetX);
+ parser.scanStr(params, "%d", &_editorBgOffsetX);
break;
case TOKEN_EDITOR_BG_OFFSET_Y:
- parser.scanStr((char *)params, "%d", &_editorBgOffsetY);
+ parser.scanStr(params, "%d", &_editorBgOffsetY);
break;
case TOKEN_EDITOR_BG_ALPHA:
- parser.scanStr((char *)params, "%d", &_editorBgAlpha);
+ parser.scanStr(params, "%d", &_editorBgAlpha);
_editorBgAlpha = MIN<int32>(_editorBgAlpha, 255);
_editorBgAlpha = MAX<int32>(_editorBgAlpha, 0);
break;
@@ -462,7 +462,7 @@ bool BaseSprite::getBoundingRect(Rect32 *rect, int x, int y, float scaleX, float
return false;
}
- BasePlatform::setRectEmpty(rect);
+ rect->setEmpty();
for (uint32 i = 0; i < _frames.size(); i++) {
Rect32 frame;
Rect32 temp;
@@ -520,29 +520,29 @@ bool BaseSprite::saveAsText(BaseDynamicBuffer *buffer, int indent) {
bool BaseSprite::persist(BasePersistenceManager *persistMgr) {
BaseScriptHolder::persist(persistMgr);
- persistMgr->transfer(TMEMBER(_canBreak));
- persistMgr->transfer(TMEMBER(_changed));
- persistMgr->transfer(TMEMBER(_paused));
- persistMgr->transfer(TMEMBER(_continuous));
- persistMgr->transfer(TMEMBER(_currentFrame));
- persistMgr->transfer(TMEMBER(_editorAllFrames));
- persistMgr->transfer(TMEMBER(_editorBgAlpha));
- persistMgr->transfer(TMEMBER(_editorBgFile));
- persistMgr->transfer(TMEMBER(_editorBgOffsetX));
- persistMgr->transfer(TMEMBER(_editorBgOffsetY));
- persistMgr->transfer(TMEMBER(_editorMuted));
- persistMgr->transfer(TMEMBER(_finished));
+ persistMgr->transferBool(TMEMBER(_canBreak));
+ persistMgr->transferBool(TMEMBER(_changed));
+ persistMgr->transferBool(TMEMBER(_paused));
+ persistMgr->transferBool(TMEMBER(_continuous));
+ persistMgr->transferSint32(TMEMBER(_currentFrame));
+ persistMgr->transferBool(TMEMBER(_editorAllFrames));
+ persistMgr->transferSint32(TMEMBER(_editorBgAlpha));
+ persistMgr->transferCharPtr(TMEMBER(_editorBgFile));
+ persistMgr->transferSint32(TMEMBER(_editorBgOffsetX));
+ persistMgr->transferSint32(TMEMBER(_editorBgOffsetY));
+ persistMgr->transferBool(TMEMBER(_editorMuted));
+ persistMgr->transferBool(TMEMBER(_finished));
_frames.persist(persistMgr);
- persistMgr->transfer(TMEMBER(_lastFrameTime));
- persistMgr->transfer(TMEMBER(_looping));
- persistMgr->transfer(TMEMBER(_moveX));
- persistMgr->transfer(TMEMBER(_moveY));
+ persistMgr->transferUint32(TMEMBER(_lastFrameTime));
+ persistMgr->transferBool(TMEMBER(_looping));
+ persistMgr->transferSint32(TMEMBER(_moveX));
+ persistMgr->transferSint32(TMEMBER(_moveY));
persistMgr->transferPtr(TMEMBER_PTR(_owner));
- persistMgr->transfer(TMEMBER(_precise));
- persistMgr->transfer(TMEMBER(_streamed));
- persistMgr->transfer(TMEMBER(_streamedKeepLoaded));
+ persistMgr->transferBool(TMEMBER(_precise));
+ persistMgr->transferBool(TMEMBER(_streamed));
+ persistMgr->transferBool(TMEMBER(_streamedKeepLoaded));
return STATUS_OK;
diff --git a/engines/wintermute/base/base_sprite.h b/engines/wintermute/base/base_sprite.h
index 1387796895..54d595f655 100644
--- a/engines/wintermute/base/base_sprite.h
+++ b/engines/wintermute/base/base_sprite.h
@@ -53,7 +53,7 @@ public:
void reset();
bool isChanged();
bool isFinished();
- bool loadBuffer(byte *buffer, bool compete = true, int lifeTime = -1, TSpriteCacheType cacheType = CACHE_ALL);
+ bool loadBuffer(char *buffer, bool compete = true, int lifeTime = -1, TSpriteCacheType cacheType = CACHE_ALL);
bool loadFile(const Common::String &filename, int lifeTime = -1, TSpriteCacheType cacheType = CACHE_ALL);
bool draw(int x, int y, BaseObject *Register = nullptr, float zoomX = kDefaultZoomX, float zoomY = kDefaultZoomY, uint32 alpha = kDefaultRgbaMod);
bool _looping;
diff --git a/engines/wintermute/base/base_sub_frame.cpp b/engines/wintermute/base/base_sub_frame.cpp
index c22e0982a6..38eebb067b 100644
--- a/engines/wintermute/base/base_sub_frame.cpp
+++ b/engines/wintermute/base/base_sub_frame.cpp
@@ -34,7 +34,6 @@
#include "engines/wintermute/base/base_surface_storage.h"
#include "engines/wintermute/base/base_game.h"
#include "engines/wintermute/base/base_engine.h"
-#include "engines/wintermute/platform_osystem.h"
#include "engines/wintermute/base/gfx/base_renderer.h"
#include "engines/wintermute/base/scriptables/script_value.h"
#include "engines/wintermute/base/scriptables/script_stack.h"
@@ -54,7 +53,7 @@ BaseSubFrame::BaseSubFrame(BaseGame *inGame) : BaseScriptable(inGame, true) {
_transparent = 0xFFFF00FF;
_wantsDefaultRect = false;
- BasePlatform::setRectEmpty(&_rect);
+ _rect.setEmpty();
_editorSelected = false;
@@ -97,7 +96,7 @@ TOKEN_DEF(EDITOR_SELECTED)
TOKEN_DEF(EDITOR_PROPERTY)
TOKEN_DEF_END
//////////////////////////////////////////////////////////////////////
-bool BaseSubFrame::loadBuffer(byte *buffer, int lifeTime, bool keepLoaded) {
+bool BaseSubFrame::loadBuffer(char *buffer, int lifeTime, bool keepLoaded) {
TOKEN_TABLE_START(commands)
TOKEN_TABLE(IMAGE)
TOKEN_TABLE(TRANSPARENT)
@@ -121,13 +120,13 @@ bool BaseSubFrame::loadBuffer(byte *buffer, int lifeTime, bool keepLoaded) {
int r = 255, g = 255, b = 255;
int ar = 255, ag = 255, ab = 255, alpha = 255;
bool custoTrans = false;
- BasePlatform::setRectEmpty(&rect);
+ rect.setEmpty();
char *surfaceFile = nullptr;
delete _surface;
_surface = nullptr;
- while ((cmd = parser.getCommand((char **)&buffer, commands, &params)) > 0) {
+ while ((cmd = parser.getCommand(&buffer, commands, &params)) > 0) {
switch (cmd) {
case TOKEN_IMAGE:
surfaceFile = params;
@@ -179,7 +178,7 @@ bool BaseSubFrame::loadBuffer(byte *buffer, int lifeTime, bool keepLoaded) {
break;
case TOKEN_EDITOR_PROPERTY:
- parseEditorProperty((byte *)params, false);
+ parseEditorProperty(params, false);
break;
}
}
@@ -208,7 +207,7 @@ bool BaseSubFrame::loadBuffer(byte *buffer, int lifeTime, bool keepLoaded) {
return STATUS_FAILED;
}
*/
- if (BasePlatform::isRectEmpty(&rect)) {
+ if (rect.isRectEmpty()) {
setDefaultRect();
} else {
setRect(rect);
@@ -219,7 +218,7 @@ bool BaseSubFrame::loadBuffer(byte *buffer, int lifeTime, bool keepLoaded) {
Rect32 BaseSubFrame::getRect() {
if (_wantsDefaultRect && _surface) {
- BasePlatform::setRect(&_rect, 0, 0, _surface->getWidth(), _surface->getHeight());
+ _rect.setRect(0, 0, _surface->getWidth(), _surface->getHeight());
_wantsDefaultRect = false;
}
return _rect;
@@ -294,11 +293,10 @@ bool BaseSubFrame::getBoundingRect(Rect32 *rect, int x, int y, float scaleX, flo
float ratioX = scaleX / 100.0f;
float ratioY = scaleY / 100.0f;
- BasePlatform::setRect(rect,
- (int)(x - _hotspotX * ratioX),
- (int)(y - _hotspotY * ratioY),
- (int)(x - _hotspotX * ratioX + (getRect().right - getRect().left) * ratioX),
- (int)(y - _hotspotY * ratioY + (getRect().bottom - getRect().top) * ratioY));
+ rect->setRect((int)(x - _hotspotX * ratioX),
+ (int)(y - _hotspotY * ratioY),
+ (int)(x - _hotspotX * ratioX + (getRect().right - getRect().left) * ratioX),
+ (int)(y - _hotspotY * ratioY + (getRect().bottom - getRect().top) * ratioY));
return true;
}
@@ -318,9 +316,9 @@ bool BaseSubFrame::saveAsText(BaseDynamicBuffer *buffer, int indent, bool comple
}
Rect32 rect;
- BasePlatform::setRectEmpty(&rect);
+ rect.setEmpty();
if (_surface) {
- BasePlatform::setRect(&rect, 0, 0, _surface->getWidth(), _surface->getHeight());
+ rect.setRect(0, 0, _surface->getWidth(), _surface->getHeight());
}
if (!(rect == getRect())) {
buffer->putTextIndent(indent + 2, "RECT { %d,%d,%d,%d }\n", getRect().left, getRect().top, getRect().right, getRect().bottom);
@@ -376,7 +374,7 @@ void BaseSubFrame::setDefaultRect() {
_wantsDefaultRect = true;
} else {
_wantsDefaultRect = false;
- BasePlatform::setRectEmpty(&_rect);
+ _rect.setEmpty();
}
}
@@ -386,27 +384,27 @@ bool BaseSubFrame::persist(BasePersistenceManager *persistMgr) {
BaseScriptable::persist(persistMgr);
- persistMgr->transfer(TMEMBER(_2DOnly));
- persistMgr->transfer(TMEMBER(_3DOnly));
- persistMgr->transfer(TMEMBER(_alpha));
- persistMgr->transfer(TMEMBER(_decoration));
- persistMgr->transfer(TMEMBER(_editorSelected));
- persistMgr->transfer(TMEMBER(_hotspotX));
- persistMgr->transfer(TMEMBER(_hotspotY));
- persistMgr->transfer(TMEMBER(_rect));
- persistMgr->transfer(TMEMBER(_wantsDefaultRect));
-
- persistMgr->transfer(TMEMBER(_surfaceFilename));
- persistMgr->transfer(TMEMBER(_cKDefault));
- persistMgr->transfer(TMEMBER(_cKRed));
- persistMgr->transfer(TMEMBER(_cKGreen));
- persistMgr->transfer(TMEMBER(_cKBlue));
- persistMgr->transfer(TMEMBER(_lifeTime));
-
- persistMgr->transfer(TMEMBER(_keepLoaded));
- persistMgr->transfer(TMEMBER(_mirrorX));
- persistMgr->transfer(TMEMBER(_mirrorY));
- persistMgr->transfer(TMEMBER(_transparent));
+ persistMgr->transferBool(TMEMBER(_2DOnly));
+ persistMgr->transferBool(TMEMBER(_3DOnly));
+ persistMgr->transferUint32(TMEMBER(_alpha));
+ persistMgr->transferBool(TMEMBER(_decoration));
+ persistMgr->transferBool(TMEMBER(_editorSelected));
+ persistMgr->transferSint32(TMEMBER(_hotspotX));
+ persistMgr->transferSint32(TMEMBER(_hotspotY));
+ persistMgr->transferRect32(TMEMBER(_rect));
+ persistMgr->transferBool(TMEMBER(_wantsDefaultRect));
+
+ persistMgr->transferCharPtr(TMEMBER(_surfaceFilename));
+ persistMgr->transferBool(TMEMBER(_cKDefault));
+ persistMgr->transferByte(TMEMBER(_cKRed));
+ persistMgr->transferByte(TMEMBER(_cKGreen));
+ persistMgr->transferByte(TMEMBER(_cKBlue));
+ persistMgr->transferSint32(TMEMBER(_lifeTime));
+
+ persistMgr->transferBool(TMEMBER(_keepLoaded));
+ persistMgr->transferBool(TMEMBER(_mirrorX));
+ persistMgr->transferBool(TMEMBER(_mirrorY));
+ persistMgr->transferUint32(TMEMBER(_transparent));
return STATUS_OK;
}
diff --git a/engines/wintermute/base/base_sub_frame.h b/engines/wintermute/base/base_sub_frame.h
index ba3d5b955a..4e164467e2 100644
--- a/engines/wintermute/base/base_sub_frame.h
+++ b/engines/wintermute/base/base_sub_frame.h
@@ -51,7 +51,7 @@ public:
bool _editorSelected;
BaseSubFrame(BaseGame *inGame);
virtual ~BaseSubFrame();
- bool loadBuffer(byte *buffer, int lifeTime, bool keepLoaded);
+ bool loadBuffer(char *buffer, int lifeTime, bool keepLoaded);
bool draw(int x, int y, BaseObject *registerOwner = nullptr, float zoomX = 100, float zoomY = 100, bool precise = true, uint32 alpha = 0xFFFFFFFF, float rotate = 0.0f, TSpriteBlendMode blendMode = BLEND_NORMAL);
bool getBoundingRect(Rect32 *rect, int x, int y, float scaleX = 100, float scaleY = 100);
const char* getSurfaceFilename();
diff --git a/engines/wintermute/base/base_viewport.cpp b/engines/wintermute/base/base_viewport.cpp
index 09ac80e9de..a6e8b17927 100644
--- a/engines/wintermute/base/base_viewport.cpp
+++ b/engines/wintermute/base/base_viewport.cpp
@@ -29,7 +29,6 @@
#include "engines/wintermute/base/base_viewport.h"
#include "engines/wintermute/base/base_engine.h"
#include "engines/wintermute/base/base_persistence_manager.h"
-#include "engines/wintermute/platform_osystem.h"
#include "engines/wintermute/base/gfx/base_renderer.h"
namespace Wintermute {
@@ -38,7 +37,7 @@ IMPLEMENT_PERSISTENT(BaseViewport, false)
//////////////////////////////////////////////////////////////////////////
BaseViewport::BaseViewport(BaseGame *inGame) : BaseClass(inGame) {
- BasePlatform::setRectEmpty(&_rect);
+ _rect.setEmpty();
_mainObject = nullptr;
_offsetX = _offsetY = 0;
}
@@ -56,9 +55,9 @@ bool BaseViewport::persist(BasePersistenceManager *persistMgr) {
persistMgr->transferPtr(TMEMBER_PTR(_gameRef));
persistMgr->transferPtr(TMEMBER_PTR(_mainObject));
- persistMgr->transfer(TMEMBER(_offsetX));
- persistMgr->transfer(TMEMBER(_offsetY));
- persistMgr->transfer(TMEMBER(_rect));
+ persistMgr->transferSint32(TMEMBER(_offsetX));
+ persistMgr->transferSint32(TMEMBER(_offsetY));
+ persistMgr->transferRect32(TMEMBER(_rect));
return STATUS_OK;
}
@@ -73,7 +72,7 @@ bool BaseViewport::setRect(int32 left, int32 top, int32 right, int32 bottom, boo
bottom = MIN(bottom, BaseEngine::instance().getRenderer()->getHeight());
}
- BasePlatform::setRect(&_rect, left, top, right, bottom);
+ _rect.setRect(left, top, right, bottom);
_offsetX = left;
_offsetY = top;
return STATUS_OK;
diff --git a/engines/wintermute/base/file/base_disk_file.cpp b/engines/wintermute/base/file/base_disk_file.cpp
index 7391d819fc..808dc9e00d 100644
--- a/engines/wintermute/base/file/base_disk_file.cpp
+++ b/engines/wintermute/base/file/base_disk_file.cpp
@@ -117,6 +117,8 @@ Common::SeekableReadStream *openDiskFile(const Common::String &filename) {
if (fixedFilename.contains(':')) {
if (fixedFilename.hasPrefix("c:/windows/fonts/")) { // East Side Story refers to "c:\windows\fonts\framd.ttf"
fixedFilename = filename.c_str() + 14;
+ } else if (fixedFilename.hasPrefix("c:/carol6/svn/data/")) { // Carol Reed 6: Black Circle refers to "c:\carol6\svn\data\sprites\system\help.png"
+ fixedFilename = fixedFilename.c_str() + 19;
} else {
error("openDiskFile::Absolute path or invalid filename used in %s", filename.c_str());
}
@@ -149,7 +151,8 @@ Common::SeekableReadStream *openDiskFile(const Common::String &filename) {
}
if (compressed) {
- uint32 dataOffset, compSize, uncompSize;
+ uint32 dataOffset, compSize;
+ unsigned long uncompSize;
dataOffset = file->readUint32LE();
compSize = file->readUint32LE();
uncompSize = file->readUint32LE();
@@ -171,7 +174,7 @@ Common::SeekableReadStream *openDiskFile(const Common::String &filename) {
file->seek(dataOffset + prefixSize, SEEK_SET);
file->read(compBuffer, compSize);
- if (Common::uncompress(data, (unsigned long *)&uncompSize, compBuffer, compSize) != true) {
+ if (Common::uncompress(data, &uncompSize, compBuffer, compSize) != true) {
error("Error uncompressing file '%s'", filename.c_str());
delete[] compBuffer;
delete file;
diff --git a/engines/wintermute/base/font/base_font.cpp b/engines/wintermute/base/font/base_font.cpp
index 26bc0e7985..2a394616d1 100644
--- a/engines/wintermute/base/font/base_font.cpp
+++ b/engines/wintermute/base/font/base_font.cpp
@@ -118,18 +118,18 @@ bool BaseFont::isTrueType(BaseGame *gameRef, const Common::String &filename) {
TOKEN_TABLE_END
- byte *buffer = BaseFileManager::getEngineInstance()->readWholeFile(filename);
+ char *buffer = (char *)BaseFileManager::getEngineInstance()->readWholeFile(filename);
if (buffer == nullptr) {
return false;
}
- byte *workBuffer = buffer;
+ char *workBuffer = buffer;
char *params;
BaseParser parser;
bool ret = false;
- if (parser.getCommand((char **)&workBuffer, commands, (char **)&params) == TOKEN_TTFONT) {
+ if (parser.getCommand(&workBuffer, commands, &params) == TOKEN_TTFONT) {
ret = true;
}
diff --git a/engines/wintermute/base/font/base_font_bitmap.cpp b/engines/wintermute/base/font/base_font_bitmap.cpp
index 890a9a2f83..95f9a83a6a 100644
--- a/engines/wintermute/base/font/base_font_bitmap.cpp
+++ b/engines/wintermute/base/font/base_font_bitmap.cpp
@@ -37,7 +37,6 @@
#include "engines/wintermute/base/base_frame.h"
#include "engines/wintermute/base/base_sprite.h"
#include "engines/wintermute/base/base_file_manager.h"
-#include "engines/wintermute/platform_osystem.h"
namespace Wintermute {
@@ -253,7 +252,7 @@ void BaseFontBitmap::drawChar(byte c, int x, int y) {
tileWidth = _widths[c];
}
- BasePlatform::setRect(&rect, col * _tileWidth, row * _tileHeight, col * _tileWidth + tileWidth, (row + 1)*_tileHeight);
+ rect.setRect(col * _tileWidth, row * _tileHeight, col * _tileWidth + tileWidth, (row + 1) * _tileHeight);
bool handled = false;
if (_sprite) {
_sprite->getCurrentFrame();
@@ -272,7 +271,7 @@ void BaseFontBitmap::drawChar(byte c, int x, int y) {
//////////////////////////////////////////////////////////////////////
bool BaseFontBitmap::loadFile(const Common::String &filename) {
- byte *buffer = BaseFileManager::getEngineInstance()->readWholeFile(filename);
+ char *buffer = (char *)BaseFileManager::getEngineInstance()->readWholeFile(filename);
if (buffer == nullptr) {
_gameRef->LOG(0, "BaseFontBitmap::LoadFile failed for file '%s'", filename.c_str());
return STATUS_FAILED;
@@ -311,7 +310,7 @@ TOKEN_DEF(WIDTHS_FRAME)
TOKEN_DEF(PAINT_WHOLE_CELL)
TOKEN_DEF_END
//////////////////////////////////////////////////////////////////////
-bool BaseFontBitmap::loadBuffer(byte *buffer) {
+bool BaseFontBitmap::loadBuffer(char *buffer) {
TOKEN_TABLE_START(commands)
TOKEN_TABLE(FONTEXT_FIX)
TOKEN_TABLE(FONT)
@@ -335,11 +334,11 @@ bool BaseFontBitmap::loadBuffer(byte *buffer) {
int cmd;
BaseParser parser;
- if (parser.getCommand((char **)&buffer, commands, (char **)&params) != TOKEN_FONT) {
+ if (parser.getCommand(&buffer, commands, &params) != TOKEN_FONT) {
_gameRef->LOG(0, "'FONT' keyword expected.");
return STATUS_FAILED;
}
- buffer = (byte *)params;
+ buffer = params;
int widths[300];
int num = 0, defaultWidth = 8;
@@ -354,15 +353,15 @@ bool BaseFontBitmap::loadBuffer(byte *buffer) {
int spaceWidth = 0;
int expandWidth = 0;
- while ((cmd = parser.getCommand((char **)&buffer, commands, (char **)&params)) > 0) {
+ while ((cmd = parser.getCommand(&buffer, commands, &params)) > 0) {
switch (cmd) {
case TOKEN_IMAGE:
- surfaceFile = (char *)params;
+ surfaceFile = params;
break;
case TOKEN_SPRITE:
- spriteFile = (char *)params;
+ spriteFile = params;
break;
case TOKEN_TRANSPARENT:
@@ -418,7 +417,7 @@ bool BaseFontBitmap::loadBuffer(byte *buffer) {
break;
case TOKEN_EDITOR_PROPERTY:
- parseEditorProperty((byte *)params, false);
+ parseEditorProperty(params, false);
break;
}
@@ -496,13 +495,13 @@ bool BaseFontBitmap::loadBuffer(byte *buffer) {
bool BaseFontBitmap::persist(BasePersistenceManager *persistMgr) {
BaseFont::persist(persistMgr);
- persistMgr->transfer(TMEMBER(_numColumns));
+ persistMgr->transferSint32(TMEMBER(_numColumns));
persistMgr->transferPtr(TMEMBER_PTR(_subframe));
- persistMgr->transfer(TMEMBER(_tileHeight));
- persistMgr->transfer(TMEMBER(_tileWidth));
+ persistMgr->transferSint32(TMEMBER(_tileHeight));
+ persistMgr->transferSint32(TMEMBER(_tileWidth));
persistMgr->transferPtr(TMEMBER_PTR(_sprite));
- persistMgr->transfer(TMEMBER(_widthsFrame));
+ persistMgr->transferSint32(TMEMBER(_widthsFrame));
if (persistMgr->getIsSaving()) {
persistMgr->putBytes(_widths, sizeof(_widths));
@@ -511,8 +510,8 @@ bool BaseFontBitmap::persist(BasePersistenceManager *persistMgr) {
}
- persistMgr->transfer(TMEMBER(_fontextFix));
- persistMgr->transfer(TMEMBER(_wholeCell));
+ persistMgr->transferBool(TMEMBER(_fontextFix));
+ persistMgr->transferBool(TMEMBER(_wholeCell));
return STATUS_OK;
diff --git a/engines/wintermute/base/font/base_font_bitmap.h b/engines/wintermute/base/font/base_font_bitmap.h
index c810777446..77620d8b88 100644
--- a/engines/wintermute/base/font/base_font_bitmap.h
+++ b/engines/wintermute/base/font/base_font_bitmap.h
@@ -37,7 +37,7 @@ class BaseSubFrame;
class BaseFontBitmap : public BaseFont {
public:
DECLARE_PERSISTENT(BaseFontBitmap, BaseFont)
- bool loadBuffer(byte *Buffer);
+ bool loadBuffer(char *buffer);
bool loadFile(const Common::String &filename);
virtual int getTextWidth(const byte *text, int maxLength = -1) override;
virtual int getTextHeight(const byte *text, int width) override;
diff --git a/engines/wintermute/base/font/base_font_truetype.cpp b/engines/wintermute/base/font/base_font_truetype.cpp
index b6f372f377..b879e789e3 100644
--- a/engines/wintermute/base/font/base_font_truetype.cpp
+++ b/engines/wintermute/base/font/base_font_truetype.cpp
@@ -34,7 +34,6 @@
#include "engines/wintermute/base/base_game.h"
#include "engines/wintermute/base/base_file_manager.h"
#include "engines/wintermute/utils/utils.h"
-#include "engines/wintermute/platform_osystem.h"
#include "engines/wintermute/wintermute.h"
#include "graphics/fonts/ttf.h"
#include "graphics/fontman.h"
@@ -122,7 +121,7 @@ int BaseFontTT::getTextWidth(const byte *text, int maxLength) {
}
if (maxLength >= 0 && textStr.size() > (uint32)maxLength) {
- textStr = Common::String(textStr.c_str(), (uint32)maxLength);
+ textStr = WideString(textStr.c_str(), (uint32)maxLength);
}
//text = text.substr(0, MaxLength); // TODO: Remove
@@ -156,19 +155,19 @@ void BaseFontTT::drawText(const byte *text, int x, int y, int width, TTextAlign
return;
}
- WideString textStr = (const char *)text;
+ WideString textStr;
// TODO: Why do we still insist on Widestrings everywhere?
- /* if (_gameRef->_textEncoding == TEXT_UTF8) text = StringUtil::Utf8ToWide((char *)Text);
- else text = StringUtil::AnsiToWide((char *)Text);*/
// HACK: J.U.L.I.A. uses CP1252, we need to fix that,
// And we still don't have any UTF8-support.
- if (_gameRef->_textEncoding != TEXT_UTF8) {
+ if (_gameRef->_textEncoding == TEXT_UTF8) {
+ textStr = StringUtil::utf8ToWide((const char *)text);
+ } else {
textStr = StringUtil::ansiToWide((const char *)text);
}
if (maxLength >= 0 && textStr.size() > (uint32)maxLength) {
- textStr = Common::String(textStr.c_str(), (uint32)maxLength);
+ textStr = WideString(textStr.c_str(), (uint32)maxLength);
}
//text = text.substr(0, MaxLength); // TODO: Remove
@@ -227,7 +226,7 @@ void BaseFontTT::drawText(const byte *text, int x, int y, int width, TTextAlign
// and paint it
if (surface) {
Rect32 rc;
- BasePlatform::setRect(&rc, 0, 0, surface->getWidth(), surface->getHeight());
+ rc.setRect(0, 0, surface->getWidth(), surface->getHeight());
for (uint32 i = 0; i < _layers.size(); i++) {
uint32 color = _layers[i]->_color;
uint32 origForceAlpha = renderer->_forceAlphaColor;
@@ -249,7 +248,7 @@ BaseSurface *BaseFontTT::renderTextToTexture(const WideString &text, int width,
//TextLineList lines;
// TODO: Use WideString-conversion here.
//WrapText(text, width, maxHeight, lines);
- Common::Array<Common::String> lines;
+ Common::Array<WideString> lines;
_font->wordWrapText(text, width, lines);
while (maxHeight > 0 && lines.size() * _lineHeight > maxHeight) {
@@ -268,7 +267,8 @@ BaseSurface *BaseFontTT::renderTextToTexture(const WideString &text, int width,
alignment = Graphics::kTextAlignRight;
}
- debugC(kWintermuteDebugFont, "%s %d %d %d %d", text.c_str(), RGBCOLGetR(_layers[0]->_color), RGBCOLGetG(_layers[0]->_color), RGBCOLGetB(_layers[0]->_color), RGBCOLGetA(_layers[0]->_color));
+ // TODO: This debug call does not work with WideString because text.c_str() returns an uint32 array.
+ //debugC(kWintermuteDebugFont, "%s %d %d %d %d", text.c_str(), RGBCOLGetR(_layers[0]->_color), RGBCOLGetG(_layers[0]->_color), RGBCOLGetB(_layers[0]->_color), RGBCOLGetA(_layers[0]->_color));
// void drawString(Surface *dst, const Common::String &str, int x, int y, int w, uint32 color, TextAlign align = kTextAlignLeft, int deltax = 0, bool useEllipsis = true) const;
Graphics::Surface *surface = new Graphics::Surface();
if (_deletableFont) { // We actually have a TTF
@@ -277,7 +277,7 @@ BaseSurface *BaseFontTT::renderTextToTexture(const WideString &text, int width,
surface->create((uint16)width, (uint16)(_lineHeight * lines.size()), Graphics::PixelFormat(2, 5, 5, 5, 1, 11, 6, 1, 0));
}
uint32 useColor = 0xffffffff;
- Common::Array<Common::String>::iterator it;
+ Common::Array<WideString>::iterator it;
int heightOffset = 0;
for (it = lines.begin(); it != lines.end(); ++it) {
_font->drawString(surface, *it, 0, heightOffset, width, useColor, alignment);
@@ -286,6 +286,26 @@ BaseSurface *BaseFontTT::renderTextToTexture(const WideString &text, int width,
BaseSurface *retSurface = _gameRef->_renderer->createSurface();
Graphics::Surface *convertedSurface = surface->convertTo(_gameRef->_renderer->getPixelFormat());
+
+ if (_deletableFont) {
+ // Reconstruct the alpha channel of the font.
+
+ // Since we painted it with color 0xFFFFFFFF onto a black background,
+ // the alpha channel is gone, but the color value of each pixel corresponds
+ // to its original alpha value.
+
+ Graphics::PixelFormat format = _gameRef->_renderer->getPixelFormat();
+ uint32 *pixels = (uint32 *)convertedSurface->getPixels();
+
+ // This is a Surface we created ourselves, so no empty space between rows.
+ for (int i = 0; i < surface->w * surface->h; ++i) {
+ uint8 a, r, g, b;
+ format.colorToRGB(*pixels, r, g, b);
+ a = r;
+ *pixels++ = format.ARGBToColor(a, r, g, b);
+ }
+ }
+
retSurface->putSurface(*convertedSurface, true);
convertedSurface->free();
surface->free();
@@ -304,7 +324,7 @@ int BaseFontTT::getLetterHeight() {
//////////////////////////////////////////////////////////////////////
bool BaseFontTT::loadFile(const Common::String &filename) {
- byte *buffer = BaseFileManager::getEngineInstance()->readWholeFile(filename);
+ char *buffer = (char *)BaseFileManager::getEngineInstance()->readWholeFile(filename);
if (buffer == nullptr) {
_gameRef->LOG(0, "BaseFontTT::LoadFile failed for file '%s'", filename.c_str());
return STATUS_FAILED;
@@ -341,7 +361,7 @@ TOKEN_DEF(OFFSET_X)
TOKEN_DEF(OFFSET_Y)
TOKEN_DEF_END
//////////////////////////////////////////////////////////////////////
-bool BaseFontTT::loadBuffer(byte *buffer) {
+bool BaseFontTT::loadBuffer(char *buffer) {
TOKEN_TABLE_START(commands)
TOKEN_TABLE(TTFONT)
TOKEN_TABLE(SIZE)
@@ -361,15 +381,15 @@ bool BaseFontTT::loadBuffer(byte *buffer) {
int cmd;
BaseParser parser;
- if (parser.getCommand((char **)&buffer, commands, (char **)&params) != TOKEN_TTFONT) {
+ if (parser.getCommand(&buffer, commands, &params) != TOKEN_TTFONT) {
_gameRef->LOG(0, "'TTFONT' keyword expected.");
return STATUS_FAILED;
}
- buffer = (byte *)params;
+ buffer = params;
uint32 baseColor = 0x00000000;
- while ((cmd = parser.getCommand((char **)&buffer, commands, (char **)&params)) > 0) {
+ while ((cmd = parser.getCommand(&buffer, commands, &params)) > 0) {
switch (cmd) {
case TOKEN_SIZE:
parser.scanStr(params, "%d", &_fontHeight);
@@ -419,7 +439,7 @@ bool BaseFontTT::loadBuffer(byte *buffer) {
case TOKEN_LAYER: {
BaseTTFontLayer *layer = new BaseTTFontLayer;
- if (layer && DID_SUCCEED(parseLayer(layer, (byte *)params))) {
+ if (layer && DID_SUCCEED(parseLayer(layer, params))) {
_layers.add(layer);
} else {
delete layer;
@@ -452,7 +472,7 @@ bool BaseFontTT::loadBuffer(byte *buffer) {
//////////////////////////////////////////////////////////////////////////
-bool BaseFontTT::parseLayer(BaseTTFontLayer *layer, byte *buffer) {
+bool BaseFontTT::parseLayer(BaseTTFontLayer *layer, char *buffer) {
TOKEN_TABLE_START(commands)
TOKEN_TABLE(OFFSET_X)
TOKEN_TABLE(OFFSET_Y)
@@ -464,7 +484,7 @@ bool BaseFontTT::parseLayer(BaseTTFontLayer *layer, byte *buffer) {
int cmd;
BaseParser parser;
- while ((cmd = parser.getCommand((char **)&buffer, commands, (char **)&params)) > 0) {
+ while ((cmd = parser.getCommand(&buffer, commands, &params)) > 0) {
switch (cmd) {
case TOKEN_OFFSET_X:
parser.scanStr(params, "%d", &layer->_offsetX);
@@ -501,25 +521,25 @@ bool BaseFontTT::parseLayer(BaseTTFontLayer *layer, byte *buffer) {
bool BaseFontTT::persist(BasePersistenceManager *persistMgr) {
BaseFont::persist(persistMgr);
- persistMgr->transfer(TMEMBER(_isBold));
- persistMgr->transfer(TMEMBER(_isItalic));
- persistMgr->transfer(TMEMBER(_isUnderline));
- persistMgr->transfer(TMEMBER(_isStriked));
- persistMgr->transfer(TMEMBER(_fontHeight));
- persistMgr->transfer(TMEMBER(_fontFile));
+ persistMgr->transferBool(TMEMBER(_isBold));
+ persistMgr->transferBool(TMEMBER(_isItalic));
+ persistMgr->transferBool(TMEMBER(_isUnderline));
+ persistMgr->transferBool(TMEMBER(_isStriked));
+ persistMgr->transferSint32(TMEMBER(_fontHeight));
+ persistMgr->transferCharPtr(TMEMBER(_fontFile));
// persist layers
int32 numLayers;
if (persistMgr->getIsSaving()) {
numLayers = _layers.size();
- persistMgr->transfer(TMEMBER(numLayers));
+ persistMgr->transferSint32(TMEMBER(numLayers));
for (int i = 0; i < numLayers; i++) {
_layers[i]->persist(persistMgr);
}
} else {
numLayers = _layers.size();
- persistMgr->transfer(TMEMBER(numLayers));
+ persistMgr->transferSint32(TMEMBER(numLayers));
for (int i = 0; i < numLayers; i++) {
BaseTTFontLayer *layer = new BaseTTFontLayer;
layer->persist(persistMgr);
@@ -549,13 +569,22 @@ bool BaseFontTT::initFont() {
return STATUS_FAILED;
}
#ifdef USE_FREETYPE2
+ Common::String fallbackFilename;
+ // Handle Bold atleast for the fallback-case.
+ // TODO: Handle italic. (Needs a test-case)
+ if (_isBold) {
+ fallbackFilename = "FreeSansBold.ttf";
+ } else {
+ fallbackFilename = "FreeSans.ttf";
+ }
+
Common::SeekableReadStream *file = BaseFileManager::getEngineInstance()->openFile(_fontFile);
if (!file) {
if (Common::String(_fontFile) != "arial.ttf") {
warning("%s has no replacement font yet, using FreeSans for now (if available)", _fontFile);
}
// Fallback1: Try to find FreeSans.ttf
- file = SearchMan.createReadStreamForMember("FreeSans.ttf");
+ file = SearchMan.createReadStreamForMember(fallbackFilename);
}
if (file) {
@@ -582,9 +611,9 @@ bool BaseFontTT::initFont() {
}
if (themeFile) {
Common::Archive *themeArchive = Common::makeZipArchive(themeFile);
- if (themeArchive->hasFile("FreeSans.ttf")) {
+ if (themeArchive->hasFile(fallbackFilename)) {
file = nullptr;
- file = themeArchive->createReadStreamForMember("FreeSans.ttf");
+ file = themeArchive->createReadStreamForMember(fallbackFilename);
_deletableFont = Graphics::loadTTFFont(*file, 96, _fontHeight); // Use the same dpi as WME (96 vs 72).
_font = _deletableFont;
}
@@ -599,7 +628,7 @@ bool BaseFontTT::initFont() {
// Fallback3: Try to ask FontMan for the FreeSans.ttf ScummModern.zip uses:
if (!_font) {
// Really not desireable, as we will get a font with dpi-72 then
- Common::String fontName = Common::String::format("%s-%s@%d", "FreeSans.ttf", "ASCII", _fontHeight);
+ Common::String fontName = Common::String::format("%s-%s@%d", fallbackFilename.c_str(), "ASCII", _fontHeight);
warning("Looking for %s", fontName.c_str());
_font = FontMan.getFontByName(fontName);
}
@@ -619,9 +648,9 @@ void BaseFontTT::measureText(const WideString &text, int maxWidth, int maxHeight
//TextLineList lines;
if (maxWidth >= 0) {
- Common::Array<Common::String> lines;
+ Common::Array<WideString> lines;
_font->wordWrapText(text, maxWidth, lines);
- Common::Array<Common::String>::iterator it;
+ Common::Array<WideString>::iterator it;
textWidth = 0;
for (it = lines.begin(); it != lines.end(); ++it) {
textWidth = MAX(textWidth, _font->getStringWidth(*it));
diff --git a/engines/wintermute/base/font/base_font_truetype.h b/engines/wintermute/base/font/base_font_truetype.h
index fdbae30684..edb41a155f 100644
--- a/engines/wintermute/base/font/base_font_truetype.h
+++ b/engines/wintermute/base/font/base_font_truetype.h
@@ -56,9 +56,8 @@ private:
bool _marked;
uint32 _lastUsed;
- BaseCachedTTFontText() {
+ BaseCachedTTFontText() : _text() {
//_text = L"";
- _text = "";
_width = _maxHeight = _maxLength = -1;
_align = TAL_LEFT;
_surface = nullptr;
@@ -84,9 +83,9 @@ public:
}
bool persist(BasePersistenceManager *persistMgr) {
- persistMgr->transfer(TMEMBER(_offsetX));
- persistMgr->transfer(TMEMBER(_offsetY));
- persistMgr->transfer(TMEMBER(_color));
+ persistMgr->transferSint32(TMEMBER(_offsetX));
+ persistMgr->transferSint32(TMEMBER(_offsetY));
+ persistMgr->transferUint32(TMEMBER(_color));
return STATUS_OK;
}
@@ -105,7 +104,7 @@ public:
virtual void drawText(const byte *text, int x, int y, int width, TTextAlign align = TAL_LEFT, int max_height = -1, int maxLength = -1) override;
virtual int getLetterHeight() override;
- bool loadBuffer(byte *buffer);
+ bool loadBuffer(char *buffer);
bool loadFile(const Common::String &filename);
float getLineHeight() const {
@@ -116,7 +115,7 @@ public:
void initLoop();
private:
- bool parseLayer(BaseTTFontLayer *layer, byte *buffer);
+ bool parseLayer(BaseTTFontLayer *layer, char *buffer);
void measureText(const WideString &text, int maxWidth, int maxHeight, int &textWidth, int &textHeight);
@@ -135,7 +134,7 @@ private:
size_t _maxCharWidth;
size_t _maxCharHeight;
-public:
+private:
bool _isBold;
bool _isItalic;
bool _isUnderline;
diff --git a/engines/wintermute/base/gfx/base_renderer.cpp b/engines/wintermute/base/gfx/base_renderer.cpp
index 1f171209d7..858a7fc6dc 100644
--- a/engines/wintermute/base/gfx/base_renderer.cpp
+++ b/engines/wintermute/base/gfx/base_renderer.cpp
@@ -65,7 +65,7 @@ BaseRenderer::BaseRenderer(BaseGame *inGame) : BaseClass(inGame) {
_loadImageX = _loadImageY = 0;
_width = _height = _bPP = 0;
- BasePlatform::setRectEmpty(&_monitorRect);
+ _monitorRect.setEmpty();
_realWidth = _realHeight = 0;
_drawOffsetX = _drawOffsetY = 0;
@@ -173,12 +173,12 @@ void BaseRenderer::endSaveLoad() {
}
void BaseRenderer::persistSaveLoadImages(BasePersistenceManager *persistMgr) {
- persistMgr->transfer(TMEMBER(_loadImageName));
- persistMgr->transfer(TMEMBER(_saveImageName));
- persistMgr->transfer(TMEMBER(_saveImageX));
- persistMgr->transfer(TMEMBER(_saveImageY));
- persistMgr->transfer(TMEMBER(_loadImageX));
- persistMgr->transfer(TMEMBER(_loadImageY));
+ persistMgr->transferString(TMEMBER(_loadImageName));
+ persistMgr->transferString(TMEMBER(_saveImageName));
+ persistMgr->transferSint32(TMEMBER(_saveImageX));
+ persistMgr->transferSint32(TMEMBER(_saveImageY));
+ persistMgr->transferSint32(TMEMBER(_loadImageX));
+ persistMgr->transferSint32(TMEMBER(_loadImageY));
}
//////////////////////////////////////////////////////////////////////
@@ -374,7 +374,7 @@ bool BaseRenderer::displayIndicator() {
}
if (_saveLoadImage && !_hasDrawnSaveLoadImage) {
Rect32 rc;
- BasePlatform::setRect(&rc, 0, 0, _saveLoadImage->getWidth(), _saveLoadImage->getHeight());
+ rc.setRect(0, 0, _saveLoadImage->getWidth(), _saveLoadImage->getHeight());
if (_loadInProgress) {
_saveLoadImage->displayTrans(_loadImageX, _loadImageY, rc);
} else {
diff --git a/engines/wintermute/base/gfx/base_surface.h b/engines/wintermute/base/gfx/base_surface.h
index 42fd593f61..a53748e9aa 100644
--- a/engines/wintermute/base/gfx/base_surface.h
+++ b/engines/wintermute/base/gfx/base_surface.h
@@ -56,7 +56,7 @@ public:
virtual bool display(int x, int y, Rect32 rect, TSpriteBlendMode blendMode = BLEND_NORMAL, bool mirrorX = false, bool mirrorY = false) = 0;
virtual bool displayTransform(int x, int y, Rect32 rect, Rect32 newRect, const TransformStruct &transform) = 0;
virtual bool displayZoom(int x, int y, Rect32 rect, float zoomX, float zoomY, uint32 alpha = 0xFFFFFFFF, bool transparent = false, TSpriteBlendMode blendMode = BLEND_NORMAL, bool mirrorX = false, bool mirrorY = false) = 0;
- virtual bool repeatLastDisplayOp(int offsetX, int offsetY, int numTimesX, int numTimesY) = 0;
+ virtual bool displayTiled(int x, int y, Rect32 rect, int numTimesX, int numTimesY) = 0;
virtual bool restore();
virtual bool create(const Common::String &filename, bool defaultCK, byte ckRed, byte ckGreen, byte ckBlue, int lifeTime = -1, bool keepLoaded = false) = 0;
virtual bool create(int width, int height);
diff --git a/engines/wintermute/base/gfx/osystem/base_render_osystem.cpp b/engines/wintermute/base/gfx/osystem/base_render_osystem.cpp
index e4c19fde8b..35918b8e90 100644
--- a/engines/wintermute/base/gfx/osystem/base_render_osystem.cpp
+++ b/engines/wintermute/base/gfx/osystem/base_render_osystem.cpp
@@ -51,22 +51,19 @@ BaseRenderer *makeOSystemRenderer(BaseGame *inGame) {
BaseRenderOSystem::BaseRenderOSystem(BaseGame *inGame) : BaseRenderer(inGame) {
_renderSurface = new Graphics::Surface();
_blankSurface = new Graphics::Surface();
- _drawNum = 1;
+ _lastFrameIter = _renderQueue.end();
_needsFlip = true;
- _spriteBatch = false;
- _batchNum = 0;
_skipThisFrame = false;
- _previousTicket = nullptr;
_borderLeft = _borderRight = _borderTop = _borderBottom = 0;
_ratioX = _ratioY = 1.0f;
- _colorMod = kDefaultRgbaMod;
_dirtyRect = nullptr;
_disableDirtyRects = false;
- _tempDisableDirtyRects = 0;
if (ConfMan.hasKey("dirty_rects")) {
_disableDirtyRects = !ConfMan.getBool("dirty_rects");
}
+
+ _lastScreenChangeID = g_system->getScreenChangeID();
}
//////////////////////////////////////////////////////////////////////////
@@ -155,20 +152,24 @@ bool BaseRenderOSystem::indicatorFlip() {
}
bool BaseRenderOSystem::flip() {
- if (_renderQueue.size() > DIRTY_RECT_LIMIT) {
- _tempDisableDirtyRects++;
- }
if (_skipThisFrame) {
_skipThisFrame = false;
delete _dirtyRect;
_dirtyRect = nullptr;
g_system->updateScreen();
_needsFlip = false;
- _drawNum = 1;
+
+ // Reset ticketing state
+ _lastFrameIter = _renderQueue.end();
+ RenderQueueIterator it;
+ for (it = _renderQueue.begin(); it != _renderQueue.end(); ++it) {
+ (*it)->_wantsDraw = false;
+ }
+
addDirtyRect(_renderRect);
return true;
}
- if (!_tempDisableDirtyRects && !_disableDirtyRects) {
+ if (!_disableDirtyRects) {
drawTickets();
} else {
// Clear the scale-buffered tickets that wasn't reused.
@@ -184,33 +185,23 @@ bool BaseRenderOSystem::flip() {
}
}
}
- if (_needsFlip || _disableDirtyRects || _tempDisableDirtyRects) {
- if (_disableDirtyRects || _tempDisableDirtyRects) {
+
+ int oldScreenChangeID = _lastScreenChangeID;
+ _lastScreenChangeID = g_system->getScreenChangeID();
+ bool screenChanged = _lastScreenChangeID != oldScreenChangeID;
+
+ if (_needsFlip || _disableDirtyRects || screenChanged) {
+ if (_disableDirtyRects || screenChanged) {
g_system->copyRectToScreen((byte *)_renderSurface->getPixels(), _renderSurface->pitch, 0, 0, _renderSurface->w, _renderSurface->h);
}
// g_system->copyRectToScreen((byte *)_renderSurface->getPixels(), _renderSurface->pitch, _dirtyRect->left, _dirtyRect->top, _dirtyRect->width(), _dirtyRect->height());
delete _dirtyRect;
_dirtyRect = nullptr;
- g_system->updateScreen();
_needsFlip = false;
}
- _drawNum = 1;
-
- if (_tempDisableDirtyRects && !_disableDirtyRects) {
- _tempDisableDirtyRects--;
- if (!_tempDisableDirtyRects) {
- Common::Rect screen(_screenRect.top, _screenRect.left, _screenRect.bottom, _screenRect.right);
- addDirtyRect(screen);
-
- // The queue has been ignored but updated, and is guaranteed to be in draw-order when run without dirty-rects.
- RenderQueueIterator it = _renderQueue.begin();
- int drawNum = 1;
- while (it != _renderQueue.end()) {
- (*it)->_drawNum = drawNum++;
- ++it;
- }
- }
- }
+ _lastFrameIter = _renderQueue.end();
+
+ g_system->updateScreen();
return STATUS_OK;
}
@@ -218,7 +209,7 @@ bool BaseRenderOSystem::flip() {
//////////////////////////////////////////////////////////////////////////
bool BaseRenderOSystem::fill(byte r, byte g, byte b, Common::Rect *rect) {
_clearColor = _renderSurface->format.ARGBToColor(0xFF, r, g, b);
- if (!_disableDirtyRects && !_tempDisableDirtyRects) {
+ if (!_disableDirtyRects) {
return STATUS_OK;
}
if (!rect) {
@@ -279,22 +270,14 @@ Graphics::PixelFormat BaseRenderOSystem::getPixelFormat() const {
void BaseRenderOSystem::drawSurface(BaseSurfaceOSystem *owner, const Graphics::Surface *surf, Common::Rect *srcRect, Common::Rect *dstRect, TransformStruct &transform) {
- if (_tempDisableDirtyRects || _disableDirtyRects) {
+ if (_disableDirtyRects) {
RenderTicket *ticket = new RenderTicket(owner, surf, srcRect, dstRect, transform);
- ticket->_transform._rgbaMod = _colorMod;
ticket->_wantsDraw = true;
_renderQueue.push_back(ticket);
- _previousTicket = ticket;
drawFromSurface(ticket);
return;
}
- // Start searching from the beginning for the first and second items (since it's empty the first time around
- // then keep incrementing the start-position, to avoid comparing against already used tickets.
- if (_drawNum == 0 || _drawNum == 1) {
- _lastAddedTicket = _renderQueue.begin();
- }
-
// Skip rects that are completely outside the screen:
if ((dstRect->left < 0 && dstRect->right < 0) || (dstRect->top < 0 && dstRect->bottom < 0)) {
return;
@@ -302,28 +285,19 @@ void BaseRenderOSystem::drawSurface(BaseSurfaceOSystem *owner, const Graphics::S
if (owner) { // Fade-tickets are owner-less
RenderTicket compare(owner, nullptr, srcRect, dstRect, transform);
- compare._batchNum = _batchNum;
- if (_spriteBatch) {
- _batchNum++;
- }
- RenderQueueIterator it;
+ RenderQueueIterator it = _lastFrameIter;
+ ++it;
// Avoid calling end() and operator* every time, when potentially going through
// LOTS of tickets.
RenderQueueIterator endIterator = _renderQueue.end();
RenderTicket *compareTicket = nullptr;
- for (it = _lastAddedTicket; it != endIterator; ++it) {
+ for (; it != endIterator; ++it) {
compareTicket = *it;
if (*(compareTicket) == compare && compareTicket->_isValid) {
- compareTicket->_transform._rgbaMod = transform._rgbaMod;
if (_disableDirtyRects) {
drawFromSurface(compareTicket);
} else {
- drawFromTicket(compareTicket);
- _previousTicket = compareTicket;
- }
- if (_renderQueue.size() > DIRTY_RECT_LIMIT) {
- drawTickets();
- _tempDisableDirtyRects = 3;
+ drawFromQueuedTicket(it);
}
return;
}
@@ -332,57 +306,13 @@ void BaseRenderOSystem::drawSurface(BaseSurfaceOSystem *owner, const Graphics::S
RenderTicket *ticket = new RenderTicket(owner, surf, srcRect, dstRect, transform);
if (!_disableDirtyRects) {
drawFromTicket(ticket);
- _previousTicket = ticket;
} else {
ticket->_wantsDraw = true;
_renderQueue.push_back(ticket);
- _previousTicket = ticket;
drawFromSurface(ticket);
}
}
-void BaseRenderOSystem::repeatLastDraw(int offsetX, int offsetY, int numTimesX, int numTimesY) {
- if (_previousTicket && _lastAddedTicket != _renderQueue.end()) {
- RenderTicket *origTicket = _previousTicket;
-
- // Make sure drawSurface WILL start from the correct _lastAddedTicket
- if (!_tempDisableDirtyRects && !_disableDirtyRects && *_lastAddedTicket != origTicket) {
- RenderQueueIterator it;
- RenderQueueIterator endIterator = _renderQueue.end();
- for (it = _renderQueue.begin(); it != endIterator; ++it) {
- if ((*it) == _previousTicket) {
- _lastAddedTicket = it;
- break;
- }
- }
- }
- Common::Rect srcRect(0, 0, 0, 0);
- srcRect.setWidth(origTicket->getSrcRect()->width());
- srcRect.setHeight(origTicket->getSrcRect()->height());
-
- Common::Rect dstRect = origTicket->_dstRect;
- int initLeft = dstRect.left;
- int initRight = dstRect.right;
-
- TransformStruct temp = TransformStruct(kDefaultZoomX, kDefaultZoomY, kDefaultAngle, kDefaultHotspotX, kDefaultHotspotY, BLEND_NORMAL, kDefaultRgbaMod, false, false, kDefaultOffsetX, kDefaultOffsetY);
-
- for (int i = 0; i < numTimesY; i++) {
- if (i == 0) {
- dstRect.translate(offsetX, 0);
- }
- for (int j = (i == 0 ? 1 : 0); j < numTimesX; j++) {
- drawSurface(origTicket->_owner, origTicket->getSurface(), &srcRect, &dstRect, temp);
- dstRect.translate(offsetX, 0);
- }
- dstRect.left = initLeft;
- dstRect.right = initRight;
- dstRect.translate(0, offsetY);
- }
- } else {
- error("Repeat-draw failed (did you forget to draw something before this?)");
- }
-}
-
void BaseRenderOSystem::invalidateTicket(RenderTicket *renderTicket) {
addDirtyRect(renderTicket->_dstRect);
renderTicket->_isValid = false;
@@ -400,59 +330,37 @@ void BaseRenderOSystem::invalidateTicketsFromSurface(BaseSurfaceOSystem *surf) {
void BaseRenderOSystem::drawFromTicket(RenderTicket *renderTicket) {
renderTicket->_wantsDraw = true;
- // A new item always has _drawNum == 0
- if (renderTicket->_drawNum == 0) {
- // In-order
- if (_renderQueue.empty() || _drawNum > (_renderQueue.back())->_drawNum) {
- renderTicket->_drawNum = _drawNum++;
- _renderQueue.push_back(renderTicket);
- addDirtyRect(renderTicket->_dstRect);
- ++_lastAddedTicket;
- } else {
- // Before something
- RenderQueueIterator pos;
- for (pos = _renderQueue.begin(); pos != _renderQueue.end(); pos++) {
- if ((*pos)->_drawNum >= _drawNum) {
- break;
- }
- }
- _renderQueue.insert(pos, renderTicket);
- renderTicket->_drawNum = _drawNum++;
- // Increment the following tickets, so they still are in line
- RenderQueueIterator it;
- for (it = pos; it != _renderQueue.end(); ++it) {
- (*it)->_drawNum++;
- (*it)->_wantsDraw = false;
- }
- addDirtyRect(renderTicket->_dstRect);
- _lastAddedTicket = pos;
- }
+
+ ++_lastFrameIter;
+ // In-order
+ if (_renderQueue.empty() || _lastFrameIter == _renderQueue.end()) {
+ _lastFrameIter--;
+ _renderQueue.push_back(renderTicket);
+ ++_lastFrameIter;
+ addDirtyRect(renderTicket->_dstRect);
} else {
- // Was drawn last round, still in the same order
- if (_drawNum == renderTicket->_drawNum) {
- _drawNum++;
- ++_lastAddedTicket;
- } else {
- // Remove the ticket from the list
- RenderQueueIterator it = _renderQueue.begin();
- while (it != _renderQueue.end()) {
- if ((*it) == renderTicket) {
- it = _renderQueue.erase(it);
- break;
- } else {
- ++it;
- }
- }
- if (it != _renderQueue.end()) {
- // Decreement the following tickets.
- for (; it != _renderQueue.end(); ++it) {
- (*it)->_drawNum--;
- }
- }
- // Is not in order, so readd it as if it was a new ticket
- renderTicket->_drawNum = 0;
- drawFromTicket(renderTicket);
- }
+ // Before something
+ RenderQueueIterator pos = _lastFrameIter;
+ _renderQueue.insert(pos, renderTicket);
+ --_lastFrameIter;
+ addDirtyRect(renderTicket->_dstRect);
+ }
+}
+
+void BaseRenderOSystem::drawFromQueuedTicket(const RenderQueueIterator &ticket) {
+ RenderTicket *renderTicket = *ticket;
+ assert(!renderTicket->_wantsDraw);
+ renderTicket->_wantsDraw = true;
+
+ ++_lastFrameIter;
+ // Not in the same order?
+ if (*_lastFrameIter != renderTicket) {
+ --_lastFrameIter;
+ // Remove the ticket from the list
+ assert(*_lastFrameIter != renderTicket);
+ _renderQueue.erase(ticket);
+ // Is not in order, so readd it as if it was a new ticket
+ drawFromTicket(renderTicket);
}
}
@@ -471,16 +379,13 @@ void BaseRenderOSystem::drawTickets() {
// Note: We draw invalid tickets too, otherwise we wouldn't be honouring
// the draw request they obviously made BEFORE becoming invalid, either way
// we have a copy of their data, so their invalidness won't affect us.
- uint32 decrement = 0;
while (it != _renderQueue.end()) {
if ((*it)->_wantsDraw == false) {
RenderTicket *ticket = *it;
addDirtyRect((*it)->_dstRect);
it = _renderQueue.erase(it);
delete ticket;
- decrement++;
} else {
- (*it)->_drawNum -= decrement;
++it;
}
}
@@ -493,17 +398,25 @@ void BaseRenderOSystem::drawTickets() {
}
return;
}
- // The color-mods are stored in the RenderTickets on add, since we set that state again during
- // draw, we need to keep track of what it was prior to draw.
- uint32 oldColorMod = _colorMod;
- // Apply the clear-color to the dirty rect.
- _renderSurface->fillRect(*_dirtyRect, _clearColor);
- _drawNum = 1;
- for (it = _renderQueue.begin(); it != _renderQueue.end(); ++it) {
+ it = _renderQueue.begin();
+ _lastFrameIter = _renderQueue.end();
+ // A special case: If the screen has one giant OPAQUE rect to be drawn, then we skip filling
+ // the background colour. Typical use-case: Fullscreen FMVs.
+ // Caveat: The FPS-counter will invalidate this.
+ if (it != _lastFrameIter && _renderQueue.front() == _renderQueue.back() && (*it)->_transform._alphaDisable == true) {
+ // If our single opaque rect fills the dirty rect, we can skip filling.
+ if (*_dirtyRect != (*it)->_dstRect) {
+ // Apply the clear-color to the dirty rect.
+ _renderSurface->fillRect(*_dirtyRect, _clearColor);
+ }
+ // Otherwise Do NOT fill.
+ } else {
+ // Apply the clear-color to the dirty rect.
+ _renderSurface->fillRect(*_dirtyRect, _clearColor);
+ }
+ for (; it != _renderQueue.end(); ++it) {
RenderTicket *ticket = *it;
- assert(ticket->_drawNum == _drawNum);
- ++_drawNum;
if (ticket->_dstRect.intersects(*_dirtyRect)) {
// dstClip is the area we want redrawn.
Common::Rect dstClip(ticket->_dstRect);
@@ -516,7 +429,6 @@ void BaseRenderOSystem::drawTickets() {
// convert from screen-coords to surface-coords.
dstClip.translate(-offsetX, -offsetY);
- _colorMod = ticket->_transform._rgbaMod;
drawFromSurface(ticket, &pos, &dstClip);
_needsFlip = true;
}
@@ -525,21 +437,15 @@ void BaseRenderOSystem::drawTickets() {
}
g_system->copyRectToScreen((byte *)_renderSurface->getBasePtr(_dirtyRect->left, _dirtyRect->top), _renderSurface->pitch, _dirtyRect->left, _dirtyRect->top, _dirtyRect->width(), _dirtyRect->height());
- // Revert the colorMod-state.
- _colorMod = oldColorMod;
-
it = _renderQueue.begin();
// Clean out the old tickets
- decrement = 0;
while (it != _renderQueue.end()) {
if ((*it)->_isValid == false) {
RenderTicket *ticket = *it;
addDirtyRect((*it)->_dstRect);
it = _renderQueue.erase(it);
delete ticket;
- decrement++;
} else {
- (*it)->_drawNum -= decrement;
++it;
}
}
@@ -559,7 +465,7 @@ void BaseRenderOSystem::drawFromSurface(RenderTicket *ticket, Common::Rect *dstR
bool BaseRenderOSystem::drawLine(int x1, int y1, int x2, int y2, uint32 color) {
// This function isn't used outside of indicator-displaying, and thus quite unused in
// BaseRenderOSystem when dirty-rects are enabled.
- if (!_tempDisableDirtyRects && !_disableDirtyRects && !_indicatorDisplay) {
+ if (!_disableDirtyRects && !_indicatorDisplay) {
error("BaseRenderOSystem::DrawLine - doesn't work for dirty rects yet");
}
@@ -665,12 +571,10 @@ void BaseRenderOSystem::endSaveLoad() {
it = _renderQueue.erase(it);
delete ticket;
}
- _lastAddedTicket = _renderQueue.begin();
- _previousTicket = nullptr;
// HACK: After a save the buffer will be drawn before the scripts get to update it,
// so just skip this single frame.
_skipThisFrame = true;
- _drawNum = 1;
+ _lastFrameIter = _renderQueue.end();
_renderSurface->fillRect(Common::Rect(0, 0, _renderSurface->h, _renderSurface->w), _renderSurface->format.ARGBToColor(255, 0, 0, 0));
g_system->copyRectToScreen((byte *)_renderSurface->getPixels(), _renderSurface->pitch, 0, 0, _renderSurface->w, _renderSurface->h);
@@ -678,14 +582,10 @@ void BaseRenderOSystem::endSaveLoad() {
}
bool BaseRenderOSystem::startSpriteBatch() {
- _spriteBatch = true;
- _batchNum = 1;
return STATUS_OK;
}
bool BaseRenderOSystem::endSpriteBatch() {
- _spriteBatch = false;
- _batchNum = 0;
return STATUS_OK;
}
diff --git a/engines/wintermute/base/gfx/osystem/base_render_osystem.h b/engines/wintermute/base/gfx/osystem/base_render_osystem.h
index 306563af3b..8996c8b2e8 100644
--- a/engines/wintermute/base/gfx/osystem/base_render_osystem.h
+++ b/engines/wintermute/base/gfx/osystem/base_render_osystem.h
@@ -62,6 +62,8 @@ public:
BaseRenderOSystem(BaseGame *inGame);
~BaseRenderOSystem();
+ typedef Common::List<RenderTicket *>::iterator RenderQueueIterator;
+
Common::String getName() const;
bool initRenderer(int width, int height, bool windowed) override;
@@ -79,11 +81,16 @@ public:
void invalidateTicket(RenderTicket *renderTicket);
void invalidateTicketsFromSurface(BaseSurfaceOSystem *surf);
/**
- * Insert a ticket into the queue, adding a dirty rect if it's
- * new, or out-of-order from last draw from the ticket.
- * param renderTicket the ticket to be added.
+ * Insert a new ticket into the queue, adding a dirty rect
+ * @param renderTicket the ticket to be added.
*/
void drawFromTicket(RenderTicket *renderTicket);
+ /**
+ * Re-insert an existing ticket into the queue, adding a dirty rect
+ * out-of-order from last draw from the ticket.
+ * @param ticket iterator pointing to the ticket to be added.
+ */
+ void drawFromQueuedTicket(const RenderQueueIterator &ticket);
bool setViewport(int left, int top, int right, int bottom) override;
bool setViewport(Rect32 *rect) override { return BaseRenderer::setViewport(rect); }
@@ -104,7 +111,6 @@ public:
virtual bool endSpriteBatch() override;
void endSaveLoad();
void drawSurface(BaseSurfaceOSystem *owner, const Graphics::Surface *surf, Common::Rect *srcRect, Common::Rect *dstRect, TransformStruct &transform);
- void repeatLastDraw(int offsetX, int offsetY, int numTimesX, int numTimesY);
BaseSurface *createSurface() override;
private:
/**
@@ -120,14 +126,11 @@ private:
void drawFromSurface(RenderTicket *ticket);
// Dirty-rects:
void drawFromSurface(RenderTicket *ticket, Common::Rect *dstRect, Common::Rect *clipRect);
- typedef Common::List<RenderTicket *>::iterator RenderQueueIterator;
Common::Rect *_dirtyRect;
Common::List<RenderTicket *> _renderQueue;
- RenderQueueIterator _lastAddedTicket;
- RenderTicket *_previousTicket;
bool _needsFlip;
- uint32 _drawNum; ///< The global number of the current draw-operation.
+ RenderQueueIterator _lastFrameIter;
Common::Rect _renderRect;
Graphics::Surface *_renderSurface;
Graphics::Surface *_blankSurface;
@@ -138,15 +141,12 @@ private:
int _borderBottom;
bool _disableDirtyRects;
- uint32 _tempDisableDirtyRects;
- bool _spriteBatch;
- uint32 _batchNum;
float _ratioX;
float _ratioY;
- uint32 _colorMod;
uint32 _clearColor;
bool _skipThisFrame;
+ int _lastScreenChangeID; // previous value of OSystem::getScreenChangeID()
};
} // End of namespace Wintermute
diff --git a/engines/wintermute/base/gfx/osystem/base_surface_osystem.cpp b/engines/wintermute/base/gfx/osystem/base_surface_osystem.cpp
index e04af45dd9..c33e8ba54b 100644
--- a/engines/wintermute/base/gfx/osystem/base_surface_osystem.cpp
+++ b/engines/wintermute/base/gfx/osystem/base_surface_osystem.cpp
@@ -37,6 +37,7 @@
#include "graphics/decoders/jpeg.h"
#include "graphics/decoders/tga.h"
#include "engines/wintermute/graphics/transparent_surface.h"
+#include "engines/wintermute/graphics/transform_tools.h"
#include "graphics/pixelformat.h"
#include "graphics/surface.h"
#include "common/stream.h"
@@ -381,6 +382,14 @@ bool BaseSurfaceOSystem::displayTransform(int x, int y, Rect32 rect, Rect32 newR
}
//////////////////////////////////////////////////////////////////////////
+bool BaseSurfaceOSystem::displayTiled(int x, int y, Rect32 rect, int numTimesX, int numTimesY) {
+ assert(numTimesX > 0 && numTimesY > 0);
+ TransformStruct transform(numTimesX, numTimesY);
+ return drawSprite(x, y, &rect, nullptr, transform);
+}
+
+
+//////////////////////////////////////////////////////////////////////////
bool BaseSurfaceOSystem::drawSprite(int x, int y, Rect32 *rect, Rect32 *newRect, TransformStruct transform) {
BaseRenderOSystem *renderer = static_cast<BaseRenderOSystem *>(_gameRef->_renderer);
@@ -392,13 +401,6 @@ bool BaseSurfaceOSystem::drawSprite(int x, int y, Rect32 *rect, Rect32 *newRect,
transform._rgbaMod = renderer->_forceAlphaColor;
}
-#if 0 // These are kept for reference if BlendMode is reimplemented at some point.
- if (alphaDisable) {
- SDL_SetTextureBlendMode(_texture, SDL_BLENDMODE_NONE);
- } else {
- SDL_SetTextureBlendMode(_texture, SDL_BLENDMODE_BLEND);
- }
-#endif
// TODO: This _might_ miss the intended behaviour by 1 in each direction
// But I think it fits the model used in Wintermute.
Common::Rect srcRect;
@@ -408,24 +410,26 @@ bool BaseSurfaceOSystem::drawSprite(int x, int y, Rect32 *rect, Rect32 *newRect,
srcRect.setHeight(rect->bottom - rect->top);
Common::Rect position;
- position.left = x + transform._offset.x;
- position.top = y + transform._offset.y;
- // Crop off-by-ones:
- if (position.left == -1) {
- position.left = 0; // TODO: Something is wrong
- }
- if (position.top == -1) {
- position.top = 0; // TODO: Something is wrong
- }
if (newRect) {
position.top = y;
position.left = x;
position.setWidth(newRect->width());
position.setHeight(newRect->height());
} else {
- position.setWidth((int16)((float)srcRect.width() * transform._zoom.x / kDefaultZoomX));
- position.setHeight((int16)((float)srcRect.height() * transform._zoom.y / kDefaultZoomY));
+
+ Rect32 r;
+ r.top = 0;
+ r.left = 0;
+ r.setWidth(rect->width());
+ r.setHeight(rect->height());
+
+ r = TransformTools::newRect(r, transform, 0);
+
+ position.top = r.top + y + transform._offset.y;
+ position.left = r.left + x + transform._offset.x;
+ position.setWidth(r.width() * transform._numTimesX);
+ position.setHeight(r.height() * transform._numTimesY);
}
renderer->modTargetRect(&position);
@@ -441,16 +445,16 @@ bool BaseSurfaceOSystem::drawSprite(int x, int y, Rect32 *rect, Rect32 *newRect,
return STATUS_OK;
}
-bool BaseSurfaceOSystem::repeatLastDisplayOp(int offsetX, int offsetY, int numTimesX, int numTimesY) {
- BaseRenderOSystem *renderer = static_cast<BaseRenderOSystem *>(_gameRef->_renderer);
- renderer->repeatLastDraw(offsetX, offsetY, numTimesX, numTimesY);
- return STATUS_OK;
-}
-
bool BaseSurfaceOSystem::putSurface(const Graphics::Surface &surface, bool hasAlpha) {
_loaded = true;
- _surface->free();
- _surface->copyFrom(surface);
+ if (surface.format == _surface->format && surface.w == _surface->w && surface.h == _surface->h) {
+ const byte *src = (const byte *)surface.getBasePtr(0, 0);
+ byte *dst = (byte *)_surface->getBasePtr(0, 0);
+ memcpy(dst, src, surface.pitch * surface.h);
+ } else {
+ _surface->free();
+ _surface->copyFrom(surface);
+ }
if (hasAlpha) {
_alphaType = TransparentSurface::ALPHA_FULL;
} else {
diff --git a/engines/wintermute/base/gfx/osystem/base_surface_osystem.h b/engines/wintermute/base/gfx/osystem/base_surface_osystem.h
index 340a5a5ffc..67f45f66db 100644
--- a/engines/wintermute/base/gfx/osystem/base_surface_osystem.h
+++ b/engines/wintermute/base/gfx/osystem/base_surface_osystem.h
@@ -58,7 +58,7 @@ public:
bool display(int x, int y, Rect32 rect, TSpriteBlendMode blendMode = BLEND_NORMAL, bool mirrorX = false, bool mirrorY = false) override;
bool displayZoom(int x, int y, Rect32 rect, float zoomX, float zoomY, uint32 alpha = kDefaultRgbaMod, bool transparent = false, TSpriteBlendMode blendMode = BLEND_NORMAL, bool mirrorX = false, bool mirrorY = false) override;
bool displayTransform(int x, int y, Rect32 rect, Rect32 newRect, const TransformStruct &transform) override;
- bool repeatLastDisplayOp(int offsetX, int offsetY, int numTimesX, int numTimesY) override;
+ virtual bool displayTiled(int x, int y, Rect32 rect, int numTimesX, int numTimesY);
virtual bool putSurface(const Graphics::Surface &surface, bool hasAlpha = false) override;
/* static unsigned DLL_CALLCONV ReadProc(void *buffer, unsigned size, unsigned count, fi_handle handle);
static int DLL_CALLCONV SeekProc(fi_handle handle, long offset, int origin);
diff --git a/engines/wintermute/base/gfx/osystem/render_ticket.cpp b/engines/wintermute/base/gfx/osystem/render_ticket.cpp
index d79d5bac4b..1cd35e3b04 100644
--- a/engines/wintermute/base/gfx/osystem/render_ticket.cpp
+++ b/engines/wintermute/base/gfx/osystem/render_ticket.cpp
@@ -38,11 +38,9 @@ RenderTicket::RenderTicket(BaseSurfaceOSystem *owner, const Graphics::Surface *s
_owner(owner),
_srcRect(*srcRect),
_dstRect(*dstRect),
- _drawNum(0),
_isValid(true),
_wantsDraw(true),
_transform(transform) {
- _batchNum = 0;
if (surf) {
_surface = new Graphics::Surface();
_surface->create((uint16)srcRect->width(), (uint16)srcRect->height(), surf->format);
@@ -52,13 +50,22 @@ RenderTicket::RenderTicket(BaseSurfaceOSystem *owner, const Graphics::Surface *s
memcpy(_surface->getBasePtr(0, i), surf->getBasePtr(srcRect->left, srcRect->top + i), srcRect->width() * _surface->format.bytesPerPixel);
}
// Then scale it if necessary
+ //
+ // NB: The numTimesX/numTimesY properties don't yet mix well with
+ // scaling and rotation, but there is no need for that functionality at
+ // the moment.
+ // NB: Mirroring and rotation are probably done in the wrong order.
+ // (Mirroring should most likely be done before rotation. See also
+ // TransformTools.)
if (_transform._angle != kDefaultAngle) {
TransparentSurface src(*_surface, false);
Graphics::Surface *temp = src.rotoscale(transform);
_surface->free();
delete _surface;
_surface = temp;
- } else if (dstRect->width() != srcRect->width() || dstRect->height() != srcRect->height()) {
+ } else if ((dstRect->width() != srcRect->width() ||
+ dstRect->height() != srcRect->height()) &&
+ _transform._numTimesX * _transform._numTimesY == 1) {
TransparentSurface src(*_surface, false);
Graphics::Surface *temp = src.scale(dstRect->width(), dstRect->height());
_surface->free();
@@ -67,14 +74,6 @@ RenderTicket::RenderTicket(BaseSurfaceOSystem *owner, const Graphics::Surface *s
}
} else {
_surface = nullptr;
-
- if (transform._angle != kDefaultAngle) { // Make sure comparison-tickets get the correct width
- Rect32 newDstRect;
- Point32 newHotspot;
- newDstRect = TransformTools::newRect(_srcRect, transform, &newHotspot);
- _dstRect.setWidth(newDstRect.right - newDstRect.left);
- _dstRect.setHeight(newDstRect.bottom - newDstRect.top);
- }
}
}
@@ -87,7 +86,6 @@ RenderTicket::~RenderTicket() {
bool RenderTicket::operator==(const RenderTicket &t) const {
if ((t._owner != _owner) ||
- (t._batchNum != _batchNum) ||
(t._transform != _transform) ||
(t._dstRect != _dstRect) ||
(t._srcRect != _srcRect)
@@ -107,12 +105,24 @@ void RenderTicket::drawToSurface(Graphics::Surface *_targetSurface) const {
if (_owner) {
if (_transform._alphaDisable) {
- src._alphaMode = TransparentSurface::ALPHA_OPAQUE;
+ src.setAlphaMode(TransparentSurface::ALPHA_OPAQUE);
} else {
- src._alphaMode = _owner->getAlphaType();
+ src.setAlphaMode(_owner->getAlphaType());
+ }
+ }
+
+ int y = _dstRect.top;
+ int w = _dstRect.width() / _transform._numTimesX;
+ int h = _dstRect.height() / _transform._numTimesY;
+
+ for (int ry = 0; ry < _transform._numTimesY; ++ry) {
+ int x = _dstRect.left;
+ for (int rx = 0; rx < _transform._numTimesX; ++rx) {
+ src.blit(*_targetSurface, x, y, _transform._flip, &clipRect, _transform._rgbaMod, clipRect.width(), clipRect.height());
+ x += w;
}
+ y += h;
}
- src.blit(*_targetSurface, _dstRect.left, _dstRect.top, _transform._flip, &clipRect, _transform._rgbaMod, clipRect.width(), clipRect.height());
}
void RenderTicket::drawToSurface(Graphics::Surface *_targetSurface, Common::Rect *dstRect, Common::Rect *clipRect) const {
@@ -121,18 +131,58 @@ void RenderTicket::drawToSurface(Graphics::Surface *_targetSurface, Common::Rect
if (!clipRect) {
doDelete = true;
clipRect = new Common::Rect();
- clipRect->setWidth(getSurface()->w);
- clipRect->setHeight(getSurface()->h);
+ clipRect->setWidth(getSurface()->w * _transform._numTimesX);
+ clipRect->setHeight(getSurface()->h * _transform._numTimesY);
}
if (_owner) {
if (_transform._alphaDisable) {
- src._alphaMode = TransparentSurface::ALPHA_OPAQUE;
+ src.setAlphaMode(TransparentSurface::ALPHA_OPAQUE);
} else {
- src._alphaMode = _owner->getAlphaType();
+ src.setAlphaMode(_owner->getAlphaType());
+ }
+ }
+
+ if (_transform._numTimesX * _transform._numTimesY == 1) {
+
+ src.blit(*_targetSurface, dstRect->left, dstRect->top, _transform._flip, clipRect, _transform._rgbaMod, clipRect->width(), clipRect->height(), _transform._blendMode);
+
+ } else {
+
+ // clipRect is a subrect of the full numTimesX*numTimesY rect
+ Common::Rect subRect;
+
+ int y = 0;
+ int w = getSurface()->w;
+ int h = getSurface()->h;
+ assert(w == _dstRect.width() / _transform._numTimesX);
+ assert(h == _dstRect.height() / _transform._numTimesY);
+
+ int basex = dstRect->left - clipRect->left;
+ int basey = dstRect->top - clipRect->top;
+
+ for (int ry = 0; ry < _transform._numTimesY; ++ry) {
+ int x = 0;
+ for (int rx = 0; rx < _transform._numTimesX; ++rx) {
+
+ subRect.left = x;
+ subRect.top = y;
+ subRect.setWidth(w);
+ subRect.setHeight(h);
+
+ if (subRect.intersects(*clipRect)) {
+ subRect.clip(*clipRect);
+ subRect.translate(-x, -y);
+ src.blit(*_targetSurface, basex + x + subRect.left, basey + y + subRect.top, _transform._flip, &subRect, _transform._rgbaMod, subRect.width(), subRect.height(), _transform._blendMode);
+
+ }
+
+ x += w;
+ }
+ y += h;
}
}
- src.blit(*_targetSurface, dstRect->left, dstRect->top, _transform._flip, clipRect, _transform._rgbaMod, clipRect->width(), clipRect->height(), _transform._blendMode);
+
if (doDelete) {
delete clipRect;
}
diff --git a/engines/wintermute/base/gfx/osystem/render_ticket.h b/engines/wintermute/base/gfx/osystem/render_ticket.h
index 875102d01c..e824c09fe7 100644
--- a/engines/wintermute/base/gfx/osystem/render_ticket.h
+++ b/engines/wintermute/base/gfx/osystem/render_ticket.h
@@ -52,7 +52,7 @@ class BaseSurfaceOSystem;
class RenderTicket {
public:
RenderTicket(BaseSurfaceOSystem *owner, const Graphics::Surface *surf, Common::Rect *srcRect, Common::Rect *dstRest, TransformStruct transform);
- RenderTicket() : _isValid(true), _wantsDraw(false), _drawNum(0), _transform(TransformStruct()) {}
+ RenderTicket() : _isValid(true), _wantsDraw(false), _transform(TransformStruct()) {}
~RenderTicket();
const Graphics::Surface *getSurface() const { return _surface; }
// Non-dirty-rects:
@@ -61,11 +61,9 @@ public:
void drawToSurface(Graphics::Surface *_targetSurface, Common::Rect *dstRect, Common::Rect *clipRect) const;
Common::Rect _dstRect;
- uint32 _batchNum;
bool _isValid;
bool _wantsDraw;
- uint32 _drawNum;
TransformStruct _transform;
diff --git a/engines/wintermute/base/particles/part_emitter.cpp b/engines/wintermute/base/particles/part_emitter.cpp
index aaffa0965a..061352b60f 100644
--- a/engines/wintermute/base/particles/part_emitter.cpp
+++ b/engines/wintermute/base/particles/part_emitter.cpp
@@ -38,7 +38,6 @@
#include "engines/wintermute/base/base_file_manager.h"
#include "engines/wintermute/base/gfx/base_renderer.h"
#include "engines/wintermute/utils/utils.h"
-#include "engines/wintermute/platform_osystem.h"
#include "common/str.h"
#include "common/math.h"
@@ -50,7 +49,7 @@ IMPLEMENT_PERSISTENT(PartEmitter, false)
PartEmitter::PartEmitter(BaseGame *inGame, BaseScriptHolder *owner) : BaseObject(inGame) {
_width = _height = 0;
- BasePlatform::setRectEmpty(&_border);
+ _border.setEmpty();
_borderThicknessLeft = _borderThicknessRight = _borderThicknessTop = _borderThicknessBottom = 0;
_angle1 = _angle2 = 0;
@@ -198,7 +197,7 @@ bool PartEmitter::initParticle(PartParticle *particle, uint32 currentTime, uint3
float angVelocity = BaseUtils::randomFloat(_angVelocity1, _angVelocity2);
float growthRate = BaseUtils::randomFloat(_growthRate1, _growthRate2);
- if (!BasePlatform::isRectEmpty(&_border)) {
+ if (!_border.isRectEmpty()) {
int thicknessLeft = (int)(_borderThicknessLeft - (float)_borderThicknessLeft * posZ / 100.0f);
int thicknessRight = (int)(_borderThicknessRight - (float)_borderThicknessRight * posZ / 100.0f);
int thicknessTop = (int)(_borderThicknessTop - (float)_borderThicknessTop * posZ / 100.0f);
@@ -386,7 +385,7 @@ bool PartEmitter::compareZ(const PartParticle *p1, const PartParticle *p2) {
//////////////////////////////////////////////////////////////////////////
bool PartEmitter::setBorder(int x, int y, int width, int height) {
- BasePlatform::setRect(&_border, x, y, x + width, y + height);
+ _border.setRect(x, y, x + width, y + height);
return STATUS_OK;
}
@@ -1157,44 +1156,44 @@ const char *PartEmitter::scToString() {
bool PartEmitter::persist(BasePersistenceManager *persistMgr) {
BaseObject::persist(persistMgr);
- persistMgr->transfer(TMEMBER(_width));
- persistMgr->transfer(TMEMBER(_height));
+ persistMgr->transferSint32(TMEMBER(_width));
+ persistMgr->transferSint32(TMEMBER(_height));
- persistMgr->transfer(TMEMBER(_angle1));
- persistMgr->transfer(TMEMBER(_angle2));
+ persistMgr->transferSint32(TMEMBER(_angle1));
+ persistMgr->transferSint32(TMEMBER(_angle2));
persistMgr->transferFloat(TMEMBER(_velocity1));
persistMgr->transferFloat(TMEMBER(_velocity2));
- persistMgr->transfer(TMEMBER(_velocityZBased));
+ persistMgr->transferBool(TMEMBER(_velocityZBased));
persistMgr->transferFloat(TMEMBER(_scale1));
persistMgr->transferFloat(TMEMBER(_scale2));
- persistMgr->transfer(TMEMBER(_scaleZBased));
+ persistMgr->transferBool(TMEMBER(_scaleZBased));
- persistMgr->transfer(TMEMBER(_maxParticles));
+ persistMgr->transferSint32(TMEMBER(_maxParticles));
- persistMgr->transfer(TMEMBER(_lifeTime1));
- persistMgr->transfer(TMEMBER(_lifeTime2));
- persistMgr->transfer(TMEMBER(_lifeTimeZBased));
+ persistMgr->transferSint32(TMEMBER(_lifeTime1));
+ persistMgr->transferSint32(TMEMBER(_lifeTime2));
+ persistMgr->transferBool(TMEMBER(_lifeTimeZBased));
- persistMgr->transfer(TMEMBER(_genInterval));
- persistMgr->transfer(TMEMBER(_genAmount));
+ persistMgr->transferSint32(TMEMBER(_genInterval));
+ persistMgr->transferSint32(TMEMBER(_genAmount));
- persistMgr->transfer(TMEMBER(_running));
- persistMgr->transfer(TMEMBER(_overheadTime));
+ persistMgr->transferBool(TMEMBER(_running));
+ persistMgr->transferSint32(TMEMBER(_overheadTime));
- persistMgr->transfer(TMEMBER(_border));
- persistMgr->transfer(TMEMBER(_borderThicknessLeft));
- persistMgr->transfer(TMEMBER(_borderThicknessRight));
- persistMgr->transfer(TMEMBER(_borderThicknessTop));
- persistMgr->transfer(TMEMBER(_borderThicknessBottom));
+ persistMgr->transferRect32(TMEMBER(_border));
+ persistMgr->transferSint32(TMEMBER(_borderThicknessLeft));
+ persistMgr->transferSint32(TMEMBER(_borderThicknessRight));
+ persistMgr->transferSint32(TMEMBER(_borderThicknessTop));
+ persistMgr->transferSint32(TMEMBER(_borderThicknessBottom));
- persistMgr->transfer(TMEMBER(_fadeInTime));
- persistMgr->transfer(TMEMBER(_fadeOutTime));
+ persistMgr->transferSint32(TMEMBER(_fadeInTime));
+ persistMgr->transferSint32(TMEMBER(_fadeOutTime));
- persistMgr->transfer(TMEMBER(_alpha1));
- persistMgr->transfer(TMEMBER(_alpha2));
- persistMgr->transfer(TMEMBER(_alphaTimeBased));
+ persistMgr->transferSint32(TMEMBER(_alpha1));
+ persistMgr->transferSint32(TMEMBER(_alpha2));
+ persistMgr->transferBool(TMEMBER(_alphaTimeBased));
persistMgr->transferFloat(TMEMBER(_angVelocity1));
persistMgr->transferFloat(TMEMBER(_angVelocity2));
@@ -1204,14 +1203,14 @@ bool PartEmitter::persist(BasePersistenceManager *persistMgr) {
persistMgr->transferFloat(TMEMBER(_growthRate1));
persistMgr->transferFloat(TMEMBER(_growthRate2));
- persistMgr->transfer(TMEMBER(_exponentialGrowth));
+ persistMgr->transferBool(TMEMBER(_exponentialGrowth));
- persistMgr->transfer(TMEMBER(_useRegion));
+ persistMgr->transferBool(TMEMBER(_useRegion));
- persistMgr->transfer(TMEMBER_INT(_maxBatches));
- persistMgr->transfer(TMEMBER_INT(_batchesGenerated));
+ persistMgr->transferSint32(TMEMBER_INT(_maxBatches));
+ persistMgr->transferSint32(TMEMBER_INT(_batchesGenerated));
- persistMgr->transfer(TMEMBER(_emitEvent));
+ persistMgr->transferCharPtr(TMEMBER(_emitEvent));
persistMgr->transferPtr(TMEMBER_PTR(_owner));
@@ -1220,12 +1219,12 @@ bool PartEmitter::persist(BasePersistenceManager *persistMgr) {
uint32 numForces;
if (persistMgr->getIsSaving()) {
numForces = _forces.size();
- persistMgr->transfer(TMEMBER(numForces));
+ persistMgr->transferUint32(TMEMBER(numForces));
for (uint32 i = 0; i < _forces.size(); i++) {
_forces[i]->persist(persistMgr);
}
} else {
- persistMgr->transfer(TMEMBER(numForces));
+ persistMgr->transferUint32(TMEMBER(numForces));
for (uint32 i = 0; i < numForces; i++) {
PartForce *force = new PartForce(_gameRef);
force->persist(persistMgr);
@@ -1236,12 +1235,12 @@ bool PartEmitter::persist(BasePersistenceManager *persistMgr) {
uint32 numParticles;
if (persistMgr->getIsSaving()) {
numParticles = _particles.size();
- persistMgr->transfer(TMEMBER(numParticles));
+ persistMgr->transferUint32(TMEMBER(numParticles));
for (uint32 i = 0; i < _particles.size(); i++) {
_particles[i]->persist(persistMgr);
}
} else {
- persistMgr->transfer(TMEMBER(numParticles));
+ persistMgr->transferUint32(TMEMBER(numParticles));
for (uint32 i = 0; i < numParticles; i++) {
PartParticle *particle = new PartParticle(_gameRef);
particle->persist(persistMgr);
diff --git a/engines/wintermute/base/particles/part_force.cpp b/engines/wintermute/base/particles/part_force.cpp
index 122cdf1afe..39d98c182e 100644
--- a/engines/wintermute/base/particles/part_force.cpp
+++ b/engines/wintermute/base/particles/part_force.cpp
@@ -49,15 +49,15 @@ PartForce::~PartForce(void) {
bool PartForce::persist(BasePersistenceManager *persistMgr) {
if (persistMgr->getIsSaving()) {
const char *name = getName();
- persistMgr->transfer(TMEMBER(name));
+ persistMgr->transferConstChar(TMEMBER(name));
} else {
const char *name;
- persistMgr->transfer(TMEMBER(name));
+ persistMgr->transferConstChar(TMEMBER(name));
setName(name);
}
- persistMgr->transfer(TMEMBER(_pos));
- persistMgr->transfer(TMEMBER(_direction));
- persistMgr->transfer(TMEMBER_INT(_type));
+ persistMgr->transferVector2(TMEMBER(_pos));
+ persistMgr->transferVector2(TMEMBER(_direction));
+ persistMgr->transferSint32(TMEMBER_INT(_type));
return STATUS_OK;
}
diff --git a/engines/wintermute/base/particles/part_particle.cpp b/engines/wintermute/base/particles/part_particle.cpp
index 86cacacb5c..11470561f0 100644
--- a/engines/wintermute/base/particles/part_particle.cpp
+++ b/engines/wintermute/base/particles/part_particle.cpp
@@ -45,7 +45,7 @@ PartParticle::PartParticle(BaseGame *inGame) : BaseClass(inGame) {
_creationTime = 0;
_lifeTime = 0;
_isDead = true;
- BasePlatform::setRectEmpty(&_border);
+ _border.setEmpty();
_state = PARTICLE_NORMAL;
_fadeStart = 0;
@@ -125,7 +125,7 @@ bool PartParticle::update(PartEmitter *emitter, uint32 currentTime, uint32 timer
}
// particle hit the border
- if (!_isDead && !BasePlatform::isRectEmpty(&_border)) {
+ if (!_isDead && !_border.isRectEmpty()) {
Point32 p;
p.x = (int32)_pos.x;
p.y = (int32)_pos.y;
@@ -230,32 +230,32 @@ bool PartParticle::fadeOut(uint32 currentTime, int fadeTime) {
//////////////////////////////////////////////////////////////////////////
bool PartParticle::persist(BasePersistenceManager *persistMgr) {
- persistMgr->transfer(TMEMBER(_alpha1));
- persistMgr->transfer(TMEMBER(_alpha2));
- persistMgr->transfer(TMEMBER(_border));
- persistMgr->transfer(TMEMBER(_pos));
+ persistMgr->transferSint32(TMEMBER(_alpha1));
+ persistMgr->transferSint32(TMEMBER(_alpha2));
+ persistMgr->transferRect32(TMEMBER(_border));
+ persistMgr->transferVector2(TMEMBER(_pos));
persistMgr->transferFloat(TMEMBER(_posZ));
- persistMgr->transfer(TMEMBER(_velocity));
+ persistMgr->transferVector2(TMEMBER(_velocity));
persistMgr->transferFloat(TMEMBER(_scale));
- persistMgr->transfer(TMEMBER(_creationTime));
- persistMgr->transfer(TMEMBER(_lifeTime));
- persistMgr->transfer(TMEMBER(_isDead));
- persistMgr->transfer(TMEMBER_INT(_state));
- persistMgr->transfer(TMEMBER(_fadeStart));
- persistMgr->transfer(TMEMBER(_fadeTime));
- persistMgr->transfer(TMEMBER(_currentAlpha));
+ persistMgr->transferUint32(TMEMBER(_creationTime));
+ persistMgr->transferSint32(TMEMBER(_lifeTime));
+ persistMgr->transferBool(TMEMBER(_isDead));
+ persistMgr->transferSint32(TMEMBER_INT(_state));
+ persistMgr->transferUint32(TMEMBER(_fadeStart));
+ persistMgr->transferSint32(TMEMBER(_fadeTime));
+ persistMgr->transferSint32(TMEMBER(_currentAlpha));
persistMgr->transferFloat(TMEMBER(_angVelocity));
persistMgr->transferFloat(TMEMBER(_rotation));
persistMgr->transferFloat(TMEMBER(_growthRate));
- persistMgr->transfer(TMEMBER(_exponentialGrowth));
- persistMgr->transfer(TMEMBER(_fadeStartAlpha));
+ persistMgr->transferBool(TMEMBER(_exponentialGrowth));
+ persistMgr->transferSint32(TMEMBER(_fadeStartAlpha));
if (persistMgr->getIsSaving()) {
const char *filename = _sprite->getFilename();
- persistMgr->transfer(TMEMBER(filename));
+ persistMgr->transferConstChar(TMEMBER(filename));
} else {
char *filename;
- persistMgr->transfer(TMEMBER(filename));
+ persistMgr->transferCharPtr(TMEMBER(filename));
SystemClassRegistry::getInstance()->_disabled = true;
setSprite(filename);
SystemClassRegistry::getInstance()->_disabled = false;
diff --git a/engines/wintermute/base/saveload.cpp b/engines/wintermute/base/saveload.cpp
index 8d37909bb4..402041cda4 100644
--- a/engines/wintermute/base/saveload.cpp
+++ b/engines/wintermute/base/saveload.cpp
@@ -48,6 +48,7 @@ bool SaveLoad::loadGame(const Common::String &filename, BaseGame *gameRef) {
bool ret;
+ gameRef->stopVideo();
gameRef->_renderer->initSaveLoad(false);
gameRef->_loadInProgress = true;
diff --git a/engines/wintermute/base/scriptables/script.cpp b/engines/wintermute/base/scriptables/script.cpp
index 5aeff78c50..5e4ae3ea95 100644
--- a/engines/wintermute/base/scriptables/script.cpp
+++ b/engines/wintermute/base/scriptables/script.cpp
@@ -1249,15 +1249,15 @@ bool ScScript::persist(BasePersistenceManager *persistMgr) {
// buffer
if (persistMgr->getIsSaving()) {
if (_state != SCRIPT_PERSISTENT && _state != SCRIPT_FINISHED && _state != SCRIPT_THREAD_FINISHED) {
- persistMgr->transfer(TMEMBER(_bufferSize));
+ persistMgr->transferUint32(TMEMBER(_bufferSize));
persistMgr->putBytes(_buffer, _bufferSize);
} else {
// don't save idle/finished scripts
int32 bufferSize = 0;
- persistMgr->transfer(TMEMBER(bufferSize));
+ persistMgr->transferSint32(TMEMBER(bufferSize));
}
} else {
- persistMgr->transfer(TMEMBER(_bufferSize));
+ persistMgr->transferUint32(TMEMBER(_bufferSize));
if (_bufferSize > 0) {
_buffer = new byte[_bufferSize];
persistMgr->getBytes(_buffer, _bufferSize);
@@ -1270,31 +1270,31 @@ bool ScScript::persist(BasePersistenceManager *persistMgr) {
}
persistMgr->transferPtr(TMEMBER_PTR(_callStack));
- persistMgr->transfer(TMEMBER(_currentLine));
+ persistMgr->transferSint32(TMEMBER(_currentLine));
persistMgr->transferPtr(TMEMBER_PTR(_engine));
- persistMgr->transfer(TMEMBER(_filename));
- persistMgr->transfer(TMEMBER(_freezable));
+ persistMgr->transferCharPtr(TMEMBER(_filename));
+ persistMgr->transferBool(TMEMBER(_freezable));
persistMgr->transferPtr(TMEMBER_PTR(_globals));
- persistMgr->transfer(TMEMBER(_iP));
+ persistMgr->transferUint32(TMEMBER(_iP));
persistMgr->transferPtr(TMEMBER_PTR(_scopeStack));
persistMgr->transferPtr(TMEMBER_PTR(_stack));
- persistMgr->transfer(TMEMBER_INT(_state));
+ persistMgr->transferSint32(TMEMBER_INT(_state));
persistMgr->transferPtr(TMEMBER_PTR(_operand));
- persistMgr->transfer(TMEMBER_INT(_origState));
+ persistMgr->transferSint32(TMEMBER_INT(_origState));
persistMgr->transferPtr(TMEMBER_PTR(_owner));
persistMgr->transferPtr(TMEMBER_PTR(_reg1));
- persistMgr->transfer(TMEMBER(_thread));
- persistMgr->transfer(TMEMBER(_threadEvent));
+ persistMgr->transferBool(TMEMBER(_thread));
+ persistMgr->transferCharPtr(TMEMBER(_threadEvent));
persistMgr->transferPtr(TMEMBER_PTR(_thisStack));
- persistMgr->transfer(TMEMBER(_timeSlice));
+ persistMgr->transferUint32(TMEMBER(_timeSlice));
persistMgr->transferPtr(TMEMBER_PTR(_waitObject));
persistMgr->transferPtr(TMEMBER_PTR(_waitScript));
- persistMgr->transfer(TMEMBER(_waitTime));
- persistMgr->transfer(TMEMBER(_waitFrozen));
+ persistMgr->transferUint32(TMEMBER(_waitTime));
+ persistMgr->transferBool(TMEMBER(_waitFrozen));
- persistMgr->transfer(TMEMBER(_methodThread));
- persistMgr->transfer(TMEMBER(_methodThread));
- persistMgr->transfer(TMEMBER(_unbreakable));
+ persistMgr->transferBool(TMEMBER(_methodThread));
+ persistMgr->transferBool(TMEMBER(_methodThread)); // TODO-SAVE: Deduplicate.
+ persistMgr->transferBool(TMEMBER(_unbreakable));
persistMgr->transferPtr(TMEMBER_PTR(_parentScript));
if (!persistMgr->getIsSaving()) {
diff --git a/engines/wintermute/base/scriptables/script_ext_array.cpp b/engines/wintermute/base/scriptables/script_ext_array.cpp
index 7f1c769ec5..c4ad045557 100644
--- a/engines/wintermute/base/scriptables/script_ext_array.cpp
+++ b/engines/wintermute/base/scriptables/script_ext_array.cpp
@@ -214,7 +214,7 @@ bool SXArray::scSetProperty(const char *name, ScValue *value) {
bool SXArray::persist(BasePersistenceManager *persistMgr) {
BaseScriptable::persist(persistMgr);
- persistMgr->transfer(TMEMBER(_length));
+ persistMgr->transferSint32(TMEMBER(_length));
persistMgr->transferPtr(TMEMBER_PTR(_values));
return STATUS_OK;
diff --git a/engines/wintermute/base/scriptables/script_ext_date.cpp b/engines/wintermute/base/scriptables/script_ext_date.cpp
index d88bfc5851..6b9c5ff68a 100644
--- a/engines/wintermute/base/scriptables/script_ext_date.cpp
+++ b/engines/wintermute/base/scriptables/script_ext_date.cpp
@@ -243,15 +243,15 @@ bool SXDate::persist(BasePersistenceManager *persistMgr) {
int32 hour = _tm.tm_hour;
int32 min = _tm.tm_min;
int32 sec = _tm.tm_sec;
- persistMgr->transfer(TMEMBER(year));
- persistMgr->transfer(TMEMBER(mon));
- persistMgr->transfer(TMEMBER(mday));
- persistMgr->transfer(TMEMBER(hour));
- persistMgr->transfer(TMEMBER(min));
- persistMgr->transfer(TMEMBER(sec));
+ persistMgr->transferSint32(TMEMBER(year));
+ persistMgr->transferSint32(TMEMBER(mon));
+ persistMgr->transferSint32(TMEMBER(mday));
+ persistMgr->transferSint32(TMEMBER(hour));
+ persistMgr->transferSint32(TMEMBER(min));
+ persistMgr->transferSint32(TMEMBER(sec));
if (persistMgr->checkVersion(1, 2, 1)) {
int32 wday = _tm.tm_wday;
- persistMgr->transfer(TMEMBER(wday));
+ persistMgr->transferSint32(TMEMBER(wday));
_tm.tm_wday = wday;
}
_tm.tm_year = year;
diff --git a/engines/wintermute/base/scriptables/script_ext_file.cpp b/engines/wintermute/base/scriptables/script_ext_file.cpp
index 18f7b8213a..dcd4f01f7c 100644
--- a/engines/wintermute/base/scriptables/script_ext_file.cpp
+++ b/engines/wintermute/base/scriptables/script_ext_file.cpp
@@ -766,16 +766,16 @@ bool SXFile::persist(BasePersistenceManager *persistMgr) {
BaseScriptable::persist(persistMgr);
- persistMgr->transfer(TMEMBER(_filename));
- persistMgr->transfer(TMEMBER(_mode));
- persistMgr->transfer(TMEMBER(_textMode));
+ persistMgr->transferCharPtr(TMEMBER(_filename));
+ persistMgr->transferSint32(TMEMBER(_mode));
+ persistMgr->transferBool(TMEMBER(_textMode));
uint32 pos = 0;
if (persistMgr->getIsSaving()) {
pos = getPos();
- persistMgr->transfer(TMEMBER(pos));
+ persistMgr->transferUint32(TMEMBER(pos));
} else {
- persistMgr->transfer(TMEMBER(pos));
+ persistMgr->transferUint32(TMEMBER(pos));
// try to re-open file if needed
_writeFile = nullptr;
diff --git a/engines/wintermute/base/scriptables/script_ext_mem_buffer.cpp b/engines/wintermute/base/scriptables/script_ext_mem_buffer.cpp
index 6a47c09136..39f8b58644 100644
--- a/engines/wintermute/base/scriptables/script_ext_mem_buffer.cpp
+++ b/engines/wintermute/base/scriptables/script_ext_mem_buffer.cpp
@@ -498,7 +498,7 @@ bool SXMemBuffer::persist(BasePersistenceManager *persistMgr) {
BaseScriptable::persist(persistMgr);
- persistMgr->transfer(TMEMBER(_size));
+ persistMgr->transferSint32(TMEMBER(_size));
if (persistMgr->getIsSaving()) {
if (_size > 0) {
diff --git a/engines/wintermute/base/scriptables/script_ext_string.cpp b/engines/wintermute/base/scriptables/script_ext_string.cpp
index 2f2422cdf9..65bec03bc1 100644
--- a/engines/wintermute/base/scriptables/script_ext_string.cpp
+++ b/engines/wintermute/base/scriptables/script_ext_string.cpp
@@ -298,21 +298,13 @@ bool SXString::scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack
uint32 start = 0;
for(uint32 i = 0; i < str.size() + 1; i++) {
- char ch = str.c_str()[i];
- if(ch=='\0' || delims.contains(ch))
- {
- char *part = new char[i - start + 1];
- if(i != start) {
- Common::strlcpy(part, str.c_str() + start, i - start + 1);
- part[i - start] = '\0';
+ uint32 ch = str[i];
+ if (ch =='\0' || delims.contains(ch)) {
+ if (i != start) {
+ parts.push_back(WideString(str.c_str() + start, i - start + 1));
} else {
- part[0] = '\0';
+ parts.push_back(WideString());
}
- val = new ScValue(_gameRef, part);
- array->push(val);
- delete[] part;
- delete val;
- val = nullptr;
start = i + 1;
}
}
@@ -406,7 +398,7 @@ bool SXString::persist(BasePersistenceManager *persistMgr) {
BaseScriptable::persist(persistMgr);
- persistMgr->transfer(TMEMBER(_capacity));
+ persistMgr->transferSint32(TMEMBER(_capacity));
if (persistMgr->getIsSaving()) {
if (_capacity > 0) {
diff --git a/engines/wintermute/base/scriptables/script_stack.cpp b/engines/wintermute/base/scriptables/script_stack.cpp
index 801ac6ab52..c828b3918e 100644
--- a/engines/wintermute/base/scriptables/script_stack.cpp
+++ b/engines/wintermute/base/scriptables/script_stack.cpp
@@ -186,7 +186,7 @@ bool ScStack::persist(BasePersistenceManager *persistMgr) {
persistMgr->transferPtr(TMEMBER_PTR(_gameRef));
- persistMgr->transfer(TMEMBER(_sP));
+ persistMgr->transferSint32(TMEMBER(_sP));
_values.persist(persistMgr);
return STATUS_OK;
diff --git a/engines/wintermute/base/scriptables/script_value.cpp b/engines/wintermute/base/scriptables/script_value.cpp
index 31ec457df1..52367646a5 100644
--- a/engines/wintermute/base/scriptables/script_value.cpp
+++ b/engines/wintermute/base/scriptables/script_value.cpp
@@ -791,32 +791,32 @@ void ScValue::setValue(ScValue *val) {
bool ScValue::persist(BasePersistenceManager *persistMgr) {
persistMgr->transferPtr(TMEMBER_PTR(_gameRef));
- persistMgr->transfer(TMEMBER(_persistent));
- persistMgr->transfer(TMEMBER(_isConstVar));
- persistMgr->transfer(TMEMBER_INT(_type));
- persistMgr->transfer(TMEMBER(_valBool));
- persistMgr->transfer(TMEMBER(_valFloat));
- persistMgr->transfer(TMEMBER(_valInt));
+ persistMgr->transferBool(TMEMBER(_persistent));
+ persistMgr->transferBool(TMEMBER(_isConstVar));
+ persistMgr->transferSint32(TMEMBER_INT(_type));
+ persistMgr->transferBool(TMEMBER(_valBool));
+ persistMgr->transferDouble(TMEMBER(_valFloat));
+ persistMgr->transferSint32(TMEMBER(_valInt));
persistMgr->transferPtr(TMEMBER_PTR(_valNative));
int32 size;
const char *str;
if (persistMgr->getIsSaving()) {
size = _valObject.size();
- persistMgr->transfer("", &size);
+ persistMgr->transferSint32("", &size);
_valIter = _valObject.begin();
while (_valIter != _valObject.end()) {
str = _valIter->_key.c_str();
- persistMgr->transfer("", &str);
+ persistMgr->transferConstChar("", &str);
persistMgr->transferPtr("", &_valIter->_value);
_valIter++;
}
} else {
ScValue *val = nullptr;
- persistMgr->transfer("", &size);
+ persistMgr->transferSint32("", &size);
for (int i = 0; i < size; i++) {
- persistMgr->transfer("", &str);
+ persistMgr->transferConstChar("", &str);
persistMgr->transferPtr("", &val);
_valObject[str] = val;
@@ -825,7 +825,7 @@ bool ScValue::persist(BasePersistenceManager *persistMgr) {
}
persistMgr->transferPtr(TMEMBER_PTR(_valRef));
- persistMgr->transfer(TMEMBER(_valString));
+ persistMgr->transferCharPtr(TMEMBER(_valString));
if (!persistMgr->getIsSaving() && !persistMgr->checkVersion(1,2,2)) {
// Savegames prior to 1.2.2 stored empty strings as NULL.
diff --git a/engines/wintermute/base/sound/base_sound.cpp b/engines/wintermute/base/sound/base_sound.cpp
index c1923b3ca8..f9cd59e4fb 100644
--- a/engines/wintermute/base/sound/base_sound.cpp
+++ b/engines/wintermute/base/sound/base_sound.cpp
@@ -166,16 +166,16 @@ bool BaseSound::persist(BasePersistenceManager *persistMgr) {
persistMgr->transferPtr(TMEMBER_PTR(_gameRef));
- persistMgr->transfer(TMEMBER(_soundFilename));
- persistMgr->transfer(TMEMBER(_soundLooping));
- persistMgr->transfer(TMEMBER(_soundPaused));
- persistMgr->transfer(TMEMBER(_soundFreezePaused));
- persistMgr->transfer(TMEMBER(_soundPlaying));
- persistMgr->transfer(TMEMBER(_soundPosition));
- persistMgr->transfer(TMEMBER(_soundPrivateVolume));
- persistMgr->transfer(TMEMBER(_soundStreamed));
- persistMgr->transfer(TMEMBER_INT(_soundType));
- persistMgr->transfer(TMEMBER(_soundLoopStart));
+ persistMgr->transferString(TMEMBER(_soundFilename));
+ persistMgr->transferBool(TMEMBER(_soundLooping));
+ persistMgr->transferBool(TMEMBER(_soundPaused));
+ persistMgr->transferBool(TMEMBER(_soundFreezePaused));
+ persistMgr->transferBool(TMEMBER(_soundPlaying));
+ persistMgr->transferUint32(TMEMBER(_soundPosition));
+ persistMgr->transferSint32(TMEMBER(_soundPrivateVolume));
+ persistMgr->transferBool(TMEMBER(_soundStreamed));
+ persistMgr->transferSint32(TMEMBER_INT(_soundType));
+ persistMgr->transferUint32(TMEMBER(_soundLoopStart));
return STATUS_OK;
}
diff --git a/engines/wintermute/base/sound/base_sound_buffer.cpp b/engines/wintermute/base/sound/base_sound_buffer.cpp
index 7666a441a3..85ba52e334 100644
--- a/engines/wintermute/base/sound/base_sound_buffer.cpp
+++ b/engines/wintermute/base/sound/base_sound_buffer.cpp
@@ -58,6 +58,7 @@ BaseSoundBuffer::BaseSoundBuffer(BaseGame *inGame) : BaseClass(inGame) {
_file = nullptr;
_privateVolume = 255;
_volume = 255;
+ _pan = 0;
_looping = false;
_loopStart = 0;
@@ -143,9 +144,9 @@ bool BaseSoundBuffer::play(bool looping, uint32 startSample) {
_handle = new Audio::SoundHandle;
if (_looping) {
Audio::AudioStream *loopStream = new Audio::LoopingAudioStream(_stream, 0, DisposeAfterUse::NO);
- g_system->getMixer()->playStream(_type, _handle, loopStream, -1, _volume, 0, DisposeAfterUse::YES);
+ g_system->getMixer()->playStream(_type, _handle, loopStream, -1, _volume, _pan, DisposeAfterUse::YES);
} else {
- g_system->getMixer()->playStream(_type, _handle, _stream, -1, _volume, 0, DisposeAfterUse::NO);
+ g_system->getMixer()->playStream(_type, _handle, _stream, -1, _volume, _pan, DisposeAfterUse::NO);
}
}
@@ -268,8 +269,11 @@ bool BaseSoundBuffer::setLoopStart(uint32 pos) {
//////////////////////////////////////////////////////////////////////////
bool BaseSoundBuffer::setPan(float pan) {
+ pan = MAX(pan, -1.0f);
+ pan = MIN(pan, 1.0f);
+ _pan = (int8)(pan * 127);
if (_handle) {
- g_system->getMixer()->setChannelBalance(*_handle, (int8)(pan * 127));
+ g_system->getMixer()->setChannelBalance(*_handle, _pan);
}
return STATUS_OK;
}
diff --git a/engines/wintermute/base/sound/base_sound_buffer.h b/engines/wintermute/base/sound/base_sound_buffer.h
index 53b86f64c6..c52b34fb23 100644
--- a/engines/wintermute/base/sound/base_sound_buffer.h
+++ b/engines/wintermute/base/sound/base_sound_buffer.h
@@ -93,6 +93,7 @@ private:
bool _streamed;
Common::SeekableReadStream *_file;
int32 _volume;
+ int8 _pan;
};
} // End of namespace Wintermute
diff --git a/engines/wintermute/base/timer.cpp b/engines/wintermute/base/timer.cpp
index 96097c10d5..f1f79af760 100644
--- a/engines/wintermute/base/timer.cpp
+++ b/engines/wintermute/base/timer.cpp
@@ -66,9 +66,9 @@ uint32 Timer::getTimeLast() const {
}
void Timer::persist(BasePersistenceManager *persistMgr) {
- persistMgr->transfer(TMEMBER(_timer));
- persistMgr->transfer(TMEMBER(_timerDelta));
- persistMgr->transfer(TMEMBER(_timerLast));
+ persistMgr->transferUint32(TMEMBER(_timer));
+ persistMgr->transferUint32(TMEMBER(_timerDelta));
+ persistMgr->transferUint32(TMEMBER(_timerLast));
}
} // End of namespace Wintermute
diff --git a/engines/wintermute/coll_templ.h b/engines/wintermute/coll_templ.h
index a3df92d6c8..307989e58d 100644
--- a/engines/wintermute/coll_templ.h
+++ b/engines/wintermute/coll_templ.h
@@ -67,7 +67,7 @@ class BaseArray : public BaseArrayBase<TYPE> {
int32 j;
if (persistMgr->getIsSaving()) {
j = Common::Array<TYPE>::size();
- persistMgr->transfer("ArraySize", &j);
+ persistMgr->transferSint32("ArraySize", &j);
typename Common::Array<TYPE>::const_iterator it = Common::Array<TYPE>::begin();
for (; it != Common::Array<TYPE>::end(); ++it) {
TYPE obj = *it;
@@ -75,7 +75,7 @@ class BaseArray : public BaseArrayBase<TYPE> {
}
} else {
Common::Array<TYPE>::clear();
- persistMgr->transfer("ArraySize", &j);
+ persistMgr->transferSint32("ArraySize", &j);
for (int i = 0; i < j; i++) {
TYPE obj = nullptr;
persistMgr->transferPtr("", &obj);
@@ -93,18 +93,18 @@ class BaseArray<char *> : public BaseArrayBase<char *> {
int32 j;
if (persistMgr->getIsSaving()) {
j = Common::Array<char *>::size();
- persistMgr->transfer("ArraySize", &j);
+ persistMgr->transferSint32("ArraySize", &j);
Common::Array<char *>::const_iterator it = Common::Array<char *>::begin();
for (; it != Common::Array<char *>::end(); ++it) {
char * obj = *it;
- persistMgr->transfer("", &obj);
+ persistMgr->transferCharPtr("", &obj);
}
} else {
Common::Array<char *>::clear();
- persistMgr->transfer("ArraySize", &j);
+ persistMgr->transferSint32("ArraySize", &j);
for (int i = 0; i < j; i++) {
char * obj = nullptr;
- persistMgr->transfer("", &obj);
+ persistMgr->transferCharPtr("", &obj);
add(obj);
}
}
@@ -119,18 +119,18 @@ public:
int32 j;
if (persistMgr->getIsSaving()) {
j = Common::Array<const char *>::size();
- persistMgr->transfer("ArraySize", &j);
+ persistMgr->transferSint32("ArraySize", &j);
Common::Array<const char *>::const_iterator it = Common::Array<const char *>::begin();
for (; it != Common::Array<const char *>::end(); ++it) {
const char * obj = *it;
- persistMgr->transfer("", &obj);
+ persistMgr->transferConstChar("", &obj);
}
} else {
Common::Array<const char *>::clear();
- persistMgr->transfer("ArraySize", &j);
+ persistMgr->transferSint32("ArraySize", &j);
for (int i = 0; i < j; i++) {
const char * obj = nullptr;
- persistMgr->transfer("", &obj);
+ persistMgr->transferConstChar("", &obj);
add(obj);
}
}
diff --git a/engines/wintermute/configure.engine b/engines/wintermute/configure.engine
new file mode 100644
index 0000000000..bdaf49de3f
--- /dev/null
+++ b/engines/wintermute/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 wintermute "Wintermute" yes "" "" "jpeg png zlib vorbis 16bit"
diff --git a/engines/wintermute/dctypes.h b/engines/wintermute/dctypes.h
index b40322147f..4371ee4889 100644
--- a/engines/wintermute/dctypes.h
+++ b/engines/wintermute/dctypes.h
@@ -31,6 +31,7 @@
#include "common/str.h"
+#include "common/ustr.h"
#include "common/list.h"
#include "common/array.h"
@@ -41,7 +42,7 @@ namespace Wintermute {
//typedef std::wstring WideString;
typedef Common::String AnsiString;
typedef Common::String Utf8String;
-typedef Common::String WideString; // NB: Not actually true I presume.
+typedef Common::U32String WideString;
typedef Common::List<WideString> WideStringList;
typedef Common::List<AnsiString> AnsiStringList;
diff --git a/engines/wintermute/detection.cpp b/engines/wintermute/detection.cpp
index ac21d78ef5..f4bd437803 100644
--- a/engines/wintermute/detection.cpp
+++ b/engines/wintermute/detection.cpp
@@ -68,6 +68,7 @@ static char s_fallbackGameIdBuf[256];
static const char *directoryGlobs[] = {
"language", // To detect the various languages
+ "languages", // To detect the various languages
0
};
diff --git a/engines/wintermute/detection_tables.h b/engines/wintermute/detection_tables.h
index 63f5078c12..e7f2ed90a9 100644
--- a/engines/wintermute/detection_tables.h
+++ b/engines/wintermute/detection_tables.h
@@ -27,8 +27,10 @@ namespace Wintermute {
static const PlainGameDescriptor wintermuteGames[] = {
{"5ld", "Five Lethal Demons"},
{"5ma", "Five Magical Amulets"},
- {"bthreshold", "Beyond the Threshold"},
{"actualdest", "Actual Destination"},
+ {"bickadoodle", "Bickadoodle"},
+ {"bookofgron", "Book of Gron Part One"},
+ {"bthreshold", "Beyond the Threshold"},
{"carolreed4", "Carol Reed 4 - East Side Story"},
{"carolreed5", "Carol Reed 5 - The Colour of Murder"},
{"carolreed6", "Carol Reed 6 - Black Circle"},
@@ -41,24 +43,33 @@ static const PlainGameDescriptor wintermuteGames[] = {
{"dirtysplit", "Dirty Split"},
{"dreamscape", "Dreamscape"},
{"escapemansion", "Escape from the Mansion"},
+ {"framed", "Framed"},
{"ghostsheet", "Ghost in the Sheet"},
{"hamlet", "Hamlet or the last game without MMORPS features, shaders and product placement"},
+ {"helga", "Helga Deep In Trouble"},
{"jamesperis", "James Peris: No License Nor Control"},
+ {"kulivocko", "Kulivocko"},
+ {"lonelyrobot", "Project Lonely Robot"},
{"looky", "Looky"},
{"julia", "J.U.L.I.A."},
{"mirage", "Mirage"},
+ {"paintaria", "Paintaria"},
{"pigeons", "Pigeons in the Park"},
+ {"projectdoom", "Project: Doom"},
{"reversion1", "Reversion: The Escape"},
{"reversion2", "Reversion: The Meeting"},
{"rosemary", "Rosemary"},
+ {"securanote", "Securanote"},
{"shaban", "Shaban"},
{"shinestar", "The Shine of a Star"},
+ {"spaceinvaders", "Space Invaders"},
{"spacemadness", "Space Madness"},
{"thebox", "The Box"},
{"tib", "Fairy Tales About Toshechka and Boshechka"},
{"tradestory", "The Trader of Stories"},
{"twc", "the white chamber"},
{"wintermute", "Wintermute engine game"},
+ {"wtetris", "Wilma Tetris"},
{0, 0}
};
@@ -103,6 +114,26 @@ static const ADGameDescription gameDescriptions[] = {
ADGF_UNSTABLE,
GUIO0()
},
+ // Bickadoodle
+ {
+ "bickadoodle",
+ "",
+ AD_ENTRY1s("data.dcp", "84db4d1594cac95e25614985775d10a8", 35303844),
+ Common::EN_ANY,
+ Common::kPlatformWindows,
+ ADGF_UNSTABLE,
+ GUIO0()
+ },
+ // Book of Gron Part One
+ {
+ "bookofgron",
+ "",
+ AD_ENTRY1s("data.dcp", "e61b2ebee044a82fa0f8ca0fce2c8946", 83129531),
+ Common::RU_RUS,
+ Common::kPlatformWindows,
+ ADGF_UNSTABLE,
+ GUIO0()
+ },
// Carol Reed 4 - East Side Story (Demo)
{
"carolreed4",
@@ -206,6 +237,22 @@ static const ADGameDescription gameDescriptions[] = {
ADGF_TESTING,
GUIO0()
},
+ // 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()
+ },
// Dead City (English)
{
"deadcity",
@@ -248,6 +295,19 @@ static const ADGameDescription gameDescriptions[] = {
ADGF_UNSTABLE,
GUIO0()
},
+ // Dirty Split (Czech)
+ {
+ "dirtysplit",
+ "",
+ {
+ {"czech.dcp", 0, "08a71446467cf8f9444cfea446b46ad6", 127697934},
+ {"data.dcp", 0, "8b4b81b718bf65f30a67fc0b1e329eb5", 88577623},
+ },
+ Common::CZ_CZE,
+ Common::kPlatformWindows,
+ ADGF_UNSTABLE,
+ GUIO0()
+ },
// Dirty Split (English)
{
"dirtysplit",
@@ -258,6 +318,20 @@ static const ADGameDescription gameDescriptions[] = {
ADGF_UNSTABLE,
GUIO0()
},
+ // Dirty Split (French)
+ {
+ "dirtysplit",
+ "",
+ {
+ {"french.dcp", 0, "a0508dedebd0fe478d0158fa4c2a1136", 125534323},
+ {"data.dcp", 0, "e6d70c7f5d181b761cfcf974adf9186a", 88577623},
+ AD_LISTEND
+ },
+ Common::FR_FRA,
+ Common::kPlatformWindows,
+ ADGF_UNSTABLE,
+ GUIO0()
+ },
// Dirty Split (German)
{
"dirtysplit",
@@ -268,6 +342,32 @@ static const ADGameDescription gameDescriptions[] = {
ADGF_UNSTABLE,
GUIO0()
},
+ // Dirty Split (Italian)
+ {
+ "dirtysplit",
+ "",
+ {
+ {"italian.dcp", 0, "8108807fbd8af70be1ec452d0fd1131b", 125513726},
+ {"data.dcp", 0, "35a150e22af274185883fdbb142c6fb1", 88577623},
+ },
+ Common::IT_ITA,
+ Common::kPlatformWindows,
+ ADGF_UNSTABLE,
+ GUIO0()
+ },
+ // Dirty Split (Spanish)
+ {
+ "dirtysplit",
+ "",
+ {
+ {"spanish.dcp", 0, "b3982c0a5e85b42e1e38240fef004aa4", 164428596},
+ {"data.dcp", 0, "63766d6c68b9f00b632ea1736fc8a95c", 88577621},
+ },
+ Common::ES_ESP,
+ Common::kPlatformWindows,
+ ADGF_UNSTABLE,
+ GUIO0()
+ },
// Des Reves Elastiques Avec Mille Insectes Nommes Georges
{
"dreaming",
@@ -308,6 +408,26 @@ static const ADGameDescription gameDescriptions[] = {
ADGF_UNSTABLE,
GUIO0()
},
+ // Escape from the Mansion
+ {
+ "escapemansion",
+ "1.3",
+ AD_ENTRY1s("data.dcp", "1e5d231b56c8a228cd15cb690f50253e", 29261972),
+ Common::EN_ANY,
+ Common::kPlatformWindows,
+ ADGF_UNSTABLE,
+ GUIO0()
+ },
+ // Framed
+ {
+ "framed",
+ "",
+ AD_ENTRY1s("data.dcp", "e7259fb36f2c6f9f28242291e0c3de98", 34690568),
+ Common::EN_ANY,
+ Common::kPlatformWindows,
+ ADGF_UNSTABLE,
+ GUIO0()
+ },
// Ghosts in the Sheet
{
"ghostsheet",
@@ -329,6 +449,35 @@ static const ADGameDescription gameDescriptions[] = {
ADGF_UNSTABLE,
GUIO0()
},
+ // 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()
+ },
+ // 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()
+ },
// James Peris: No License Nor Control (English)
{
"jamesperis",
@@ -403,6 +552,27 @@ static const ADGameDescription gameDescriptions[] = {
ADGF_DEMO,
GUIO0()
},
+ // Kulivocko (Czech)
+ {
+ "kulivocko",
+ "",
+ AD_ENTRY1s("data.dcp", "44306dc470e9b27474043932eccee02f", 155106392),
+ Common::CZ_CZE,
+ Common::kPlatformWindows,
+ ADGF_UNSTABLE,
+ GUIO0()
+ },
+ // Kulivocko (Czech) (Demo)
+ {
+ "kulivocko",
+ "Demo",
+ AD_ENTRY1s("data.dcp", "63b164bdfadecbb0deb5da691afb8154", 48362234),
+ Common::CZ_CZE,
+ Common::kPlatformWindows,
+ ADGF_UNSTABLE |
+ ADGF_DEMO,
+ GUIO0()
+ },
// Looky Demo (English)
{
"looky",
@@ -414,7 +584,8 @@ static const ADGameDescription gameDescriptions[] = {
},
Common::EN_ANY,
Common::kPlatformWindows,
- ADGF_UNSTABLE,
+ ADGF_UNSTABLE |
+ ADGF_DEMO,
GUIO0()
},
// Looky Demo (German)
@@ -428,7 +599,8 @@ static const ADGameDescription gameDescriptions[] = {
},
Common::DE_DEU,
Common::kPlatformWindows,
- ADGF_UNSTABLE,
+ ADGF_UNSTABLE |
+ ADGF_DEMO,
GUIO0()
},
// Looky (German)
@@ -455,6 +627,16 @@ static const ADGameDescription gameDescriptions[] = {
ADGF_UNSTABLE,
GUIO0()
},
+ // Paintaria
+ {
+ "paintaria",
+ "",
+ AD_ENTRY1s("data.dcp", "354c08440c98150ff0d4008dd2865880", 48326040),
+ Common::EN_ANY,
+ Common::kPlatformWindows,
+ ADGF_UNSTABLE,
+ GUIO0()
+ },
// Pigeons in the Park
{
"pigeons",
@@ -465,6 +647,27 @@ static const ADGameDescription gameDescriptions[] = {
ADGF_UNSTABLE,
GUIO0()
},
+ // Project: Doom
+ {
+ "projectdoom",
+ "",
+ AD_ENTRY1s("data.dcp", "d5894b65a40706845434b99870bcab92", 99223761),
+ Common::EN_ANY,
+ Common::kPlatformWindows,
+ ADGF_UNSTABLE,
+ GUIO0()
+ },
+ // Project Lonely Robot
+ {
+ "lonelyrobot",
+ "beta",
+ AD_ENTRY1s("data.dcp", "a0cf7ad5bab957416dcda454e9f28ef0", 3420120),
+ Common::EN_ANY,
+ Common::kPlatformWindows,
+ ADGF_UNSTABLE |
+ ADGF_DEMO,
+ GUIO0()
+ },
// Reversion: The Escape Version 1.0
{
"reversion1",
@@ -643,6 +846,118 @@ static const ADGameDescription gameDescriptions[] = {
ADGF_UNSTABLE,
GUIO0()
},
+ // 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()
+ },
+ // 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()
+ },
+ // 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()
+ },
+ // 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()
+ },
+ // 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()
+ },
+ // 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()
+ },
+ // 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()
+ },
+ // 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()
+ },
// Reversion: The Meeting (Chinese)
{
"reversion2",
@@ -691,6 +1006,16 @@ static const ADGameDescription gameDescriptions[] = {
ADGF_UNSTABLE,
GUIO0()
},
+ // Securanote
+ {
+ "securanote",
+ "",
+ AD_ENTRY1s("data.dcp", "5213d3e59b9e95b7fbd5c56f7de5341a", 2625554),
+ Common::EN_ANY,
+ Common::kPlatformIOS,
+ ADGF_UNSTABLE,
+ GUIO0()
+ },
// Shaban
{
"shaban",
@@ -711,6 +1036,17 @@ static const ADGameDescription gameDescriptions[] = {
ADGF_UNSTABLE,
GUIO0()
},
+ // Space Invaders (Demo)
+ {
+ "spaceinvaders",
+ "Demo",
+ AD_ENTRY1s("data.dcp", "3f27adefdf72f2c1601cf555c80a509f", 1308361),
+ Common::EN_ANY,
+ Common::kPlatformWindows,
+ ADGF_UNSTABLE |
+ ADGF_DEMO,
+ GUIO0()
+ },
// Space Madness
{
"spacemadness",
@@ -762,6 +1098,16 @@ static const ADGameDescription gameDescriptions[] = {
ADGF_UNSTABLE,
GUIO0()
},
+ // Wilma Tetris
+ {
+ "wtetris",
+ "",
+ AD_ENTRY1s("data.dcp", "946e3a0496e6c12fb344c9ed861ff015", 2780093),
+ Common::EN_ANY,
+ Common::kPlatformWindows,
+ ADGF_UNSTABLE,
+ GUIO0()
+ },
AD_TABLE_END_MARKER
};
diff --git a/engines/wintermute/graphics/transform_struct.cpp b/engines/wintermute/graphics/transform_struct.cpp
index 643c6b413f..822c06f42f 100644
--- a/engines/wintermute/graphics/transform_struct.cpp
+++ b/engines/wintermute/graphics/transform_struct.cpp
@@ -35,6 +35,8 @@ void TransformStruct::init(Point32 zoom, uint32 angle, Point32 hotspot, bool alp
_flip += TransparentSurface::FLIP_H * mirrorX;
_flip += TransparentSurface::FLIP_V * mirrorY;
_offset = offset;
+ _numTimesX = 1;
+ _numTimesY = 1;
}
TransformStruct::TransformStruct(int32 zoomX, int32 zoomY, uint32 angle, int32 hotspotX, int32 hotspotY, TSpriteBlendMode blendMode, uint32 rgbaMod, bool mirrorX, bool mirrorY, int32 offsetX, int32 offsetY) {
@@ -83,6 +85,19 @@ TransformStruct::TransformStruct(int32 zoomX, int32 zoomY, uint32 angle, int32 h
Point32(kDefaultOffsetX, kDefaultOffsetY));
}
+TransformStruct::TransformStruct(int32 numTimesX, int32 numTimesY) {
+ init(Point32(kDefaultZoomX, kDefaultZoomY),
+ kDefaultAngle,
+ Point32(kDefaultHotspotX, kDefaultHotspotY),
+ false,
+ BLEND_NORMAL,
+ kDefaultRgbaMod,
+ false, false,
+ Point32(kDefaultOffsetX, kDefaultOffsetY));
+ _numTimesX = numTimesX;
+ _numTimesY = numTimesY;
+}
+
TransformStruct::TransformStruct() {
init(Point32(kDefaultZoomX, kDefaultZoomY),
kDefaultAngle,
diff --git a/engines/wintermute/graphics/transform_struct.h b/engines/wintermute/graphics/transform_struct.h
index 90a4c1f846..d5a03ea331 100644
--- a/engines/wintermute/graphics/transform_struct.h
+++ b/engines/wintermute/graphics/transform_struct.h
@@ -51,6 +51,7 @@ public:
TransformStruct(float zoomX, float zoomY, uint32 angle, int32 hotspotX, int32 hotspotY, TSpriteBlendMode blendMode, uint32 alpha, bool mirrorX = false, bool mirrorY = false, int32 offsetX = 0, int32 offsetY = 0);
TransformStruct(int32 zoomX, int32 zoomY, TSpriteBlendMode blendMode, uint32 alpha, bool mirrorX = false, bool mirrorY = false);
TransformStruct(int32 zoomX, int32 zoomY, uint32 angle, int32 hotspotX = 0, int32 hotspotY = 0);
+ TransformStruct(int32 numTimesX, int32 numTimesY);
TransformStruct();
Point32 _zoom; ///< Zoom; 100 = no zoom
@@ -61,6 +62,8 @@ public:
TSpriteBlendMode _blendMode;
uint32 _rgbaMod; ///< RGBa
Point32 _offset;
+ int32 _numTimesX;
+ int32 _numTimesY;
bool getMirrorX() const;
bool getMirrorY() const;
@@ -72,7 +75,9 @@ public:
compare._offset == _offset &&
compare._alphaDisable == _alphaDisable &&
compare._rgbaMod == _rgbaMod &&
- compare._blendMode == _blendMode
+ compare._blendMode == _blendMode &&
+ compare._numTimesX == _numTimesX &&
+ compare._numTimesY == _numTimesY
);
}
diff --git a/engines/wintermute/graphics/transform_tools.cpp b/engines/wintermute/graphics/transform_tools.cpp
index ebf9092aaa..dc92cdbbfd 100644
--- a/engines/wintermute/graphics/transform_tools.cpp
+++ b/engines/wintermute/graphics/transform_tools.cpp
@@ -26,11 +26,23 @@
namespace Wintermute {
-FloatPoint TransformTools::transformPoint(const FloatPoint &point, const float rotate, const Point32 &zoom, const bool mirrorX, const bool mirrorY) {
+FloatPoint TransformTools::transformPoint(FloatPoint point, const float rotate, const Point32 &zoom, const bool mirrorX, const bool mirrorY) {
float rotateRad = rotate * M_PI / 180.0f;
+ float x = point.x;
+ float y = point.y;
+ x = (x * zoom.x) / kDefaultZoomX;
+ y = (y * zoom.y) / kDefaultZoomY;
+#if 0
+ // TODO: Mirroring should be done before rotation, but the blitting
+ // code does the inverse, so we match that for now.
+ if (mirrorX)
+ x *= -1;
+ if (mirrorY)
+ y *= -1;
+#endif
FloatPoint newPoint;
- newPoint.x = (point.x * cos(rotateRad) - point.y * sin(rotateRad)) * zoom.x / kDefaultZoomX;
- newPoint.y = (point.x * sin(rotateRad) + point.y * cos(rotateRad)) * zoom.y / kDefaultZoomY;
+ newPoint.x = x * cos(rotateRad) - y * sin(rotateRad);
+ newPoint.y = x * sin(rotateRad) + y * cos(rotateRad);
if (mirrorX) {
newPoint.x *= -1;
}
@@ -58,10 +70,12 @@ Rect32 TransformTools::newRect(const Rect32 &oldRect, const TransformStruct &tra
float left = MIN(nw1.x, MIN(ne1.x, MIN(sw1.x, se1.x)));
float right = MAX(nw1.x, MAX(ne1.x, MAX(sw1.x, se1.x)));
- Rect32 res;
- newHotspot->y = (uint32)(-floor(top));
- newHotspot->x = (uint32)(-floor(left));
+ if (newHotspot) {
+ newHotspot->y = (uint32)(-floor(top));
+ newHotspot->x = (uint32)(-floor(left));
+ }
+ Rect32 res;
res.top = (int32)(floor(top)) + transform._hotspot.y;
res.bottom = (int32)(ceil(bottom)) + transform._hotspot.y;
res.left = (int32)(floor(left)) + transform._hotspot.x;
diff --git a/engines/wintermute/graphics/transform_tools.h b/engines/wintermute/graphics/transform_tools.h
index c92b81fd11..9a73e3b69f 100644
--- a/engines/wintermute/graphics/transform_tools.h
+++ b/engines/wintermute/graphics/transform_tools.h
@@ -34,7 +34,7 @@ public:
/**
* Basic transform (scale + rotate) for a single point
*/
- static FloatPoint transformPoint(const FloatPoint &point, const float rotate, const Point32 &zoom, const bool mirrorX = false, const bool mirrorY = false);
+ static FloatPoint transformPoint(FloatPoint point, const float rotate, const Point32 &zoom, const bool mirrorX = false, const bool mirrorY = false);
/**
* @param &point the point on which the transform is to be applied
diff --git a/engines/wintermute/graphics/transparent_surface.cpp b/engines/wintermute/graphics/transparent_surface.cpp
index 411ff1f477..79722439bd 100644
--- a/engines/wintermute/graphics/transparent_surface.cpp
+++ b/engines/wintermute/graphics/transparent_surface.cpp
@@ -17,8 +17,16 @@
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ * The bottom part of this is file is adapted from SDL_rotozoom.c. The
+ * relevant copyright notice for those specific functions can be found at the
+ * top of that section.
+ *
*/
+
+
#include "common/algorithm.h"
#include "common/endian.h"
#include "common/util.h"
@@ -29,6 +37,8 @@
#include "engines/wintermute/graphics/transparent_surface.h"
#include "engines/wintermute/graphics/transform_tools.h"
+//#define ENABLE_BILINEAR
+
namespace Wintermute {
void doBlitOpaqueFast(byte *ino, byte *outo, uint32 width, uint32 height, uint32 pitch, int32 inStep, int32 inoStep);
@@ -38,26 +48,26 @@ void doBlitBinaryFast(byte *ino, byte *outo, uint32 width, uint32 height, uint32
class BlenderAdditive {
public:
- static void blendPixel(byte ina, byte inr, byte ing, byte inb, byte *outa, byte *outr, byte *outg, byte *outb);
- static void blendPixel(byte ina, byte inr, byte ing, byte inb, byte *outa, byte *outr, byte *outg, byte *outb, byte *ca, byte *cr, byte *cg, byte *cb);
- static void blendPixel(byte *in, byte *out);
- static void blendPixel(byte *in, byte *out, int colorMod);
+ inline void blendPixel(byte ina, byte inr, byte ing, byte inb, byte *outa, byte *outr, byte *outg, byte *outb);
+ inline void blendPixel(byte ina, byte inr, byte ing, byte inb, byte *outa, byte *outr, byte *outg, byte *outb, byte *ca, byte *cr, byte *cg, byte *cb);
+ inline void blendPixel(byte *in, byte *out);
+ inline void blendPixel(byte *in, byte *out, int colorMod);
};
class BlenderSubtractive {
public:
- static void blendPixel(byte ina, byte inr, byte ing, byte inb, byte *outa, byte *outr, byte *outg, byte *outb);
- static void blendPixel(byte ina, byte inr, byte ing, byte inb, byte *outa, byte *outr, byte *outg, byte *outb, byte *ca, byte *cr, byte *cg, byte *cb);
- static void blendPixel(byte *in, byte *out);
- static void blendPixel(byte *in, byte *out, int colorMod);
+ inline void blendPixel(byte ina, byte inr, byte ing, byte inb, byte *outa, byte *outr, byte *outg, byte *outb);
+ inline void blendPixel(byte ina, byte inr, byte ing, byte inb, byte *outa, byte *outr, byte *outg, byte *outb, byte *ca, byte *cr, byte *cg, byte *cb);
+ inline void blendPixel(byte *in, byte *out);
+ inline void blendPixel(byte *in, byte *out, int colorMod);
};
class BlenderNormal {
public:
- static void blendPixel(byte ina, byte inr, byte ing, byte inb, byte *outa, byte *outr, byte *outg, byte *outb);
- static void blendPixel(byte ina, byte inr, byte ing, byte inb, byte *outa, byte *outr, byte *outg, byte *outb, byte *ca, byte *cr, byte *cg, byte *cb);
- static void blendPixel(byte *in, byte *out);
- static void blendPixel(byte *in, byte *out, int colorMod);
+ inline void blendPixel(byte ina, byte inr, byte ing, byte inb, byte *outa, byte *outr, byte *outg, byte *outb);
+ inline void blendPixel(byte ina, byte inr, byte ing, byte inb, byte *outa, byte *outr, byte *outg, byte *outb, byte *ca, byte *cr, byte *cg, byte *cb);
+ inline void blendPixel(byte *in, byte *out);
+ inline void blendPixel(byte *in, byte *out, int colorMod);
};
/**
@@ -66,7 +76,6 @@ public:
* @param *outa, *outr, *outg, *outb pointer to the output pixel.
* @param *outa, *outr, *outg, *outb pointer to the colormod components.
*/
-
void BlenderAdditive::blendPixel(byte ina, byte inr, byte ing, byte inb, byte *outa, byte *outr, byte *outg, byte *outb, byte *ca, byte *cr, byte *cg, byte *cb) {
if (*ca != 255) {
ina = (ina) * (*ca) >> 8;
@@ -98,7 +107,6 @@ void BlenderAdditive::blendPixel(byte ina, byte inr, byte ing, byte inb, byte *o
* @param *outa, *outr, *outg, *outb pointer to the output pixel.
* @param *outa, *outr, *outg, *outb pointer to the colormod components.
*/
-
void BlenderSubtractive::blendPixel(byte ina, byte inr, byte ing, byte inb, byte *outa, byte *outr, byte *outg, byte *outb, byte *ca, byte *cr, byte *cg, byte *cb) {
//if (*ca != 255) {
// ina = ina * (*ca) >> 8;
@@ -224,7 +232,6 @@ void BlenderNormal::blendPixel(byte ina, byte inr, byte ing, byte inb, byte *out
* @param ina, inr, ing, inb: the input pixel, split into its components.
* @param *outa, *outr, *outg, *outb pointer to the output pixel.
*/
-
void BlenderSubtractive::blendPixel(byte ina, byte inr, byte ing, byte inb, byte *outa, byte *outr, byte *outg, byte *outb) {
if (ina == 0) {
@@ -249,7 +256,6 @@ void BlenderSubtractive::blendPixel(byte ina, byte inr, byte ing, byte inb, byte
* @param ina, inr, ing, inb: the input pixel, split into its components.
* @param *outa, *outr, *outg, *outb pointer to the output pixel.
*/
-
void BlenderAdditive::blendPixel(byte ina, byte inr, byte ing, byte inb, byte *outa, byte *outr, byte *outg, byte *outb) {
if (ina == 0) {
@@ -269,119 +275,6 @@ void BlenderAdditive::blendPixel(byte ina, byte inr, byte ing, byte inb, byte *o
}
}
-#if ENABLE_BILINEAR
-void TransparentSurface::copyPixelBilinear(float projX, float projY, int dstX, int dstY, const Common::Rect &srcRect, const Common::Rect &dstRect, const TransparentSurface *src, TransparentSurface *dst) {
-
- // TODO: Do some optimization on this. This is completely naive.
-
- int srcW = srcRect.width();
- int srcH = srcRect.height();
- int dstW = dstRect.width();
- int dstH = dstRect.height();
-
- assert(dstX >= 0 && dstX < dstW);
- assert(dstY >= 0 && dstY < dstH);
-
- float x1 = floor(projX);
- float x2 = ceil(projX);
- float y1 = floor(projY);
- float y2 = ceil(projY);
-
- uint32 Q11, Q12, Q21, Q22;
-
- if (x1 >= srcW || x1 < 0 || y1 >= srcH || y1 < 0) {
- Q11 = 0;
- } else {
- Q11 = READ_UINT32((const byte *)src->getBasePtr((int)(x1 + srcRect.left), (int)(y1 + srcRect.top)));
- }
-
- if (x1 >= srcW || x1 < 0 || y2 >= srcH || y2 < 0) {
- Q12 = 0;
- } else {
- Q12 = READ_UINT32((const byte *)src->getBasePtr((int)(x1 + srcRect.left), (int)(y2 + srcRect.top)));
- }
-
- if (x2 >= srcW || x2 < 0 || y1 >= srcH || y1 < 0) {
- Q21 = 0;
- } else {
- Q21 = READ_UINT32((const byte *)src->getBasePtr((int)(x2 + srcRect.left), (int)(y1 + srcRect.top)));
- }
-
- if (x2 >= srcW || x2 < 0 || y2 >= srcH || y2 < 0) {
- Q22 = 0;
- } else {
- Q22 = READ_UINT32((const byte *)src->getBasePtr((int)(x2 + srcRect.left), (int)(y2 + srcRect.top)));
- }
-
- byte *Q11s = (byte *)&Q11;
- byte *Q12s = (byte *)&Q12;
- byte *Q21s = (byte *)&Q21;
- byte *Q22s = (byte *)&Q22;
-
- uint32 color;
- byte *dest = (byte *)&color;
-
- float q11x = (x2 - projX);
- float q11y = (y2 - projY);
- float q21x = (projX - x1);
- float q21y = (y2 - projY);
- float q12x = (x2 - projX);
- float q12y = (projY - y1);
-
- if (x1 == x2 && y1 == y2) {
- for (int c = 0; c < 4; c++) {
- dest[c] = ((float)Q11s[c]);
- }
- } else {
-
- if (x1 == x2) {
- q11x = 0.5;
- q12x = 0.5;
- q21x = 0.5;
- } else if (y1 == y2) {
- q11y = 0.5;
- q12y = 0.5;
- q21y = 0.5;
- }
-
- for (int c = 0; c < 4; c++) {
- dest[c] = (byte)(
- ((float)Q11s[c]) * q11x * q11y +
- ((float)Q21s[c]) * q21x * q21y +
- ((float)Q12s[c]) * q12x * q12y +
- ((float)Q22s[c]) * (1.0 -
- q11x * q11y -
- q21x * q21y -
- q12x * q12y)
- );
- }
- }
- WRITE_UINT32((byte *)dst->getBasePtr(dstX + dstRect.left, dstY + dstRect.top), color);
-}
-#else
-void TransparentSurface::copyPixelNearestNeighbor(float projX, float projY, int dstX, int dstY, const Common::Rect &srcRect, const Common::Rect &dstRect, const TransparentSurface *src, TransparentSurface *dst) {
-
- // TODO: Have the Rect arguments become completely useless at this point?
-
- int srcW = srcRect.width();
- int srcH = srcRect.height();
- int dstW = dstRect.width();
- int dstH = dstRect.height();
-
- assert(dstX >= 0 && dstX < dstW);
- assert(dstY >= 0 && dstY < dstH);
-
- uint32 color;
-
- if (projX >= srcW || projX < 0 || projY >= srcH || projY < 0) {
- color = 0;
- } else {
- color = READ_UINT32((const byte *)src->getBasePtr((int)projX, (int)projY));
- }
-
- WRITE_UINT32((byte *)dst->getBasePtr(dstX, dstY), color);
-}
-#endif
TransparentSurface::TransparentSurface() : Surface(), _alphaMode(ALPHA_FULL) {}
@@ -400,10 +293,11 @@ TransparentSurface::TransparentSurface(const Surface &surf, bool copyData) : Sur
}
}
-void doBlitOpaqueFast(byte *ino, byte *outo, uint32 width, uint32 height, uint32 pitch, int32 inStep, int32 inoStep) {
/**
* Optimized version of doBlit to be used w/opaque blitting (no alpha).
*/
+void doBlitOpaqueFast(byte *ino, byte *outo, uint32 width, uint32 height, uint32 pitch, int32 inStep, int32 inoStep) {
+
byte *in;
byte *out;
@@ -423,7 +317,6 @@ void doBlitOpaqueFast(byte *ino, byte *outo, uint32 width, uint32 height, uint32
/**
* Optimized version of doBlit to be used w/binary blitting (blit or no-blit, no blending).
*/
-
void doBlitBinaryFast(byte *ino, byte *outo, uint32 width, uint32 height, uint32 pitch, int32 inStep, int32 inoStep) {
byte *in;
@@ -453,8 +346,8 @@ void doBlitBinaryFast(byte *ino, byte *outo, uint32 width, uint32 height, uint32
* What we have here is a template method that calls blendPixel() from a different
* class - the one we call it with - thus performing a different type of blending.
*
- * @param *ino a pointer to the input surface
- * @param *outo a pointer to the output surface
+ * @param ino a pointer to the input surface
+ * @param outo a pointer to the output surface
* @param width width of the input surface
* @param height height of the input surface
* @param pitch pitch of the output surface - that is, width in bytes of every row, usually bpp * width of the TARGET surface (the area we are blitting to might be smaller, do the math)
@@ -465,7 +358,7 @@ void doBlitBinaryFast(byte *ino, byte *outo, uint32 width, uint32 height, uint32
template<class Blender>
void doBlit(byte *ino, byte *outo, uint32 width, uint32 height, uint32 pitch, int32 inStep, int32 inoStep, uint32 color) {
-
+ Blender b;
byte *in;
byte *out;
@@ -481,7 +374,7 @@ void doBlit(byte *ino, byte *outo, uint32 width, uint32 height, uint32 pitch, in
byte *outg = &out[TransparentSurface::kGIndex];
byte *outb = &out[TransparentSurface::kBIndex];
- Blender::blendPixel(in[TransparentSurface::kAIndex],
+ b.blendPixel(in[TransparentSurface::kAIndex],
in[TransparentSurface::kRIndex],
in[TransparentSurface::kGIndex],
in[TransparentSurface::kBIndex],
@@ -510,7 +403,7 @@ void doBlit(byte *ino, byte *outo, uint32 width, uint32 height, uint32 pitch, in
byte *outg = &out[TransparentSurface::kGIndex];
byte *outb = &out[TransparentSurface::kBIndex];
- Blender::blendPixel(in[TransparentSurface::kAIndex],
+ b.blendPixel(in[TransparentSurface::kAIndex],
in[TransparentSurface::kRIndex],
in[TransparentSurface::kGIndex],
in[TransparentSurface::kBIndex],
@@ -626,9 +519,9 @@ Common::Rect TransparentSurface::blit(Graphics::Surface &target, int posX, int p
byte *ino= (byte *)img->getBasePtr(xp, yp);
byte *outo = (byte *)target.getBasePtr(posX, posY);
- if (color == 0xFFFFFF && blendMode == BLEND_NORMAL && _alphaMode == ALPHA_OPAQUE) {
+ if (color == 0xFFFFFFFF && blendMode == BLEND_NORMAL && _alphaMode == ALPHA_OPAQUE) {
doBlitOpaqueFast(ino, outo, img->w, img->h, target.pitch, inStep, inoStep);
- } else if (color == 0xFFFFFF && blendMode == BLEND_NORMAL && _alphaMode == ALPHA_BINARY) {
+ } else if (color == 0xFFFFFFFF && blendMode == BLEND_NORMAL && _alphaMode == ALPHA_BINARY) {
doBlitBinaryFast(ino, outo, img->w, img->h, target.pitch, inStep, inoStep);
} else {
if (blendMode == BLEND_ADDITIVE) {
@@ -655,6 +548,88 @@ Common::Rect TransparentSurface::blit(Graphics::Surface &target, int posX, int p
return retSize;
}
+/**
+ * Writes a color key to the alpha channel of the surface
+ * @param rKey the red component of the color key
+ * @param gKey the green component of the color key
+ * @param bKey the blue component of the color key
+ * @param overwriteAlpha if true, all other alpha will be set fully opaque
+ */
+void TransparentSurface::applyColorKey(uint8 rKey, uint8 gKey, uint8 bKey, bool overwriteAlpha) {
+ assert(format.bytesPerPixel == 4);
+ for (int i = 0; i < h; i++) {
+ for (int j = 0; j < w; j++) {
+ uint32 pix = ((uint32 *)pixels)[i * w + j];
+ uint8 r, g, b, a;
+ format.colorToARGB(pix, a, r, g, b);
+ if (r == rKey && g == gKey && b == bKey) {
+ a = 0;
+ ((uint32 *)pixels)[i * w + j] = format.ARGBToColor(a, r, g, b);
+ } else if (overwriteAlpha) {
+ a = 255;
+ ((uint32 *)pixels)[i * w + j] = format.ARGBToColor(a, r, g, b);
+ }
+ }
+ }
+}
+
+TransparentSurface::AlphaType TransparentSurface::getAlphaMode() const {
+ return _alphaMode;
+}
+
+void TransparentSurface::setAlphaMode(TransparentSurface::AlphaType mode) {
+ _alphaMode = mode;
+}
+
+
+
+
+
+
+/*
+
+The below two functions are adapted from SDL_rotozoom.c,
+taken from SDL_gfx-2.0.18.
+
+Its copyright notice:
+
+=============================================================================
+SDL_rotozoom.c: rotozoomer, zoomer and shrinker for 32bit or 8bit surfaces
+
+Copyright (C) 2001-2012 Andreas Schiffler
+
+This software is provided 'as-is', without any express or implied
+warranty. In no event will the authors be held liable for any damages
+arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose,
+including commercial applications, and to alter it and redistribute it
+freely, subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not
+claim that you wrote the original software. If you use this software
+in a product, an acknowledgment in the product documentation would be
+appreciated but is not required.
+
+2. Altered source versions must be plainly marked as such, and must not be
+misrepresented as being the original software.
+
+3. This notice may not be removed or altered from any source
+distribution.
+
+Andreas Schiffler -- aschiffler at ferzkopp dot net
+=============================================================================
+
+
+The functions have been adapted for different structures and coordinate
+systems.
+
+*/
+
+
+
+
+
TransparentSurface *TransparentSurface::rotoscale(const TransformStruct &transform) const {
assert(transform._angle != 0); // This would not be ideal; rotoscale() should never be called in conditional branches where angle = 0 anyway.
@@ -667,33 +642,98 @@ TransparentSurface *TransparentSurface::rotoscale(const TransformStruct &transfo
TransparentSurface *target = new TransparentSurface();
assert(format.bytesPerPixel == 4);
+ int srcW = w;
+ int srcH = h;
int dstW = dstRect.width();
int dstH = dstRect.height();
target->create((uint16)dstW, (uint16)dstH, this->format);
+ if (transform._zoom.x == 0 || transform._zoom.y == 0)
+ return target;
+
uint32 invAngle = 360 - (transform._angle % 360);
float invCos = cos(invAngle * M_PI / 180.0);
float invSin = sin(invAngle * M_PI / 180.0);
- float targX;
- float targY;
- for (int y = 0; y < dstH; y++) {
- for (int x = 0; x < dstW; x++) {
- int x1 = x - newHotspot.x;
- int y1 = y - newHotspot.y;
+ struct tColorRGBA { byte r; byte g; byte b; byte a; };
+ int icosx = (int)(invCos * (65536.0f * kDefaultZoomX / transform._zoom.x));
+ int isinx = (int)(invSin * (65536.0f * kDefaultZoomX / transform._zoom.x));
+ int icosy = (int)(invCos * (65536.0f * kDefaultZoomY / transform._zoom.y));
+ int isiny = (int)(invSin * (65536.0f * kDefaultZoomY / transform._zoom.y));
+
- targX = ((x1 * invCos - y1 * invSin)) * kDefaultZoomX / transform._zoom.x + srcRect.left;
- targY = ((x1 * invSin + y1 * invCos)) * kDefaultZoomY / transform._zoom.y + srcRect.top;
+ bool flipx = false, flipy = false; // TODO: See mirroring comment in RenderTicket ctor
- targX += transform._hotspot.x;
- targY += transform._hotspot.y;
+ int xd = (srcRect.left + transform._hotspot.x) << 16;
+ int yd = (srcRect.top + transform._hotspot.y) << 16;
+ int cx = newHotspot.x;
+ int cy = newHotspot.y;
-#if ENABLE_BILINEAR
- copyPixelBilinear(targX, targY, x, y, srcRect, dstRect, this, target);
+ int ax = -icosx * cx;
+ int ay = -isiny * cx;
+ int sw = srcW - 1;
+ int sh = srcH - 1;
+
+ tColorRGBA *pc = (tColorRGBA*)target->getBasePtr(0, 0);
+
+ for (int y = 0; y < dstH; y++) {
+ int t = cy - y;
+ int sdx = ax + (isinx * t) + xd;
+ int sdy = ay - (icosy * t) + yd;
+ for (int x = 0; x < dstW; x++) {
+ int dx = (sdx >> 16);
+ int dy = (sdy >> 16);
+ if (flipx) dx = sw - dx;
+ if (flipy) dy = sh - dy;
+
+#ifdef ENABLE_BILINEAR
+ if ((dx > -1) && (dy > -1) && (dx < sw) && (dy < sh)) {
+ const tColorRGBA *sp = (const tColorRGBA *)getBasePtr(dx, dy);
+ tColorRGBA c00, c01, c10, c11, cswap;
+ c00 = *sp;
+ sp += 1;
+ c01 = *sp;
+ sp += (this->pitch/4);
+ c11 = *sp;
+ sp -= 1;
+ c10 = *sp;
+ if (flipx) {
+ cswap = c00; c00=c01; c01=cswap;
+ cswap = c10; c10=c11; c11=cswap;
+ }
+ if (flipy) {
+ cswap = c00; c00=c10; c10=cswap;
+ cswap = c01; c01=c11; c11=cswap;
+ }
+ /*
+ * Interpolate colors
+ */
+ int ex = (sdx & 0xffff);
+ int ey = (sdy & 0xffff);
+ int t1, t2;
+ t1 = ((((c01.r - c00.r) * ex) >> 16) + c00.r) & 0xff;
+ t2 = ((((c11.r - c10.r) * ex) >> 16) + c10.r) & 0xff;
+ pc->r = (((t2 - t1) * ey) >> 16) + t1;
+ t1 = ((((c01.g - c00.g) * ex) >> 16) + c00.g) & 0xff;
+ t2 = ((((c11.g - c10.g) * ex) >> 16) + c10.g) & 0xff;
+ pc->g = (((t2 - t1) * ey) >> 16) + t1;
+ t1 = ((((c01.b - c00.b) * ex) >> 16) + c00.b) & 0xff;
+ t2 = ((((c11.b - c10.b) * ex) >> 16) + c10.b) & 0xff;
+ pc->b = (((t2 - t1) * ey) >> 16) + t1;
+ t1 = ((((c01.a - c00.a) * ex) >> 16) + c00.a) & 0xff;
+ t2 = ((((c11.a - c10.a) * ex) >> 16) + c10.a) & 0xff;
+ pc->a = (((t2 - t1) * ey) >> 16) + t1;
+ }
#else
- copyPixelNearestNeighbor(targX, targY, x, y, srcRect, dstRect, this, target);
+ if ((dx >= 0) && (dy >= 0) && (dx < srcW) && (dy < srcH)) {
+ const tColorRGBA *sp = (const tColorRGBA *)getBasePtr(dx, dy);
+ *pc = *sp;
+ }
#endif
+ sdx += icosx;
+ sdy += isiny;
+ pc++;
}
}
return target;
@@ -715,47 +755,169 @@ TransparentSurface *TransparentSurface::scale(uint16 newWidth, uint16 newHeight)
target->create((uint16)dstW, (uint16)dstH, this->format);
+#ifdef ENABLE_BILINEAR
- float projX;
- float projY;
- for (int y = 0; y < dstH; y++) {
- for (int x = 0; x < dstW; x++) {
- projX = x / (float)dstW * srcW;
- projY = y / (float)dstH * srcH;
-#if ENABLE_BILINEAR
- copyPixelBilinear(projX, projY, x, y, srcRect, dstRect, this, target);
-#else
- copyPixelNearestNeighbor(projX, projY, x, y, srcRect, dstRect, this, target);
-#endif
+ // NB: The actual order of these bytes may not be correct, but
+ // since all values are treated equal, that does not matter.
+ struct tColorRGBA { byte r; byte g; byte b; byte a; };
+
+ bool flipx = false, flipy = false; // TODO: See mirroring comment in RenderTicket ctor
+
+
+ int *sax = new int[dstW+1];
+ int *say = new int[dstH+1];
+ assert(sax && say);
+
+ /*
+ * Precalculate row increments
+ */
+ int spixelw = (srcW - 1);
+ int spixelh = (srcH - 1);
+ int sx = (int) (65536.0f * (float) spixelw / (float) (dstW - 1));
+ int sy = (int) (65536.0f * (float) spixelh / (float) (dstH - 1));
+
+ /* Maximum scaled source size */
+ int ssx = (srcW << 16) - 1;
+ int ssy = (srcH << 16) - 1;
+
+ /* Precalculate horizontal row increments */
+ int csx = 0;
+ int *csax = sax;
+ for (int x = 0; x <= dstW; x++) {
+ *csax = csx;
+ csax++;
+ csx += sx;
+
+ /* Guard from overflows */
+ if (csx > ssx) {
+ csx = ssx;
}
}
- return target;
-}
+ /* Precalculate vertical row increments */
+ int csy = 0;
+ int *csay = say;
+ for (int y = 0; y <= dstH; y++) {
+ *csay = csy;
+ csay++;
+ csy += sy;
+
+ /* Guard from overflows */
+ if (csy > ssy) {
+ csy = ssy;
+ }
+ }
-/**
- * Writes a color key to the alpha channel of the surface
- * @param rKey the red component of the color key
- * @param gKey the green component of the color key
- * @param bKey the blue component of the color key
- * @param overwriteAlpha if true, all other alpha will be set fully opaque
- */
-void TransparentSurface::applyColorKey(uint8 rKey, uint8 gKey, uint8 bKey, bool overwriteAlpha) {
- assert(format.bytesPerPixel == 4);
- for (int i = 0; i < h; i++) {
- for (int j = 0; j < w; j++) {
- uint32 pix = ((uint32 *)pixels)[i * w + j];
- uint8 r, g, b, a;
- format.colorToARGB(pix, a, r, g, b);
- if (r == rKey && g == gKey && b == bKey) {
- a = 0;
- ((uint32 *)pixels)[i * w + j] = format.ARGBToColor(a, r, g, b);
- } else if (overwriteAlpha) {
- a = 255;
- ((uint32 *)pixels)[i * w + j] = format.ARGBToColor(a, r, g, b);
+ const tColorRGBA *sp = (const tColorRGBA *) getBasePtr(0,0);
+ tColorRGBA *dp = (tColorRGBA *) target->getBasePtr(0,0);
+ int spixelgap = srcW;
+
+ if (flipx)
+ sp += spixelw;
+ if (flipy)
+ sp += spixelgap * spixelh;
+
+ csay = say;
+ for (int y = 0; y < dstH; y++) {
+ const tColorRGBA *csp = sp;
+ csax = sax;
+ for (int x = 0; x < dstW; x++) {
+ /*
+ * Setup color source pointers
+ */
+ int ex = (*csax & 0xffff);
+ int ey = (*csay & 0xffff);
+ int cx = (*csax >> 16);
+ int cy = (*csay >> 16);
+
+ const tColorRGBA *c00, *c01, *c10, *c11;
+ c00 = sp;
+ c01 = sp;
+ c10 = sp;
+ if (cy < spixelh) {
+ if (flipy)
+ c10 -= spixelgap;
+ else
+ c10 += spixelgap;
+ }
+ c11 = c10;
+ if (cx < spixelw) {
+ if (flipx) {
+ c01--;
+ c11--;
+ } else {
+ c01++;
+ c11++;
+ }
}
+
+ /*
+ * Draw and interpolate colors
+ */
+ int t1, t2;
+ t1 = ((((c01->r - c00->r) * ex) >> 16) + c00->r) & 0xff;
+ t2 = ((((c11->r - c10->r) * ex) >> 16) + c10->r) & 0xff;
+ dp->r = (((t2 - t1) * ey) >> 16) + t1;
+ t1 = ((((c01->g - c00->g) * ex) >> 16) + c00->g) & 0xff;
+ t2 = ((((c11->g - c10->g) * ex) >> 16) + c10->g) & 0xff;
+ dp->g = (((t2 - t1) * ey) >> 16) + t1;
+ t1 = ((((c01->b - c00->b) * ex) >> 16) + c00->b) & 0xff;
+ t2 = ((((c11->b - c10->b) * ex) >> 16) + c10->b) & 0xff;
+ dp->b = (((t2 - t1) * ey) >> 16) + t1;
+ t1 = ((((c01->a - c00->a) * ex) >> 16) + c00->a) & 0xff;
+ t2 = ((((c11->a - c10->a) * ex) >> 16) + c10->a) & 0xff;
+ dp->a = (((t2 - t1) * ey) >> 16) + t1;
+
+ /*
+ * Advance source pointer x
+ */
+ int *salastx = csax;
+ csax++;
+ int sstepx = (*csax >> 16) - (*salastx >> 16);
+ if (flipx)
+ sp -= sstepx;
+ else
+ sp += sstepx;
+
+ /*
+ * Advance destination pointer x
+ */
+ dp++;
}
+ /*
+ * Advance source pointer y
+ */
+ int *salasty = csay;
+ csay++;
+ int sstepy = (*csay >> 16) - (*salasty >> 16);
+ sstepy *= spixelgap;
+ if (flipy)
+ sp = csp - sstepy;
+ else
+ sp = csp + sstepy;
+ }
+
+ delete[] sax;
+ delete[] say;
+
+#else
+
+ int *scaleCacheX = new int[dstW];
+ for (int x = 0; x < dstW; x++)
+ scaleCacheX[x] = (x * srcW) / dstW;
+
+ for (int y = 0; y < dstH; y++) {
+ uint32 *destP = (uint32 *)target->getBasePtr(0, y);
+ const uint32 *srcP = (const uint32 *)getBasePtr(0, (y * srcH) / dstH);
+ for (int x = 0; x < dstW; x++)
+ *destP++ = srcP[scaleCacheX[x]];
}
+ delete[] scaleCacheX;
+
+#endif
+
+ return target;
+
}
} // End of namespace Wintermute
diff --git a/engines/wintermute/graphics/transparent_surface.h b/engines/wintermute/graphics/transparent_surface.h
index 821b5c5943..1f3827d1a9 100644
--- a/engines/wintermute/graphics/transparent_surface.h
+++ b/engines/wintermute/graphics/transparent_surface.h
@@ -25,9 +25,6 @@
#include "graphics/surface.h"
#include "engines/wintermute/graphics/transform_struct.h"
-#define ENABLE_BILINEAR 0
-
-
/*
* This code is based on Broken Sword 2.5 engine
*
@@ -53,31 +50,6 @@ struct TransparentSurface : public Graphics::Surface {
void setColorKey(char r, char g, char b);
void disableColorKey();
-#if ENABLE_BILINEAR
- /*
- * Pick color from a point in source and copy it to a pixel in target.
- * The point in the source can be a float - we have subpixel accuracy in the arguments.
- * We do bilinear interpolation to estimate the color of the point even if the
- * point is specuified w/subpixel accuracy.
- *
- * @param projX, projY, point in the source to pick color from.
- * @param dstX, dstY destionation pixel
- * @param *src, *dst pointer to the source and dest surfaces
- */
- static void copyPixelBilinear(float projX, float projY, int dstX, int dstY, const Common::Rect &srcRect, const Common::Rect &dstRect, const TransparentSurface *src, TransparentSurface *dst);
-#else
- /*
- * Pick color from a point in source and copy it to a pixel in target.
- * The point in the source can be a float - we have subpixel accuracy in the arguments.
- * HOWEVER, this particular function just does nearest neighbor.
- * Use copyPixelBilinear if you interpolation.
- *
- * @param projX, projY, point in the source to pick color from.
- * @param dstX, dstY destionation pixel
- * @param *src, *dst pointer to the source and dest surfaces
- */
- static void copyPixelNearestNeighbor(float projX, float projY, int dstX, int dstY, const Common::Rect &srcRect, const Common::Rect &dstRect, const TransparentSurface *src, TransparentSurface *dst);
-#endif
// Enums
/**
@brief The possible flipping parameters for the blit methode.
@@ -101,8 +73,6 @@ struct TransparentSurface : public Graphics::Surface {
ALPHA_FULL = 2
};
- AlphaType _alphaMode;
-
#ifdef SCUMM_LITTLE_ENDIAN
static const int kAIndex = 0;
static const int kBIndex = 1;
@@ -129,32 +99,31 @@ struct TransparentSurface : public Graphics::Surface {
/**
@brief renders the surface to another surface
- @param pDest a pointer to the target image. In most cases this is the framebuffer.
- @param PosX the position on the X-axis in the target image in pixels where the image is supposed to be rendered.<br>
+ @param target a pointer to the target surface. In most cases this is the framebuffer.
+ @param posX the position on the X-axis in the target image in pixels where the image is supposed to be rendered.<br>
The default value is 0.
- @param PosY the position on the Y-axis in the target image in pixels where the image is supposed to be rendered.<br>
+ @param posY the position on the Y-axis in the target image in pixels where the image is supposed to be rendered.<br>
The default value is 0.
- @param Flipping how the the image should be flipped.<br>
+ @param flipping how the the image should be flipped.<br>
The default value is BS_Image::FLIP_NONE (no flipping)
- @param pSrcPartRect Pointer on Common::Rect which specifies the section to be rendered. If the whole image has to be rendered the Pointer is NULL.<br>
+ @param pPartRect Pointer on Common::Rect which specifies the section to be rendered. If the whole image has to be rendered the Pointer is NULL.<br>
This referes to the unflipped and unscaled image.<br>
The default value is NULL.
- @param Color an ARGB color value, which determines the parameters for the color modulation und alpha blending.<br>
+ @param color an ARGB color value, which determines the parameters for the color modulation und alpha blending.<br>
The alpha component of the color determines the alpha blending parameter (0 = no covering, 255 = full covering).<br>
The color components determines the color for color modulation.<br>
The default value is BS_ARGB(255, 255, 255, 255) (full covering, no color modulation).
The macros BS_RGB and BS_ARGB can be used for the creation of the color value.
- @param Width the output width of the screen section.
+ @param width the output width of the screen section.
The images will be scaled if the output width of the screen section differs from the image section.<br>
The value -1 determines that the image should not be scaled.<br>
The default value is -1.
- @param Width the output height of the screen section.
+ @param height the output height of the screen section.
The images will be scaled if the output width of the screen section differs from the image section.<br>
The value -1 determines that the image should not be scaled.<br>
The default value is -1.
@return returns false if the rendering failed.
*/
-
Common::Rect blit(Graphics::Surface &target, int posX = 0, int posY = 0,
int flipping = FLIP_NONE,
Common::Rect *pPartRect = nullptr,
@@ -167,8 +136,9 @@ struct TransparentSurface : public Graphics::Surface {
* @brief Scale function; this returns a transformed version of this surface after rotation and
* scaling. Please do not use this if angle != 0, use rotoscale.
*
- * @param transform a TransformStruct wrapping the required info. @see TransformStruct
- *
+ * @param newWidth the resulting width.
+ * @param newHeight the resulting height.
+ * @see TransformStruct
*/
TransparentSurface *scale(uint16 newWidth, uint16 newHeight) const;
@@ -180,6 +150,11 @@ struct TransparentSurface : public Graphics::Surface {
*
*/
TransparentSurface *rotoscale(const TransformStruct &transform) const;
+ AlphaType getAlphaMode() const;
+ void setAlphaMode(AlphaType);
+private:
+ AlphaType _alphaMode;
+
};
/**
diff --git a/engines/wintermute/math/rect32.h b/engines/wintermute/math/rect32.h
index f522ab3a35..a4a64690e2 100644
--- a/engines/wintermute/math/rect32.h
+++ b/engines/wintermute/math/rect32.h
@@ -94,12 +94,24 @@ struct Rect32 {
left = right = top = bottom = 0;
}
+ bool isRectEmpty() const {
+ return (left >= right) || (top >= bottom);
+ }
+
void offsetRect(int dx, int dy) {
left += dx;
top += dy;
right += dx;
bottom += dy;
}
+
+ void setRect(int32 newLeft, int32 newTop, int32 newRight, int32 newBottom) {
+ this->left = newLeft;
+ this->top = newTop;
+ this->right = newRight;
+ this->bottom = newBottom;
+ }
+
/**
* Check if the given rect is equal to this one.
*
diff --git a/engines/wintermute/platform_osystem.cpp b/engines/wintermute/platform_osystem.cpp
index 87a127d001..9fa23c6074 100644
--- a/engines/wintermute/platform_osystem.cpp
+++ b/engines/wintermute/platform_osystem.cpp
@@ -169,52 +169,16 @@ bool BasePlatform::setCursorPos(int x, int y) {
}
//////////////////////////////////////////////////////////////////////////
-bool BasePlatform::showWindow(int nCmdShow) {
- return false;
-}
-
-//////////////////////////////////////////////////////////////////////////
-void BasePlatform::setCapture() {
- return;
-}
-
-//////////////////////////////////////////////////////////////////////////
-bool BasePlatform::releaseCapture() {
- return false;
-}
-
-//////////////////////////////////////////////////////////////////////////
-bool BasePlatform::setRectEmpty(Rect32 *lprc) {
- lprc->left = lprc->right = lprc->top = lprc->bottom = 0;
- return true;
-}
-
-//////////////////////////////////////////////////////////////////////////
-bool BasePlatform::isRectEmpty(const Rect32 *lprc) {
- return (lprc->left >= lprc->right) || (lprc->top >= lprc->bottom);
-}
-
-//////////////////////////////////////////////////////////////////////////
bool BasePlatform::ptInRect(Rect32 *lprc, Point32 p) {
return (p.x >= lprc->left) && (p.x < lprc->right) && (p.y >= lprc->top) && (p.y < lprc->bottom);
}
//////////////////////////////////////////////////////////////////////////
-bool BasePlatform::setRect(Rect32 *lprc, int left, int top, int right, int bottom) {
- lprc->left = left;
- lprc->top = top;
- lprc->right = right;
- lprc->bottom = bottom;
-
- return true;
-}
-
-//////////////////////////////////////////////////////////////////////////
bool BasePlatform::intersectRect(Rect32 *lprcDst, const Rect32 *lprcSrc1, const Rect32 *lprcSrc2) {
- if (isRectEmpty(lprcSrc1) || isRectEmpty(lprcSrc2) ||
+ if (lprcSrc1->isRectEmpty() || lprcSrc2->isRectEmpty() ||
lprcSrc1->left >= lprcSrc2->right || lprcSrc2->left >= lprcSrc1->right ||
lprcSrc1->top >= lprcSrc2->bottom || lprcSrc2->top >= lprcSrc1->bottom) {
- setRectEmpty(lprcDst);
+ lprcDst->setEmpty();
return false;
}
lprcDst->left = MAX(lprcSrc1->left, lprcSrc2->left);
@@ -227,15 +191,15 @@ bool BasePlatform::intersectRect(Rect32 *lprcDst, const Rect32 *lprcSrc1, const
//////////////////////////////////////////////////////////////////////////
bool BasePlatform::unionRect(Rect32 *lprcDst, Rect32 *lprcSrc1, Rect32 *lprcSrc2) {
- if (isRectEmpty(lprcSrc1)) {
- if (isRectEmpty(lprcSrc2)) {
- setRectEmpty(lprcDst);
+ if (lprcSrc1->isRectEmpty()) {
+ if (lprcSrc2->isRectEmpty()) {
+ lprcDst->setEmpty();
return false;
} else {
*lprcDst = *lprcSrc2;
}
} else {
- if (isRectEmpty(lprcSrc2)) {
+ if (lprcSrc2->isRectEmpty()) {
*lprcDst = *lprcSrc1;
} else {
lprcDst->left = MIN(lprcSrc1->left, lprcSrc2->left);
diff --git a/engines/wintermute/platform_osystem.h b/engines/wintermute/platform_osystem.h
index 46c86df909..16d55745b9 100644
--- a/engines/wintermute/platform_osystem.h
+++ b/engines/wintermute/platform_osystem.h
@@ -48,13 +48,7 @@ public:
// Win32 API bindings
static bool getCursorPos(Point32 *lpPoint);
static bool setCursorPos(int x, int y);
- static bool showWindow(int nCmdShow);
- static void setCapture();
- static bool releaseCapture();
-
- static bool setRectEmpty(Rect32 *lprc);
- static bool isRectEmpty(const Rect32 *lprc);
static bool ptInRect(Rect32 *lprc, Point32 p);
static bool setRect(Rect32 *lprc, int left, int top, int right, int bottom);
static bool intersectRect(Rect32 *lprcDst, const Rect32 *lprcSrc1, const Rect32 *lprcSrc2);
diff --git a/engines/wintermute/ui/ui_button.cpp b/engines/wintermute/ui/ui_button.cpp
index b2e6c3953b..7526174b64 100644
--- a/engines/wintermute/ui/ui_button.cpp
+++ b/engines/wintermute/ui/ui_button.cpp
@@ -103,7 +103,7 @@ UIButton::~UIButton() {
//////////////////////////////////////////////////////////////////////////
bool UIButton::loadFile(const char *filename) {
- byte *buffer = BaseFileManager::getEngineInstance()->readWholeFile(filename);
+ char *buffer = (char *)BaseFileManager::getEngineInstance()->readWholeFile(filename);
if (buffer == nullptr) {
_gameRef->LOG(0, "UIButton::LoadFile failed for file '%s'", filename);
return STATUS_FAILED;
@@ -162,7 +162,7 @@ TOKEN_DEF(PIXEL_PERFECT)
TOKEN_DEF(EDITOR_PROPERTY)
TOKEN_DEF_END
//////////////////////////////////////////////////////////////////////////
-bool UIButton::loadBuffer(byte *buffer, bool complete) {
+bool UIButton::loadBuffer(char *buffer, bool complete) {
TOKEN_TABLE_START(commands)
TOKEN_TABLE(BUTTON)
TOKEN_TABLE(TEMPLATE)
@@ -202,38 +202,38 @@ bool UIButton::loadBuffer(byte *buffer, bool complete) {
TOKEN_TABLE(EDITOR_PROPERTY)
TOKEN_TABLE_END
- byte *params;
+ char *params;
int cmd = 2;
BaseParser parser;
if (complete) {
- if (parser.getCommand((char **)&buffer, commands, (char **)&params) != TOKEN_BUTTON) {
+ if (parser.getCommand(&buffer, commands, &params) != TOKEN_BUTTON) {
_gameRef->LOG(0, "'BUTTON' keyword expected.");
return STATUS_FAILED;
}
buffer = params;
}
- while (cmd > 0 && (cmd = parser.getCommand((char **)&buffer, commands, (char **)&params)) > 0) {
+ while (cmd > 0 && (cmd = parser.getCommand(&buffer, commands, &params)) > 0) {
switch (cmd) {
case TOKEN_TEMPLATE:
- if (DID_FAIL(loadFile((char *)params))) {
+ if (DID_FAIL(loadFile(params))) {
cmd = PARSERR_GENERIC;
}
break;
case TOKEN_NAME:
- setName((char *)params);
+ setName(params);
break;
case TOKEN_CAPTION:
- setCaption((char *)params);
+ setCaption(params);
break;
case TOKEN_BACK:
delete _back;
_back = new UITiledImage(_gameRef);
- if (!_back || DID_FAIL(_back->loadFile((char *)params))) {
+ if (!_back || DID_FAIL(_back->loadFile(params))) {
delete _back;
_back = nullptr;
cmd = PARSERR_GENERIC;
@@ -243,7 +243,7 @@ bool UIButton::loadBuffer(byte *buffer, bool complete) {
case TOKEN_BACK_HOVER:
delete _backHover;
_backHover = new UITiledImage(_gameRef);
- if (!_backHover || DID_FAIL(_backHover->loadFile((char *)params))) {
+ if (!_backHover || DID_FAIL(_backHover->loadFile(params))) {
delete _backHover;
_backHover = nullptr;
cmd = PARSERR_GENERIC;
@@ -253,7 +253,7 @@ bool UIButton::loadBuffer(byte *buffer, bool complete) {
case TOKEN_BACK_PRESS:
delete _backPress;
_backPress = new UITiledImage(_gameRef);
- if (!_backPress || DID_FAIL(_backPress->loadFile((char *)params))) {
+ if (!_backPress || DID_FAIL(_backPress->loadFile(params))) {
delete _backPress;
_backPress = nullptr;
cmd = PARSERR_GENERIC;
@@ -263,7 +263,7 @@ bool UIButton::loadBuffer(byte *buffer, bool complete) {
case TOKEN_BACK_DISABLE:
delete _backDisable;
_backDisable = new UITiledImage(_gameRef);
- if (!_backDisable || DID_FAIL(_backDisable->loadFile((char *)params))) {
+ if (!_backDisable || DID_FAIL(_backDisable->loadFile(params))) {
delete _backDisable;
_backDisable = nullptr;
cmd = PARSERR_GENERIC;
@@ -273,7 +273,7 @@ bool UIButton::loadBuffer(byte *buffer, bool complete) {
case TOKEN_BACK_FOCUS:
delete _backFocus;
_backFocus = new UITiledImage(_gameRef);
- if (!_backFocus || DID_FAIL(_backFocus->loadFile((char *)params))) {
+ if (!_backFocus || DID_FAIL(_backFocus->loadFile(params))) {
delete _backFocus;
_backFocus = nullptr;
cmd = PARSERR_GENERIC;
@@ -283,7 +283,7 @@ bool UIButton::loadBuffer(byte *buffer, bool complete) {
case TOKEN_IMAGE:
delete _image;
_image = new BaseSprite(_gameRef);
- if (!_image || DID_FAIL(_image->loadFile((char *)params))) {
+ if (!_image || DID_FAIL(_image->loadFile(params))) {
delete _image;
_image = nullptr;
cmd = PARSERR_GENERIC;
@@ -293,7 +293,7 @@ bool UIButton::loadBuffer(byte *buffer, bool complete) {
case TOKEN_IMAGE_HOVER:
delete _imageHover;
_imageHover = new BaseSprite(_gameRef);
- if (!_imageHover || DID_FAIL(_imageHover->loadFile((char *)params))) {
+ if (!_imageHover || DID_FAIL(_imageHover->loadFile(params))) {
delete _imageHover;
_imageHover = nullptr;
cmd = PARSERR_GENERIC;
@@ -303,7 +303,7 @@ bool UIButton::loadBuffer(byte *buffer, bool complete) {
case TOKEN_IMAGE_PRESS:
delete _imagePress;
_imagePress = new BaseSprite(_gameRef);
- if (!_imagePress || DID_FAIL(_imagePress->loadFile((char *)params))) {
+ if (!_imagePress || DID_FAIL(_imagePress->loadFile(params))) {
delete _imagePress;
_imagePress = nullptr;
cmd = PARSERR_GENERIC;
@@ -313,7 +313,7 @@ bool UIButton::loadBuffer(byte *buffer, bool complete) {
case TOKEN_IMAGE_DISABLE:
delete _imageDisable;
_imageDisable = new BaseSprite(_gameRef);
- if (!_imageDisable || DID_FAIL(_imageDisable->loadFile((char *)params))) {
+ if (!_imageDisable || DID_FAIL(_imageDisable->loadFile(params))) {
delete _imageDisable;
_imageDisable = nullptr;
cmd = PARSERR_GENERIC;
@@ -323,7 +323,7 @@ bool UIButton::loadBuffer(byte *buffer, bool complete) {
case TOKEN_IMAGE_FOCUS:
delete _imageFocus;
_imageFocus = new BaseSprite(_gameRef);
- if (!_imageFocus || DID_FAIL(_imageFocus->loadFile((char *)params))) {
+ if (!_imageFocus || DID_FAIL(_imageFocus->loadFile(params))) {
delete _imageFocus;
_imageFocus = nullptr;
cmd = PARSERR_GENERIC;
@@ -334,7 +334,7 @@ bool UIButton::loadBuffer(byte *buffer, bool complete) {
if (_font) {
_gameRef->_fontStorage->removeFont(_font);
}
- _font = _gameRef->_fontStorage->addFont((char *)params);
+ _font = _gameRef->_fontStorage->addFont(params);
if (!_font) {
cmd = PARSERR_GENERIC;
}
@@ -344,7 +344,7 @@ bool UIButton::loadBuffer(byte *buffer, bool complete) {
if (_fontHover) {
_gameRef->_fontStorage->removeFont(_fontHover);
}
- _fontHover = _gameRef->_fontStorage->addFont((char *)params);
+ _fontHover = _gameRef->_fontStorage->addFont(params);
if (!_fontHover) {
cmd = PARSERR_GENERIC;
}
@@ -354,7 +354,7 @@ bool UIButton::loadBuffer(byte *buffer, bool complete) {
if (_fontPress) {
_gameRef->_fontStorage->removeFont(_fontPress);
}
- _fontPress = _gameRef->_fontStorage->addFont((char *)params);
+ _fontPress = _gameRef->_fontStorage->addFont(params);
if (!_fontPress) {
cmd = PARSERR_GENERIC;
}
@@ -364,7 +364,7 @@ bool UIButton::loadBuffer(byte *buffer, bool complete) {
if (_fontDisable) {
_gameRef->_fontStorage->removeFont(_fontDisable);
}
- _fontDisable = _gameRef->_fontStorage->addFont((char *)params);
+ _fontDisable = _gameRef->_fontStorage->addFont(params);
if (!_fontDisable) {
cmd = PARSERR_GENERIC;
}
@@ -374,21 +374,21 @@ bool UIButton::loadBuffer(byte *buffer, bool complete) {
if (_fontFocus) {
_gameRef->_fontStorage->removeFont(_fontFocus);
}
- _fontFocus = _gameRef->_fontStorage->addFont((char *)params);
+ _fontFocus = _gameRef->_fontStorage->addFont(params);
if (!_fontFocus) {
cmd = PARSERR_GENERIC;
}
break;
case TOKEN_TEXT:
- setText((char *)params);
+ setText(params);
_gameRef->expandStringByStringTable(&_text);
break;
case TOKEN_TEXT_ALIGN:
- if (scumm_stricmp((char *)params, "left") == 0) {
+ if (scumm_stricmp(params, "left") == 0) {
_align = TAL_LEFT;
- } else if (scumm_stricmp((char *)params, "right") == 0) {
+ } else if (scumm_stricmp(params, "right") == 0) {
_align = TAL_RIGHT;
} else {
_align = TAL_CENTER;
@@ -396,25 +396,25 @@ bool UIButton::loadBuffer(byte *buffer, bool complete) {
break;
case TOKEN_X:
- parser.scanStr((char *)params, "%d", &_posX);
+ parser.scanStr(params, "%d", &_posX);
break;
case TOKEN_Y:
- parser.scanStr((char *)params, "%d", &_posY);
+ parser.scanStr(params, "%d", &_posY);
break;
case TOKEN_WIDTH:
- parser.scanStr((char *)params, "%d", &_width);
+ parser.scanStr(params, "%d", &_width);
break;
case TOKEN_HEIGHT:
- parser.scanStr((char *)params, "%d", &_height);
+ parser.scanStr(params, "%d", &_height);
break;
case TOKEN_CURSOR:
delete _cursor;
_cursor = new BaseSprite(_gameRef);
- if (!_cursor || DID_FAIL(_cursor->loadFile((char *)params))) {
+ if (!_cursor || DID_FAIL(_cursor->loadFile(params))) {
delete _cursor;
_cursor = nullptr;
cmd = PARSERR_GENERIC;
@@ -422,35 +422,35 @@ bool UIButton::loadBuffer(byte *buffer, bool complete) {
break;
case TOKEN_SCRIPT:
- addScript((char *)params);
+ addScript(params);
break;
case TOKEN_PARENT_NOTIFY:
- parser.scanStr((char *)params, "%b", &_parentNotify);
+ parser.scanStr(params, "%b", &_parentNotify);
break;
case TOKEN_DISABLED:
- parser.scanStr((char *)params, "%b", &_disable);
+ parser.scanStr(params, "%b", &_disable);
break;
case TOKEN_VISIBLE:
- parser.scanStr((char *)params, "%b", &_visible);
+ parser.scanStr(params, "%b", &_visible);
break;
case TOKEN_FOCUSABLE:
- parser.scanStr((char *)params, "%b", &_canFocus);
+ parser.scanStr(params, "%b", &_canFocus);
break;
case TOKEN_CENTER_IMAGE:
- parser.scanStr((char *)params, "%b", &_centerImage);
+ parser.scanStr(params, "%b", &_centerImage);
break;
case TOKEN_PRESSED:
- parser.scanStr((char *)params, "%b", &_stayPressed);
+ parser.scanStr(params, "%b", &_stayPressed);
break;
case TOKEN_PIXEL_PERFECT:
- parser.scanStr((char *)params, "%b", &_pixelPerfect);
+ parser.scanStr(params, "%b", &_pixelPerfect);
break;
case TOKEN_EDITOR_PROPERTY:
@@ -655,12 +655,12 @@ bool UIButton::display(int offsetX, int offsetY) {
BaseFont *font = 0;
//RECT rect;
- //BasePlatform::setRect(&rect, OffsetX + _posX, OffsetY + _posY, OffsetX+_posX+_width, OffsetY+_posY+_height);
+ //rect.setRect(OffsetX + _posX, OffsetY + _posY, OffsetX+_posX+_width, OffsetY+_posY+_height);
//_hover = (!_disable && BasePlatform::ptInRect(&rect, _gameRef->_mousePos)!=FALSE);
_hover = (!_disable && _gameRef->_activeObject == this && (_gameRef->_interactive || _gameRef->_state == GAME_SEMI_FROZEN));
if ((_press && _hover && !_gameRef->_mouseLeftDown) ||
- (_oneTimePress && g_system->getMillis() - _oneTimePressTime >= 100)) {
+ (_oneTimePress && g_system->getMillis() - _oneTimePressTime >= 100)) {
press();
}
@@ -1178,25 +1178,25 @@ bool UIButton::persist(BasePersistenceManager *persistMgr) {
UIObject::persist(persistMgr);
- persistMgr->transfer(TMEMBER_INT(_align));
+ persistMgr->transferSint32(TMEMBER_INT(_align));
persistMgr->transferPtr(TMEMBER_PTR(_backDisable));
persistMgr->transferPtr(TMEMBER_PTR(_backFocus));
persistMgr->transferPtr(TMEMBER_PTR(_backHover));
persistMgr->transferPtr(TMEMBER_PTR(_backPress));
- persistMgr->transfer(TMEMBER(_centerImage));
+ persistMgr->transferBool(TMEMBER(_centerImage));
persistMgr->transferPtr(TMEMBER_PTR(_fontDisable));
persistMgr->transferPtr(TMEMBER_PTR(_fontFocus));
persistMgr->transferPtr(TMEMBER_PTR(_fontHover));
persistMgr->transferPtr(TMEMBER_PTR(_fontPress));
- persistMgr->transfer(TMEMBER(_hover));
+ persistMgr->transferBool(TMEMBER(_hover));
persistMgr->transferPtr(TMEMBER_PTR(_image));
persistMgr->transferPtr(TMEMBER_PTR(_imageDisable));
persistMgr->transferPtr(TMEMBER_PTR(_imageFocus));
persistMgr->transferPtr(TMEMBER_PTR(_imageHover));
persistMgr->transferPtr(TMEMBER_PTR(_imagePress));
- persistMgr->transfer(TMEMBER(_pixelPerfect));
- persistMgr->transfer(TMEMBER(_press));
- persistMgr->transfer(TMEMBER(_stayPressed));
+ persistMgr->transferBool(TMEMBER(_pixelPerfect));
+ persistMgr->transferBool(TMEMBER(_press));
+ persistMgr->transferBool(TMEMBER(_stayPressed));
if (!persistMgr->getIsSaving()) {
_oneTimePress = false;
@@ -1206,4 +1206,28 @@ bool UIButton::persist(BasePersistenceManager *persistMgr) {
return STATUS_OK;
}
+void UIButton::setFontHover(BaseFont *font) {
+ _fontHover = font;
+}
+
+BaseFont *UIButton::getFontHover() {
+ return _fontHover;
+}
+
+void UIButton::setFontPress(BaseFont *font) {
+ _fontPress = font;
+}
+
+void UIButton::setImageHover(BaseSprite *sprite) {
+ _imageHover = sprite;
+}
+
+void UIButton::setImagePress(BaseSprite *sprite) {
+ _imagePress = sprite;
+}
+
+void UIButton::setTextAlign(TTextAlign align) {
+ _align = align;
+}
+
} // End of namespace Wintermute
diff --git a/engines/wintermute/ui/ui_button.h b/engines/wintermute/ui/ui_button.h
index b5002f3166..6452cfc4f7 100644
--- a/engines/wintermute/ui/ui_button.h
+++ b/engines/wintermute/ui/ui_button.h
@@ -37,35 +37,18 @@ namespace Wintermute {
class UIButton : public UIObject {
public:
- bool _pixelPerfect;
- bool _stayPressed;
- bool _centerImage;
- bool _oneTimePress;
- uint32 _oneTimePressTime;
+
DECLARE_PERSISTENT(UIButton, UIObject)
void press();
virtual bool display() { return display(0, 0); }
virtual bool display(int offsetX, int offsetY);
- bool _press;
- bool _hover;
+
void correctSize();
- TTextAlign _align;
- BaseSprite *_imageHover;
- BaseSprite *_imagePress;
- BaseSprite *_imageDisable;
- BaseSprite *_imageFocus;
- BaseFont *_fontDisable;
- BaseFont *_fontPress;
- BaseFont *_fontHover;
- BaseFont *_fontFocus;
- UITiledImage *_backPress;
- UITiledImage *_backHover;
- UITiledImage *_backDisable;
- UITiledImage *_backFocus;
+
UIButton(BaseGame *inGame = nullptr);
virtual ~UIButton();
bool loadFile(const char *filename);
- bool loadBuffer(byte *buffer, bool complete = true);
+ bool loadBuffer(char *buffer, bool complete = true);
virtual bool saveAsText(BaseDynamicBuffer *buffer, int indent) override;
// scripting interface
@@ -73,6 +56,39 @@ public:
virtual bool scSetProperty(const char *name, ScValue *value) override;
virtual bool scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name) override;
virtual const char *scToString() override;
+
+
+ void setFontHover(BaseFont *font);
+ BaseFont *getFontHover();
+ void setFontPress(BaseFont *font);
+
+ void setTextAlign(TTextAlign align);
+
+ void setImageHover(BaseSprite *sprite);
+ void setImagePress(BaseSprite *sprite);
+
+private:
+ bool _pixelPerfect;
+ bool _stayPressed;
+ bool _centerImage;
+ bool _oneTimePress;
+ UITiledImage *_backPress;
+ UITiledImage *_backHover;
+ UITiledImage *_backDisable;
+ UITiledImage *_backFocus;
+ bool _press;
+ bool _hover;
+ BaseFont *_fontDisable;
+ BaseFont *_fontPress;
+ BaseFont *_fontHover;
+ BaseFont *_fontFocus;
+ BaseSprite *_imageHover;
+ BaseSprite *_imagePress;
+ BaseSprite *_imageDisable;
+ BaseSprite *_imageFocus;
+ uint32 _oneTimePressTime;
+ TTextAlign _align;
+
};
} // End of namespace Wintermute
diff --git a/engines/wintermute/ui/ui_edit.cpp b/engines/wintermute/ui/ui_edit.cpp
index caed157e0b..1f224c79c8 100644
--- a/engines/wintermute/ui/ui_edit.cpp
+++ b/engines/wintermute/ui/ui_edit.cpp
@@ -94,7 +94,7 @@ UIEdit::~UIEdit() {
//////////////////////////////////////////////////////////////////////////
bool UIEdit::loadFile(const char *filename) {
- byte *buffer = BaseFileManager::getEngineInstance()->readWholeFile(filename);
+ char *buffer = (char *)BaseFileManager::getEngineInstance()->readWholeFile(filename);
if (buffer == nullptr) {
_gameRef->LOG(0, "UIEdit::LoadFile failed for file '%s'", filename);
return STATUS_FAILED;
@@ -139,7 +139,7 @@ TOKEN_DEF(EDIT)
TOKEN_DEF(CAPTION)
TOKEN_DEF_END
//////////////////////////////////////////////////////////////////////////
-bool UIEdit::loadBuffer(byte *buffer, bool complete) {
+bool UIEdit::loadBuffer(char *buffer, bool complete) {
TOKEN_TABLE_START(commands)
TOKEN_TABLE(TEMPLATE)
TOKEN_TABLE(DISABLED)
@@ -165,34 +165,34 @@ bool UIEdit::loadBuffer(byte *buffer, bool complete) {
TOKEN_TABLE(CAPTION)
TOKEN_TABLE_END
- byte *params;
+ char *params;
int cmd = 2;
BaseParser parser;
if (complete) {
- if (parser.getCommand((char **)&buffer, commands, (char **)&params) != TOKEN_EDIT) {
+ if (parser.getCommand(&buffer, commands, &params) != TOKEN_EDIT) {
_gameRef->LOG(0, "'EDIT' keyword expected.");
return STATUS_FAILED;
}
buffer = params;
}
- while (cmd > 0 && (cmd = parser.getCommand((char **)&buffer, commands, (char **)&params)) > 0) {
+ while (cmd > 0 && (cmd = parser.getCommand(&buffer, commands, &params)) > 0) {
switch (cmd) {
case TOKEN_TEMPLATE:
- if (DID_FAIL(loadFile((char *)params))) {
+ if (DID_FAIL(loadFile(params))) {
cmd = PARSERR_GENERIC;
}
break;
case TOKEN_NAME:
- setName((char *)params);
+ setName(params);
break;
case TOKEN_BACK:
delete _back;
_back = new UITiledImage(_gameRef);
- if (!_back || DID_FAIL(_back->loadFile((char *)params))) {
+ if (!_back || DID_FAIL(_back->loadFile(params))) {
delete _back;
_back = nullptr;
cmd = PARSERR_GENERIC;
@@ -202,7 +202,7 @@ bool UIEdit::loadBuffer(byte *buffer, bool complete) {
case TOKEN_IMAGE:
delete _image;
_image = new BaseSprite(_gameRef);
- if (!_image || DID_FAIL(_image->loadFile((char *)params))) {
+ if (!_image || DID_FAIL(_image->loadFile(params))) {
delete _image;
_image = nullptr;
cmd = PARSERR_GENERIC;
@@ -213,7 +213,7 @@ bool UIEdit::loadBuffer(byte *buffer, bool complete) {
if (_font) {
_gameRef->_fontStorage->removeFont(_font);
}
- _font = _gameRef->_fontStorage->addFont((char *)params);
+ _font = _gameRef->_fontStorage->addFont(params);
if (!_font) {
cmd = PARSERR_GENERIC;
}
@@ -223,45 +223,45 @@ bool UIEdit::loadBuffer(byte *buffer, bool complete) {
if (_fontSelected) {
_gameRef->_fontStorage->removeFont(_fontSelected);
}
- _fontSelected = _gameRef->_fontStorage->addFont((char *)params);
+ _fontSelected = _gameRef->_fontStorage->addFont(params);
if (!_fontSelected) {
cmd = PARSERR_GENERIC;
}
break;
case TOKEN_TEXT:
- setText((char *)params);
+ setText(params);
_gameRef->expandStringByStringTable(&_text);
break;
case TOKEN_X:
- parser.scanStr((char *)params, "%d", &_posX);
+ parser.scanStr(params, "%d", &_posX);
break;
case TOKEN_Y:
- parser.scanStr((char *)params, "%d", &_posY);
+ parser.scanStr(params, "%d", &_posY);
break;
case TOKEN_WIDTH:
- parser.scanStr((char *)params, "%d", &_width);
+ parser.scanStr(params, "%d", &_width);
break;
case TOKEN_HEIGHT:
- parser.scanStr((char *)params, "%d", &_height);
+ parser.scanStr(params, "%d", &_height);
break;
case TOKEN_MAX_LENGTH:
- parser.scanStr((char *)params, "%d", &_maxLength);
+ parser.scanStr(params, "%d", &_maxLength);
break;
case TOKEN_CAPTION:
- setCaption((char *)params);
+ setCaption(params);
break;
case TOKEN_CURSOR:
delete _cursor;
_cursor = new BaseSprite(_gameRef);
- if (!_cursor || DID_FAIL(_cursor->loadFile((char *)params))) {
+ if (!_cursor || DID_FAIL(_cursor->loadFile(params))) {
delete _cursor;
_cursor = nullptr;
cmd = PARSERR_GENERIC;
@@ -269,27 +269,27 @@ bool UIEdit::loadBuffer(byte *buffer, bool complete) {
break;
case TOKEN_CURSOR_BLINK_RATE:
- parser.scanStr((char *)params, "%d", &_cursorBlinkRate);
+ parser.scanStr(params, "%d", &_cursorBlinkRate);
break;
case TOKEN_FRAME_WIDTH:
- parser.scanStr((char *)params, "%d", &_frameWidth);
+ parser.scanStr(params, "%d", &_frameWidth);
break;
case TOKEN_SCRIPT:
- addScript((char *)params);
+ addScript(params);
break;
case TOKEN_PARENT_NOTIFY:
- parser.scanStr((char *)params, "%b", &_parentNotify);
+ parser.scanStr(params, "%b", &_parentNotify);
break;
case TOKEN_DISABLED:
- parser.scanStr((char *)params, "%b", &_disable);
+ parser.scanStr(params, "%b", &_disable);
break;
case TOKEN_VISIBLE:
- parser.scanStr((char *)params, "%b", &_visible);
+ parser.scanStr(params, "%b", &_visible);
break;
case TOKEN_EDITOR_PROPERTY:
@@ -627,9 +627,9 @@ bool UIEdit::display(int offsetX, int offsetY) {
curFirst = true;
} else {
while (font->getTextWidth((byte *)_text + _scrollOffset, MAX<int32>(0, _selStart - _scrollOffset)) +
- sfont->getTextWidth((byte *)(_text + MAX<int32>(_scrollOffset, _selStart)), _selEnd - MAX(_scrollOffset, _selStart))
+ sfont->getTextWidth((byte *)(_text + MAX<int32>(_scrollOffset, _selStart)), _selEnd - MAX(_scrollOffset, _selStart))
- > _width - cursorWidth - 2 * _frameWidth) {
+ > _width - cursorWidth - 2 * _frameWidth) {
_scrollOffset++;
if (_scrollOffset >= (int)strlen(_text)) {
break;
@@ -932,14 +932,14 @@ bool UIEdit::persist(BasePersistenceManager *persistMgr) {
UIObject::persist(persistMgr);
- persistMgr->transfer(TMEMBER(_cursorBlinkRate));
- persistMgr->transfer(TMEMBER(_cursorChar));
+ persistMgr->transferUint32(TMEMBER(_cursorBlinkRate));
+ persistMgr->transferCharPtr(TMEMBER(_cursorChar));
persistMgr->transferPtr(TMEMBER_PTR(_fontSelected));
- persistMgr->transfer(TMEMBER(_frameWidth));
- persistMgr->transfer(TMEMBER(_maxLength));
- persistMgr->transfer(TMEMBER(_scrollOffset));
- persistMgr->transfer(TMEMBER(_selEnd));
- persistMgr->transfer(TMEMBER(_selStart));
+ persistMgr->transferSint32(TMEMBER(_frameWidth));
+ persistMgr->transferSint32(TMEMBER(_maxLength));
+ persistMgr->transferSint32(TMEMBER(_scrollOffset));
+ persistMgr->transferSint32(TMEMBER(_selEnd));
+ persistMgr->transferSint32(TMEMBER(_selStart));
if (!persistMgr->getIsSaving()) {
_cursorVisible = false;
diff --git a/engines/wintermute/ui/ui_edit.h b/engines/wintermute/ui/ui_edit.h
index a057be9ead..19ea5ecc5d 100644
--- a/engines/wintermute/ui/ui_edit.h
+++ b/engines/wintermute/ui/ui_edit.h
@@ -38,26 +38,20 @@ class BaseFont;
class UIEdit : public UIObject {
public:
DECLARE_PERSISTENT(UIEdit, UIObject)
- int32 _maxLength;
+
int insertChars(int pos, const byte *chars, int num);
int deleteChars(int start, int end);
- bool _cursorVisible;
- uint32 _lastBlinkTime;
+
virtual bool display(int offsetX, int offsetY);
virtual bool handleKeypress(Common::Event *event, bool printable = false);
- int32 _scrollOffset;
- int32 _frameWidth;
- uint32 _cursorBlinkRate;
+
void setCursorChar(const char *character);
- char *_cursorChar;
- int32 _selEnd;
- int32 _selStart;
- BaseFont *_fontSelected;
+
UIEdit(BaseGame *inGame);
virtual ~UIEdit();
bool loadFile(const char *filename);
- bool loadBuffer(byte *buffer, bool complete = true);
+ bool loadBuffer(char *buffer, bool complete = true);
virtual bool saveAsText(BaseDynamicBuffer *buffer, int indent);
// scripting interface
@@ -65,6 +59,17 @@ public:
virtual bool scSetProperty(const char *name, ScValue *value) override;
virtual bool scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name) override;
virtual const char *scToString() override;
+private:
+ uint32 _cursorBlinkRate;
+ uint32 _lastBlinkTime;
+ int32 _selEnd;
+ int32 _selStart;
+ int32 _scrollOffset;
+ int32 _frameWidth;
+ BaseFont *_fontSelected;
+ int32 _maxLength;
+ bool _cursorVisible;
+ char *_cursorChar;
};
} // End of namespace Wintermute
diff --git a/engines/wintermute/ui/ui_entity.cpp b/engines/wintermute/ui/ui_entity.cpp
index 6d4cfdb7eb..0dbf8df00b 100644
--- a/engines/wintermute/ui/ui_entity.cpp
+++ b/engines/wintermute/ui/ui_entity.cpp
@@ -58,7 +58,7 @@ UIEntity::~UIEntity() {
//////////////////////////////////////////////////////////////////////////
bool UIEntity::loadFile(const char *filename) {
- byte *buffer = BaseFileManager::getEngineInstance()->readWholeFile(filename);
+ char *buffer = (char *)BaseFileManager::getEngineInstance()->readWholeFile(filename);
if (buffer == nullptr) {
_gameRef->LOG(0, "UIEntity::LoadFile failed for file '%s'", filename);
return STATUS_FAILED;
@@ -92,7 +92,7 @@ TOKEN_DEF(SCRIPT)
TOKEN_DEF(EDITOR_PROPERTY)
TOKEN_DEF_END
//////////////////////////////////////////////////////////////////////////
-bool UIEntity::loadBuffer(byte *buffer, bool complete) {
+bool UIEntity::loadBuffer(char *buffer, bool complete) {
TOKEN_TABLE_START(commands)
TOKEN_TABLE(ENTITY_CONTAINER)
TOKEN_TABLE(TEMPLATE)
@@ -106,54 +106,54 @@ bool UIEntity::loadBuffer(byte *buffer, bool complete) {
TOKEN_TABLE(EDITOR_PROPERTY)
TOKEN_TABLE_END
- byte *params;
+ char *params;
int cmd = 2;
BaseParser parser;
if (complete) {
- if (parser.getCommand((char **)&buffer, commands, (char **)&params) != TOKEN_ENTITY_CONTAINER) {
+ if (parser.getCommand(&buffer, commands, &params) != TOKEN_ENTITY_CONTAINER) {
_gameRef->LOG(0, "'ENTITY_CONTAINER' keyword expected.");
return STATUS_FAILED;
}
buffer = params;
}
- while (cmd > 0 && (cmd = parser.getCommand((char **)&buffer, commands, (char **)&params)) > 0) {
+ while (cmd > 0 && (cmd = parser.getCommand(&buffer, commands, &params)) > 0) {
switch (cmd) {
case TOKEN_TEMPLATE:
- if (DID_FAIL(loadFile((char *)params))) {
+ if (DID_FAIL(loadFile(params))) {
cmd = PARSERR_GENERIC;
}
break;
case TOKEN_NAME:
- setName((char *)params);
+ setName(params);
break;
case TOKEN_X:
- parser.scanStr((char *)params, "%d", &_posX);
+ parser.scanStr(params, "%d", &_posX);
break;
case TOKEN_Y:
- parser.scanStr((char *)params, "%d", &_posY);
+ parser.scanStr(params, "%d", &_posY);
break;
case TOKEN_DISABLED:
- parser.scanStr((char *)params, "%b", &_disable);
+ parser.scanStr(params, "%b", &_disable);
break;
case TOKEN_VISIBLE:
- parser.scanStr((char *)params, "%b", &_visible);
+ parser.scanStr(params, "%b", &_visible);
break;
case TOKEN_ENTITY:
- if (DID_FAIL(setEntity((char *)params))) {
+ if (DID_FAIL(setEntity(params))) {
cmd = PARSERR_GENERIC;
}
break;
case TOKEN_SCRIPT:
- addScript((char *)params);
+ addScript(params);
break;
case TOKEN_EDITOR_PROPERTY:
diff --git a/engines/wintermute/ui/ui_entity.h b/engines/wintermute/ui/ui_entity.h
index 1b6e8a10d6..63f0026412 100644
--- a/engines/wintermute/ui/ui_entity.h
+++ b/engines/wintermute/ui/ui_entity.h
@@ -39,12 +39,11 @@ public:
UIEntity(BaseGame *inGame);
virtual ~UIEntity();
bool loadFile(const char *filename);
- bool loadBuffer(byte *buffer, bool complete);
+ bool loadBuffer(char *buffer, bool complete);
virtual bool saveAsText(BaseDynamicBuffer *buffer, int indent) override;
virtual bool display() override { return display(0, 0); }
virtual bool display(int offsetX, int offsetY) override;
- AdEntity *_entity;
bool setEntity(const char *filename);
// scripting interface
@@ -52,6 +51,9 @@ public:
virtual bool scSetProperty(const char *name, ScValue *value) override;
virtual bool scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name);
virtual const char *scToString();
+
+private:
+ AdEntity *_entity;
};
} // End of namespace Wintermute
diff --git a/engines/wintermute/ui/ui_object.cpp b/engines/wintermute/ui/ui_object.cpp
index c32ae75c20..c04c7cbd28 100644
--- a/engines/wintermute/ui/ui_object.cpp
+++ b/engines/wintermute/ui/ui_object.cpp
@@ -622,23 +622,23 @@ bool UIObject::persist(BasePersistenceManager *persistMgr) {
BaseObject::persist(persistMgr);
persistMgr->transferPtr(TMEMBER_PTR(_back));
- persistMgr->transfer(TMEMBER(_canFocus));
- persistMgr->transfer(TMEMBER(_disable));
+ persistMgr->transferBool(TMEMBER(_canFocus));
+ persistMgr->transferBool(TMEMBER(_disable));
persistMgr->transferPtr(TMEMBER_PTR(_focusedWidget));
persistMgr->transferPtr(TMEMBER_PTR(_font));
- persistMgr->transfer(TMEMBER(_height));
+ persistMgr->transferSint32(TMEMBER(_height));
persistMgr->transferPtr(TMEMBER_PTR(_image));
persistMgr->transferPtr(TMEMBER_PTR(_listenerObject));
persistMgr->transferPtr(TMEMBER_PTR(_listenerParamObject));
- persistMgr->transfer(TMEMBER(_listenerParamDWORD));
+ persistMgr->transferUint32(TMEMBER(_listenerParamDWORD));
persistMgr->transferPtr(TMEMBER_PTR(_parent));
- persistMgr->transfer(TMEMBER(_parentNotify));
- persistMgr->transfer(TMEMBER(_sharedFonts));
- persistMgr->transfer(TMEMBER(_sharedImages));
- persistMgr->transfer(TMEMBER(_text));
- persistMgr->transfer(TMEMBER_INT(_type));
- persistMgr->transfer(TMEMBER(_visible));
- persistMgr->transfer(TMEMBER(_width));
+ persistMgr->transferBool(TMEMBER(_parentNotify));
+ persistMgr->transferBool(TMEMBER(_sharedFonts));
+ persistMgr->transferBool(TMEMBER(_sharedImages));
+ persistMgr->transferCharPtr(TMEMBER(_text));
+ persistMgr->transferSint32(TMEMBER_INT(_type));
+ persistMgr->transferBool(TMEMBER(_visible));
+ persistMgr->transferSint32(TMEMBER(_width));
return STATUS_OK;
}
@@ -648,4 +648,82 @@ bool UIObject::saveAsText(BaseDynamicBuffer *buffer, int indent) {
return STATUS_FAILED;
}
+int32 UIObject::getWidth() const {
+ return _width;
+}
+
+// Has to be non-const to allow the virtual override to work,
+// as other getHeight()-functions currently have the potential
+// of having side-effects.
+int32 UIObject::getHeight() {
+ return _height;
+}
+
+void UIObject::setWidth(int32 width) {
+ assert(width >= 0);
+ _width = width;
+}
+
+void UIObject::setHeight(int32 height) {
+ assert(height >= 0);
+ _height = height;
+}
+
+bool UIObject::isDisabled() const {
+ return _disable;
+}
+
+bool UIObject::isVisible() const {
+ return _visible;
+}
+
+void UIObject::setVisible(bool visible) {
+ _visible = visible;
+}
+
+void UIObject::setDisabled(bool disable) {
+ _disable = disable;
+}
+
+bool UIObject::hasSharedFonts() const {
+ return _sharedFonts;
+}
+
+void UIObject::setSharedFonts(bool shared) {
+ _sharedFonts = shared;
+}
+
+bool UIObject::hasSharedImages() const {
+ return _sharedImages;
+}
+
+void UIObject::setSharedImages(bool shared) {
+ _sharedImages = shared;
+}
+
+BaseSprite *UIObject::getImage() const {
+ return _image;
+}
+
+void UIObject::setImage(BaseSprite *image) {
+ _image = image;
+}
+
+bool UIObject::canFocus() const {
+ return _canFocus;
+}
+
+void UIObject::setFont(BaseFont *font) {
+ _font = font;
+}
+
+BaseFont *UIObject::getFont() {
+ return _font;
+}
+
+BaseScriptHolder *UIObject::getListener() const {
+ return _listenerObject;
+}
+
+
} // End of namespace Wintermute
diff --git a/engines/wintermute/ui/ui_object.h b/engines/wintermute/ui/ui_object.h
index 5d9508c2cf..ecbaebcee6 100644
--- a/engines/wintermute/ui/ui_object.h
+++ b/engines/wintermute/ui/ui_object.h
@@ -41,35 +41,23 @@ class UIObject : public BaseObject {
public:
bool getTotalOffset(int *offsetX, int *offsetY);
- bool _canFocus;
bool focus();
virtual bool handleMouse(TMouseEvent event, TMouseButton button);
bool isFocused();
- bool _parentNotify;
+
DECLARE_PERSISTENT(UIObject, BaseObject)
UIObject *_parent;
virtual bool display() override { return display(0, 0); }
virtual bool display(int offsetX) { return display(offsetX, 0); }
virtual bool display(int offsetX, int offsetY);
virtual void correctSize();
- bool _sharedFonts;
- bool _sharedImages;
void setText(const char *text);
- char *_text;
- BaseFont *_font;
- bool _visible;
- UITiledImage *_back;
- bool _disable;
+
UIObject(BaseGame *inGame = nullptr);
virtual ~UIObject();
- int32 _width;
- int32 _height;
- TUIObjectType _type;
- BaseSprite *_image;
void setListener(BaseScriptHolder *object, BaseScriptHolder *listenerObject, uint32 listenerParam);
- BaseScriptHolder *_listenerParamObject;
- uint32 _listenerParamDWORD;
- BaseScriptHolder *_listenerObject;
+ BaseScriptHolder *getListener() const;
+
UIObject *_focusedWidget;
virtual bool saveAsText(BaseDynamicBuffer *buffer, int indent) override;
@@ -78,6 +66,42 @@ public:
virtual bool scSetProperty(const char *name, ScValue *value) override;
virtual bool scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name) override;
virtual const char *scToString() override;
+ TUIObjectType _type;
+
+ int32 getWidth() const;
+ int32 getHeight() override;
+ void setHeight(int32 height);
+ void setWidth(int32 width);
+ bool isDisabled() const;
+ void setDisabled(bool disable);
+ bool isVisible() const;
+ void setVisible(bool visible);
+ bool hasSharedFonts() const;
+ void setSharedFonts(bool shared);
+ bool hasSharedImages() const;
+ void setSharedImages(bool shared);
+ BaseSprite *getImage() const;
+ void setImage(BaseSprite *image);
+ void setFont(BaseFont *font);
+ BaseFont *getFont();
+ bool canFocus() const;
+
+protected:
+ BaseScriptHolder *_listenerParamObject;
+ uint32 _listenerParamDWORD;
+ BaseScriptHolder *_listenerObject;
+ BaseSprite *_image;
+ BaseFont *_font;
+ bool _sharedFonts;
+ bool _sharedImages;
+ char *_text;
+ bool _visible;
+ bool _disable;
+ int32 _width;
+ int32 _height;
+ bool _canFocus;
+ bool _parentNotify;
+ UITiledImage *_back;
};
} // End of namespace Wintermute
diff --git a/engines/wintermute/ui/ui_text.cpp b/engines/wintermute/ui/ui_text.cpp
index 5dc25f5852..b255e6e790 100644
--- a/engines/wintermute/ui/ui_text.cpp
+++ b/engines/wintermute/ui/ui_text.cpp
@@ -103,7 +103,7 @@ bool UIText::display(int offsetX, int offsetY) {
//////////////////////////////////////////////////////////////////////////
bool UIText::loadFile(const char *filename) {
- byte *buffer = BaseFileManager::getEngineInstance()->readWholeFile(filename);
+ char *buffer = (char *)BaseFileManager::getEngineInstance()->readWholeFile(filename);
if (buffer == nullptr) {
_gameRef->LOG(0, "UIText::LoadFile failed for file '%s'", filename);
return STATUS_FAILED;
@@ -146,7 +146,7 @@ TOKEN_DEF(PARENT_NOTIFY)
TOKEN_DEF(EDITOR_PROPERTY)
TOKEN_DEF_END
//////////////////////////////////////////////////////////////////////////
-bool UIText::loadBuffer(byte *buffer, bool complete) {
+bool UIText::loadBuffer(char *buffer, bool complete) {
TOKEN_TABLE_START(commands)
TOKEN_TABLE(STATIC)
TOKEN_TABLE(TEMPLATE)
@@ -170,38 +170,38 @@ bool UIText::loadBuffer(byte *buffer, bool complete) {
TOKEN_TABLE(EDITOR_PROPERTY)
TOKEN_TABLE_END
- byte *params;
+ char *params;
int cmd = 2;
BaseParser parser;
if (complete) {
- if (parser.getCommand((char **)&buffer, commands, (char **)&params) != TOKEN_STATIC) {
+ if (parser.getCommand(&buffer, commands, &params) != TOKEN_STATIC) {
_gameRef->LOG(0, "'STATIC' keyword expected.");
return STATUS_FAILED;
}
buffer = params;
}
- while (cmd > 0 && (cmd = parser.getCommand((char **)&buffer, commands, (char **)&params)) > 0) {
+ while (cmd > 0 && (cmd = parser.getCommand(&buffer, commands, &params)) > 0) {
switch (cmd) {
case TOKEN_TEMPLATE:
- if (DID_FAIL(loadFile((char *)params))) {
+ if (DID_FAIL(loadFile(params))) {
cmd = PARSERR_GENERIC;
}
break;
case TOKEN_NAME:
- setName((char *)params);
+ setName(params);
break;
case TOKEN_CAPTION:
- setCaption((char *)params);
+ setCaption(params);
break;
case TOKEN_BACK:
delete _back;
_back = new UITiledImage(_gameRef);
- if (!_back || DID_FAIL(_back->loadFile((char *)params))) {
+ if (!_back || DID_FAIL(_back->loadFile(params))) {
delete _back;
_back = nullptr;
cmd = PARSERR_GENERIC;
@@ -211,7 +211,7 @@ bool UIText::loadBuffer(byte *buffer, bool complete) {
case TOKEN_IMAGE:
delete _image;
_image = new BaseSprite(_gameRef);
- if (!_image || DID_FAIL(_image->loadFile((char *)params))) {
+ if (!_image || DID_FAIL(_image->loadFile(params))) {
delete _image;
_image = nullptr;
cmd = PARSERR_GENERIC;
@@ -222,21 +222,21 @@ bool UIText::loadBuffer(byte *buffer, bool complete) {
if (_font) {
_gameRef->_fontStorage->removeFont(_font);
}
- _font = _gameRef->_fontStorage->addFont((char *)params);
+ _font = _gameRef->_fontStorage->addFont(params);
if (!_font) {
cmd = PARSERR_GENERIC;
}
break;
case TOKEN_TEXT:
- setText((char *)params);
+ setText(params);
_gameRef->expandStringByStringTable(&_text);
break;
case TOKEN_TEXT_ALIGN:
- if (scumm_stricmp((char *)params, "left") == 0) {
+ if (scumm_stricmp(params, "left") == 0) {
_textAlign = TAL_LEFT;
- } else if (scumm_stricmp((char *)params, "right") == 0) {
+ } else if (scumm_stricmp(params, "right") == 0) {
_textAlign = TAL_RIGHT;
} else {
_textAlign = TAL_CENTER;
@@ -244,9 +244,9 @@ bool UIText::loadBuffer(byte *buffer, bool complete) {
break;
case TOKEN_VERTICAL_ALIGN:
- if (scumm_stricmp((char *)params, "top") == 0) {
+ if (scumm_stricmp(params, "top") == 0) {
_verticalAlign = VAL_TOP;
- } else if (scumm_stricmp((char *)params, "bottom") == 0) {
+ } else if (scumm_stricmp(params, "bottom") == 0) {
_verticalAlign = VAL_BOTTOM;
} else {
_verticalAlign = VAL_CENTER;
@@ -254,25 +254,25 @@ bool UIText::loadBuffer(byte *buffer, bool complete) {
break;
case TOKEN_X:
- parser.scanStr((char *)params, "%d", &_posX);
+ parser.scanStr(params, "%d", &_posX);
break;
case TOKEN_Y:
- parser.scanStr((char *)params, "%d", &_posY);
+ parser.scanStr(params, "%d", &_posY);
break;
case TOKEN_WIDTH:
- parser.scanStr((char *)params, "%d", &_width);
+ parser.scanStr(params, "%d", &_width);
break;
case TOKEN_HEIGHT:
- parser.scanStr((char *)params, "%d", &_height);
+ parser.scanStr(params, "%d", &_height);
break;
case TOKEN_CURSOR:
delete _cursor;
_cursor = new BaseSprite(_gameRef);
- if (!_cursor || DID_FAIL(_cursor->loadFile((char *)params))) {
+ if (!_cursor || DID_FAIL(_cursor->loadFile(params))) {
delete _cursor;
_cursor = nullptr;
cmd = PARSERR_GENERIC;
@@ -280,19 +280,19 @@ bool UIText::loadBuffer(byte *buffer, bool complete) {
break;
case TOKEN_SCRIPT:
- addScript((char *)params);
+ addScript(params);
break;
case TOKEN_PARENT_NOTIFY:
- parser.scanStr((char *)params, "%b", &_parentNotify);
+ parser.scanStr(params, "%b", &_parentNotify);
break;
case TOKEN_DISABLED:
- parser.scanStr((char *)params, "%b", &_disable);
+ parser.scanStr(params, "%b", &_disable);
break;
case TOKEN_VISIBLE:
- parser.scanStr((char *)params, "%b", &_visible);
+ parser.scanStr(params, "%b", &_visible);
break;
case TOKEN_EDITOR_PROPERTY:
@@ -503,8 +503,8 @@ const char *UIText::scToString() {
bool UIText::persist(BasePersistenceManager *persistMgr) {
UIObject::persist(persistMgr);
- persistMgr->transfer(TMEMBER_INT(_textAlign));
- persistMgr->transfer(TMEMBER_INT(_verticalAlign));
+ persistMgr->transferSint32(TMEMBER_INT(_textAlign));
+ persistMgr->transferSint32(TMEMBER_INT(_verticalAlign));
return STATUS_OK;
}
diff --git a/engines/wintermute/ui/ui_text.h b/engines/wintermute/ui/ui_text.h
index 29ed62a5ef..c39260b228 100644
--- a/engines/wintermute/ui/ui_text.h
+++ b/engines/wintermute/ui/ui_text.h
@@ -37,15 +37,15 @@ namespace Wintermute {
class UIText : public UIObject {
private:
bool sizeToFit();
+ TTextAlign _textAlign;
+ TVerticalAlign _verticalAlign;
public:
virtual bool display(int offsetX, int offsetY);
DECLARE_PERSISTENT(UIText, UIObject)
UIText(BaseGame *inGame = nullptr);
virtual ~UIText();
- TTextAlign _textAlign;
- TVerticalAlign _verticalAlign;
bool loadFile(const char *filename);
- bool loadBuffer(byte *buffer, bool complete = true);
+ bool loadBuffer(char *buffer, bool complete = true);
virtual bool saveAsText(BaseDynamicBuffer *buffer, int indent) override;
// scripting interface
diff --git a/engines/wintermute/ui/ui_tiled_image.cpp b/engines/wintermute/ui/ui_tiled_image.cpp
index de4b86a6dd..e895477a36 100644
--- a/engines/wintermute/ui/ui_tiled_image.cpp
+++ b/engines/wintermute/ui/ui_tiled_image.cpp
@@ -44,15 +44,15 @@ IMPLEMENT_PERSISTENT(UITiledImage, false)
UITiledImage::UITiledImage(BaseGame *inGame) : BaseObject(inGame) {
_image = nullptr;
- BasePlatform::setRectEmpty(&_upLeft);
- BasePlatform::setRectEmpty(&_upMiddle);
- BasePlatform::setRectEmpty(&_upRight);
- BasePlatform::setRectEmpty(&_middleLeft);
- BasePlatform::setRectEmpty(&_middleMiddle);
- BasePlatform::setRectEmpty(&_middleRight);
- BasePlatform::setRectEmpty(&_downLeft);
- BasePlatform::setRectEmpty(&_downMiddle);
- BasePlatform::setRectEmpty(&_downRight);
+ _upLeft.setEmpty();
+ _upMiddle.setEmpty();
+ _upRight.setEmpty();
+ _middleLeft.setEmpty();
+ _middleMiddle.setEmpty();
+ _middleRight.setEmpty();
+ _downLeft.setEmpty();
+ _downMiddle.setEmpty();
+ _downRight.setEmpty();
}
@@ -75,8 +75,6 @@ bool UITiledImage::display(int x, int y, int width, int height) {
int nuColumns = (width - (_middleLeft.right - _middleLeft.left) - (_middleRight.right - _middleRight.left)) / tileWidth;
int nuRows = (height - (_upMiddle.bottom - _upMiddle.top) - (_downMiddle.bottom - _downMiddle.top)) / tileHeight;
- int col, row;
-
_gameRef->_renderer->startSpriteBatch();
// top left/right
@@ -88,27 +86,24 @@ bool UITiledImage::display(int x, int y, int width, int height) {
_image->_surface->displayTrans(x + (_upLeft.right - _upLeft.left) + nuColumns * tileWidth, y + (_upMiddle.bottom - _upMiddle.top) + nuRows * tileHeight, _downRight);
// left/right
- int yyy = y + (_upMiddle.bottom - _upMiddle.top);
- for (row = 0; row < nuRows; row++) {
- _image->_surface->displayTrans(x, yyy, _middleLeft);
- _image->_surface->displayTrans(x + (_middleLeft.right - _middleLeft.left) + nuColumns * tileWidth, yyy, _middleRight);
- yyy += tileWidth;
+ if (nuRows > 0) {
+ int yyy = y + (_upMiddle.bottom - _upMiddle.top);
+ _image->_surface->displayTiled(x, yyy, _middleLeft, 1, nuRows);
+ _image->_surface->displayTiled(x + (_middleLeft.right - _middleLeft.left) + nuColumns * tileWidth, yyy, _middleRight, 1, nuRows);
}
// top/bottom
- int xxx = x + (_upLeft.right - _upLeft.left);
- for (col = 0; col < nuColumns; col++) {
- _image->_surface->displayTrans(xxx, y, _upMiddle);
- _image->_surface->displayTrans(xxx, y + (_upMiddle.bottom - _upMiddle.top) + nuRows * tileHeight, _downMiddle);
- xxx += tileWidth;
+ if (nuColumns > 0) {
+ int xxx = x + (_upLeft.right - _upLeft.left);
+ _image->_surface->displayTiled(xxx, y, _upMiddle, nuColumns, 1);
+ _image->_surface->displayTiled(xxx, y + (_upMiddle.bottom - _upMiddle.top) + nuRows * tileHeight, _downMiddle, nuColumns, 1);
}
// tiles
if (nuRows > 0 && nuColumns > 0) {
- yyy = y + (_upMiddle.bottom - _upMiddle.top);
- xxx = x + (_upLeft.right - _upLeft.left);
- _image->_surface->displayTrans(xxx, yyy, _middleMiddle);
- _image->_surface->repeatLastDisplayOp(tileWidth, tileWidth, nuColumns, nuRows);
+ int yyy = y + (_upMiddle.bottom - _upMiddle.top);
+ int xxx = x + (_upLeft.right - _upLeft.left);
+ _image->_surface->displayTiled(xxx, yyy, _middleMiddle, nuColumns, nuRows);
}
_gameRef->_renderer->endSpriteBatch();
@@ -119,7 +114,7 @@ bool UITiledImage::display(int x, int y, int width, int height) {
//////////////////////////////////////////////////////////////////////////
bool UITiledImage::loadFile(const char *filename) {
- byte *buffer = BaseFileManager::getEngineInstance()->readWholeFile(filename);
+ char *buffer = (char *)BaseFileManager::getEngineInstance()->readWholeFile(filename);
if (buffer == nullptr) {
_gameRef->LOG(0, "UITiledImage::LoadFile failed for file '%s'", filename);
return STATUS_FAILED;
@@ -158,7 +153,7 @@ TOKEN_DEF(HORIZONTAL_TILES)
TOKEN_DEF(EDITOR_PROPERTY)
TOKEN_DEF_END
//////////////////////////////////////////////////////////////////////////
-bool UITiledImage::loadBuffer(byte *buffer, bool complete) {
+bool UITiledImage::loadBuffer(char *buffer, bool complete) {
TOKEN_TABLE_START(commands)
TOKEN_TABLE(TILED_IMAGE)
TOKEN_TABLE(TEMPLATE)
@@ -177,7 +172,7 @@ bool UITiledImage::loadBuffer(byte *buffer, bool complete) {
TOKEN_TABLE(EDITOR_PROPERTY)
TOKEN_TABLE_END
- byte *params;
+ char *params;
int cmd;
BaseParser parser;
bool hTiles = false, vTiles = false;
@@ -185,17 +180,17 @@ bool UITiledImage::loadBuffer(byte *buffer, bool complete) {
int v1 = 0, v2 = 0, v3 = 0;
if (complete) {
- if (parser.getCommand((char **)&buffer, commands, (char **)&params) != TOKEN_TILED_IMAGE) {
+ if (parser.getCommand(&buffer, commands, &params) != TOKEN_TILED_IMAGE) {
_gameRef->LOG(0, "'TILED_IMAGE' keyword expected.");
return STATUS_FAILED;
}
buffer = params;
}
- while ((cmd = parser.getCommand((char **)&buffer, commands, (char **)&params)) > 0) {
+ while ((cmd = parser.getCommand(&buffer, commands, &params)) > 0) {
switch (cmd) {
case TOKEN_TEMPLATE:
- if (DID_FAIL(loadFile((char *)params))) {
+ if (DID_FAIL(loadFile(params))) {
cmd = PARSERR_GENERIC;
}
break;
@@ -203,7 +198,7 @@ bool UITiledImage::loadBuffer(byte *buffer, bool complete) {
case TOKEN_IMAGE:
delete _image;
_image = new BaseSubFrame(_gameRef);
- if (!_image || DID_FAIL(_image->setSurface((char *)params))) {
+ if (!_image || DID_FAIL(_image->setSurface(params))) {
delete _image;
_image = nullptr;
cmd = PARSERR_GENERIC;
@@ -211,48 +206,48 @@ bool UITiledImage::loadBuffer(byte *buffer, bool complete) {
break;
case TOKEN_UP_LEFT:
- parser.scanStr((char *)params, "%d,%d,%d,%d", &_upLeft.left, &_upLeft.top, &_upLeft.right, &_upLeft.bottom);
+ parser.scanStr(params, "%d,%d,%d,%d", &_upLeft.left, &_upLeft.top, &_upLeft.right, &_upLeft.bottom);
break;
case TOKEN_UP_RIGHT:
- parser.scanStr((char *)params, "%d,%d,%d,%d", &_upRight.left, &_upRight.top, &_upRight.right, &_upRight.bottom);
+ parser.scanStr(params, "%d,%d,%d,%d", &_upRight.left, &_upRight.top, &_upRight.right, &_upRight.bottom);
break;
case TOKEN_UP_MIDDLE:
- parser.scanStr((char *)params, "%d,%d,%d,%d", &_upMiddle.left, &_upMiddle.top, &_upMiddle.right, &_upMiddle.bottom);
+ parser.scanStr(params, "%d,%d,%d,%d", &_upMiddle.left, &_upMiddle.top, &_upMiddle.right, &_upMiddle.bottom);
break;
case TOKEN_DOWN_LEFT:
- parser.scanStr((char *)params, "%d,%d,%d,%d", &_downLeft.left, &_downLeft.top, &_downLeft.right, &_downLeft.bottom);
+ parser.scanStr(params, "%d,%d,%d,%d", &_downLeft.left, &_downLeft.top, &_downLeft.right, &_downLeft.bottom);
break;
case TOKEN_DOWN_RIGHT:
- parser.scanStr((char *)params, "%d,%d,%d,%d", &_downRight.left, &_downRight.top, &_downRight.right, &_downRight.bottom);
+ parser.scanStr(params, "%d,%d,%d,%d", &_downRight.left, &_downRight.top, &_downRight.right, &_downRight.bottom);
break;
case TOKEN_DOWN_MIDDLE:
- parser.scanStr((char *)params, "%d,%d,%d,%d", &_downMiddle.left, &_downMiddle.top, &_downMiddle.right, &_downMiddle.bottom);
+ parser.scanStr(params, "%d,%d,%d,%d", &_downMiddle.left, &_downMiddle.top, &_downMiddle.right, &_downMiddle.bottom);
break;
case TOKEN_MIDDLE_LEFT:
- parser.scanStr((char *)params, "%d,%d,%d,%d", &_middleLeft.left, &_middleLeft.top, &_middleLeft.right, &_middleLeft.bottom);
+ parser.scanStr(params, "%d,%d,%d,%d", &_middleLeft.left, &_middleLeft.top, &_middleLeft.right, &_middleLeft.bottom);
break;
case TOKEN_MIDDLE_RIGHT:
- parser.scanStr((char *)params, "%d,%d,%d,%d", &_middleRight.left, &_middleRight.top, &_middleRight.right, &_middleRight.bottom);
+ parser.scanStr(params, "%d,%d,%d,%d", &_middleRight.left, &_middleRight.top, &_middleRight.right, &_middleRight.bottom);
break;
case TOKEN_MIDDLE_MIDDLE:
- parser.scanStr((char *)params, "%d,%d,%d,%d", &_middleMiddle.left, &_middleMiddle.top, &_middleMiddle.right, &_middleMiddle.bottom);
+ parser.scanStr(params, "%d,%d,%d,%d", &_middleMiddle.left, &_middleMiddle.top, &_middleMiddle.right, &_middleMiddle.bottom);
break;
case TOKEN_HORIZONTAL_TILES:
- parser.scanStr((char *)params, "%d,%d,%d", &h1, &h2, &h3);
+ parser.scanStr(params, "%d,%d,%d", &h1, &h2, &h3);
hTiles = true;
break;
case TOKEN_VERTICAL_TILES:
- parser.scanStr((char *)params, "%d,%d,%d", &v1, &v2, &v3);
+ parser.scanStr(params, "%d,%d,%d", &v1, &v2, &v3);
vTiles = true;
break;
@@ -272,19 +267,19 @@ bool UITiledImage::loadBuffer(byte *buffer, bool complete) {
if (vTiles && hTiles) {
// up row
- BasePlatform::setRect(&_upLeft, 0, 0, h1, v1);
- BasePlatform::setRect(&_upMiddle, h1, 0, h1 + h2, v1);
- BasePlatform::setRect(&_upRight, h1 + h2, 0, h1 + h2 + h3, v1);
+ _upLeft.setRect(0, 0, h1, v1);
+ _upMiddle.setRect(h1, 0, h1 + h2, v1);
+ _upRight.setRect(h1 + h2, 0, h1 + h2 + h3, v1);
// middle row
- BasePlatform::setRect(&_middleLeft, 0, v1, h1, v1 + v2);
- BasePlatform::setRect(&_middleMiddle, h1, v1, h1 + h2, v1 + v2);
- BasePlatform::setRect(&_middleRight, h1 + h2, v1, h1 + h2 + h3, v1 + v2);
+ _middleLeft.setRect(0, v1, h1, v1 + v2);
+ _middleMiddle.setRect(h1, v1, h1 + h2, v1 + v2);
+ _middleRight.setRect(h1 + h2, v1, h1 + h2 + h3, v1 + v2);
// down row
- BasePlatform::setRect(&_downLeft, 0, v1 + v2, h1, v1 + v2 + v3);
- BasePlatform::setRect(&_downMiddle, h1, v1 + v2, h1 + h2, v1 + v2 + v3);
- BasePlatform::setRect(&_downRight, h1 + h2, v1 + v2, h1 + h2 + h3, v1 + v2 + v3);
+ _downLeft.setRect(0, v1 + v2, h1, v1 + v2 + v3);
+ _downMiddle.setRect(h1, v1 + v2, h1 + h2, v1 + v2 + v3);
+ _downRight.setRect(h1 + h2, v1 + v2, h1 + h2 + h3, v1 + v2 + v3);
}
// default
@@ -292,34 +287,34 @@ bool UITiledImage::loadBuffer(byte *buffer, bool complete) {
int width = _image->_surface->getWidth() / 3;
int height = _image->_surface->getHeight() / 3;
- if (BasePlatform::isRectEmpty(&_upLeft)) {
- BasePlatform::setRect(&_upLeft, 0, 0, width, height);
+ if (_upLeft.isRectEmpty()) {
+ _upLeft.setRect(0, 0, width, height);
}
- if (BasePlatform::isRectEmpty(&_upMiddle)) {
- BasePlatform::setRect(&_upMiddle, width, 0, 2 * width, height);
+ if (_upMiddle.isRectEmpty()) {
+ _upMiddle.setRect(width, 0, 2 * width, height);
}
- if (BasePlatform::isRectEmpty(&_upRight)) {
- BasePlatform::setRect(&_upRight, 2 * width, 0, 3 * width, height);
+ if (_upRight.isRectEmpty()) {
+ _upRight.setRect(2 * width, 0, 3 * width, height);
}
- if (BasePlatform::isRectEmpty(&_middleLeft)) {
- BasePlatform::setRect(&_middleLeft, 0, height, width, 2 * height);
+ if (_middleLeft.isRectEmpty()) {
+ _middleLeft.setRect(0, height, width, 2 * height);
}
- if (BasePlatform::isRectEmpty(&_middleMiddle)) {
- BasePlatform::setRect(&_middleMiddle, width, height, 2 * width, 2 * height);
+ if (_middleMiddle.isRectEmpty()) {
+ _middleMiddle.setRect(width, height, 2 * width, 2 * height);
}
- if (BasePlatform::isRectEmpty(&_middleRight)) {
- BasePlatform::setRect(&_middleRight, 2 * width, height, 3 * width, 2 * height);
+ if (_middleRight.isRectEmpty()) {
+ _middleRight.setRect(2 * width, height, 3 * width, 2 * height);
}
- if (BasePlatform::isRectEmpty(&_downLeft)) {
- BasePlatform::setRect(&_downLeft, 0, 2 * height, width, 3 * height);
+ if (_downLeft.isRectEmpty()) {
+ _downLeft.setRect(0, 2 * height, width, 3 * height);
}
- if (BasePlatform::isRectEmpty(&_downMiddle)) {
- BasePlatform::setRect(&_downMiddle, width, 2 * height, 2 * width, 3 * height);
+ if (_downMiddle.isRectEmpty()) {
+ _downMiddle.setRect(width, 2 * height, 2 * width, 3 * height);
}
- if (BasePlatform::isRectEmpty(&_downRight)) {
- BasePlatform::setRect(&_downRight, 2 * width, 2 * height, 3 * width, 3 * height);
+ if (_downRight.isRectEmpty()) {
+ _downRight.setRect(2 * width, 2 * height, 3 * width, 3 * height);
}
}
@@ -374,16 +369,16 @@ void UITiledImage::correctSize(int32 *width, int32 *height) {
bool UITiledImage::persist(BasePersistenceManager *persistMgr) {
BaseObject::persist(persistMgr);
- persistMgr->transfer(TMEMBER(_downLeft));
- persistMgr->transfer(TMEMBER(_downMiddle));
- persistMgr->transfer(TMEMBER(_downRight));
+ persistMgr->transferRect32(TMEMBER(_downLeft));
+ persistMgr->transferRect32(TMEMBER(_downMiddle));
+ persistMgr->transferRect32(TMEMBER(_downRight));
persistMgr->transferPtr(TMEMBER_PTR(_image));
- persistMgr->transfer(TMEMBER(_middleLeft));
- persistMgr->transfer(TMEMBER(_middleMiddle));
- persistMgr->transfer(TMEMBER(_middleRight));
- persistMgr->transfer(TMEMBER(_upLeft));
- persistMgr->transfer(TMEMBER(_upMiddle));
- persistMgr->transfer(TMEMBER(_upRight));
+ persistMgr->transferRect32(TMEMBER(_middleLeft));
+ persistMgr->transferRect32(TMEMBER(_middleMiddle));
+ persistMgr->transferRect32(TMEMBER(_middleRight));
+ persistMgr->transferRect32(TMEMBER(_upLeft));
+ persistMgr->transferRect32(TMEMBER(_upMiddle));
+ persistMgr->transferRect32(TMEMBER(_upRight));
return STATUS_OK;
}
diff --git a/engines/wintermute/ui/ui_tiled_image.h b/engines/wintermute/ui/ui_tiled_image.h
index 39bc6495a9..fa92c46781 100644
--- a/engines/wintermute/ui/ui_tiled_image.h
+++ b/engines/wintermute/ui/ui_tiled_image.h
@@ -36,11 +36,13 @@
namespace Wintermute {
class BaseSubFrame;
class UITiledImage : public BaseObject {
+ using Wintermute::BaseObject::display;
+
public:
DECLARE_PERSISTENT(UITiledImage, BaseObject)
void correctSize(int32 *width, int32 *height);
bool loadFile(const char *filename);
- bool loadBuffer(byte *buffer, bool complete = true);
+ bool loadBuffer(char *buffer, bool complete = true);
virtual bool saveAsText(BaseDynamicBuffer *buffer, int indent) override;
bool display(int x, int y, int width, int height);
diff --git a/engines/wintermute/ui/ui_window.cpp b/engines/wintermute/ui/ui_window.cpp
index 9066ee9f5b..842bf700b5 100644
--- a/engines/wintermute/ui/ui_window.cpp
+++ b/engines/wintermute/ui/ui_window.cpp
@@ -54,8 +54,8 @@ IMPLEMENT_PERSISTENT(UIWindow, false)
//////////////////////////////////////////////////////////////////////////
UIWindow::UIWindow(BaseGame *inGame) : UIObject(inGame) {
- BasePlatform::setRectEmpty(&_titleRect);
- BasePlatform::setRectEmpty(&_dragRect);
+ _titleRect.setEmpty();
+ _dragRect.setEmpty();
_titleAlign = TAL_LEFT;
_transparent = false;
@@ -141,8 +141,8 @@ bool UIWindow::display(int offsetX, int offsetY) {
}
if (_shieldButton) {
_shieldButton->_posX = _shieldButton->_posY = 0;
- _shieldButton->_width = _gameRef->_renderer->getWidth();
- _shieldButton->_height = _gameRef->_renderer->getHeight();
+ _shieldButton->setWidth(_gameRef->_renderer->getWidth());
+ _shieldButton->setHeight(_gameRef->_renderer->getHeight());
_shieldButton->display();
}
@@ -170,7 +170,7 @@ bool UIWindow::display(int offsetX, int offsetY) {
_dragFrom.y = _gameRef->_mousePos.y;
}
- if (!_focusedWidget || (!_focusedWidget->_canFocus || _focusedWidget->_disable || !_focusedWidget->_visible)) {
+ if (!_focusedWidget || (!_focusedWidget->canFocus() || _focusedWidget->isDisabled() || !_focusedWidget->isVisible())) {
moveFocus();
}
@@ -213,7 +213,7 @@ bool UIWindow::display(int offsetX, int offsetY) {
image->draw(_posX + offsetX, _posY + offsetY, _transparent ? nullptr : this);
}
- if (!BasePlatform::isRectEmpty(&_titleRect) && font && _text) {
+ if (!_titleRect.isRectEmpty() && font && _text) {
font->drawText((byte *)_text, _posX + offsetX + _titleRect.left, _posY + offsetY + _titleRect.top, _titleRect.right - _titleRect.left, _titleAlign, _titleRect.bottom - _titleRect.top);
}
@@ -239,7 +239,7 @@ bool UIWindow::display(int offsetX, int offsetY) {
//////////////////////////////////////////////////////////////////////////
bool UIWindow::loadFile(const char *filename) {
- byte *buffer = BaseFileManager::getEngineInstance()->readWholeFile(filename);
+ char *buffer = (char *)BaseFileManager::getEngineInstance()->readWholeFile(filename);
if (buffer == nullptr) {
_gameRef->LOG(0, "UIWindow::LoadFile failed for file '%s'", filename);
return STATUS_FAILED;
@@ -298,7 +298,7 @@ TOKEN_DEF(EDITOR_PROPERTY)
TOKEN_DEF(EDIT)
TOKEN_DEF_END
//////////////////////////////////////////////////////////////////////////
-bool UIWindow::loadBuffer(byte *buffer, bool complete) {
+bool UIWindow::loadBuffer(char *buffer, bool complete) {
TOKEN_TABLE_START(commands)
TOKEN_TABLE(WINDOW)
TOKEN_TABLE(ALPHA_COLOR)
@@ -338,7 +338,7 @@ bool UIWindow::loadBuffer(byte *buffer, bool complete) {
TOKEN_TABLE(EDIT)
TOKEN_TABLE_END
- byte *params;
+ char *params;
int cmd = 2;
BaseParser parser;
@@ -346,33 +346,33 @@ bool UIWindow::loadBuffer(byte *buffer, bool complete) {
int ar = 0, ag = 0, ab = 0, alpha = 0;
if (complete) {
- if (parser.getCommand((char **)&buffer, commands, (char **)&params) != TOKEN_WINDOW) {
+ if (parser.getCommand(&buffer, commands, &params) != TOKEN_WINDOW) {
_gameRef->LOG(0, "'WINDOW' keyword expected.");
return STATUS_FAILED;
}
buffer = params;
}
- while (cmd >= PARSERR_TOKENNOTFOUND && (cmd = parser.getCommand((char **)&buffer, commands, (char **)&params)) >= PARSERR_TOKENNOTFOUND) {
+ while (cmd >= PARSERR_TOKENNOTFOUND && (cmd = parser.getCommand(&buffer, commands, &params)) >= PARSERR_TOKENNOTFOUND) {
switch (cmd) {
case TOKEN_TEMPLATE:
- if (DID_FAIL(loadFile((char *)params))) {
+ if (DID_FAIL(loadFile(params))) {
cmd = PARSERR_GENERIC;
}
break;
case TOKEN_NAME:
- setName((char *)params);
+ setName(params);
break;
case TOKEN_CAPTION:
- setCaption((char *)params);
+ setCaption(params);
break;
case TOKEN_BACK:
delete _back;
_back = new UITiledImage(_gameRef);
- if (!_back || DID_FAIL(_back->loadFile((char *)params))) {
+ if (!_back || DID_FAIL(_back->loadFile(params))) {
delete _back;
_back = nullptr;
cmd = PARSERR_GENERIC;
@@ -382,7 +382,7 @@ bool UIWindow::loadBuffer(byte *buffer, bool complete) {
case TOKEN_BACK_INACTIVE:
delete _backInactive;
_backInactive = new UITiledImage(_gameRef);
- if (!_backInactive || DID_FAIL(_backInactive->loadFile((char *)params))) {
+ if (!_backInactive || DID_FAIL(_backInactive->loadFile(params))) {
delete _backInactive;
_backInactive = nullptr;
cmd = PARSERR_GENERIC;
@@ -392,7 +392,7 @@ bool UIWindow::loadBuffer(byte *buffer, bool complete) {
case TOKEN_IMAGE:
delete _image;
_image = new BaseSprite(_gameRef);
- if (!_image || DID_FAIL(_image->loadFile((char *)params))) {
+ if (!_image || DID_FAIL(_image->loadFile(params))) {
delete _image;
_image = nullptr;
cmd = PARSERR_GENERIC;
@@ -400,9 +400,9 @@ bool UIWindow::loadBuffer(byte *buffer, bool complete) {
break;
case TOKEN_IMAGE_INACTIVE:
- delete _imageInactive,
- _imageInactive = new BaseSprite(_gameRef);
- if (!_imageInactive || DID_FAIL(_imageInactive->loadFile((char *)params))) {
+ delete _imageInactive;
+ _imageInactive = new BaseSprite(_gameRef);
+ if (!_imageInactive || DID_FAIL(_imageInactive->loadFile(params))) {
delete _imageInactive;
_imageInactive = nullptr;
cmd = PARSERR_GENERIC;
@@ -413,7 +413,7 @@ bool UIWindow::loadBuffer(byte *buffer, bool complete) {
if (_font) {
_gameRef->_fontStorage->removeFont(_font);
}
- _font = _gameRef->_fontStorage->addFont((char *)params);
+ _font = _gameRef->_fontStorage->addFont(params);
if (!_font) {
cmd = PARSERR_GENERIC;
}
@@ -423,21 +423,21 @@ bool UIWindow::loadBuffer(byte *buffer, bool complete) {
if (_fontInactive) {
_gameRef->_fontStorage->removeFont(_fontInactive);
}
- _fontInactive = _gameRef->_fontStorage->addFont((char *)params);
+ _fontInactive = _gameRef->_fontStorage->addFont(params);
if (!_fontInactive) {
cmd = PARSERR_GENERIC;
}
break;
case TOKEN_TITLE:
- setText((char *)params);
+ setText(params);
_gameRef->expandStringByStringTable(&_text);
break;
case TOKEN_TITLE_ALIGN:
- if (scumm_stricmp((char *)params, "left") == 0) {
+ if (scumm_stricmp(params, "left") == 0) {
_titleAlign = TAL_LEFT;
- } else if (scumm_stricmp((char *)params, "right") == 0) {
+ } else if (scumm_stricmp(params, "right") == 0) {
_titleAlign = TAL_RIGHT;
} else {
_titleAlign = TAL_CENTER;
@@ -445,33 +445,33 @@ bool UIWindow::loadBuffer(byte *buffer, bool complete) {
break;
case TOKEN_TITLE_RECT:
- parser.scanStr((char *)params, "%d,%d,%d,%d", &_titleRect.left, &_titleRect.top, &_titleRect.right, &_titleRect.bottom);
+ parser.scanStr(params, "%d,%d,%d,%d", &_titleRect.left, &_titleRect.top, &_titleRect.right, &_titleRect.bottom);
break;
case TOKEN_DRAG_RECT:
- parser.scanStr((char *)params, "%d,%d,%d,%d", &_dragRect.left, &_dragRect.top, &_dragRect.right, &_dragRect.bottom);
+ parser.scanStr(params, "%d,%d,%d,%d", &_dragRect.left, &_dragRect.top, &_dragRect.right, &_dragRect.bottom);
break;
case TOKEN_X:
- parser.scanStr((char *)params, "%d", &_posX);
+ parser.scanStr(params, "%d", &_posX);
break;
case TOKEN_Y:
- parser.scanStr((char *)params, "%d", &_posY);
+ parser.scanStr(params, "%d", &_posY);
break;
case TOKEN_WIDTH:
- parser.scanStr((char *)params, "%d", &_width);
+ parser.scanStr(params, "%d", &_width);
break;
case TOKEN_HEIGHT:
- parser.scanStr((char *)params, "%d", &_height);
+ parser.scanStr(params, "%d", &_height);
break;
case TOKEN_CURSOR:
delete _cursor;
_cursor = new BaseSprite(_gameRef);
- if (!_cursor || DID_FAIL(_cursor->loadFile((char *)params))) {
+ if (!_cursor || DID_FAIL(_cursor->loadFile(params))) {
delete _cursor;
_cursor = nullptr;
cmd = PARSERR_GENERIC;
@@ -532,48 +532,48 @@ bool UIWindow::loadBuffer(byte *buffer, bool complete) {
case TOKEN_TRANSPARENT:
- parser.scanStr((char *)params, "%b", &_transparent);
+ parser.scanStr(params, "%b", &_transparent);
break;
case TOKEN_SCRIPT:
- addScript((char *)params);
+ addScript(params);
break;
case TOKEN_PARENT_NOTIFY:
- parser.scanStr((char *)params, "%b", &_parentNotify);
+ parser.scanStr(params, "%b", &_parentNotify);
break;
case TOKEN_PAUSE_MUSIC:
- parser.scanStr((char *)params, "%b", &_pauseMusic);
+ parser.scanStr(params, "%b", &_pauseMusic);
break;
case TOKEN_DISABLED:
- parser.scanStr((char *)params, "%b", &_disable);
+ parser.scanStr(params, "%b", &_disable);
break;
case TOKEN_VISIBLE:
- parser.scanStr((char *)params, "%b", &_visible);
+ parser.scanStr(params, "%b", &_visible);
break;
case TOKEN_MENU:
- parser.scanStr((char *)params, "%b", &_isMenu);
+ parser.scanStr(params, "%b", &_isMenu);
break;
case TOKEN_IN_GAME:
- parser.scanStr((char *)params, "%b", &_inGame);
+ parser.scanStr(params, "%b", &_inGame);
break;
case TOKEN_CLIP_CONTENTS:
- parser.scanStr((char *)params, "%b", &_clipContents);
+ parser.scanStr(params, "%b", &_clipContents);
break;
case TOKEN_FADE_COLOR:
- parser.scanStr((char *)params, "%d,%d,%d", &fadeR, &fadeG, &fadeB);
+ parser.scanStr(params, "%d,%d,%d", &fadeR, &fadeG, &fadeB);
_fadeBackground = true;
break;
case TOKEN_FADE_ALPHA:
- parser.scanStr((char *)params, "%d", &fadeA);
+ parser.scanStr(params, "%d", &fadeA);
_fadeBackground = true;
break;
@@ -582,16 +582,16 @@ bool UIWindow::loadBuffer(byte *buffer, bool complete) {
break;
case TOKEN_ALPHA_COLOR:
- parser.scanStr((char *)params, "%d,%d,%d", &ar, &ag, &ab);
+ parser.scanStr(params, "%d,%d,%d", &ar, &ag, &ab);
break;
case TOKEN_ALPHA:
- parser.scanStr((char *)params, "%d", &alpha);
+ parser.scanStr(params, "%d", &alpha);
break;
default:
- if (DID_FAIL(_gameRef->windowLoadHook(this, (char **)&buffer, (char **)params))) {
+ if (DID_FAIL(_gameRef->windowLoadHook(this, &buffer, &params))) {
cmd = PARSERR_GENERIC;
}
}
@@ -676,11 +676,11 @@ bool UIWindow::saveAsText(BaseDynamicBuffer *buffer, int indent) {
error("UIWindow::SaveAsText - Unhandled enum-value NUM_TEXT_ALIGN");
}
- if (!BasePlatform::isRectEmpty(&_titleRect)) {
+ if (!_titleRect.isRectEmpty()) {
buffer->putTextIndent(indent + 2, "TITLE_RECT { %d, %d, %d, %d }\n", _titleRect.left, _titleRect.top, _titleRect.right, _titleRect.bottom);
}
- if (!BasePlatform::isRectEmpty(&_dragRect)) {
+ if (!_dragRect.isRectEmpty()) {
buffer->putTextIndent(indent + 2, "DRAG_RECT { %d, %d, %d, %d }\n", _dragRect.left, _dragRect.top, _dragRect.right, _dragRect.bottom);
}
@@ -737,7 +737,7 @@ bool UIWindow::saveAsText(BaseDynamicBuffer *buffer, int indent) {
bool UIWindow::enableWidget(const char *name, bool enable) {
for (uint32 i = 0; i < _widgets.size(); i++) {
if (scumm_stricmp(_widgets[i]->getName(), name) == 0) {
- _widgets[i]->_disable = !enable;
+ _widgets[i]->setDisabled(!enable);
}
}
return STATUS_OK;
@@ -748,7 +748,7 @@ bool UIWindow::enableWidget(const char *name, bool enable) {
bool UIWindow::showWidget(const char *name, bool visible) {
for (uint32 i = 0; i < _widgets.size(); i++) {
if (scumm_stricmp(_widgets[i]->getName(), name) == 0) {
- _widgets[i]->_visible = visible;
+ _widgets[i]->setVisible(visible);
}
}
return STATUS_OK;
@@ -1227,7 +1227,7 @@ bool UIWindow::handleMouse(TMouseEvent event, TMouseButton button) {
bool res = UIObject::handleMouse(event, button);
// handle window dragging
- if (!BasePlatform::isRectEmpty(&_dragRect)) {
+ if (!_dragRect.isRectEmpty()) {
// start drag
if (event == MOUSE_CLICK && button == MOUSE_BUTTON_LEFT) {
Rect32 dragRect = _dragRect;
@@ -1258,24 +1258,24 @@ bool UIWindow::persist(BasePersistenceManager *persistMgr) {
UIObject::persist(persistMgr);
persistMgr->transferPtr(TMEMBER_PTR(_backInactive));
- persistMgr->transfer(TMEMBER(_clipContents));
- persistMgr->transfer(TMEMBER(_dragFrom));
- persistMgr->transfer(TMEMBER(_dragging));
- persistMgr->transfer(TMEMBER(_dragRect));
- persistMgr->transfer(TMEMBER(_fadeBackground));
- persistMgr->transfer(TMEMBER(_fadeColor));
+ persistMgr->transferBool(TMEMBER(_clipContents));
+ persistMgr->transferPoint32(TMEMBER(_dragFrom));
+ persistMgr->transferBool(TMEMBER(_dragging));
+ persistMgr->transferRect32(TMEMBER(_dragRect));
+ persistMgr->transferBool(TMEMBER(_fadeBackground));
+ persistMgr->transferUint32(TMEMBER(_fadeColor));
persistMgr->transferPtr(TMEMBER_PTR(_fontInactive));
persistMgr->transferPtr(TMEMBER_PTR(_imageInactive));
- persistMgr->transfer(TMEMBER(_inGame));
- persistMgr->transfer(TMEMBER(_isMenu));
- persistMgr->transfer(TMEMBER_INT(_mode));
+ persistMgr->transferBool(TMEMBER(_inGame));
+ persistMgr->transferBool(TMEMBER(_isMenu));
+ persistMgr->transferSint32(TMEMBER_INT(_mode));
persistMgr->transferPtr(TMEMBER_PTR(_shieldButton));
persistMgr->transferPtr(TMEMBER_PTR(_shieldWindow));
- persistMgr->transfer(TMEMBER_INT(_titleAlign));
- persistMgr->transfer(TMEMBER(_titleRect));
- persistMgr->transfer(TMEMBER(_transparent));
+ persistMgr->transferSint32(TMEMBER_INT(_titleAlign));
+ persistMgr->transferRect32(TMEMBER(_titleRect));
+ persistMgr->transferBool(TMEMBER(_transparent));
persistMgr->transferPtr(TMEMBER_PTR(_viewport));
- persistMgr->transfer(TMEMBER(_pauseMusic));
+ persistMgr->transferBool(TMEMBER(_pauseMusic));
_widgets.persist(persistMgr);
@@ -1309,7 +1309,7 @@ bool UIWindow::moveFocus(bool forward) {
bool done = false;
while (numTries <= (int32)_widgets.size()) {
- if (_widgets[i] != _focusedWidget && _widgets[i]->_canFocus && _widgets[i]->_visible && !_widgets[i]->_disable) {
+ if (_widgets[i] != _focusedWidget && _widgets[i]->canFocus() && _widgets[i]->isVisible() && !_widgets[i]->isDisabled()) {
_focusedWidget = _widgets[i];
done = true;
break;
@@ -1419,7 +1419,7 @@ void UIWindow::makeFreezable(bool freezable) {
bool UIWindow::getWindowObjects(BaseArray<UIObject *> &objects, bool interactiveOnly) {
for (uint32 i = 0; i < _widgets.size(); i++) {
UIObject *control = _widgets[i];
- if (control->_disable && interactiveOnly) {
+ if (control->isDisabled() && interactiveOnly) {
continue;
}
@@ -1442,4 +1442,14 @@ bool UIWindow::getWindowObjects(BaseArray<UIObject *> &objects, bool interactive
return STATUS_OK;
}
+bool UIWindow::getInGame() const {
+ return _inGame;
+}
+
+TWindowMode UIWindow::getMode() const {
+ return _mode;
+}
+
+
+
} // End of namespace Wintermute
diff --git a/engines/wintermute/ui/ui_window.h b/engines/wintermute/ui/ui_window.h
index 8a726fdff8..6b4d970581 100644
--- a/engines/wintermute/ui/ui_window.h
+++ b/engines/wintermute/ui/ui_window.h
@@ -38,47 +38,32 @@ namespace Wintermute {
class UIButton;
class BaseViewport;
class UIWindow : public UIObject {
- uint32 _fadeColor;
public:
bool getWindowObjects(BaseArray<UIObject *> &Objects, bool InteractiveOnly);
- bool _pauseMusic;
void cleanup();
virtual void makeFreezable(bool freezable);
- BaseViewport *_viewport;
- bool _clipContents;
- bool _inGame;
- bool _isMenu;
- bool _fadeBackground;
virtual bool handleMouseWheel(int delta);
- UIWindow *_shieldWindow;
- UIButton *_shieldButton;
+
bool close();
bool goSystemExclusive();
bool goExclusive();
- TWindowMode _mode;
bool moveFocus(bool forward = true);
virtual bool handleMouse(TMouseEvent Event, TMouseButton Button);
- Point32 _dragFrom;
- bool _dragging;
DECLARE_PERSISTENT(UIWindow, UIObject)
- bool _transparent;
bool showWidget(const char *name, bool visible = true);
bool enableWidget(const char *name, bool enable = true);
- Rect32 _titleRect;
- Rect32 _dragRect;
+
virtual bool display(int offsetX = 0, int offsetY = 0) override;
UIWindow(BaseGame *inGame);
virtual ~UIWindow();
virtual bool handleKeypress(Common::Event *event, bool printable = false) override;
BaseArray<UIObject *> _widgets;
- TTextAlign _titleAlign;
+
bool loadFile(const char *filename);
- bool loadBuffer(byte *buffer, bool complete = true);
- UITiledImage *_backInactive;
- BaseFont *_fontInactive;
- BaseSprite *_imageInactive;
+ bool loadBuffer(char *buffer, bool complete = true);
+
virtual bool listen(BaseScriptHolder *param1, uint32 param2);
virtual bool saveAsText(BaseDynamicBuffer *buffer, int indent) override;
@@ -87,6 +72,30 @@ public:
virtual bool scSetProperty(const char *name, ScValue *value) override;
virtual bool scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name) override;
virtual const char *scToString();
+
+ bool getInGame() const;
+ TWindowMode getMode() const;
+
+private:
+ bool _pauseMusic;
+ BaseViewport *_viewport;
+ bool _clipContents;
+ bool _inGame;
+ bool _isMenu;
+ bool _fadeBackground;
+ TWindowMode _mode;
+ Point32 _dragFrom;
+ bool _dragging;
+ bool _transparent;
+ uint32 _fadeColor;
+ UIWindow *_shieldWindow;
+ UIButton *_shieldButton;
+ Rect32 _titleRect;
+ Rect32 _dragRect;
+ UITiledImage *_backInactive;
+ BaseFont *_fontInactive;
+ BaseSprite *_imageInactive;
+ TTextAlign _titleAlign;
};
} // End of namespace Wintermute
diff --git a/engines/wintermute/utils/string_util.cpp b/engines/wintermute/utils/string_util.cpp
index e8e078aba8..702dd04c27 100644
--- a/engines/wintermute/utils/string_util.cpp
+++ b/engines/wintermute/utils/string_util.cpp
@@ -50,142 +50,94 @@ bool StringUtil::compareNoCase(const AnsiString &str1, const AnsiString &str2) {
//////////////////////////////////////////////////////////////////////////
WideString StringUtil::utf8ToWide(const Utf8String &Utf8Str) {
- error("StringUtil::Utf8ToWide - WideString not supported yet");
- /* size_t WideSize = Utf8Str.size();
-
- if (sizeof(wchar_t) == 2) {
- wchar_t *WideStringNative = new wchar_t[WideSize + 1];
-
- const UTF8 *SourceStart = reinterpret_cast<const UTF8 *>(Utf8Str.c_str());
- const UTF8 *SourceEnd = SourceStart + WideSize;
-
- UTF16 *TargetStart = reinterpret_cast<UTF16 *>(WideStringNative);
- UTF16 *TargetEnd = TargetStart + WideSize + 1;
-
- ConversionResult res = ConvertUTF8toUTF16(&SourceStart, SourceEnd, &TargetStart, TargetEnd, strictConversion);
- if (res != conversionOK) {
- delete[] WideStringNative;
- return L"";
- }
- *TargetStart = 0;
- WideString ResultString(WideStringNative);
- delete[] WideStringNative;
-
- return ResultString;
- } else if (sizeof(wchar_t) == 4) {
- wchar_t *WideStringNative = new wchar_t[WideSize + 1];
-
- const UTF8 *SourceStart = reinterpret_cast<const UTF8 *>(Utf8Str.c_str());
- const UTF8 *SourceEnd = SourceStart + WideSize;
-
- UTF32 *TargetStart = reinterpret_cast<UTF32 *>(WideStringNative);
- UTF32 *TargetEnd = TargetStart + WideSize;
-
- ConversionResult res = ConvertUTF8toUTF32(&SourceStart, SourceEnd, &TargetStart, TargetEnd, strictConversion);
- if (res != conversionOK) {
- delete[] WideStringNative;
- return L"";
- }
- *TargetStart = 0;
- WideString ResultString(WideStringNative);
- delete[] WideStringNative;
-
- return ResultString;
- } else {
- return L"";
- }*/
- return "";
+ size_t wideSize = Utf8Str.size();
+
+ uint32 *wideStringNative = new uint32[wideSize + 1];
+
+ const UTF8 *sourceStart = reinterpret_cast<const UTF8 *>(Utf8Str.c_str());
+ const UTF8 *sourceEnd = sourceStart + wideSize;
+
+ UTF32 *targetStart = reinterpret_cast<UTF32 *>(wideStringNative);
+ UTF32 *targetEnd = targetStart + wideSize;
+
+ ConversionResult res = ConvertUTF8toUTF32(&sourceStart, sourceEnd, &targetStart, targetEnd, strictConversion);
+ if (res != conversionOK) {
+ delete[] wideStringNative;
+ return WideString();
+ }
+ *targetStart = 0;
+ WideString resultString(wideStringNative);
+ delete[] wideStringNative;
+ return resultString;
}
//////////////////////////////////////////////////////////////////////////
Utf8String StringUtil::wideToUtf8(const WideString &WideStr) {
- error("StringUtil::wideToUtf8 - Widestring not supported yet");
- /* size_t WideSize = WideStr.length();
-
- if (sizeof(wchar_t) == 2) {
- size_t utf8Size = 3 * WideSize + 1;
- char *utf8StringNative = new char[Utf8Size];
-
- const UTF16 *SourceStart = reinterpret_cast<const UTF16 *>(WideStr.c_str());
- const UTF16 *SourceEnd = SourceStart + WideSize;
-
- UTF8 *TargetStart = reinterpret_cast<UTF8 *>(Utf8StringNative);
- UTF8 *TargetEnd = TargetStart + Utf8Size;
-
- ConversionResult res = ConvertUTF16toUTF8(&SourceStart, SourceEnd, &TargetStart, TargetEnd, strictConversion);
- if (res != conversionOK) {
- delete[] Utf8StringNative;
- return (Utf8String)"";
- }
- *TargetStart = 0;
- Utf8String ResultString(Utf8StringNative);
- delete[] Utf8StringNative;
- return ResultString;
- } else if (sizeof(wchar_t) == 4) {
- size_t utf8Size = 4 * WideSize + 1;
- char *utf8StringNative = new char[Utf8Size];
-
- const UTF32 *SourceStart = reinterpret_cast<const UTF32 *>(WideStr.c_str());
- const UTF32 *SourceEnd = SourceStart + WideSize;
-
- UTF8 *TargetStart = reinterpret_cast<UTF8 *>(Utf8StringNative);
- UTF8 *TargetEnd = TargetStart + Utf8Size;
-
- ConversionResult res = ConvertUTF32toUTF8(&SourceStart, SourceEnd, &TargetStart, TargetEnd, strictConversion);
- if (res != conversionOK) {
- delete[] Utf8StringNative;
- return (Utf8String)"";
- }
- *TargetStart = 0;
- Utf8String ResultString(Utf8StringNative);
- delete[] Utf8StringNative;
- return ResultString;
- } else {
- return (Utf8String)"";
- }*/
- return "";
+ size_t wideSize = WideStr.size();
+
+ size_t utf8Size = 4 * wideSize + 1;
+ char *utf8StringNative = new char[utf8Size];
+
+ const UTF32 *sourceStart = reinterpret_cast<const UTF32 *>(WideStr.c_str());
+ const UTF32 *sourceEnd = sourceStart + wideSize;
+
+ UTF8 *targetStart = reinterpret_cast<UTF8 *>(utf8StringNative);
+ UTF8 *targetEnd = targetStart + utf8Size;
+
+ ConversionResult res = ConvertUTF32toUTF8(&sourceStart, sourceEnd, &targetStart, targetEnd, strictConversion);
+ if (res != conversionOK) {
+ delete[] utf8StringNative;
+ return Utf8String();
+ }
+ *targetStart = 0;
+ Utf8String resultString(utf8StringNative);
+ delete[] utf8StringNative;
+ return resultString;
}
//////////////////////////////////////////////////////////////////////////
WideString StringUtil::ansiToWide(const AnsiString &str) {
- // TODO: This function gets called a lot, so warnings like these drown out the usefull information
- Common::String converted = "";
- uint32 index = 0;
- while (index != str.size()) {
- byte c = str[index];
- if (c == 146) {
- converted += (char)39; // Replace right-quote with apostrophe
- } else if (c == 133) {
- converted += Common::String("..."); // Replace ...-symbol with ...
+ WideString result;
+ for (AnsiString::const_iterator i = str.begin(), end = str.end(); i != end; ++i) {
+ const byte c = *i;
+ if (c < 0x80 || c >= 0xA0) {
+ result += c;
} else {
- converted += c;
+ uint32 utf32 = _ansiToUTF32[c - 0x80];
+ if (utf32) {
+ result += utf32;
+ } else {
+ // It's an invalid CP1252 character...
+ }
}
- index++;
}
- // using default os locale!
-
- /* setlocale(LC_CTYPE, "");
- size_t wideSize = mbstowcs(NULL, str.c_str(), 0) + 1;
- wchar_t *wstr = new wchar_t[WideSize];
- mbstowcs(wstr, str.c_str(), WideSize);
- WideString ResultString(wstr);
- delete[] wstr;
- return ResultString;*/
- return WideString(converted);
+ return result;
}
//////////////////////////////////////////////////////////////////////////
AnsiString StringUtil::wideToAnsi(const WideString &wstr) {
- // using default os locale!
- // TODO: This function gets called a lot, so warnings like these drown out the usefull information
- /* setlocale(LC_CTYPE, "");
- size_t wideSize = wcstombs(NULL, wstr.c_str(), 0) + 1;
- char *str = new char[WideSize];
- wcstombs(str, wstr.c_str(), WideSize);
- AnsiString ResultString(str);
- delete[] str;
- return ResultString;*/
- return AnsiString(wstr);
+ AnsiString result;
+ for (WideString::const_iterator i = wstr.begin(), end = wstr.end(); i != end; ++i) {
+ const uint32 c = *i;
+ if (c < 0x80 || (c >= 0xA0 && c <= 0xFF)) {
+ result += c;
+ } else {
+ uint32 ansi = 0xFFFFFFFF;
+ for (uint j = 0; j < ARRAYSIZE(_ansiToUTF32); ++j) {
+ if (_ansiToUTF32[j] == c) {
+ ansi = j + 0x80;
+ break;
+ }
+ }
+
+ if (ansi != 0xFFFFFFFF) {
+ result += ansi;
+ } else {
+ // There's no valid CP1252 code for this character...
+ }
+ }
+ }
+ return result;
}
//////////////////////////////////////////////////////////////////////////
@@ -199,12 +151,7 @@ bool StringUtil::isUtf8BOM(const byte *buffer, uint32 bufferSize) {
//////////////////////////////////////////////////////////////////////////
int StringUtil::indexOf(const WideString &str, const WideString &toFind, size_t startFrom) {
- const char *index = strstr(str.c_str(), toFind.c_str());
- if (index == nullptr) {
- return -1;
- } else {
- return index - str.c_str();
- }
+ return str.find(toFind, startFrom);
}
Common::String StringUtil::encodeSetting(const Common::String &str) {
@@ -225,5 +172,10 @@ AnsiString StringUtil::toString(int val) {
return Common::String::format("%d", val);
}
+// Mapping of CP1252 characters 0x80...0x9F into UTF-32
+uint32 StringUtil::_ansiToUTF32[32] = {
+ 0x20AC, 0x0000, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021, 0x02C6, 0x2030, 0x0160, 0x2039, 0x0152, 0x0000, 0x017D, 0x0000,
+ 0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, 0x02DC, 0x2122, 0x0161, 0x203A, 0x0153, 0x0000, 0x017E, 0x0178
+};
} // End of namespace Wintermute
diff --git a/engines/wintermute/utils/string_util.h b/engines/wintermute/utils/string_util.h
index 3ae5e47493..14c40fcb2b 100644
--- a/engines/wintermute/utils/string_util.h
+++ b/engines/wintermute/utils/string_util.h
@@ -49,6 +49,9 @@ public:
static Common::String decodeSetting(const Common::String &str);
static AnsiString toString(int val);
+
+private:
+ static uint32 _ansiToUTF32[32];
};
} // End of namespace Wintermute
diff --git a/engines/wintermute/video/video_theora_player.cpp b/engines/wintermute/video/video_theora_player.cpp
index f3317684b5..299b64f915 100644
--- a/engines/wintermute/video/video_theora_player.cpp
+++ b/engines/wintermute/video/video_theora_player.cpp
@@ -34,7 +34,6 @@
#include "engines/wintermute/base/gfx/base_image.h"
#include "engines/wintermute/base/gfx/base_renderer.h"
#include "engines/wintermute/base/sound/base_sound_manager.h"
-#include "engines/wintermute/platform_osystem.h"
#include "video/theora_decoder.h"
#include "engines/wintermute/wintermute.h"
#include "common/system.h"
@@ -306,8 +305,15 @@ bool VideoTheoraPlayer::update() {
if (!_theoraDecoder->endOfVideo() && _theoraDecoder->getTimeToNextFrame() == 0) {
const Graphics::Surface *decodedFrame = _theoraDecoder->decodeNextFrame();
if (decodedFrame) {
- _surface.free();
- _surface.copyFrom(*decodedFrame);
+ if (decodedFrame->format == _surface.format && decodedFrame->w == _surface.w && decodedFrame->h == _surface.h) {
+ const byte *src = (const byte *)decodedFrame->getBasePtr(0, 0);
+ byte *dst = (byte *)_surface.getBasePtr(0, 0);
+ memcpy(dst, src, _surface.pitch * _surface.h);
+ } else {
+ _surface.free();
+ _surface.copyFrom(*decodedFrame);
+ }
+
if (_texture) {
writeVideo();
}
@@ -396,7 +402,7 @@ bool VideoTheoraPlayer::display(uint32 alpha) {
bool res;
if (_texture && _videoFrameReady) {
- BasePlatform::setRect(&rc, 0, 0, _texture->getWidth(), _texture->getHeight());
+ rc.setRect(0, 0, _texture->getWidth(), _texture->getHeight());
if (_playZoom == 100.0f) {
res = _texture->displayTrans(_posX, _posY, rc, alpha);
} else {
@@ -492,16 +498,16 @@ bool VideoTheoraPlayer::persist(BasePersistenceManager *persistMgr) {
}
persistMgr->transferPtr(TMEMBER_PTR(_gameRef));
- persistMgr->transfer(TMEMBER(_savedPos));
- persistMgr->transfer(TMEMBER(_savedState));
- persistMgr->transfer(TMEMBER(_filename));
- persistMgr->transfer(TMEMBER(_alphaFilename));
- persistMgr->transfer(TMEMBER(_posX));
- persistMgr->transfer(TMEMBER(_posY));
+ persistMgr->transferUint32(TMEMBER(_savedPos));
+ persistMgr->transferSint32(TMEMBER(_savedState));
+ persistMgr->transferString(TMEMBER(_filename));
+ persistMgr->transferString(TMEMBER(_alphaFilename));
+ persistMgr->transferSint32(TMEMBER(_posX));
+ persistMgr->transferSint32(TMEMBER(_posY));
persistMgr->transferFloat(TMEMBER(_playZoom));
- persistMgr->transfer(TMEMBER_INT(_playbackType));
- persistMgr->transfer(TMEMBER(_looping));
- persistMgr->transfer(TMEMBER(_volume));
+ persistMgr->transferSint32(TMEMBER_INT(_playbackType));
+ persistMgr->transferBool(TMEMBER(_looping));
+ persistMgr->transferSint32(TMEMBER(_volume));
if (!persistMgr->getIsSaving() && (_savedState != THEORA_STATE_NONE)) {
initializeSimple();
diff --git a/engines/wintermute/video/video_theora_player.h b/engines/wintermute/video/video_theora_player.h
index ddeba48bbc..7b28a71e17 100644
--- a/engines/wintermute/video/video_theora_player.h
+++ b/engines/wintermute/video/video_theora_player.h
@@ -62,7 +62,7 @@ public:
//CVidSubtitler *_subtitler;
// control methods
- bool initialize(const Common::String &filename, const Common::String &subtitleFile = nullptr);
+ bool initialize(const Common::String &filename, const Common::String &subtitleFile = Common::String());
bool initializeSimple();
bool update();
bool play(TVideoPlayback type = VID_PLAY_CENTER, int x = 0, int y = 0, bool freezeGame = false, bool freezeMusic = true, bool looping = false, uint32 startTime = 0, float forceZoom = -1.0f, int volume = -1);
@@ -90,7 +90,7 @@ public:
BaseImage *_alphaImage;
Common::String _alphaFilename;
bool setAlphaImage(const Common::String &filename);
- __inline byte getAlphaAt(int x, int y) const;
+ byte getAlphaAt(int x, int y) const;
void writeAlpha();
bool seekToTime(uint32 Time);
diff --git a/engines/zvision/animation/rlf_animation.cpp b/engines/zvision/animation/rlf_animation.cpp
new file mode 100644
index 0000000000..c7307265c0
--- /dev/null
+++ b/engines/zvision/animation/rlf_animation.cpp
@@ -0,0 +1,331 @@
+/* ScummVM - Graphic Adventure Engine
+*
+* ScummVM is the legal property of its developers, whose names
+* are too numerous to list here. Please refer to the COPYRIGHT
+* file distributed with this source distribution.
+*
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License
+* as published by the Free Software Foundation; either version 2
+* of the License, or (at your option) any later version.
+
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+
+* You should have received a copy of the GNU General Public 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
new file mode 100644
index 0000000000..fe5b0d68b4
--- /dev/null
+++ b/engines/zvision/animation/rlf_animation.h
@@ -0,0 +1,163 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public 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/archives/zfs_archive.cpp b/engines/zvision/archives/zfs_archive.cpp
new file mode 100644
index 0000000000..b8175b4903
--- /dev/null
+++ b/engines/zvision/archives/zfs_archive.cpp
@@ -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.
+ *
+ */
+
+#include "common/scummsys.h"
+
+#include "zvision/archives/zfs_archive.h"
+
+#include "common/memstream.h"
+#include "common/debug.h"
+#include "common/file.h"
+
+namespace ZVision {
+
+ZfsArchive::ZfsArchive(const Common::String &fileName) : _fileName(fileName) {
+ Common::File zfsFile;
+
+ if (!zfsFile.open(_fileName)) {
+ warning("ZFSArchive::ZFSArchive(): Could not find the archive file");
+ return;
+ }
+
+ readHeaders(&zfsFile);
+
+ debug(1, "ZfsArchive::ZfsArchive(%s): Located %d files", _fileName.c_str(), _entryHeaders.size());
+}
+
+ZfsArchive::ZfsArchive(const Common::String &fileName, Common::SeekableReadStream *stream) : _fileName(fileName) {
+ readHeaders(stream);
+
+ debug(1, "ZfsArchive::ZfsArchive(%s): Located %d files", _fileName.c_str(), _entryHeaders.size());
+}
+
+ZfsArchive::~ZfsArchive() {
+ debug(1, "ZfsArchive Destructor Called");
+ ZfsEntryHeaderMap::iterator it = _entryHeaders.begin();
+ for ( ; it != _entryHeaders.end(); ++it) {
+ delete it->_value;
+ }
+}
+
+void ZfsArchive::readHeaders(Common::SeekableReadStream *stream) {
+ // Don't do a straight struct cast since we can't guarantee endianness
+ _header.magic = stream->readUint32LE();
+ _header.unknown1 = stream->readUint32LE();
+ _header.maxNameLength = stream->readUint32LE();
+ _header.filesPerBlock = stream->readUint32LE();
+ _header.fileCount = stream->readUint32LE();
+ _header.xorKey[0] = stream->readByte();
+ _header.xorKey[1] = stream->readByte();
+ _header.xorKey[2] = stream->readByte();
+ _header.xorKey[3] = stream->readByte();
+ _header.fileSectionOffset = stream->readUint32LE();
+
+ uint32 nextOffset;
+
+ do {
+ // Read the offset to the next block
+ nextOffset = stream->readUint32LE();
+
+ // 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();
+ entryHeader.size = stream->readUint32LE();
+ entryHeader.time = stream->readUint32LE();
+ entryHeader.unknown = stream->readUint32LE();
+
+ if (entryHeader.size != 0)
+ _entryHeaders[entryHeader.name] = new ZfsEntryHeader(entryHeader);
+ }
+
+ // Seek to the next block of headers
+ stream->seek(nextOffset);
+ } while (nextOffset != 0);
+}
+
+Common::String ZfsArchive::readEntryName(Common::SeekableReadStream *stream) const {
+ // Entry Names are at most 16 bytes and are null padded
+ char buffer[16];
+ stream->read(buffer, 16);
+
+ return Common::String(buffer);
+}
+
+bool ZfsArchive::hasFile(const Common::String &name) const {
+ return _entryHeaders.contains(name);
+}
+
+int ZfsArchive::listMembers(Common::ArchiveMemberList &list) const {
+ int matches = 0;
+
+ for (ZfsEntryHeaderMap::const_iterator it = _entryHeaders.begin(); it != _entryHeaders.end(); ++it) {
+ list.push_back(Common::ArchiveMemberList::value_type(new Common::GenericArchiveMember(it->_value->name, this)));
+ matches++;
+ }
+
+ return matches;
+}
+
+const Common::ArchiveMemberPtr ZfsArchive::getMember(const Common::String &name) const {
+ if (!_entryHeaders.contains(name))
+ return Common::ArchiveMemberPtr();
+
+ return Common::ArchiveMemberPtr(new Common::GenericArchiveMember(name, this));
+}
+
+Common::SeekableReadStream *ZfsArchive::createReadStreamForMember(const Common::String &name) const {
+ if (!_entryHeaders.contains(name)) {
+ return 0;
+ }
+
+ ZfsEntryHeader *entryHeader = _entryHeaders[name];
+
+ Common::File zfsArchive;
+ zfsArchive.open(_fileName);
+ 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);
+ zfsArchive.read(buffer, entryHeader->size);
+ // Decrypt the data in place
+ if (_header.xorKey != 0)
+ unXor(buffer, entryHeader->size, _header.xorKey);
+
+ return new Common::MemoryReadStream(buffer, entryHeader->size, DisposeAfterUse::YES);
+}
+
+void ZfsArchive::unXor(byte *buffer, uint32 length, const byte *xorKey) const {
+ for (uint32 i = 0; i < length; ++i)
+ buffer[i] ^= xorKey[i % 4];
+}
+
+} // End of namespace ZVision
+
+
diff --git a/engines/zvision/archives/zfs_archive.h b/engines/zvision/archives/zfs_archive.h
new file mode 100644
index 0000000000..d7b45e4b47
--- /dev/null
+++ b/engines/zvision/archives/zfs_archive.h
@@ -0,0 +1,126 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public 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_ZFS_ARCHIVE_H
+#define ZVISION_ZFS_ARCHIVE_H
+
+#include "common/archive.h"
+#include "common/hashmap.h"
+#include "common/hash-str.h"
+
+
+namespace Common {
+class String;
+}
+
+namespace ZVision {
+
+struct ZfsHeader {
+ uint32 magic;
+ uint32 unknown1;
+ uint32 maxNameLength;
+ uint32 filesPerBlock;
+ uint32 fileCount;
+ byte xorKey[4];
+ uint32 fileSectionOffset;
+};
+
+struct ZfsEntryHeader {
+ Common::String name;
+ uint32 offset;
+ uint32 id;
+ uint32 size;
+ uint32 time;
+ uint32 unknown;
+};
+
+typedef Common::HashMap<Common::String, ZfsEntryHeader*, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> ZfsEntryHeaderMap;
+
+class ZfsArchive : public Common::Archive {
+public:
+ ZfsArchive(const Common::String &fileName);
+ ZfsArchive(const Common::String &fileName, Common::SeekableReadStream *stream);
+ ~ZfsArchive();
+
+ /**
+ * Check if a member with the given name is present in the Archive.
+ * Patterns are not allowed, as this is meant to be a quick File::exists()
+ * replacement.
+ */
+ bool hasFile(const Common::String &fileName) const;
+
+ /**
+ * Add all members of the Archive to list.
+ * Must only append to list, and not remove elements from it.
+ *
+ * @return The number of names added to list
+ */
+ int listMembers(Common::ArchiveMemberList &list) const;
+
+ /**
+ * Returns a ArchiveMember representation of the given file.
+ */
+ const Common::ArchiveMemberPtr getMember(const Common::String &name) const;
+
+ /**
+ * Create a stream bound to a member with the specified name in the
+ * archive. If no member with this name exists, 0 is returned.
+ *
+ * @return The newly created input stream
+ */
+ Common::SeekableReadStream *createReadStreamForMember(const Common::String &name) const;
+
+private:
+ const Common::String _fileName;
+ ZfsHeader _header;
+ ZfsEntryHeaderMap _entryHeaders;
+
+ /**
+ * Parses the zfs file into file entry headers that can be used later
+ * to get the entry data.
+ *
+ * @param stream The contents of the zfs file
+ */
+ void readHeaders(Common::SeekableReadStream *stream);
+
+ /**
+ * Entry names are contained within a 16 byte block. This reads the block
+ * and converts it the name to a Common::String
+ *
+ * @param stream The zfs file stream
+ * @return The entry file name
+ */
+ Common::String readEntryName(Common::SeekableReadStream *stream) const;
+
+ /**
+ * ZFS file entries can be encrypted using XOR encoding. This method
+ * decodes the buffer in place using the supplied xorKey.
+ *
+ * @param buffer The data to decode
+ * @param length Length of buffer
+ */
+ void unXor(byte *buffer, uint32 length, const byte *xorKey) const;
+};
+
+} // End of namespace ZVision
+
+#endif
diff --git a/engines/zvision/configure.engine b/engines/zvision/configure.engine
new file mode 100644
index 0000000000..02e31943af
--- /dev/null
+++ b/engines/zvision/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 zvision "ZVision" no "" "" "freetype2 16bit"
diff --git a/engines/zvision/core/console.cpp b/engines/zvision/core/console.cpp
new file mode 100644
index 0000000000..0d325ef7f7
--- /dev/null
+++ b/engines/zvision/core/console.cpp
@@ -0,0 +1,218 @@
+/* ScummVM - Graphic Adventure Engine
+*
+* ScummVM is the legal property of its developers, whose names
+* are too numerous to list here. Please refer to the COPYRIGHT
+* file distributed with this source distribution.
+*
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License
+* as published by the Free Software Foundation; either version 2
+* of the License, or (at your option) any later version.
+
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+
+* You should have received a copy of the GNU General Public 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/console.h"
+
+#include "zvision/zvision.h"
+#include "zvision/scripting/script_manager.h"
+#include "zvision/graphics/render_manager.h"
+#include "zvision/strings/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 "common/system.h"
+#include "common/file.h"
+#include "common/bufferedstream.h"
+
+#include "gui/debugger.h"
+
+#include "audio/mixer.h"
+
+
+namespace ZVision {
+
+Console::Console(ZVision *engine) : GUI::Debugger(), _engine(engine) {
+ DCmd_Register("loadimage", WRAP_METHOD(Console, cmdLoadImage));
+ DCmd_Register("loadvideo", WRAP_METHOD(Console, cmdLoadVideo));
+ DCmd_Register("loadsound", WRAP_METHOD(Console, cmdLoadSound));
+ DCmd_Register("raw2wav", WRAP_METHOD(Console, cmdRawToWav));
+ DCmd_Register("setrenderstate", WRAP_METHOD(Console, cmdSetRenderState));
+ DCmd_Register("generaterendertable", WRAP_METHOD(Console, cmdGenerateRenderTable));
+ DCmd_Register("setpanoramafov", WRAP_METHOD(Console, cmdSetPanoramaFoV));
+ DCmd_Register("setpanoramascale", WRAP_METHOD(Console, cmdSetPanoramaScale));
+ DCmd_Register("changelocation", WRAP_METHOD(Console, cmdChangeLocation));
+ DCmd_Register("dumpfile", WRAP_METHOD(Console, cmdDumpFile));
+ DCmd_Register("parseallscrfiles", WRAP_METHOD(Console, cmdParseAllScrFiles));
+ DCmd_Register("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;
+}
+
+bool Console::cmdLoadVideo(int argc, const char **argv) {
+ if (argc != 2) {
+ DebugPrintf("Use loadvideo <fileName> to load a video to the screen\n");
+ return true;
+ }
+
+ ZorkAVIDecoder videoDecoder;
+ if (videoDecoder.loadFile(argv[1])) {
+ _engine->playVideo(videoDecoder);
+ }
+
+ return true;
+}
+
+bool Console::cmdLoadSound(int argc, const char **argv) {
+ if (!Common::File::exists(argv[1])) {
+ DebugPrintf("File does not exist\n");
+ return true;
+ }
+
+ if (argc == 2) {
+ 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]);
+
+ 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");
+ return true;
+ }
+
+ return true;
+}
+
+bool Console::cmdRawToWav(int argc, const char **argv) {
+ if (argc != 3) {
+ DebugPrintf("Use raw2wav <rawFilePath> <wavFileName> to dump a .RAW file to .WAV\n");
+ return true;
+ }
+
+ convertRawToWav(argv[1], _engine, argv[2]);
+ 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");
+ return true;
+ }
+
+ Common::String renderState(argv[1]);
+
+ if (renderState.matchString("panorama", true))
+ _engine->getRenderManager()->getRenderTable()->setRenderState(RenderTable::PANORAMA);
+ else if (renderState.matchString("tilt", true))
+ _engine->getRenderManager()->getRenderTable()->setRenderState(RenderTable::TILT);
+ 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");
+
+ return true;
+}
+
+bool Console::cmdGenerateRenderTable(int argc, const char **argv) {
+ _engine->getRenderManager()->getRenderTable()->generateRenderTable();
+
+ return true;
+}
+
+bool Console::cmdSetPanoramaFoV(int argc, const char **argv) {
+ if (argc != 2) {
+ DebugPrintf("Use setpanoramafov <fieldOfView> to change the current panorama field of view\n");
+ return true;
+ }
+
+ _engine->getRenderManager()->getRenderTable()->setPanoramaFoV(atof(argv[1]));
+
+ return true;
+}
+
+bool Console::cmdSetPanoramaScale(int argc, const char **argv) {
+ if (argc != 2) {
+ DebugPrintf("Use setpanoramascale <scale> to change the current panorama scale\n");
+ return true;
+ }
+
+ _engine->getRenderManager()->getRenderTable()->setPanoramaScale(atof(argv[1]));
+
+ return true;
+}
+
+bool Console::cmdChangeLocation(int argc, const char **argv) {
+ if (argc != 6) {
+ DebugPrintf("Use changelocation <char: world> <char: room> <char:node> <char:view> <int: x position> to change your location\n");
+ return true;
+ }
+
+ _engine->getScriptManager()->changeLocation(*(argv[1]), *(argv[2]), *(argv[3]), *(argv[4]), atoi(argv[5]));
+
+ return true;
+}
+
+bool Console::cmdDumpFile(int argc, const char **argv) {
+ if (argc != 2) {
+ DebugPrintf("Use dumpfile <fileName> to dump a file\n");
+ return true;
+ }
+
+ writeFileContentsToFile(argv[1], argv[1]);
+
+ return true;
+}
+
+bool Console::cmdParseAllScrFiles(int argc, const char **argv) {
+ Common::ArchiveMemberList list;
+ SearchMan.listMatchingMembers(list, "*.scr");
+
+ for (Common::ArchiveMemberList::iterator iter = list.begin(); iter != list.end(); ++iter) {
+ _engine->getScriptManager()->parseScrFile((*iter)->getName());
+ }
+
+ 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");
+ 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);
+
+ return true;
+}
+
+} // End of namespace ZVision
diff --git a/engines/zvision/core/console.h b/engines/zvision/core/console.h
new file mode 100644
index 0000000000..0ca1b8cc70
--- /dev/null
+++ b/engines/zvision/core/console.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_CONSOLE_H
+#define ZVISION_CONSOLE_H
+
+#include "gui/debugger.h"
+
+namespace ZVision {
+
+class ZVision;
+
+class Console : public GUI::Debugger {
+public:
+ Console(ZVision *engine);
+ virtual ~Console() {}
+
+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);
+ bool cmdSetRenderState(int argc, const char **argv);
+ 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 cmdDumpFile(int argc, const char **argv);
+ bool cmdParseAllScrFiles(int argc, const char **argv);
+ bool cmdRenderText(int argc, const char **argv);
+};
+
+} // End of namespace ZVision
+#endif
diff --git a/engines/zvision/core/events.cpp b/engines/zvision/core/events.cpp
new file mode 100644
index 0000000000..40bfb879b1
--- /dev/null
+++ b/engines/zvision/core/events.cpp
@@ -0,0 +1,186 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public 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/core/console.h"
+#include "zvision/cursors/cursor_manager.h"
+#include "zvision/graphics/render_manager.h"
+#include "zvision/scripting/script_manager.h"
+#include "zvision/animation/rlf_animation.h"
+
+#include "common/events.h"
+#include "common/system.h"
+#include "common/rational.h"
+
+#include "engines/util.h"
+
+
+namespace ZVision {
+
+void ZVision::processEvents() {
+ while (_eventMan->pollEvent(_event)) {
+ switch (_event.type) {
+ case Common::EVENT_LBUTTONDOWN:
+ onMouseDown(_event.mouse);
+ break;
+
+ case Common::EVENT_LBUTTONUP:
+ onMouseUp(_event.mouse);
+ break;
+
+ case Common::EVENT_RBUTTONDOWN:
+ // TODO: Inventory logic
+ break;
+
+ case Common::EVENT_MOUSEMOVE:
+ onMouseMove(_event.mouse);
+ break;
+
+ case Common::EVENT_KEYDOWN:
+ switch (_event.kbd.keycode) {
+ case Common::KEYCODE_d:
+ if (_event.kbd.hasFlags(Common::KBD_CTRL)) {
+ // Start the debugger
+ _console->attach();
+ _console->onFrame();
+ }
+ break;
+ case Common::KEYCODE_q:
+ if (_event.kbd.hasFlags(Common::KBD_CTRL))
+ quitGame();
+ break;
+ default:
+ break;
+ }
+
+ _scriptManager->onKeyDown(_event.kbd);
+ break;
+ case Common::EVENT_KEYUP:
+ _scriptManager->onKeyUp(_event.kbd);
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+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) {
+ Common::Point imageCoord(_renderManager->screenSpaceToImageSpace(pos));
+
+ bool cursorWasChanged = _scriptManager->onMouseMove(pos, imageCoord);
+
+ // Graph of the function governing rotation velocity:
+ //
+ // |---------------- working window ------------------|
+ // ^ |---------|
+ // | |
+ // +Max velocity | rotation screen edge offset
+ // | /|
+ // | / |
+ // | / |
+ // | / |
+ // | / |
+ // | / |
+ // | / |
+ // | / |
+ // | / |
+ // Zero velocity |______________________________ ______________________________/_________|__________________________>
+ // | Position -> | /
+ // | | /
+ // | | /
+ // | | /
+ // | | /
+ // | | /
+ // | | /
+ // | | /
+ // | | /
+ // -Max velocity | |/
+ // |
+ // |
+ // ^
+
+ if (_workingWindow.contains(pos)) {
+ 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();
+ 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();
+ cursorWasChanged = true;
+ } else {
+ _renderManager->setBackgroundVelocity(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();
+ 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();
+ cursorWasChanged = true;
+ } else {
+ _renderManager->setBackgroundVelocity(0);
+ }
+ }
+ } else {
+ _renderManager->setBackgroundVelocity(0);
+ }
+
+ if (!cursorWasChanged) {
+ _cursorManager->revertToIdle();
+ }
+}
+
+} // End of namespace ZVision
diff --git a/backends/graphics/opengl/glerrorcheck.h b/engines/zvision/core/menu.h
index 2d5491bdfd..affc69abd5 100644
--- a/backends/graphics/opengl/glerrorcheck.h
+++ b/engines/zvision/core/menu.h
@@ -11,7 +11,7 @@
* This program is distributed in the hope 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
@@ -20,16 +20,9 @@
*
*/
-#if !defined(DEBUG)
+#ifndef ZVISION_MENU_H
+#define ZVISION_MENU_H
-// If not in debug, do nothing
-#define CHECK_GL_ERROR() do {} while (false)
-
-#else
-
-// If in debug, check for an error after a GL call
-#define CHECK_GL_ERROR() checkGlError(__FILE__, __LINE__)
-
-void checkGlError(const char *file, int line);
+// TODO: Implement MenuHandler
#endif
diff --git a/engines/zvision/core/save_manager.cpp b/engines/zvision/core/save_manager.cpp
new file mode 100644
index 0000000000..b91f8eacad
--- /dev/null
+++ b/engines/zvision/core/save_manager.cpp
@@ -0,0 +1,206 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public 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/core/save_manager.h b/engines/zvision/core/save_manager.h
new file mode 100644
index 0000000000..b4770e68b2
--- /dev/null
+++ b/engines/zvision/core/save_manager.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.
+ *
+ */
+
+#ifndef ZVISION_SAVE_MANAGER_H
+#define ZVISION_SAVE_MANAGER_H
+
+#include "common/savefile.h"
+
+namespace Common {
+class String;
+}
+
+namespace Graphics {
+struct Surface;
+}
+
+namespace ZVision {
+
+class ZVision;
+
+struct SaveGameHeader {
+ byte version;
+ Common::String saveName;
+ Graphics::Surface *thumbnail;
+ int saveYear, saveMonth, saveDay;
+ int saveHour, saveMinutes;
+};
+
+class SaveManager {
+public:
+ SaveManager(ZVision *engine) : _engine(engine) {}
+
+private:
+ ZVision *_engine;
+ static const uint32 SAVEGAME_ID;
+
+ enum {
+ SAVE_VERSION = 1
+ };
+
+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.
+ */
+ void autoSave();
+ /**
+ * Copies the data from the last auto-save into a new save file. We
+ * can't use the current state data because the save menu *IS* a room.
+ * The file is named using ZVision::generateSaveFileName(slot)
+ *
+ * @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);
+ /**
+ * 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);
+
+private:
+ void writeSaveGameData(Common::OutSaveFile *file);
+ bool readSaveGameHeader(Common::InSaveFile *in, SaveGameHeader &header);
+};
+
+} // End of namespace ZVision
+
+#endif
diff --git a/engines/zvision/cursors/cursor.cpp b/engines/zvision/cursors/cursor.cpp
new file mode 100644
index 0000000000..be80f6585b
--- /dev/null
+++ b/engines/zvision/cursors/cursor.cpp
@@ -0,0 +1,94 @@
+/* ScummVM - Graphic Adventure Engine
+*
+* ScummVM is the legal property of its developers, whose names
+* are too numerous to list here. Please refer to the COPYRIGHT
+* file distributed with this source distribution.
+*
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License
+* as published by the Free Software Foundation; either version 2
+* of the License, or (at your option) any later version.
+
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+
+* You should have received a copy of the GNU General Public 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.h b/engines/zvision/cursors/cursor.h
new file mode 100644
index 0000000000..18ac28ce8b
--- /dev/null
+++ b/engines/zvision/cursors/cursor.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 ZVISION_CURSOR_H
+#define ZVISION_CURSOR_H
+
+#include "graphics/surface.h"
+
+
+namespace Common {
+class String;
+}
+
+namespace ZVision {
+
+/**
+ * Utility class to parse and hold cursor data
+ * Modeled off Graphics::Cursor
+ */
+class ZorkCursor {
+public:
+ ZorkCursor();
+ ZorkCursor(const Common::String &fileName);
+ ZorkCursor(const ZorkCursor &other);
+ ~ZorkCursor();
+
+private:
+ uint16 _width;
+ uint16 _height;
+ uint16 _hotspotX;
+ uint16 _hotspotY;
+ Graphics::Surface _surface;
+
+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(); }
+};
+
+} // End of namespace ZVision
+
+#endif
diff --git a/engines/zvision/cursors/cursor_manager.cpp b/engines/zvision/cursors/cursor_manager.cpp
new file mode 100644
index 0000000000..671f26ba2d
--- /dev/null
+++ b/engines/zvision/cursors/cursor_manager.cpp
@@ -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.
+*
+*/
+
+#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/cursors/cursor_manager.h b/engines/zvision/cursors/cursor_manager.h
new file mode 100644
index 0000000000..e982a40188
--- /dev/null
+++ b/engines/zvision/cursors/cursor_manager.h
@@ -0,0 +1,114 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef ZVISION_CURSOR_MANAGER_H
+#define ZVISION_CURSOR_MANAGER_H
+
+#include "zvision/cursors/cursor.h"
+
+#include "common/str.h"
+
+
+namespace Graphics {
+struct PixelFormat;
+}
+
+namespace ZVision {
+
+class ZVision;
+
+/**
+ * Class to manage cursor changes. The actual changes have to be done
+ * through CursorMan. Otherwise the cursor will disappear after GMM
+ * or debug console.
+ * TODO: Figure out a way to get rid of the extraneous data copying due to having to use CursorMan
+ */
+class CursorManager {
+public:
+ 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
+ };
+
+ ZVision *_engine;
+ const Graphics::PixelFormat *_pixelFormat;
+ ZorkCursor _idleCursor;
+ Common::String _currentCursor;
+ bool _cursorIsPushed;
+
+ static const char *_cursorNames[];
+ static const char *_zgiCursorFileNames[];
+ static const char *_zNemCursorFileNames[];
+
+public:
+ /** Creates the idle cursor and shows it */
+ 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
+ *
+ * @param cursorName The name of a cursor. This *HAS* to correspond to one of the entries in _cursorNames[]
+ */
+ void changeCursor(const Common::String &cursorName);
+ /**
+ * Parses a cursor name into a cursor file then creates and shows that cursor.
+ *
+ * @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)
+ */
+ void changeCursor(const Common::String &cursorName, bool pushed);
+ /**
+ * Change the cursor to a certain push state. If the cursor is already in the specified push state, nothing will happen.
+ *
+ * @param pushed Should the cursor be pushed (true) or not pushed (false) (Another way to say it: down or up)
+ */
+ 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();
+
+private:
+ /**
+ * Calls CursorMan.replaceCursor() using the data in cursor
+ *
+ * @param cursor The cursor to show
+ */
+ void changeCursor(const ZorkCursor &cursor);
+};
+
+} // End of namespace ZVision
+
+#endif
diff --git a/engines/zvision/detection.cpp b/engines/zvision/detection.cpp
new file mode 100644
index 0000000000..49664935e1
--- /dev/null
+++ b/engines/zvision/detection.cpp
@@ -0,0 +1,272 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public 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 "base/plugins.h"
+
+#include "zvision/zvision.h"
+#include "zvision/detection.h"
+
+#include "common/translation.h"
+#include "common/savefile.h"
+#include "common/str-array.h"
+#include "common/system.h"
+
+
+namespace ZVision {
+
+uint32 ZVision::getFeatures() const {
+ return _gameDescription->desc.flags;
+}
+
+Common::Language ZVision::getLanguage() const {
+ return _gameDescription->desc.language;
+}
+
+} // End of namespace ZVision
+
+
+static const PlainGameDescriptor zVisionGames[] = {
+ {"zvision", "ZVision Game"},
+ {"znemesis", "Zork Nemesis: The Forbidden Lands"},
+ {"zgi", "Zork: Grand Inquisitor"},
+ {0, 0}
+};
+
+
+namespace ZVision {
+
+static const ZVisionGameDescription gameDescriptions[] = {
+
+ {
+ // Zork Nemesis English version
+ {
+ "znemesis",
+ 0,
+ AD_ENTRY1s("CSCR.ZFS", "88226e51a205d2e50c67a5237f3bd5f2", 2397741),
+ Common::EN_ANY,
+ Common::kPlatformDOS,
+ ADGF_NO_FLAGS,
+ GUIO1(GUIO_NONE)
+ },
+ GID_NEMESIS
+ },
+
+ {
+ // Zork Grand Inquisitor English version
+ {
+ "zgi",
+ 0,
+ AD_ENTRY1s("SCRIPTS.ZFS", "81efd40ecc3d22531e211368b779f17f", 8336944),
+ Common::EN_ANY,
+ Common::kPlatformWindows,
+ ADGF_NO_FLAGS,
+ GUIO1(GUIO_NONE)
+ },
+ GID_GRANDINQUISITOR
+ },
+
+ {
+ AD_TABLE_END_MARKER,
+ GID_NONE
+ }
+};
+
+} // End of namespace ZVision
+
+static const char *directoryGlobs[] = {
+ "znemscr",
+ 0
+};
+
+static const ExtraGuiOption ZVisionExtraGuiOption = {
+ _s("Use original save/load screens"),
+ _s("Use the original save/load screens, instead of the ScummVM ones"),
+ "originalsaveload",
+ false
+};
+
+class ZVisionMetaEngine : public AdvancedMetaEngine {
+public:
+ ZVisionMetaEngine() : AdvancedMetaEngine(ZVision::gameDescriptions, sizeof(ZVision::ZVisionGameDescription), zVisionGames) {
+ _maxScanDepth = 2;
+ _directoryGlobs = directoryGlobs;
+ _singleid = "zvision";
+ }
+
+ virtual const char *getName() const {
+ return "ZVision";
+ }
+
+ virtual const char *getOriginalCopyright() const {
+ return "ZVision Activision (C) 1996";
+ }
+
+ 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;
+ SaveStateDescriptor querySaveMetaInfos(const char *target, int slot) const;
+};
+
+bool ZVisionMetaEngine::hasFeature(MetaEngineFeature f) const {
+ return false;
+ /*
+ (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 ZVisionMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const {
+ const ZVision::ZVisionGameDescription *gd = (const ZVision::ZVisionGameDescription *)desc;
+ if (gd) {
+ *engine = new ZVision::ZVision(syst, gd);
+ }
+ 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::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..)*/
+
+ 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;
+ }
+ }
+ }*/
+
+ return saveList;
+}
+
+int ZVisionMetaEngine::getMaximumSaveSlot() const {
+ return 999;
+}
+
+void ZVisionMetaEngine::removeSaveState(const char *target, int slot) const {
+ /*
+ Common::SaveFileManager *saveFileMan = g_system->getSavefileManager();
+ Common::String filename = ZVision::ZVision::getSavegameFilename(target, slot);
+
+ saveFileMan->removeSavefile(filename.c_str());
+
+ Common::StringArray filenames;
+ Common::String pattern = target;
+ pattern += ".???";
+ filenames = saveFileMan->listSavefiles(pattern.c_str());
+ 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);
+ }
+ }
+ */
+}
+
+SaveStateDescriptor ZVisionMetaEngine::querySaveMetaInfos(const char *target, int slot) const {
+ /*
+ Common::String filename = ZVision::ZVision::getSavegameFilename(target, slot);
+ Common::InSaveFile *in = g_system->getSavefileManager()->openForLoading(filename.c_str());
+
+ if (in) {
+ ZVision::ZVision::SaveHeader header;
+ ZVision::ZVision::kReadSaveHeaderError error;
+
+ error = ZVision::ZVision::readSaveHeader(in, true, header);
+ delete in;
+
+ if (error == ZVision::ZVision::kRSHENoError) {
+ SaveStateDescriptor desc(slot, header.description);
+
+ desc.setThumbnail(header.thumbnail);
+
+ if (header.version > 0) {
+ int day = (header.saveDate >> 24) & 0xFF;
+ int month = (header.saveDate >> 16) & 0xFF;
+ int year = header.saveDate & 0xFFFF;
+
+ desc.setSaveDate(year, month, day);
+
+ int hour = (header.saveTime >> 16) & 0xFF;
+ int minutes = (header.saveTime >> 8) & 0xFF;
+
+ desc.setSaveTime(hour, minutes);
+
+ desc.setPlayTime(header.playTime * 1000);
+ }
+
+ return desc;
+ }
+ }
+ */
+
+ return SaveStateDescriptor();
+}
+
+#if PLUGIN_ENABLED_DYNAMIC(ZVISION)
+ REGISTER_PLUGIN_DYNAMIC(ZVISION, PLUGIN_TYPE_ENGINE, ZVisionMetaEngine);
+#else
+ REGISTER_PLUGIN_STATIC(ZVISION, PLUGIN_TYPE_ENGINE, ZVisionMetaEngine);
+#endif
diff --git a/engines/zvision/detection.h b/engines/zvision/detection.h
new file mode 100644
index 0000000000..34417601e8
--- /dev/null
+++ b/engines/zvision/detection.h
@@ -0,0 +1,44 @@
+/* ScummVM - Graphic Adventure Engine
+*
+* ScummVM is the legal property of its developers, whose names
+* are too numerous to list here. Please refer to the COPYRIGHT
+* file distributed with this source distribution.
+*
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License
+* as published by the Free Software Foundation; either version 2
+* of the License, or (at your option) any later version.
+
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+*/
+
+#ifndef ZVISION_DETECTION_H
+#define ZVISION_DETECTION_H
+
+#include "engines/advancedDetector.h"
+
+
+namespace ZVision {
+
+enum ZVisionGameId {
+ GID_NONE = 0,
+ GID_NEMESIS = 1,
+ GID_GRANDINQUISITOR = 2
+};
+
+struct ZVisionGameDescription {
+ ADGameDescription desc;
+ ZVisionGameId gameId;
+};
+
+}
+
+#endif
diff --git a/engines/zvision/fonts/truetype_font.cpp b/engines/zvision/fonts/truetype_font.cpp
new file mode 100644
index 0000000000..f8910bfe06
--- /dev/null
+++ b/engines/zvision/fonts/truetype_font.cpp
@@ -0,0 +1,116 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public 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)
+ : _engine(engine),
+ _fontHeight(fontHeight),
+ _font(0),
+ _lineHeight(0),
+ _maxCharWidth(0),
+ _maxCharHeight(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/fonts/truetype_font.h b/engines/zvision/fonts/truetype_font.h
new file mode 100644
index 0000000000..33f016cffd
--- /dev/null
+++ b/engines/zvision/fonts/truetype_font.h
@@ -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.
+ *
+ */
+
+// This file is based on engines/wintermute/base/fonts/base_font_truetype.h/.cpp
+
+#ifndef ZVISION_TRUETYPE_FONT_H
+#define ZVISION_TRUETYPE_FONT_H
+
+#include "graphics/font.h"
+#include "graphics/pixelformat.h"
+
+
+namespace Graphics {
+struct Surface;
+}
+
+namespace ZVision {
+
+class ZVision;
+
+class TruetypeFont {
+public:
+ TruetypeFont(ZVision *engine, int32 fontHeight);
+ ~TruetypeFont();
+
+private:
+ ZVision *_engine;
+ Graphics::Font *_font;
+ int _lineHeight;
+
+ size_t _maxCharWidth;
+ size_t _maxCharHeight;
+
+public:
+ int32 _fontHeight;
+
+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);
+};
+
+} // End of namespace ZVision
+
+#endif
diff --git a/engines/zvision/graphics/render_manager.cpp b/engines/zvision/graphics/render_manager.cpp
new file mode 100644
index 0000000000..f19df88935
--- /dev/null
+++ b/engines/zvision/graphics/render_manager.cpp
@@ -0,0 +1,526 @@
+/* ScummVM - Graphic Adventure Engine
+*
+* ScummVM is the legal property of its developers, whose names
+* are too numerous to list here. Please refer to the COPYRIGHT
+* file distributed with this source distribution.
+*
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License
+* as published by the Free Software Foundation; either version 2
+* of the License, or (at your option) any later version.
+
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+
+* You should have received a copy of the GNU General Public 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/render_manager.h"
+
+#include "zvision/utility/lzss_read_stream.h"
+
+#include "common/file.h"
+#include "common/system.h"
+#include "common/stream.h"
+
+#include "engines/util.h"
+
+#include "graphics/decoders/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() {
+ _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);
+ }
+}
+
+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
+
+ // Render alpha entries
+ processAlphaEntries();
+
+ if (!_backBufferDirtyRect.isEmpty()) {
+ _system->copyRectToScreen(_backBuffer.getBasePtr(_backBufferDirtyRect.left, _backBufferDirtyRect.top), _backBuffer.pitch, _backBufferDirtyRect.left, _backBufferDirtyRect.top, _backBufferDirtyRect.width(), _backBufferDirtyRect.height());
+ _backBufferDirtyRect = Common::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();
+
+ 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;
+ }
+ }
+
+ 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));
+ }
+ }
+}
+
+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;
+ }
+}
+
+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;
+ }
+ }
+
+ // Clip subRect to working window bounds
+ Common::Rect subRect(subRectX, subRectY, subRectX + _workingWidth, subRectY + _workingHeight);
+
+ if (!wrap) {
+ // Clip to image bounds
+ subRect.clip(surface.w, surface.h);
+ }
+
+ // Check destRect for validity
+ if (!subRect.isValidRect() || subRect.isEmpty())
+ return;
+
+ copyRectToWorkingWindow((const uint16 *)surface.getBasePtr(subRect.left, subRect.top), destinationX, destinationY, surface.w, subRect.width(), subRect.height());
+}
+
+void RenderManager::renderImageToScreen(const Common::String &fileName, int16 destinationX, int16 destinationY, bool wrap) {
+ Graphics::Surface surface;
+ readImageToSurface(fileName, surface);
+
+ renderSubRectToScreen(surface, destinationX, destinationY, wrap);
+}
+
+void RenderManager::renderImageToScreen(Graphics::Surface &surface, int16 destinationX, int16 destinationY, bool wrap) {
+ renderSubRectToScreen(surface, destinationX, destinationY, wrap);
+}
+
+void RenderManager::readImageToSurface(const Common::String &fileName, Graphics::Surface &destination) {
+ Common::File file;
+
+ if (!file.open(fileName)) {
+ warning("Could not open file %s", fileName.c_str());
+ return;
+ }
+
+ // Read the magic number
+ // Some files are true TGA, while others are TGZ
+ uint32 fileType = file.readUint32BE();
+
+ uint32 imageWidth;
+ uint32 imageHeight;
+ Graphics::TGADecoder tga;
+ uint16 *buffer;
+ bool isTransposed = _renderTable.getRenderState() == RenderTable::PANORAMA;
+ // All ZVision images are in RGB 555
+ Graphics::PixelFormat pixelFormat555 = Graphics::PixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0);
+ destination.format = pixelFormat555;
+
+ bool isTGZ;
+
+ // Check for TGZ files
+ if (fileType == MKTAG('T', 'G', 'Z', '\0')) {
+ isTGZ = true;
+
+ // TGZ files have a header and then Bitmap data that is compressed with LZSS
+ uint32 decompressedSize = file.readSint32LE();
+ imageWidth = file.readSint32LE();
+ imageHeight = file.readSint32LE();
+
+ LzssReadStream lzssStream(&file);
+ buffer = (uint16 *)(new uint16[decompressedSize]);
+ lzssStream.read(buffer, decompressedSize);
+ } else {
+ isTGZ = false;
+
+ // Reset the cursor
+ file.seek(0);
+
+ // Decode
+ if (!tga.loadStream(file)) {
+ warning("Error while reading TGA image");
+ return;
+ }
+
+ Graphics::Surface tgaSurface = *(tga.getSurface());
+ imageWidth = tgaSurface.w;
+ imageHeight = tgaSurface.h;
+
+ buffer = (uint16 *)tgaSurface.getPixels();
+ }
+
+ // Flip the width and height if transposed
+ if (isTransposed) {
+ uint16 temp = imageHeight;
+ imageHeight = imageWidth;
+ imageWidth = temp;
+ }
+
+ // If the destination internal buffer is the same size as what we're copying into it,
+ // there is no need to free() and re-create
+ if (imageWidth != destination.w || imageHeight != destination.h) {
+ destination.create(imageWidth, imageHeight, pixelFormat555);
+ }
+
+ // If transposed, 'un-transpose' the data while copying it to the destination
+ // Otherwise, just do a simple copy
+ if (isTransposed) {
+ uint16 *dest = (uint16 *)destination.getPixels();
+
+ for (uint32 y = 0; y < imageHeight; ++y) {
+ uint32 columnIndex = y * imageWidth;
+
+ for (uint32 x = 0; x < imageWidth; ++x) {
+ dest[columnIndex + x] = buffer[x * imageHeight + y];
+ }
+ }
+ } else {
+ memcpy(destination.getPixels(), buffer, imageWidth * imageHeight * _pixelFormat.bytesPerPixel);
+ }
+
+ // Cleanup
+ if (isTGZ) {
+ delete[] buffer;
+ } else {
+ tga.destroy();
+ }
+
+ // Convert in place to RGB 565 from RGB 555
+ destination.convertToInPlace(_pixelFormat);
+}
+
+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);
+
+ for (int32 y = 0; y < height; ++y) {
+ for (int32 x = 0; x < width; ++x) {
+ workingWindowBufferPtr[destOffset + x] = buffer[sourceOffset + x];
+ }
+
+ destOffset += _workingWidth;
+ sourceOffset += imageWidth;
+ }
+
+ if (_workingWindowDirtyRect.isEmpty()) {
+ _workingWindowDirtyRect = Common::Rect(destX, destY, destX + width, destY + height);
+ } else {
+ _workingWindowDirtyRect.extend(Common::Rect(destX, destY, destX + width, destY + height));
+ }
+
+ // 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);
+}
+
+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;
+
+ uint32 sourceOffset = 0;
+ uint32 destOffset = 0;
+ uint16 *surfacePtr = (uint16 *)entry.data->getPixels();
+
+ for (int32 y = 0; y < height; ++y) {
+ for (int32 x = 0; x < width; ++x) {
+ surfacePtr[destOffset + x] = buffer[sourceOffset + x];
+ }
+
+ destOffset += width;
+ sourceOffset += imageWidth;
+ }
+
+ _alphaDataEntries[idNumber] = entry;
+}
+
+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;
+
+ // 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;
+
+ _alphaDataEntries[idNumber] = entry;
+
+ return Common::Rect(destX, destY, destX + entry.width, destY + entry.height);
+}
+
+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));
+
+ RenderTable::RenderState state = _renderTable.getRenderState();
+ if (state == RenderTable::PANORAMA || state == RenderTable::TILT) {
+ newPoint = _renderTable.convertWarpedCoordToFlatCoord(newPoint);
+ }
+
+ if (state == RenderTable::PANORAMA) {
+ newPoint -= (Common::Point(_screenCenterX, 0) - _backgroundOffset);
+ } else if (state == RenderTable::TILT) {
+ newPoint -= (Common::Point(0, _screenCenterY) - _backgroundOffset);
+ }
+
+ 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;
+
+ return newPoint;
+}
+
+const Common::Point RenderManager::imageSpaceToWorkingWindowSpace(const Common::Point &point) {
+ Common::Point newPoint(point);
+
+ RenderTable::RenderState state = _renderTable.getRenderState();
+ if (state == RenderTable::PANORAMA) {
+ newPoint += (Common::Point(_screenCenterX, 0) - _backgroundOffset);
+ } else if (state == RenderTable::TILT) {
+ newPoint += (Common::Point(0, _screenCenterY) - _backgroundOffset);
+ }
+
+ return newPoint;
+}
+
+bool RenderManager::clipRectToWorkingWindow(Common::Rect &rect) {
+ if (!_workingWindow.contains(rect)) {
+ return false;
+ }
+
+ // 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;
+}
+
+RenderTable *RenderManager::getRenderTable() {
+ return &_renderTable;
+}
+
+void RenderManager::setBackgroundImage(const Common::String &fileName) {
+ readImageToSurface(fileName, _currentBackground);
+
+ moveBackground(0);
+}
+
+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::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;
+ }
+ } else {
+ _backgroundInverseVelocity = 1000 / velocity;
+ }
+}
+
+void RenderManager::moveBackground(int offset) {
+ RenderTable::RenderState state = _renderTable.getRenderState();
+ if (state == RenderTable::TILT) {
+ _backgroundOffset += Common::Point(0, offset);
+
+ _backgroundOffset.y = CLIP<int16>(_backgroundOffset.y, _screenCenterY, (int16)_backgroundHeight - _screenCenterY);
+
+ renderImageToScreen(_currentBackground, 0, _screenCenterY - _backgroundOffset.y, true);
+ } else if (state == RenderTable::PANORAMA) {
+ _backgroundOffset += Common::Point(offset, 0);
+
+ if (_backgroundOffset.x <= -_backgroundWidth)
+ _backgroundOffset.x += _backgroundWidth;
+ else if (_backgroundOffset.x >= _backgroundWidth)
+ _backgroundOffset.x -= _backgroundWidth;
+
+ renderImageToScreen(_currentBackground, _screenCenterX - _backgroundOffset.x, 0, true);
+ } else {
+ renderImageToScreen(_currentBackground, 0, 0);
+ }
+}
+
+uint32 RenderManager::getCurrentBackgroundOffset() {
+ RenderTable::RenderState state = _renderTable.getRenderState();
+
+ if (state == RenderTable::PANORAMA) {
+ return _backgroundOffset.x;
+ } else if (state == RenderTable::TILT) {
+ return _backgroundOffset.y;
+ } else {
+ 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];
+ }
+ }
+
+ return tranposedSurface;
+}
+
+} // End of namespace ZVision
diff --git a/engines/zvision/graphics/render_manager.h b/engines/zvision/graphics/render_manager.h
new file mode 100644
index 0000000000..cb71308bc3
--- /dev/null
+++ b/engines/zvision/graphics/render_manager.h
@@ -0,0 +1,328 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef ZVISION_RENDER_MANAGER_H
+#define ZVISION_RENDER_MANAGER_H
+
+#include "zvision/graphics/render_table.h"
+#include "zvision/fonts/truetype_font.h"
+
+#include "common/rect.h"
+#include "common/hashmap.h"
+
+#include "graphics/surface.h"
+
+
+class OSystem;
+
+namespace Common {
+class String;
+class SeekableReadStream;
+}
+
+namespace Video {
+class VideoDecoder;
+}
+
+namespace ZVision {
+
+class RenderManager {
+public:
+ RenderManager(OSystem *system, uint32 windowWidth, uint32 windowHeight, const Common::Rect workingWindow, const Graphics::PixelFormat pixelFormat);
+ ~RenderManager();
+
+private:
+ struct AlphaDataEntry {
+ Graphics::Surface *data;
+ uint16 alphaColor;
+ uint16 destX;
+ uint16 destY;
+ uint16 width;
+ uint16 height;
+ };
+
+ typedef Common::HashMap<uint32, AlphaDataEntry> AlphaEntryMap;
+
+private:
+ 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;
+
+ Graphics::Surface _currentBackground;
+ /** The (x1,y1) coordinates of the subRectangle of the background that is currently displayed on the screen */
+ Common::Point _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;
+
+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);
+
+ /**
+ * Renders the current state of the backbuffer to the screen
+ */
+ void renderBackbufferToScreen();
+
+ /**
+ * 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); }
+
+ /**
+ * 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);
+
+ /**
+ * 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);
+
+ /**
+ * 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)
+ */
+ void clearWorkingWindowTo555Color(uint16 color);
+
+ /**
+ * 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!
+ *
+ * @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);
+
+ /**
+ * 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!
+ *
+ * @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!
+ */
+ void renderImageToScreen(Graphics::Surface &surface, int16 destinationX, int16 destinationY, bool wrap = false);
+
+ /**
+ * Sets the current background image to be used by the RenderManager and immediately
+ * blits it to the screen. (It won't show up until the end of the frame)
+ *
+ * @param fileName The name of the image file
+ */
+ void setBackgroundImage(const Common::String &fileName);
+
+ /**
+ * Set the background position (_backgroundOffset). If the current RenderState is PANORAMA, the offset
+ * will be in the horizontal direction. If the current RenderState is TILT, the offset will be in the
+ * vertical direction.
+ *
+ * This method will not render anything on the screen. So if nothing else is called that renders the
+ * background, the change won't be seen until next frame.
+ *
+ * @param offset The amount to offset the background
+ */
+ 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);
+
+ RenderTable *getRenderTable();
+ uint32 getCurrentBackgroundOffset();
+ const Graphics::Surface *getBackBuffer() { return &_backBuffer; }
+
+ /**
+ * Creates a copy of surface and transposes the data.
+ *
+ * Note: The user is responsible for calling free() on the returned surface
+ * and then deleting it
+ *
+ * @param surface The data to be transposed
+ * @return A copy of the surface with the data transposed
+ */
+ 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);
+
+ /**
+ * 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
+ * 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 fileName The name of a .tga file
+ * @param destination A reference to the Surface to store the pixel data in
+ */
+ 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.
+ *
+ * @param offset The amount to move the background
+ */
+ void moveBackground(int offset);
+};
+
+} // End of namespace ZVision
+
+#endif
diff --git a/engines/zvision/graphics/render_table.cpp b/engines/zvision/graphics/render_table.cpp
new file mode 100644
index 0000000000..ffd42e6a60
--- /dev/null
+++ b/engines/zvision/graphics/render_table.cpp
@@ -0,0 +1,240 @@
+/* ScummVM - Graphic Adventure Engine
+*
+* ScummVM is the legal property of its developers, whose names
+* are too numerous to list here. Please refer to the COPYRIGHT
+* file distributed with this source distribution.
+*
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License
+* as published by the Free Software Foundation; either version 2
+* of the License, or (at your option) any later version.
+
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+
+* You should have received a copy of the GNU General Public 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/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) {
+ assert(numRows != 0 && numColumns != 0);
+
+ _internalBuffer = new Common::Point[numRows * numColumns];
+}
+
+RenderTable::~RenderTable() {
+ delete[] _internalBuffer;
+}
+
+void RenderTable::setRenderState(RenderState newState) {
+ _renderState = newState;
+
+ switch (newState) {
+ case PANORAMA:
+ _panoramaOptions.fieldOfView = 27.0f;
+ _panoramaOptions.linearScale = 0.55f;
+ _panoramaOptions.reverse = false;
+ break;
+ case TILT:
+ _tiltOptions.fieldOfView = 27.0f;
+ _tiltOptions.linearScale = 0.55f;
+ _tiltOptions.reverse = false;
+ break;
+ case FLAT:
+ // Intentionally left empty
+ break;
+ }
+}
+
+const Common::Point RenderTable::convertWarpedCoordToFlatCoord(const Common::Point &point) {
+ // If we're outside the range of the RenderTable, no warping is happening. Return the maximum image coords
+ if (point.x >= (int16)_numColumns || point.y >= (int16)_numRows || point.x < 0 || point.y < 0) {
+ int16 x = CLIP<int16>(point.x, 0, (int16)_numColumns);
+ int16 y = CLIP<int16>(point.y, 0, (int16)_numRows);
+ return Common::Point(x, y);
+ }
+
+ uint32 index = point.y * _numColumns + point.x;
+
+ Common::Point newPoint(point);
+ newPoint.x += _internalBuffer[index].x;
+ newPoint.y += _internalBuffer[index].y;
+
+ return newPoint;
+}
+
+uint16 mixTwoRGB(uint16 colorOne, uint16 colorTwo, float percentColorOne) {
+ assert(percentColorOne < 1.0f);
+
+ float rOne = float((colorOne & Graphics::ColorMasks<555>::kRedMask) >> Graphics::ColorMasks<555>::kRedShift);
+ float rTwo = float((colorTwo & Graphics::ColorMasks<555>::kRedMask) >> Graphics::ColorMasks<555>::kRedShift);
+ float gOne = float((colorOne & Graphics::ColorMasks<555>::kGreenMask) >> Graphics::ColorMasks<555>::kGreenShift);
+ float gTwo = float((colorTwo & Graphics::ColorMasks<555>::kGreenMask) >> Graphics::ColorMasks<555>::kGreenShift);
+ float bOne = float((colorOne & Graphics::ColorMasks<555>::kBlueMask) >> Graphics::ColorMasks<555>::kBlueShift);
+ float bTwo = float((colorTwo & Graphics::ColorMasks<555>::kBlueMask) >> Graphics::ColorMasks<555>::kBlueShift);
+
+ float rFinal = rOne * percentColorOne + rTwo * (1.0f - percentColorOne);
+ float gFinal = gOne * percentColorOne + gTwo * (1.0f - percentColorOne);
+ float bFinal = bOne * percentColorOne + bTwo * (1.0f - percentColorOne);
+
+ uint16 returnColor = (byte(rFinal + 0.5f) << Graphics::ColorMasks<555>::kRedShift) |
+ (byte(gFinal + 0.5f) << Graphics::ColorMasks<555>::kGreenShift) |
+ (byte(bFinal + 0.5f) << Graphics::ColorMasks<555>::kBlueShift);
+
+ return returnColor;
+}
+
+void RenderTable::mutateImage(uint16 *sourceBuffer, uint16* destBuffer, uint32 destWidth, const Common::Rect &subRect) {
+ uint32 destOffset = 0;
+
+ for (int16 y = subRect.top; y < subRect.bottom; ++y) {
+ uint32 sourceOffset = y * _numColumns;
+
+ for (int16 x = subRect.left; x < subRect.right; ++x) {
+ uint32 normalizedX = x - subRect.left;
+ 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 + normalizedX] = sourceBuffer[sourceYIndex * _numColumns + sourceXIndex];
+ }
+
+ destOffset += destWidth;
+ }
+}
+
+void RenderTable::generateRenderTable() {
+ switch (_renderState) {
+ case ZVision::RenderTable::PANORAMA:
+ generatePanoramaLookupTable();
+ break;
+ case ZVision::RenderTable::TILT:
+ generateTiltLookupTable();
+ break;
+ case ZVision::RenderTable::FLAT:
+ // Intentionally left empty
+ break;
+ }
+}
+
+void RenderTable::generatePanoramaLookupTable() {
+ memset(_internalBuffer, 0, _numRows * _numColumns * sizeof(uint16));
+
+ float halfWidth = (float)_numColumns / 2.0f;
+ float halfHeight = (float)_numRows / 2.0f;
+
+ float fovInRadians = (_panoramaOptions.fieldOfView * M_PI / 180.0f);
+ float cylinderRadius = halfHeight / tan(fovInRadians);
+
+ for (uint x = 0; x < _numColumns; ++x) {
+ // Add an offset of 0.01 to overcome zero tan/atan issue (vertical line on half of screen)
+ // Alpha represents the horizontal angle between the viewer at the center of a cylinder and x
+ float alpha = atan(((float)x - halfWidth + 0.01f) / cylinderRadius);
+
+ // To get x in cylinder coordinates, we just need to calculate the arc length
+ // We also scale it by _panoramaOptions.linearScale
+ int32 xInCylinderCoords = int32(floor((cylinderRadius * _panoramaOptions.linearScale * alpha) + halfWidth));
+
+ float cosAlpha = cos(alpha);
+
+ for (uint y = 0; y < _numRows; ++y) {
+ // To calculate y in cylinder coordinates, we can do similar triangles comparison,
+ // comparing the triangle from the center to the screen and from the center to the edge of the cylinder
+ int32 yInCylinderCoords = int32(floor(halfHeight + ((float)y - halfHeight) * cosAlpha));
+
+ uint32 index = y * _numColumns + x;
+
+ // Only store the (x,y) offsets instead of the absolute positions
+ _internalBuffer[index].x = xInCylinderCoords - x;
+ _internalBuffer[index].y = yInCylinderCoords - y;
+ }
+ }
+}
+
+void RenderTable::generateTiltLookupTable() {
+ float halfWidth = (float)_numColumns / 2.0f;
+ float halfHeight = (float)_numRows / 2.0f;
+
+ float fovInRadians = (_tiltOptions.fieldOfView * M_PI / 180.0f);
+ float cylinderRadius = halfWidth / tan(fovInRadians);
+
+ for (uint y = 0; y < _numRows; ++y) {
+
+ // Add an offset of 0.01 to overcome zero tan/atan issue (horizontal line on half of screen)
+ // Alpha represents the vertical angle between the viewer at the center of a cylinder and y
+ float alpha = atan(((float)y - halfHeight + 0.01f) / cylinderRadius);
+
+ // To get y in cylinder coordinates, we just need to calculate the arc length
+ // We also scale it by _tiltOptions.linearScale
+ int32 yInCylinderCoords = int32(floor((cylinderRadius * _tiltOptions.linearScale * alpha) + halfHeight));
+
+ float cosAlpha = cos(alpha);
+ uint32 columnIndex = y * _numColumns;
+
+ for (uint x = 0; x < _numColumns; ++x) {
+ // To calculate x in cylinder coordinates, we can do similar triangles comparison,
+ // comparing the triangle from the center to the screen and from the center to the edge of the cylinder
+ int32 xInCylinderCoords = int32(floor(halfWidth + ((float)x - halfWidth) * cosAlpha));
+
+ uint32 index = columnIndex + x;
+
+ // Only store the (x,y) offsets instead of the absolute positions
+ _internalBuffer[index].x = xInCylinderCoords - x;
+ _internalBuffer[index].y = yInCylinderCoords - y;
+ }
+ }
+}
+
+void RenderTable::setPanoramaFoV(float fov) {
+ assert(fov > 0.0f);
+
+ _panoramaOptions.fieldOfView = fov;
+}
+
+void RenderTable::setPanoramaScale(float scale) {
+ assert(scale > 0.0f);
+
+ _panoramaOptions.linearScale = scale;
+}
+
+void RenderTable::setPanoramaReverse(bool reverse) {
+ _panoramaOptions.reverse = reverse;
+}
+
+void RenderTable::setTiltFoV(float fov) {
+ assert(fov > 0.0f);
+
+ _tiltOptions.fieldOfView = fov;
+}
+
+void RenderTable::setTiltScale(float scale) {
+ assert(scale > 0.0f);
+
+ _tiltOptions.linearScale = scale;
+}
+
+void RenderTable::setTiltReverse(bool reverse) {
+ _tiltOptions.reverse = reverse;
+}
+
+} // End of namespace ZVision
diff --git a/engines/zvision/graphics/render_table.h b/engines/zvision/graphics/render_table.h
new file mode 100644
index 0000000000..898091193a
--- /dev/null
+++ b/engines/zvision/graphics/render_table.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 ZVISION_RENDER_TABLE_H
+#define ZVISION_RENDER_TABLE_H
+
+#include "common/rect.h"
+
+
+namespace ZVision {
+
+class RenderTable {
+public:
+ RenderTable(uint numRows, uint numColumns);
+ ~RenderTable();
+
+public:
+ enum RenderState {
+ PANORAMA,
+ TILT,
+ FLAT
+ };
+
+private:
+ uint _numColumns, _numRows;
+ Common::Point *_internalBuffer;
+ RenderState _renderState;
+
+ struct {
+ float fieldOfView;
+ float linearScale;
+ bool reverse;
+ } _panoramaOptions;
+
+ // TODO: See if tilt and panorama need to have separate options
+ struct {
+ float fieldOfView;
+ float linearScale;
+ bool reverse;
+ } _tiltOptions;
+
+public:
+ 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 generateRenderTable();
+
+ void setPanoramaFoV(float fov);
+ void setPanoramaScale(float scale);
+ void setPanoramaReverse(bool reverse);
+
+ void setTiltFoV(float fov);
+ void setTiltScale(float scale);
+ void setTiltReverse(bool reverse);
+
+private:
+ void generatePanoramaLookupTable();
+ void generateTiltLookupTable();
+};
+
+} // End of namespace ZVision
+
+#endif
diff --git a/engines/zvision/inventory/inventory_manager.h b/engines/zvision/inventory/inventory_manager.h
new file mode 100644
index 0000000000..ae6d116b18
--- /dev/null
+++ b/engines/zvision/inventory/inventory_manager.h
@@ -0,0 +1,28 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public 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_INVENTORY_MANAGER_H
+#define ZVISION_INVENTORY_MANAGER_H
+
+// TODO: Implement InventoryManager
+
+#endif
diff --git a/engines/zvision/module.mk b/engines/zvision/module.mk
new file mode 100644
index 0000000000..4cf9c989cd
--- /dev/null
+++ b/engines/zvision/module.mk
@@ -0,0 +1,43 @@
+MODULE := engines/zvision
+
+MODULE_OBJS := \
+ animation/rlf_animation.o \
+ archives/zfs_archive.o \
+ core/console.o \
+ core/events.o \
+ core/save_manager.o \
+ cursors/cursor.o \
+ cursors/cursor_manager.o \
+ detection.o \
+ fonts/truetype_font.o \
+ graphics/render_manager.o \
+ graphics/render_table.o \
+ scripting/actions.o \
+ scripting/control.o \
+ scripting/controls/animation_control.o \
+ scripting/controls/input_control.o \
+ scripting/controls/lever_control.o \
+ scripting/controls/push_toggle_control.o \
+ scripting/controls/timer_node.o \
+ scripting/scr_file_handling.o \
+ scripting/script_manager.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 \
+ video/video.o \
+ video/zork_avi_decoder.o \
+ zvision.o
+
+MODULE_DIRS += \
+ engines/zvision
+
+# This module can be built as a plugin
+ifeq ($(ENABLE_ZVISION), DYNAMIC_PLUGIN)
+PLUGIN := 1
+endif
+
+# Include common rules
+include $(srcdir)/rules.mk
diff --git a/engines/zvision/scripting/actions.cpp b/engines/zvision/scripting/actions.cpp
new file mode 100644
index 0000000000..878fa752d5
--- /dev/null
+++ b/engines/zvision/scripting/actions.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 "common/scummsys.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"
+
+
+namespace ZVision {
+
+//////////////////////////////////////////////////////////////////////////////
+// ActionAdd
+//////////////////////////////////////////////////////////////////////////////
+
+ActionAdd::ActionAdd(const Common::String &line) {
+ sscanf(line.c_str(), "%*[^(](%u,%u)", &_key, &_value);
+}
+
+bool ActionAdd::execute(ZVision *engine) {
+ engine->getScriptManager()->addToStateValue(_key, _value);
+ return true;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// ActionAssign
+//////////////////////////////////////////////////////////////////////////////
+
+ActionAssign::ActionAssign(const Common::String &line) {
+ sscanf(line.c_str(), "%*[^(](%u, %u)", &_key, &_value);
+}
+
+bool ActionAssign::execute(ZVision *engine) {
+ engine->getScriptManager()->setStateValue(_key, _value);
+ return true;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// ActionAttenuate
+//////////////////////////////////////////////////////////////////////////////
+
+ActionAttenuate::ActionAttenuate(const Common::String &line) {
+ sscanf(line.c_str(), "%*[^(](%u, %d)", &_key, &_attenuation);
+}
+
+bool ActionAttenuate::execute(ZVision *engine) {
+ // TODO: Implement
+ return true;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// ActionChangeLocation
+//////////////////////////////////////////////////////////////////////////////
+
+ActionChangeLocation::ActionChangeLocation(const Common::String &line) {
+ sscanf(line.c_str(), "%*[^(](%c,%c,%c%c,%u)", &_world, &_room, &_node, &_view, &_offset);
+}
+
+bool ActionChangeLocation::execute(ZVision *engine) {
+ // 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);
+ // Tell the puzzle system to stop checking any more puzzles
+ return false;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// ActionCrossfade
+//////////////////////////////////////////////////////////////////////////////
+
+ActionCrossfade::ActionCrossfade(const Common::String &line) {
+ sscanf(line.c_str(),
+ "%*[^(](%u %u %u %u %u %u %u)",
+ &_keyOne, &_keyTwo, &_oneStartVolume, &_twoStartVolume, &_oneEndVolume, &_twoEndVolume, &_timeInMillis);
+}
+
+bool ActionCrossfade::execute(ZVision *engine) {
+ // TODO: Implement
+ return true;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// ActionDisableControl
+//////////////////////////////////////////////////////////////////////////////
+
+ActionDisableControl::ActionDisableControl(const Common::String &line) {
+ sscanf(line.c_str(), "%*[^(](%u)", &_key);
+}
+
+bool ActionDisableControl::execute(ZVision *engine) {
+ debug("Disabling control %u", _key);
+
+ ScriptManager *scriptManager = engine->getScriptManager();
+ scriptManager->setStateFlags(_key, scriptManager->getStateFlags(_key) | ScriptManager::DISABLED);
+
+ return true;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// ActionEnableControl
+//////////////////////////////////////////////////////////////////////////////
+
+ActionEnableControl::ActionEnableControl(const Common::String &line) {
+ sscanf(line.c_str(), "%*[^(](%u)", &_key);
+}
+
+bool ActionEnableControl::execute(ZVision *engine) {
+ debug("Enabling control %u", _key);
+
+ ScriptManager *scriptManager = engine->getScriptManager();
+ scriptManager->setStateFlags(_key, scriptManager->getStateFlags(_key) & ~ScriptManager::DISABLED);
+
+ return true;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// ActionMusic
+//////////////////////////////////////////////////////////////////////////////
+
+ActionMusic::ActionMusic(const Common::String &line) : _volume(255) {
+ uint type;
+ char fileNameBuffer[25];
+ uint loop;
+ uint volume = 255;
+
+ sscanf(line.c_str(), "%*[^:]:%*[^:]:%u(%u %25s %u %u)", &_key, &type, fileNameBuffer, &loop, &volume);
+
+ // type 4 are midi sound effect files
+ if (type == 4) {
+ _soundType = Audio::Mixer::kSFXSoundType;
+ _fileName = Common::String::format("midi/%s/%u.wav", fileNameBuffer, loop);
+ _loop = false;
+ } 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;
+ _fileName = Common::String(fileNameBuffer);
+ _loop = loop == 1 ? true : false;
+ }
+
+ // Volume is optional. If it doesn't appear, assume full volume
+ if (volume != 255) {
+ // Volume in the script files is mapped to [0, 100], but the ScummVM mixer uses [0, 255]
+ _volume = volume * 255 / 100;
+ }
+}
+
+bool ActionMusic::execute(ZVision *engine) {
+ Audio::RewindableAudioStream *audioStream;
+
+ 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);
+ }
+
+ if (_loop) {
+ Audio::LoopingAudioStream *loopingAudioStream = new Audio::LoopingAudioStream(audioStream, 0, DisposeAfterUse::YES);
+ engine->_mixer->playStream(_soundType, 0, loopingAudioStream, -1, _volume);
+ } else {
+ engine->_mixer->playStream(_soundType, 0, audioStream, -1, _volume);
+ }
+
+ return true;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// ActionPreloadAnimation
+//////////////////////////////////////////////////////////////////////////////
+
+ActionPreloadAnimation::ActionPreloadAnimation(const Common::String &line) {
+ 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)", &_key, fileName, &_mask, &_framerate);
+
+ _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
+
+ // 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);
+
+ return true;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// ActionPlayAnimation
+//////////////////////////////////////////////////////////////////////////////
+
+ActionPlayAnimation::ActionPlayAnimation(const Common::String &line) {
+ 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);
+
+ _fileName = Common::String(fileName);
+}
+
+bool ActionPlayAnimation::execute(ZVision *engine) {
+ // TODO: Implement
+ return true;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// ActionPlayPreloadAnimation
+//////////////////////////////////////////////////////////////////////////////
+
+ActionPlayPreloadAnimation::ActionPlayPreloadAnimation(const Common::String &line) {
+ sscanf(line.c_str(),
+ "%*[^:]:%*[^:]:%u(%u %u %u %u %u %u %u %u)",
+ &_animationKey, &_controlKey, &_x1, &_y1, &_x2, &_y2, &_startFrame, &_endFrame, &_loopCount);
+}
+
+bool ActionPlayPreloadAnimation::execute(ZVision *engine) {
+ // Find the control
+ AnimationControl *control = (AnimationControl *)engine->getScriptManager()->getControl(_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();
+
+ return true;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// ActionQuit
+//////////////////////////////////////////////////////////////////////////////
+
+bool ActionQuit::execute(ZVision *engine) {
+ engine->quitGame();
+
+ return true;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// ActionRandom
+//////////////////////////////////////////////////////////////////////////////
+
+ActionRandom::ActionRandom(const Common::String &line) {
+ sscanf(line.c_str(), "%*[^:]:%*[^:]:%u, %u)", &_key, &_max);
+}
+
+bool ActionRandom::execute(ZVision *engine) {
+ uint randNumber = engine->getRandomSource()->getRandomNumber(_max);
+ engine->getScriptManager()->setStateValue(_key, randNumber);
+ return true;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// ActionSetPartialScreen
+//////////////////////////////////////////////////////////////////////////////
+
+ActionSetPartialScreen::ActionSetPartialScreen(const Common::String &line) {
+ char fileName[25];
+ uint color;
+
+ sscanf(line.c_str(), "%*[^(](%u %u %25s %*u %u)", &_x, &_y, fileName, &color);
+
+ _fileName = Common::String(fileName);
+
+ if (color > 0xFFFF) {
+ 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);
+ }
+ renderManager->renderImageToScreen(_fileName, _x, _y);
+
+ return true;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// ActionSetScreen
+//////////////////////////////////////////////////////////////////////////////
+
+ActionSetScreen::ActionSetScreen(const Common::String &line) {
+ char fileName[25];
+ sscanf(line.c_str(), "%*[^(](%25[^)])", fileName);
+
+ _fileName = Common::String(fileName);
+}
+
+bool ActionSetScreen::execute(ZVision *engine) {
+ engine->getRenderManager()->setBackgroundImage(_fileName);
+
+ return true;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// ActionStreamVideo
+//////////////////////////////////////////////////////////////////////////////
+
+ActionStreamVideo::ActionStreamVideo(const Common::String &line) {
+ char fileName[25];
+ uint skippable;
+
+ sscanf(line.c_str(), "%*[^(](%25s %u %u %u %u %u %u)", fileName, &_x1, &_y1, &_x2, &_y2, &_flags, &skippable);
+
+ _fileName = Common::String(fileName);
+ _skippable = (skippable == 0) ? false : true;
+}
+
+bool ActionStreamVideo::execute(ZVision *engine) {
+ ZorkAVIDecoder decoder;
+ if (!decoder.loadFile(_fileName)) {
+ return true;
+ }
+
+ Common::Rect destRect;
+ if ((_flags & DIFFERENT_DIMENSIONS) == DIFFERENT_DIMENSIONS) {
+ destRect = Common::Rect(_x1, _y1, _x2, _y2);
+ }
+
+ engine->playVideo(decoder, destRect, _skippable);
+ return true;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// ActionTimer
+//////////////////////////////////////////////////////////////////////////////
+
+ActionTimer::ActionTimer(const Common::String &line) {
+ sscanf(line.c_str(), "%*[^:]:%*[^:]:%u(%u)", &_key, &_time);
+}
+
+bool ActionTimer::execute(ZVision *engine) {
+ engine->getScriptManager()->addControl(new TimerNode(engine, _key, _time));
+ return true;
+}
+
+} // End of namespace ZVision
diff --git a/engines/zvision/scripting/actions.h b/engines/zvision/scripting/actions.h
new file mode 100644
index 0000000000..afa3e3a2ac
--- /dev/null
+++ b/engines/zvision/scripting/actions.h
@@ -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.
+ *
+ */
+
+#ifndef ZVISION_ACTIONS_H
+#define ZVISION_ACTIONS_H
+
+#include "common/str.h"
+
+#include "audio/mixer.h"
+
+
+namespace ZVision {
+
+// Forward declaration of ZVision. This file is included before ZVision is declared
+class ZVision;
+
+/**
+ * The base class that represents any action that a Puzzle can take.
+ * This class is purely virtual.
+ */
+class ResultAction {
+public:
+ virtual ~ResultAction() {}
+ /**
+ * This is called by the script system whenever a Puzzle's criteria are found to be true.
+ * It should execute any necessary actions and return a value indicating whether the script
+ * system should continue to test puzzles. In 99% of cases this will be 'true'.
+ *
+ * @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,
+
+class ActionAdd : public ResultAction {
+public:
+ ActionAdd(const Common::String &line);
+ bool execute(ZVision *engine);
+
+private:
+ uint32 _key;
+ uint _value;
+};
+
+class ActionAssign : public ResultAction {
+public:
+ ActionAssign(const Common::String &line);
+ bool execute(ZVision *engine);
+
+private:
+ uint32 _key;
+ uint _value;
+};
+
+class ActionAttenuate : public ResultAction {
+public:
+ ActionAttenuate(const Common::String &line);
+ bool execute(ZVision *engine);
+
+private:
+ uint32 _key;
+ int _attenuation;
+};
+
+class ActionChangeLocation : public ResultAction {
+public:
+ ActionChangeLocation(const Common::String &line);
+ bool execute(ZVision *engine);
+
+private:
+ char _world;
+ char _room;
+ char _node;
+ char _view;
+ uint32 _offset;
+};
+
+class ActionCrossfade : public ResultAction {
+public:
+ ActionCrossfade(const Common::String &line);
+ bool execute(ZVision *engine);
+
+private:
+ uint32 _keyOne;
+ uint32 _keyTwo;
+ uint _oneStartVolume;
+ uint _twoStartVolume;
+ uint _oneEndVolume;
+ uint _twoEndVolume;
+ uint _timeInMillis;
+};
+
+class ActionDebug : public ResultAction {
+public:
+ ActionDebug(const Common::String &line);
+ bool execute(ZVision *engine);
+
+private:
+};
+
+class ActionDelayRender : public ResultAction {
+public:
+ ActionDelayRender(const Common::String &line);
+ bool execute(ZVision *engine);
+
+private:
+ // TODO: Check if this should actually be frames or if it should be milliseconds/seconds
+ uint32 framesToDelay;
+};
+
+class ActionDisableControl : public ResultAction {
+public:
+ ActionDisableControl(const Common::String &line);
+ bool execute(ZVision *engine);
+
+private:
+ uint32 _key;
+};
+
+class ActionDisableVenus : public ResultAction {
+public:
+ ActionDisableVenus(const Common::String &line);
+ bool execute(ZVision *engine);
+
+private:
+};
+
+class ActionDisplayMessage : public ResultAction {
+public:
+ ActionDisplayMessage(const Common::String &line);
+ bool execute(ZVision *engine);
+
+private:
+};
+
+class ActionDissolve : public ResultAction {
+public:
+ ActionDissolve();
+ bool execute(ZVision *engine);
+};
+
+class ActionDistort : public ResultAction {
+public:
+ ActionDistort(const Common::String &line);
+ bool execute(ZVision *engine);
+
+private:
+};
+
+class ActionEnableControl : public ResultAction {
+public:
+ ActionEnableControl(const Common::String &line);
+ bool execute(ZVision *engine);
+
+private:
+ uint32 _key;
+};
+
+class ActionMusic : public ResultAction {
+public:
+ ActionMusic(const Common::String &line);
+ bool execute(ZVision *engine);
+
+private:
+ uint32 _key;
+ Audio::Mixer::SoundType _soundType;
+ Common::String _fileName;
+ bool _loop;
+ byte _volume;
+};
+
+class ActionPlayAnimation : public ResultAction {
+public:
+ ActionPlayAnimation(const Common::String &line);
+ bool execute(ZVision *engine);
+
+private:
+ uint32 _key;
+ Common::String _fileName;
+ uint32 _x;
+ uint32 _y;
+ uint32 _width;
+ uint32 _height;
+ uint32 _start;
+ uint32 _end;
+ uint _mask;
+ uint _framerate;
+ uint _loopCount;
+};
+
+class ActionPlayPreloadAnimation : public ResultAction {
+public:
+ ActionPlayPreloadAnimation(const Common::String &line);
+ bool execute(ZVision *engine);
+
+private:
+ uint32 _animationKey;
+ uint32 _controlKey;
+ uint32 _x1;
+ uint32 _y1;
+ uint32 _x2;
+ uint32 _y2;
+ uint _startFrame;
+ uint _endFrame;
+ uint _loopCount;
+};
+
+class ActionPreloadAnimation : public ResultAction {
+public:
+ ActionPreloadAnimation(const Common::String &line);
+ bool execute(ZVision *engine);
+
+private:
+ uint32 _key;
+ Common::String _fileName;
+ uint _mask;
+ uint _framerate;
+};
+
+class ActionQuit : public ResultAction {
+public:
+ ActionQuit() {}
+ bool execute(ZVision *engine);
+};
+
+// TODO: See if this exists in ZGI. It doesn't in ZNem
+class ActionUnloadAnimation : public ResultAction {
+public:
+ ActionUnloadAnimation(const Common::String &line);
+ bool execute(ZVision *engine);
+};
+
+class ActionRandom : public ResultAction {
+public:
+ ActionRandom(const Common::String &line);
+ bool execute(ZVision *engine);
+
+private:
+ uint32 _key;
+ uint _max;
+};
+
+class ActionSetPartialScreen : public ResultAction {
+public:
+ ActionSetPartialScreen(const Common::String &line);
+ bool execute(ZVision *engine);
+
+private:
+ uint _x;
+ uint _y;
+ Common::String _fileName;
+ uint16 _backgroundColor;
+};
+
+class ActionSetScreen : public ResultAction {
+public:
+ ActionSetScreen(const Common::String &line);
+ bool execute(ZVision *engine);
+
+private:
+ Common::String _fileName;
+};
+
+class ActionStreamVideo : public ResultAction {
+public:
+ ActionStreamVideo(const Common::String &line);
+ bool execute(ZVision *engine);
+
+private:
+ enum {
+ DIFFERENT_DIMENSIONS = 0x1 // 0x1 flags that the destRect dimensions are different from the original video dimensions
+ };
+
+ Common::String _fileName;
+ uint _x1;
+ uint _y1;
+ uint _x2;
+ uint _y2;
+ uint _flags;
+ bool _skippable;
+};
+
+class ActionTimer : public ResultAction {
+public:
+ ActionTimer(const Common::String &line);
+ bool execute(ZVision *engine);
+
+private:
+ uint32 _key;
+ uint _time;
+};
+
+} // End of namespace ZVision
+
+#endif
diff --git a/engines/zvision/scripting/control.cpp b/engines/zvision/scripting/control.cpp
new file mode 100644
index 0000000000..35c4ea1441
--- /dev/null
+++ b/engines/zvision/scripting/control.cpp
@@ -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.
+ *
+ */
+
+#include "common/scummsys.h"
+
+#include "zvision/scripting/control.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);
+}
+
+void Control::parsePanoramaControl(ZVision *engine, Common::SeekableReadStream &stream) {
+ RenderTable *renderTable = engine->getRenderManager()->getRenderTable();
+ renderTable->setRenderState(RenderTable::PANORAMA);
+
+ // Loop until we find the closing brace
+ Common::String line = stream.readLine();
+ trimCommentsAndWhiteSpace(&line);
+
+ while (!stream.eos() && !line.contains('}')) {
+ if (line.matchString("angle*", true)) {
+ float fov;
+ sscanf(line.c_str(), "angle(%f)", &fov);
+ renderTable->setPanoramaFoV(fov);
+ } else if (line.matchString("linscale*", true)) {
+ float scale;
+ sscanf(line.c_str(), "linscale(%f)", &scale);
+ renderTable->setPanoramaScale(scale);
+ } else if (line.matchString("reversepana*", true)) {
+ uint reverse;
+ sscanf(line.c_str(), "reversepana(%u)", &reverse);
+ if (reverse == 1) {
+ renderTable->setPanoramaReverse(true);
+ }
+ } else if (line.matchString("zeropoint*", true)) {
+ // TODO: Implement
+ }
+
+ line = stream.readLine();
+ trimCommentsAndWhiteSpace(&line);
+ }
+
+ renderTable->generateRenderTable();
+}
+
+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);
+
+ while (!stream.eos() && !line.contains('}')) {
+ if (line.matchString("angle*", true)) {
+ float fov;
+ sscanf(line.c_str(), "angle(%f)", &fov);
+ renderTable->setTiltFoV(fov);
+ } else if (line.matchString("linscale*", true)) {
+ float scale;
+ sscanf(line.c_str(), "linscale(%f)", &scale);
+ renderTable->setTiltScale(scale);
+ } else if (line.matchString("reversepana*", true)) {
+ uint reverse;
+ sscanf(line.c_str(), "reversepana(%u)", &reverse);
+ if (reverse == 1) {
+ renderTable->setTiltReverse(true);
+ }
+ }
+
+ line = stream.readLine();
+ trimCommentsAndWhiteSpace(&line);
+ }
+
+ renderTable->generateRenderTable();
+}
+
+} // End of namespace ZVision
diff --git a/engines/zvision/scripting/control.h b/engines/zvision/scripting/control.h
new file mode 100644
index 0000000000..770c540a12
--- /dev/null
+++ b/engines/zvision/scripting/control.h
@@ -0,0 +1,146 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public 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_CONTROL_H
+#define ZVISION_CONTROL_H
+
+#include "common/keyboard.h"
+
+
+namespace Common {
+class SeekableReadStream;
+struct Point;
+class WriteStream;
+}
+
+namespace ZVision {
+
+class ZVision;
+
+class Control {
+public:
+ Control() : _engine(0), _key(0), _enabled(false) {}
+ Control(ZVision *engine, uint32 key) : _engine(engine), _key(key), _enabled(false) {}
+ virtual ~Control() {}
+
+ uint32 getKey() { return _key; }
+
+ virtual void enable();
+ virtual void disable();
+ virtual void focus() {}
+ virtual void unfocus() {}
+ /**
+ * 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
+ */
+ virtual void onMouseDown(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos) {}
+ /**
+ * 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) {}
+ /**
+ * Called on every MouseMove. Default is NOP.
+ *
+ * @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?
+ */
+ 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) {}
+ /**
+ * Called when a key is released. Default is NOP.
+ *
+ * @param keycode The key that was pressed
+ */
+ virtual void onKeyUp(Common::KeyState keyState) {}
+ /**
+ * 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; }
+
+protected:
+ ZVision * _engine;
+ uint32 _key;
+ bool _enabled;
+
+// 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);
+};
+
+// 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
new file mode 100644
index 0000000000..ec8f7a9647
--- /dev/null
+++ b/engines/zvision/scripting/controls/animation_control.cpp
@@ -0,0 +1,263 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public 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/animation_control.h b/engines/zvision/scripting/controls/animation_control.h
new file mode 100644
index 0000000000..77663aaf1e
--- /dev/null
+++ b/engines/zvision/scripting/controls/animation_control.h
@@ -0,0 +1,87 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef ZVISION_ANIMATION_CONTROL_H
+#define ZVISION_ANIMATION_CONTROL_H
+
+#include "zvision/scripting/control.h"
+
+
+namespace Common {
+class String;
+}
+
+namespace Video {
+class VideoDecoder;
+}
+
+namespace Graphics {
+struct Surface;
+}
+
+namespace ZVision {
+
+class ZVision;
+class RlfAnimation;
+
+class AnimationControl : public Control {
+public:
+ AnimationControl(ZVision *engine, uint32 controlKey, const Common::String &fileName);
+ ~AnimationControl();
+
+private:
+ enum FileType {
+ RLF = 1,
+ AVI = 2
+ };
+
+private:
+ uint32 _animationKey;
+
+ union {
+ RlfAnimation *rlf;
+ Video::VideoDecoder *avi;
+ } _animation;
+
+ FileType _fileType;
+ uint _loopCount;
+ int32 _x;
+ int32 _y;
+
+ uint _accumulatedTime;
+ uint _currentLoop;
+
+ Graphics::Surface *_cachedFrame;
+ bool _cachedFrameNeedsDeletion;
+
+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; }
+};
+
+} // End of namespace ZVision
+
+#endif
diff --git a/engines/zvision/scripting/controls/input_control.cpp b/engines/zvision/scripting/controls/input_control.cpp
new file mode 100644
index 0000000000..2685b01312
--- /dev/null
+++ b/engines/zvision/scripting/controls/input_control.cpp
@@ -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.
+ *
+ */
+
+#include "common/scummsys.h"
+
+#include "zvision/scripting/controls/input_control.h"
+
+#include "zvision/zvision.h"
+#include "zvision/scripting/script_manager.h"
+#include "zvision/strings/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"
+
+
+namespace ZVision {
+
+InputControl::InputControl(ZVision *engine, uint32 key, Common::SeekableReadStream &stream)
+ : Control(engine, key),
+ _nextTabstop(0),
+ _focused(false),
+ _textChanged(false),
+ _cursorOffset(0) {
+ // Loop until we find the closing brace
+ Common::String line = stream.readLine();
+ trimCommentsAndWhiteSpace(&line);
+
+ while (!stream.eos() && !line.contains('}')) {
+ if (line.matchString("*rectangle*", true)) {
+ int x1;
+ int y1;
+ int x2;
+ int y2;
+
+ sscanf(line.c_str(), "%*[^(](%d %d %d %d)", &x1, &y1, &x2, &y2);
+
+ _textRectangle = Common::Rect(x1, y1, x2, y2);
+ } else if (line.matchString("*aux_hotspot*", true)) {
+ int x1;
+ int y1;
+ int x2;
+ int y2;
+
+ sscanf(line.c_str(), "%*[^(](%d %d %d %d)", &x1, &y1, &x2, &y2);
+
+ _headerRectangle = Common::Rect(x1, y1, x2, y2);
+ } else if (line.matchString("*string_init*", true)) {
+ uint fontFormatNumber;
+
+ sscanf(line.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[25];
+
+ sscanf(line.c_str(), "%*[^(](%25s %*u)", fileName);
+
+ _cursorAnimationFileName = Common::String(fileName);
+ } else if (line.matchString("*cursor_dimensions*", true)) {
+ // Ignore, use the dimensions in the animation file
+ } else if (line.matchString("*cursor_animation_frames*", true)) {
+ // Ignore, use the frame count in the animation file
+ } else if (line.matchString("*focus*", true)) {
+ _focused = true;
+ }
+
+ line = stream.readLine();
+ trimCommentsAndWhiteSpace(&line);
+ }
+}
+
+void InputControl::onMouseUp(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos) {
+ _engine->getScriptManager()->focusControl(_key);
+}
+
+void InputControl::onKeyDown(Common::KeyState keyState) {
+ if (!_focused) {
+ return;
+ }
+
+ if (keyState.keycode == Common::KEYCODE_BACKSPACE) {
+ _currentInputText.deleteLastChar();
+ } else if (keyState.keycode == Common::KEYCODE_TAB) {
+ _focused = false;
+ // Focus the next input control
+ _engine->getScriptManager()->focusControl(_nextTabstop);
+ } 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;
+ }
+ }
+}
+
+bool InputControl::process(uint32 deltaTimeInMillis) {
+ if (!_focused) {
+ return false;
+ }
+
+ // 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;
+ }
+
+ // Render the next frame of the animation
+ // TODO: Implement animation handling
+
+ return false;
+}
+
+} // End of namespace ZVision
diff --git a/engines/zvision/scripting/controls/input_control.h b/engines/zvision/scripting/controls/input_control.h
new file mode 100644
index 0000000000..f0fd8b502d
--- /dev/null
+++ b/engines/zvision/scripting/controls/input_control.h
@@ -0,0 +1,60 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public 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_INPUT_CONTROL_H
+#define ZVISION_INPUT_CONTROL_H
+
+#include "zvision/scripting/control.h"
+#include "zvision/strings/string_manager.h"
+
+#include "common/rect.h"
+
+
+namespace ZVision {
+
+class InputControl : public Control {
+public:
+ InputControl(ZVision *engine, uint32 key, Common::SeekableReadStream &stream);
+
+private:
+ Common::Rect _textRectangle;
+ Common::Rect _headerRectangle;
+ StringManager::TextStyle _textStyle;
+ uint32 _nextTabstop;
+ Common::String _cursorAnimationFileName;
+ bool _focused;
+
+ Common::String _currentInputText;
+ bool _textChanged;
+ uint _cursorOffset;
+
+public:
+ void focus() { _focused = true; }
+ void unfocus() { _focused = false; }
+ void onMouseUp(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos);
+ void onKeyDown(Common::KeyState keyState);
+ bool process(uint32 deltaTimeInMillis);
+};
+
+} // End of namespace ZVision
+
+#endif
diff --git a/engines/zvision/scripting/controls/lever_control.cpp b/engines/zvision/scripting/controls/lever_control.cpp
new file mode 100644
index 0000000000..e08fdd10f3
--- /dev/null
+++ b/engines/zvision/scripting/controls/lever_control.cpp
@@ -0,0 +1,402 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public 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/lever_control.h"
+
+#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 "common/stream.h"
+#include "common/file.h"
+#include "common/tokenizer.h"
+#include "common/system.h"
+
+#include "graphics/surface.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) {
+
+ // Loop until we find the closing brace
+ Common::String line = stream.readLine();
+ trimCommentsAndWhiteSpace(&line);
+
+ while (!stream.eos() && !line.contains('}')) {
+ if (line.matchString("*descfile*", true)) {
+ char levFileName[25];
+ sscanf(line.c_str(), "%*[^(](%25[^)])", levFileName);
+
+ parseLevFile(levFileName);
+ } else if (line.matchString("*cursor*", true)) {
+ char cursorName[25];
+ sscanf(line.c_str(), "%*[^(](%25[^)])", cursorName);
+
+ _cursorName = Common::String(cursorName);
+ }
+
+ line = stream.readLine();
+ trimCommentsAndWhiteSpace(&line);
+ }
+
+ renderFrame(_currentFrame);
+}
+
+LeverControl::~LeverControl() {
+ if (_fileType == AVI) {
+ delete _animation.avi;
+ } else if (_fileType == RLF) {
+ delete _animation.rlf;
+ }
+
+ delete[] _frameInfo;
+}
+
+void LeverControl::parseLevFile(const Common::String &fileName) {
+ Common::File file;
+ if (!file.open(fileName)) {
+ warning("LEV file %s could could be opened", fileName.c_str());
+ return;
+ }
+
+ Common::String line = file.readLine();
+
+ while (!file.eos()) {
+ if (line.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)) {
+ // Not used
+ } else if (line.matchString("*anim_coords*", true)) {
+ int left, top, right, bottom;
+ sscanf(line.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)) {
+ uint mirrored;
+ sscanf(line.c_str(), "%*[^:]:%u~", &mirrored);
+
+ _mirrored = mirrored == 0 ? false : true;
+ } else if (line.matchString("*frames*", true)) {
+ sscanf(line.c_str(), "%*[^:]:%u~", &_frameCount);
+
+ _frameInfo = new FrameInfo[_frameCount];
+ } else if (line.matchString("*elsewhere*", true)) {
+ // Not used
+ } else if (line.matchString("*out_of_control*", true)) {
+ // Not used
+ } else if (line.matchString("*start_pos*", true)) {
+ sscanf(line.c_str(), "%*[^:]:%u~", &_startFrame);
+ _currentFrame = _startFrame;
+ } else if (line.matchString("*hotspot_deltas*", true)) {
+ uint x;
+ uint y;
+ sscanf(line.c_str(), "%*[^:]:%u %u~", &x, &y);
+
+ _hotspotDelta.x = x;
+ _hotspotDelta.y = y;
+ } else {
+ uint frameNumber;
+ uint x, y;
+
+ if (sscanf(line.c_str(), "%u:%u %u", &frameNumber, &x, &y) == 3) {
+ _frameInfo[frameNumber].hotspot.left = x;
+ _frameInfo[frameNumber].hotspot.top = y;
+ _frameInfo[frameNumber].hotspot.right = x + _hotspotDelta.x;
+ _frameInfo[frameNumber].hotspot.bottom = y + _hotspotDelta.y;
+ }
+
+ Common::StringTokenizer tokenizer(line, " ^=()");
+ tokenizer.nextToken();
+ tokenizer.nextToken();
+
+ Common::String token = tokenizer.nextToken();
+ while (!tokenizer.empty()) {
+ if (token == "D") {
+ token = tokenizer.nextToken();
+
+ uint angle;
+ uint toFrame;
+ sscanf(token.c_str(), "%u,%u", &toFrame, &angle);
+
+ _frameInfo[frameNumber].directions.push_back(Direction(angle, toFrame));
+ } else if (token.hasPrefix("P")) {
+ // Format: P(<from> to <to>)
+ tokenizer.nextToken();
+ tokenizer.nextToken();
+ token = tokenizer.nextToken();
+ uint to = atoi(token.c_str());
+
+ _frameInfo[frameNumber].returnRoute.push_back(to);
+ }
+
+ token = tokenizer.nextToken();
+ }
+ }
+
+ line = file.readLine();
+ }
+}
+
+void LeverControl::onMouseDown(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos) {
+ if (!_enabled) {
+ return;
+ }
+
+ if (_frameInfo[_currentFrame].hotspot.contains(backgroundImageSpacePos)) {
+ _mouseIsCaptured = true;
+ _lastMousePos = backgroundImageSpacePos;
+ }
+}
+
+void LeverControl::onMouseUp(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos) {
+ if (!_enabled) {
+ return;
+ }
+
+ if (_mouseIsCaptured) {
+ _mouseIsCaptured = false;
+ _engine->getScriptManager()->setStateValue(_key, _currentFrame);
+
+ _isReturning = true;
+ _returnRoutesCurrentProgress = _frameInfo[_currentFrame].returnRoute.begin();
+ _returnRoutesCurrentFrame = _currentFrame;
+ }
+}
+
+bool LeverControl::onMouseMove(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos) {
+ if (!_enabled) {
+ return false;
+ }
+
+ bool cursorWasChanged = false;
+
+ if (_mouseIsCaptured) {
+ // Make sure the square distance between the last point and the current point is greater than 64
+ // 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) {
+ int angle = calculateVectorAngle(_lastMousePos, backgroundImageSpacePos);
+ _lastMousePos = backgroundImageSpacePos;
+
+ for (Common::List<Direction>::iterator iter = _frameInfo[_currentFrame].directions.begin(); iter != _frameInfo[_currentFrame].directions.end(); ++iter) {
+ if (angle >= (int)iter->angle - ANGLE_DELTA && angle <= (int)iter->angle + ANGLE_DELTA) {
+ _currentFrame = iter->toFrame;
+ renderFrame(_currentFrame);
+ break;
+ }
+ }
+ }
+ } else if (_frameInfo[_currentFrame].hotspot.contains(backgroundImageSpacePos)) {
+ _engine->getCursorManager()->changeCursor(_cursorName);
+ cursorWasChanged = true;
+ }
+
+ return cursorWasChanged;
+}
+
+bool LeverControl::process(uint32 deltaTimeInMillis) {
+ if (!_enabled) {
+ return false;
+ }
+
+ if (_isReturning) {
+ _accumulatedTime += deltaTimeInMillis;
+ while (_accumulatedTime >= ANIMATION_FRAME_TIME) {
+ _accumulatedTime -= ANIMATION_FRAME_TIME;
+ if (_returnRoutesCurrentFrame == *_returnRoutesCurrentProgress) {
+ _returnRoutesCurrentProgress++;
+ }
+ if (_returnRoutesCurrentProgress == _frameInfo[_currentFrame].returnRoute.end()) {
+ _isReturning = false;
+ _currentFrame = _returnRoutesCurrentFrame;
+ return false;
+ }
+
+ uint toFrame = *_returnRoutesCurrentProgress;
+ if (_returnRoutesCurrentFrame < toFrame) {
+ _returnRoutesCurrentFrame++;
+ } else if (_returnRoutesCurrentFrame > toFrame) {
+ _returnRoutesCurrentFrame--;
+ }
+
+ _engine->getScriptManager()->setStateValue(_key, _returnRoutesCurrentFrame);
+ renderFrame(_returnRoutesCurrentFrame);
+ }
+ }
+
+ return false;
+}
+
+int LeverControl::calculateVectorAngle(const Common::Point &pointOne, const Common::Point &pointTwo) {
+ // Check for the easy angles first
+ if (pointOne.x == pointTwo.x && pointOne.y == pointTwo.y)
+ return -1; // This should never happen
+ else if (pointOne.x == pointTwo.x) {
+ if (pointTwo.y < pointOne.y)
+ return 90;
+ else
+ return 270;
+ } else if (pointOne.y == pointTwo.y) {
+ if (pointTwo.x > pointOne.x)
+ return 0;
+ else
+ return 180;
+ } else {
+ // Calculate the angle with trig
+ int16 xDist = pointTwo.x - pointOne.x;
+ int16 yDist = pointTwo.y - pointOne.y;
+
+ // Calculate the angle using arctan
+ // Then convert to degrees. (180 / 3.14159 = 57.2958)
+ int angle = int(atan((float)yDist / (float)xDist) * 57);
+
+ // Calculate what quadrant pointTwo is in
+ uint quadrant = ((yDist > 0 ? 1 : 0) << 1) | (xDist < 0 ? 1 : 0);
+
+ // Explanation of quadrants:
+ //
+ // yDist > 0 | xDist < 0 | Quadrant number
+ // 0 | 0 | 0
+ // 0 | 1 | 1
+ // 1 | 0 | 2
+ // 1 | 1 | 3
+ //
+ // Note: I know this doesn't line up with traditional mathematical quadrants
+ // but doing it this way allows you can use a switch and is a bit cleaner IMO.
+ //
+ // The graph below shows the 4 quadrants pointTwo can end up in as well
+ // as what the angle as calculated above refers to.
+ // Note: The calculated angle in quadrants 0 and 3 is negative
+ // due to arctan(-x) = -theta
+ //
+ // Origin => (pointOne.x, pointOne.y)
+ // * => (pointTwo.x, pointTwo.y)
+ //
+ // 90 |
+ // ^ |
+ // * | * |
+ // \ | / |
+ // \ | / |
+ // \ | / |
+ // Quadrant 1 \ | / Quadrant 0 |
+ // \ | / |
+ // \ | / |
+ // angle ( \|/ ) -angle |
+ // 180 <----------------------------------------> 0 |
+ // -angle ( /|\ ) angle |
+ // / | \ |
+ // / | \ |
+ // Quadrant 3 / | \ Quadrant 2 |
+ // / | \ |
+ // / | \ |
+ // / | \ |
+ // * | * |
+ // ^ |
+ // 270 |
+
+ // Convert the local angles to unit circle angles
+ switch (quadrant) {
+ case 0:
+ angle = 180 + angle;
+ break;
+ case 1:
+ // Do nothing
+ break;
+ case 2:
+ angle = 180 + angle;
+ break;
+ case 3:
+ angle = 360 + angle;
+ break;
+ }
+
+ return angle;
+ }
+}
+
+void LeverControl::renderFrame(uint frameNumber) {
+ if (frameNumber == 0) {
+ _lastRenderedFrame = frameNumber;
+ } else if (frameNumber < _lastRenderedFrame && _mirrored) {
+ _lastRenderedFrame = frameNumber;
+ frameNumber = (_frameCount * 2) - frameNumber - 1;
+ } else {
+ _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;
+ }
+
+ _engine->getRenderManager()->copyRectToWorkingWindow(frameData, x, y, width, width, height);
+}
+
+} // End of namespace ZVision
diff --git a/engines/zvision/scripting/controls/lever_control.h b/engines/zvision/scripting/controls/lever_control.h
new file mode 100644
index 0000000000..69473cf119
--- /dev/null
+++ b/engines/zvision/scripting/controls/lever_control.h
@@ -0,0 +1,127 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef ZVISION_LEVER_CONTROL_H
+#define ZVISION_LEVER_CONTROL_H
+
+#include "zvision/scripting/control.h"
+
+#include "common/list.h"
+#include "common/rect.h"
+
+
+namespace ZVision {
+
+class ZorkAVIDecoder;
+class RlfAnimation;
+
+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) {}
+
+ uint angle;
+ uint toFrame;
+ };
+
+ struct FrameInfo {
+ Common::Rect hotspot;
+ Common::List<Direction> directions;
+ Common::List<uint> returnRoute;
+ };
+
+ enum {
+ ANGLE_DELTA = 30, // How far off a mouse angle can be and still be considered valid. This is in both directions, so the total buffer zone is (2 * ANGLE_DELTA)
+ ANIMATION_FRAME_TIME = 30 // In millis
+ };
+
+private:
+ union {
+ RlfAnimation *rlf;
+ ZorkAVIDecoder *avi;
+ } _animation;
+ FileType _fileType;
+
+ Common::String _cursorName;
+ Common::Rect _animationCoords;
+ bool _mirrored;
+ uint _frameCount;
+ uint _startFrame;
+ Common::Point _hotspotDelta;
+ FrameInfo *_frameInfo;
+
+ uint _currentFrame;
+ uint _lastRenderedFrame;
+ bool _mouseIsCaptured;
+ bool _isReturning;
+ Common::Point _lastMousePos;
+ Common::List<uint>::iterator _returnRoutesCurrentProgress;
+ uint _returnRoutesCurrentFrame;
+ uint32 _accumulatedTime;
+
+public:
+ void onMouseDown(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos);
+ void 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 parseLevFile(const Common::String &fileName);
+ /**
+ * Calculates the angle a vector makes with the negative y-axis
+ *
+ * 90
+ * pointTwo * ^
+ * \ |
+ * \ |
+ * \ |
+ * \ |
+ * angle ( \|pointOne
+ * 180 <-----------*-----------> 0
+ * |
+ * |
+ * |
+ * |
+ * |
+ * ^
+ * 270
+ *
+ * @param pointOne The origin of the vector
+ * @param pointTwo The end of the vector
+ * @return The angle the vector makes with the negative y-axis
+ */
+ static int calculateVectorAngle(const Common::Point &pointOne, const Common::Point &pointTwo);
+ void renderFrame(uint frameNumber);
+};
+
+} // 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
new file mode 100644
index 0000000000..11ec4bb73f
--- /dev/null
+++ b/engines/zvision/scripting/controls/push_toggle_control.cpp
@@ -0,0 +1,98 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public 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/push_toggle_control.h"
+
+#include "zvision/zvision.h"
+#include "zvision/scripting/script_manager.h"
+#include "zvision/cursors/cursor_manager.h"
+#include "zvision/utility/utility.h"
+
+#include "common/stream.h"
+
+
+namespace ZVision {
+
+PushToggleControl::PushToggleControl(ZVision *engine, uint32 key, Common::SeekableReadStream &stream)
+ : Control(engine, key) {
+ // Loop until we find the closing brace
+ Common::String line = stream.readLine();
+ trimCommentsAndWhiteSpace(&line);
+
+ while (!stream.eos() && !line.contains('}')) {
+ if (line.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);
+ }
+
+ line = stream.readLine();
+ trimCommentsAndWhiteSpace(&line);
+ }
+
+ if (_hotspot.isEmpty() || _hoverCursor.empty()) {
+ warning("Push_toggle cursor %u was parsed incorrectly", key);
+ }
+}
+
+PushToggleControl::~PushToggleControl() {
+ // Clear the state value back to 0
+ _engine->getScriptManager()->setStateValue(_key, 0);
+}
+
+void PushToggleControl::onMouseUp(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos) {
+ if (!_enabled) {
+ return;
+ }
+
+ if (_hotspot.contains(backgroundImageSpacePos)) {
+ _engine->getScriptManager()->setStateValue(_key, 1);
+ }
+}
+
+bool PushToggleControl::onMouseMove(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos) {
+ if (!_enabled) {
+ return false;
+ }
+
+ if (_hotspot.contains(backgroundImageSpacePos)) {
+ _engine->getCursorManager()->changeCursor(_hoverCursor);
+ 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
new file mode 100644
index 0000000000..13dc54a65f
--- /dev/null
+++ b/engines/zvision/scripting/controls/push_toggle_control.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 ZVISION_PUSH_TOGGLE_CONTROL_H
+#define ZVISION_PUSH_TOGGLE_CONTROL_H
+
+#include "zvision/scripting/control.h"
+
+#include "common/rect.h"
+
+
+namespace ZVision {
+
+class PushToggleControl : public Control {
+public:
+ PushToggleControl(ZVision *engine, uint32 key, Common::SeekableReadStream &stream);
+ ~PushToggleControl();
+
+ /**
+ * 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);
+ /**
+ * 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);
+
+private:
+ /**
+ * The area that will trigger the event
+ * This is in image space coordinates, NOT screen space
+ */
+ Common::Rect _hotspot;
+ /** The cursor to use when hovering over _hotspot */
+ Common::String _hoverCursor;
+};
+
+} // End of namespace ZVision
+
+#endif
diff --git a/engines/zvision/scripting/controls/timer_node.cpp b/engines/zvision/scripting/controls/timer_node.cpp
new file mode 100644
index 0000000000..3b691be275
--- /dev/null
+++ b/engines/zvision/scripting/controls/timer_node.cpp
@@ -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.
+ *
+ */
+
+#include "common/scummsys.h"
+
+#include "zvision/scripting/controls/timer_node.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) {
+ _timeLeft = timeInSeconds * 1000;
+ } else if (_engine->getGameId() == GID_GRANDINQUISITOR) {
+ _timeLeft = timeInSeconds * 100;
+ }
+
+ _engine->getScriptManager()->setStateValue(_key, 1);
+}
+
+TimerNode::~TimerNode() {
+ if (_timeLeft <= 0)
+ _engine->getScriptManager()->setStateValue(_key, 2);
+ else
+ _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;
+ }
+
+ return false;
+}
+
+void TimerNode::serialize(Common::WriteStream *stream) {
+ stream->writeUint32LE(_key);
+ stream->writeUint32LE(_timeLeft);
+}
+
+void TimerNode::deserialize(Common::SeekableReadStream *stream) {
+ _timeLeft = stream->readUint32LE();
+}
+
+} // End of namespace ZVision
diff --git a/engines/zvision/scripting/controls/timer_node.h b/engines/zvision/scripting/controls/timer_node.h
new file mode 100644
index 0000000000..a8e579cbe4
--- /dev/null
+++ b/engines/zvision/scripting/controls/timer_node.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_TIMER_NODE_H
+#define ZVISION_TIMER_NODE_H
+
+#include "zvision/scripting/control.h"
+
+namespace ZVision {
+
+class ZVision;
+
+class TimerNode : public Control {
+public:
+ TimerNode(ZVision *engine, uint32 key, uint timeInSeconds);
+ ~TimerNode();
+
+ /**
+ * 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 serialize(Common::WriteStream *stream);
+ void deserialize(Common::SeekableReadStream *stream);
+ inline bool needsSerialization() { return true; }
+
+private:
+ int32 _timeLeft;
+};
+
+} // End of namespace ZVision
+
+#endif
diff --git a/engines/zvision/scripting/puzzle.h b/engines/zvision/scripting/puzzle.h
new file mode 100644
index 0000000000..0d717f1fa9
--- /dev/null
+++ b/engines/zvision/scripting/puzzle.h
@@ -0,0 +1,74 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef ZVISION_PUZZLE_H
+#define ZVISION_PUZZLE_H
+
+#include "zvision/scripting/actions.h"
+
+#include "common/list.h"
+#include "common/ptr.h"
+
+
+namespace ZVision {
+
+struct Puzzle {
+ Puzzle() : key(0) {}
+
+ ~Puzzle() {
+ for (Common::List<ResultAction *>::iterator iter = resultActions.begin(); iter != resultActions.end(); ++iter) {
+ delete *iter;
+ }
+ }
+
+ /** How criteria should be decided */
+ enum CriteriaOperator {
+ EQUAL_TO,
+ NOT_EQUAL_TO,
+ GREATER_THAN,
+ LESS_THAN
+ };
+
+ /** Criteria for a Puzzle result to be fired */
+ struct CriteriaEntry {
+ /** The key of a global state */
+ uint32 key;
+ /**
+ * What we're comparing the value of the global state against
+ * This can either be a pure value or it can be the key of another global state
+ */
+ uint32 argument;
+ /** How to do the comparison */
+ CriteriaOperator criteriaOperator;
+ /** Whether 'argument' is the key of a global state (true) or a pure value (false) */
+ bool argumentIsAKey;
+ };
+
+ uint32 key;
+ Common::List<Common::List <CriteriaEntry> > criteriaList;
+ // This has to be list of pointers because ResultAction is abstract
+ Common::List<ResultAction *> resultActions;
+};
+
+} // End of namespace ZVision
+
+#endif
diff --git a/engines/zvision/scripting/scr_file_handling.cpp b/engines/zvision/scripting/scr_file_handling.cpp
new file mode 100644
index 0000000000..d93094a3b2
--- /dev/null
+++ b/engines/zvision/scripting/scr_file_handling.cpp
@@ -0,0 +1,302 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public 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"
+
+#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 "common/textconsole.h"
+#include "common/file.h"
+#include "common/tokenizer.h"
+
+
+namespace ZVision {
+
+void ScriptManager::parseScrFile(const Common::String &fileName, bool isGlobal) {
+ Common::File file;
+ if (!file.open(fileName)) {
+ warning("Script file not found: %s", fileName.c_str());
+ return;
+ }
+
+ while(!file.eos()) {
+ Common::String line = file.readLine();
+ if (file.err()) {
+ warning("Error parsing scr file: %s", fileName.c_str());
+ return;
+ }
+
+ trimCommentsAndWhiteSpace(&line);
+ if (line.empty())
+ continue;
+
+ if (line.matchString("puzzle:*", true)) {
+ Puzzle *puzzle = new Puzzle();
+ sscanf(line.c_str(),"puzzle:%u",&(puzzle->key));
+
+ parsePuzzle(puzzle, file);
+ if (isGlobal) {
+ _globalPuzzles.push_back(puzzle);
+ } else {
+ _activePuzzles.push_back(puzzle);
+ }
+ } else if (line.matchString("control:*", true)) {
+ parseControl(line, file);
+ }
+ }
+}
+
+void ScriptManager::parsePuzzle(Puzzle *puzzle, Common::SeekableReadStream &stream) {
+ Common::String line = stream.readLine();
+ trimCommentsAndWhiteSpace(&line);
+
+ while (!stream.eos() && !line.contains('}')) {
+ if (line.matchString("criteria {", true)) {
+ parseCriteria(stream, puzzle->criteriaList);
+ } else if (line.matchString("results {", true)) {
+ parseResults(stream, puzzle->resultActions);
+ } else if (line.matchString("flags {", true)) {
+ setStateFlags(puzzle->key, parseFlags(stream));
+ }
+
+ line = stream.readLine();
+ trimCommentsAndWhiteSpace(&line);
+ }
+}
+
+bool ScriptManager::parseCriteria(Common::SeekableReadStream &stream, Common::List<Common::List<Puzzle::CriteriaEntry> > &criteriaList) const {
+ // Loop until we find the closing brace
+ Common::String line = stream.readLine();
+ trimCommentsAndWhiteSpace(&line);
+
+ // Criteria can be empty
+ if (line.contains('}')) {
+ return false;
+ }
+
+ // Create a new List to hold the CriteriaEntries
+ criteriaList.push_back(Common::List<Puzzle::CriteriaEntry>());
+
+ while (!stream.eos() && !line.contains('}')) {
+ Puzzle::CriteriaEntry entry;
+
+ // Split the string into tokens using ' ' as a delimiter
+ Common::StringTokenizer tokenizer(line);
+ Common::String token;
+
+ // Parse the id out of the first token
+ token = tokenizer.nextToken();
+ sscanf(token.c_str(), "[%u]", &(entry.key));
+
+ // Parse the operator out of the second token
+ token = tokenizer.nextToken();
+ if (token.c_str()[0] == '=')
+ entry.criteriaOperator = Puzzle::EQUAL_TO;
+ else if (token.c_str()[0] == '!')
+ entry.criteriaOperator = Puzzle::NOT_EQUAL_TO;
+ else if (token.c_str()[0] == '>')
+ entry.criteriaOperator = Puzzle::GREATER_THAN;
+ else if (token.c_str()[0] == '<')
+ entry.criteriaOperator = Puzzle::LESS_THAN;
+
+ // 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;
+ } else {
+ sscanf(token.c_str(), "%u", &(entry.argument));
+ entry.argumentIsAKey = false;
+ }
+
+ criteriaList.back().push_back(entry);
+
+ line = stream.readLine();
+ trimCommentsAndWhiteSpace(&line);
+ }
+
+ return true;
+}
+
+void ScriptManager::parseResults(Common::SeekableReadStream &stream, Common::List<ResultAction *> &actionList) const {
+ // Loop until we find the closing brace
+ Common::String line = stream.readLine();
+ trimCommentsAndWhiteSpace(&line);
+
+ // 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);
+
+ 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());
+ }
+
+ line = stream.readLine();
+ trimCommentsAndWhiteSpace(&line);
+ }
+
+ return;
+}
+
+uint ScriptManager::parseFlags(Common::SeekableReadStream &stream) const {
+ uint flags = 0;
+
+ // Loop until we find the closing brace
+ Common::String line = stream.readLine();
+ trimCommentsAndWhiteSpace(&line);
+
+ while (!stream.eos() && !line.contains('}')) {
+ if (line.matchString("ONCE_PER_INST", true)) {
+ flags |= ONCE_PER_INST;
+ } else if (line.matchString("DO_ME_NOW", true)) {
+ flags |= DO_ME_NOW;
+ } else if (line.matchString("DISABLED", true)) {
+ flags |= DISABLED;
+ }
+
+ line = stream.readLine();
+ trimCommentsAndWhiteSpace(&line);
+ }
+
+ return flags;
+}
+
+void ScriptManager::parseControl(Common::String &line, Common::SeekableReadStream &stream) {
+ uint32 key;
+ char controlTypeBuffer[20];
+
+ sscanf(line.c_str(), "control:%u %s {", &key, controlTypeBuffer);
+
+ Common::String controlType(controlTypeBuffer);
+
+ if (controlType.equalsIgnoreCase("push_toggle")) {
+ _activeControls.push_back(new PushToggleControl(_engine, key, stream));
+ return;
+ } else if (controlType.equalsIgnoreCase("flat")) {
+ Control::parseFlatControl(_engine);
+ return;
+ } else if (controlType.equalsIgnoreCase("pana")) {
+ Control::parsePanoramaControl(_engine, stream);
+ return;
+ } else if (controlType.equalsIgnoreCase("tilt")) {
+ Control::parseTiltControl(_engine, stream);
+ return;
+ } else if (controlType.equalsIgnoreCase("lever")) {
+ _activeControls.push_back(new LeverControl(_engine, key, stream));
+ return;
+ }
+}
+
+} // End of namespace ZVision
diff --git a/engines/zvision/scripting/script_manager.cpp b/engines/zvision/scripting/script_manager.cpp
new file mode 100644
index 0000000000..adcc5c7545
--- /dev/null
+++ b/engines/zvision/scripting/script_manager.cpp
@@ -0,0 +1,444 @@
+/* ScummVM - Graphic Adventure Engine
+*
+* ScummVM is the legal property of its developers, whose names
+* are too numerous to list here. Please refer to the COPYRIGHT
+* file distributed with this source distribution.
+*
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License
+* as published by the Free Software Foundation; either version 2
+* of the License, or (at your option) any later version.
+
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+
+* You should have received a copy of the GNU General Public 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"
+
+#include "zvision/zvision.h"
+#include "zvision/graphics/render_manager.h"
+#include "zvision/cursors/cursor_manager.h"
+#include "zvision/core/save_manager.h"
+#include "zvision/scripting/actions.h"
+#include "zvision/utility/utility.h"
+
+#include "common/algorithm.h"
+#include "common/hashmap.h"
+#include "common/debug.h"
+#include "common/stream.h"
+
+
+namespace ZVision {
+
+ScriptManager::ScriptManager(ZVision *engine)
+ : _engine(engine),
+ _currentlyFocusedControl(0) {
+}
+
+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);
+ }
+}
+
+void ScriptManager::initialize() {
+ parseScrFile("universe.scr", true);
+ changeLocation('g', 'a', 'r', 'y', 0);
+}
+
+void ScriptManager::update(uint deltaTimeMillis) {
+ updateNodes(deltaTimeMillis);
+ checkPuzzleCriteria();
+}
+
+void ScriptManager::createReferenceTable() {
+ // Iterate through each local Puzzle
+ for (PuzzleList::iterator activePuzzleIter = _activePuzzles.begin(); activePuzzleIter != _activePuzzles.end(); ++activePuzzleIter) {
+ Puzzle *puzzlePtr = (*activePuzzleIter);
+
+ // 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);
+
+ // If the argument is a key, add a reference to it as well
+ if (entryIter->argumentIsAKey) {
+ _referenceTable[entryIter->argument].push_back(puzzlePtr);
+ }
+ }
+ }
+ }
+
+ // 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 the argument is a key, add a reference to it as well
+ if (entryIter->argumentIsAKey) {
+ _referenceTable[entryIter->argument].push_back(puzzlePtr);
+ }
+ }
+ }
+ }
+
+ // Remove duplicate entries
+ for (PuzzleMap::iterator referenceTableIter = _referenceTable.begin(); referenceTableIter != _referenceTable.end(); ++referenceTableIter) {
+ removeDuplicateEntries(referenceTableIter->_value);
+ }
+}
+
+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();) {
+ if ((*iter)->process(deltaTimeMillis)) {
+ delete (*iter);
+ // Remove the node
+ iter = _activeControls.erase(iter);
+ } else {
+ ++iter;
+ }
+ }
+}
+
+void ScriptManager::checkPuzzleCriteria() {
+ while (!_puzzlesToCheck.empty()) {
+ Puzzle *puzzle = _puzzlesToCheck.pop();
+
+ // 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;
+ }
+
+ // Check each Criteria
+
+ 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
+ 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;
+ }
+ }
+
+ // If any of the Criteria are *fully* met, then execute the results
+ 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);
+
+ // Set the puzzle as completed
+ setStateValue(puzzle->key, 1);
+
+ 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;
+ }
+ }
+
+ if (!shouldContinue) {
+ break;
+ }
+ }
+ }
+}
+
+void ScriptManager::cleanStateTable() {
+ for (StateMap::iterator iter = _globalState.begin(); iter != _globalState.end(); ++iter) {
+ // If the value is equal to zero, we can purge it since getStateValue()
+ // will return zero if _globalState doesn't contain a key
+ if (iter->_value == 0) {
+ // Remove the node
+ _globalState.erase(iter);
+ }
+ }
+}
+
+uint ScriptManager::getStateValue(uint32 key) {
+ if (_globalState.contains(key))
+ return _globalState[key];
+ else
+ return 0;
+}
+
+void ScriptManager::setStateValue(uint32 key, uint value) {
+ _globalState[key] = value;
+
+ if (_referenceTable.contains(key)) {
+ for (Common::Array<Puzzle *>::iterator iter = _referenceTable[key].begin(); iter != _referenceTable[key].end(); ++iter) {
+ _puzzlesToCheck.push((*iter));
+ }
+ }
+}
+
+uint ScriptManager::getStateFlags(uint32 key) {
+ if (_globalStateFlags.contains(key))
+ return _globalStateFlags[key];
+ else
+ return 0;
+}
+
+void ScriptManager::setStateFlags(uint32 key, uint flags) {
+ _globalStateFlags[key] = flags;
+
+ if (_referenceTable.contains(key)) {
+ for (Common::Array<Puzzle *>::iterator iter = _referenceTable[key].begin(); iter != _referenceTable[key].end(); ++iter) {
+ _puzzlesToCheck.push((*iter));
+ }
+ }
+}
+
+void ScriptManager::addToStateValue(uint32 key, uint valueToAdd) {
+ _globalState[key] += valueToAdd;
+}
+
+void ScriptManager::addControl(Control *control) {
+ _activeControls.push_back(control);
+}
+
+Control *ScriptManager::getControl(uint32 key) {
+ for (ControlList::iterator iter = _activeControls.begin(); iter != _activeControls.end(); ++iter) {
+ if ((*iter)->getKey() == key) {
+ return (*iter);
+ }
+ }
+
+ return nullptr;
+}
+
+void ScriptManager::focusControl(uint32 key) {
+ for (ControlList::iterator iter = _activeControls.begin(); iter != _activeControls.end(); ++iter) {
+ uint32 controlKey = (*iter)->getKey();
+
+ if (controlKey == key) {
+ (*iter)->focus();
+ } else if (controlKey == _currentlyFocusedControl) {
+ (*iter)->unfocus();
+ }
+ }
+
+ _currentlyFocusedControl = key;
+}
+
+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);
+ }
+}
+
+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);
+ }
+}
+
+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);
+ }
+
+ return cursorWasChanged;
+}
+
+void ScriptManager::onKeyDown(Common::KeyState keyState) {
+ for (ControlList::iterator iter = _activeControls.begin(); iter != _activeControls.end(); ++iter) {
+ (*iter)->onKeyDown(keyState);
+ }
+}
+
+void ScriptManager::onKeyUp(Common::KeyState keyState) {
+ for (ControlList::iterator iter = _activeControls.begin(); iter != _activeControls.end(); ++iter) {
+ (*iter)->onKeyUp(keyState);
+ }
+}
+
+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);
+
+ // Auto save
+ _engine->getSaveManager()->autoSave();
+
+ // Clear all the containers
+ _referenceTable.clear();
+ _puzzlesToCheck.clear();
+ for (PuzzleList::iterator iter = _activePuzzles.begin(); iter != _activePuzzles.end(); ++iter) {
+ delete (*iter);
+ }
+ _activePuzzles.clear();
+ for (ControlList::iterator iter = _activeControls.begin(); iter != _activeControls.end(); ++iter) {
+ delete (*iter);
+ }
+ _activeControls.clear();
+
+ // Revert to the idle cursor
+ _engine->getCursorManager()->revertToIdle();
+
+ // Reset the background velocity
+ _engine->getRenderManager()->setBackgroundVelocity(0);
+
+ // Remove any alphaEntries
+ _engine->getRenderManager()->clearAlphaEntries();
+
+ // Clean the global state table
+ cleanStateTable();
+
+ // Parse into puzzles and controls
+ Common::String fileName = Common::String::format("%c%c%c%c.scr", world, room, node, view);
+ parseScrFile(fileName);
+
+ // Change the background position
+ _engine->getRenderManager()->setBackgroundPosition(offset);
+
+ // Enable all the controls
+ for (ControlList::iterator iter = _activeControls.begin(); iter != _activeControls.end(); ++iter) {
+ (*iter)->enable();
+ }
+
+ // 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);
+ }
+
+ _puzzlesToCheck.push((*iter));
+ }
+
+ // 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);
+ }
+
+ _puzzlesToCheck.push((*iter));
+ }
+
+ // Create the puzzle reference table
+ createReferenceTable();
+
+ // Update _currentLocation
+ _currentLocation.world = world;
+ _currentLocation.room = room;
+ _currentLocation.node = node;
+ _currentLocation.view = view;
+ _currentLocation.offset = offset;
+}
+
+void ScriptManager::serializeStateTable(Common::WriteStream *stream) {
+ // Write the number of state value entries
+ stream->writeUint32LE(_globalState.size());
+
+ for (StateMap::iterator iter = _globalState.begin(); iter != _globalState.end(); ++iter) {
+ // Write out the key/value pair
+ stream->writeUint32LE(iter->_key);
+ stream->writeUint32LE(iter->_value);
+ }
+}
+
+void ScriptManager::deserializeStateTable(Common::SeekableReadStream *stream) {
+ // Clear out the current table values
+ _globalState.clear();
+
+ // Read the number of key/value pairs
+ uint32 numberOfPairs = stream->readUint32LE();
+
+ 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;
+ }
+}
+
+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++;
+ }
+ }
+ stream->writeUint32LE(numberOfControlsNeedingSerialization);
+
+ for (ControlList::iterator iter = _activeControls.begin(); iter != _activeControls.end(); ++iter) {
+ (*iter)->serialize(stream);
+ }
+}
+
+void ScriptManager::deserializeControls(Common::SeekableReadStream *stream) {
+ uint32 numberOfControls = stream->readUint32LE();
+
+ 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;
+ }
+ }
+ }
+}
+
+Location ScriptManager::getCurrentLocation() const {
+ Location location = _currentLocation;
+ location.offset = _engine->getRenderManager()->getCurrentBackgroundOffset();
+
+ return location;
+}
+
+} // End of namespace ZVision
diff --git a/engines/zvision/scripting/script_manager.h b/engines/zvision/scripting/script_manager.h
new file mode 100644
index 0000000000..ab9b03ed30
--- /dev/null
+++ b/engines/zvision/scripting/script_manager.h
@@ -0,0 +1,225 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public 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_SCRIPT_MANAGER_H
+#define ZVISION_SCRIPT_MANAGER_H
+
+#include "zvision/scripting/puzzle.h"
+#include "zvision/scripting/control.h"
+
+#include "common/hashmap.h"
+#include "common/queue.h"
+
+
+namespace Common {
+class String;
+class SeekableReadStream;
+}
+
+namespace ZVision {
+
+class ZVision;
+
+struct Location {
+ Location() : world('g'), room('a'), node('r'), view('y'), offset(0) {}
+
+ char world;
+ char room;
+ char node;
+ char view;
+ uint32 offset;
+};
+
+typedef Common::HashMap<uint32, Common::Array<Puzzle *> > PuzzleMap;
+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;
+
+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;
+ /**
+ * 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;
+ /** 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;
+
+ Location _currentLocation;
+
+ uint32 _currentlyFocusedControl;
+
+public:
+ void initialize();
+ void update(uint deltaTimeMillis);
+
+ uint getStateValue(uint32 key);
+ void setStateValue(uint32 key, uint value);
+ void addToStateValue(uint32 key, uint valueToAdd);
+
+ uint getStateFlags(uint32 key);
+ void setStateFlags(uint32 key, uint flags);
+
+ void addControl(Control *control);
+ Control *getControl(uint32 key);
+
+ void focusControl(uint32 key);
+
+ /**
+ * Called when LeftMouse is pushed.
+ *
+ * @param screenSpacePos The position of the mouse in screen space
+ * @param backgroundImageSpacePos The position of the mouse in background image space
+ */
+ void onMouseDown(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos);
+ /**
+ * Called when LeftMouse is lifted.
+ *
+ * @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);
+ /**
+ * Called on every MouseMove.
+ *
+ * @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);
+ /**
+ * Called when a key is pressed.
+ *
+ * @param keycode The key that was pressed
+ */
+ void onKeyDown(Common::KeyState keyState);
+ /**
+ * Called when a key is released.
+ *
+ * @param keycode The key that was pressed
+ */
+ void onKeyUp(Common::KeyState keyState);
+
+ void changeLocation(char world, char room, char node, char view, uint32 offset);
+
+ void serializeStateTable(Common::WriteStream *stream);
+ void deserializeStateTable(Common::SeekableReadStream *stream);
+ void serializeControls(Common::WriteStream *stream);
+ void deserializeControls(Common::SeekableReadStream *stream);
+
+ Location getCurrentLocation() const;
+
+private:
+ void createReferenceTable();
+ void updateNodes(uint deltaTimeMillis);
+ void checkPuzzleCriteria();
+ void cleanStateTable();
+
+// TODO: Make this private. It was only made public so Console::cmdParseAllScrFiles() could use it
+public:
+ /**
+ * 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);
+
+private:
+ /**
+ * Parses the stream into a Puzzle object
+ * Helper method for parseScrFile.
+ *
+ * @param puzzle The object to store what is parsed
+ * @param stream Scr file stream
+ */
+ void parsePuzzle(Puzzle *puzzle, Common::SeekableReadStream &stream);
+
+ /**
+ * Parses the stream into a Criteria object
+ * Helper method for parsePuzzle.
+ *
+ * @param criteria Pointer to the Criteria object to fill
+ * @param stream Scr file stream
+ * @return Whether any criteria were read
+ */
+ bool parseCriteria(Common::SeekableReadStream &stream, Common::List<Common::List<Puzzle::CriteriaEntry> > &criteriaList) const;
+
+ /**
+ * Parses the stream into a ResultAction objects
+ * Helper method for parsePuzzle.
+ *
+ * @param stream Scr file stream
+ * @param actionList The list where the results will be added
+ * @return Created Results object
+ */
+ void parseResults(Common::SeekableReadStream &stream, Common::List<ResultAction *> &actionList) const;
+
+ /**
+ * Helper method for parsePuzzle. Parses the stream into a bitwise or of the StateFlags enum
+ *
+ * @param stream Scr file stream
+ * @return Bitwise OR of all the flags set within the puzzle
+ */
+ uint parseFlags(Common::SeekableReadStream &stream) const;
+
+ /**
+ * Helper method for parseScrFile. Parses the stream into a Control object
+ *
+ * @param line The line initially read
+ * @param stream Scr file stream
+ */
+ void parseControl(Common::String &line, Common::SeekableReadStream &stream);
+};
+
+
+} // End of namespace ZVision
+
+#endif
diff --git a/engines/zvision/sound/zork_raw.cpp b/engines/zvision/sound/zork_raw.cpp
new file mode 100644
index 0000000000..321ac93de2
--- /dev/null
+++ b/engines/zvision/sound/zork_raw.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/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 "audio/audiostream.h"
+#include "audio/decoders/raw.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) {
+ if (stereo)
+ _stereo = 1;
+
+ _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);
+}
+
+int RawZorkStream::readBuffer(int16 *buffer, const int numSamples) {
+ int bytesRead = 0;
+
+ // 0: Left, 1: Right
+ uint channel = 0;
+
+ while (bytesRead < numSamples) {
+ byte encodedSample = _stream->readByte();
+ if (_stream->eos()) {
+ _endOfData = true;
+ return bytesRead;
+ }
+ bytesRead++;
+
+ int16 index = _lastSample[channel].index;
+ uint32 lookUpSample = _amplitudeLookupTable[index];
+
+ int32 sample = 0;
+
+ if (encodedSample & 0x40)
+ sample += lookUpSample;
+ if (encodedSample & 0x20)
+ sample += lookUpSample >> 1;
+ if (encodedSample & 0x10)
+ sample += lookUpSample >> 2;
+ if (encodedSample & 8)
+ sample += lookUpSample >> 3;
+ if (encodedSample & 4)
+ sample += lookUpSample >> 4;
+ if (encodedSample & 2)
+ sample += lookUpSample >> 5;
+ if (encodedSample & 1)
+ sample += lookUpSample >> 6;
+ if (encodedSample & 0x80)
+ sample = -sample;
+
+ sample += _lastSample[channel].sample;
+ sample = CLIP<int32>(sample, -32768, 32767);
+
+ buffer[bytesRead - 1] = (int16)sample;
+
+ index += _stepAdjustmentTable[(encodedSample >> 4) & 7];
+ index = CLIP<int16>(index, 0, 88);
+
+ _lastSample[channel].sample = sample;
+ _lastSample[channel].index = index;
+
+ // Increment and wrap the channel
+ channel = (channel + 1) & _stereo;
+ }
+
+ return bytesRead;
+}
+
+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;
+
+ return true;
+}
+
+Audio::RewindableAudioStream *makeRawZorkStream(Common::SeekableReadStream *stream,
+ 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 fileName = getFileName(filePath);
+ fileName.toLowercase();
+
+ SoundParams soundParams = { ' ', 0, false, false };
+ bool foundParams = false;
+ char fileIdentifier = (engine->getGameId() == GID_NEMESIS) ? fileName[6] : fileName[7];
+
+ if (engine->getGameId() == GID_NEMESIS) {
+ for (int i = 0; i < 6; ++i) {
+ if (RawZorkStream::_zNemSoundParamLookupTable[i].identifier == fileIdentifier) {
+ soundParams = RawZorkStream::_zNemSoundParamLookupTable[i];
+ foundParams = true;
+ }
+ }
+ } else if (engine->getGameId() == GID_GRANDINQUISITOR) {
+ for (int i = 0; i < 6; ++i) {
+ if (RawZorkStream::_zgiSoundParamLookupTable[i].identifier == fileIdentifier) {
+ soundParams = RawZorkStream::_zgiSoundParamLookupTable[i];
+ foundParams = true;
+ }
+ }
+ }
+
+ if (!foundParams)
+ error("Unable to find sound params for file '%s'. File identifier is '%c'", filePath.c_str(), fileIdentifier);
+
+ if (soundParams.packed) {
+ return makeRawZorkStream(wrapBufferedSeekableReadStream(file, 2048, DisposeAfterUse::YES), soundParams.rate, soundParams.stereo, DisposeAfterUse::YES);
+ } else {
+ byte flags = 0;
+ if (soundParams.stereo)
+ flags |= Audio::FLAG_STEREO;
+
+ return Audio::makeRawStream(file, soundParams.rate, flags, DisposeAfterUse::YES);
+ }
+}
+
+} // End of namespace ZVision
diff --git a/engines/zvision/sound/zork_raw.h b/engines/zvision/sound/zork_raw.h
new file mode 100644
index 0000000000..481ea79f2d
--- /dev/null
+++ b/engines/zvision/sound/zork_raw.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.
+ *
+ */
+
+#ifndef ZVISION_ZORK_RAW_H
+#define ZVISION_ZORK_RAW_H
+
+#include "audio/audiostream.h"
+
+
+namespace Common {
+class SeekableReadStream;
+}
+
+namespace ZVision {
+
+class ZVision;
+
+struct SoundParams {
+ char identifier;
+ uint32 rate;
+ bool stereo;
+ bool packed;
+};
+
+/**
+ * This is a stream, which allows for playing raw ADPCM data from a stream.
+ */
+class RawZorkStream : public Audio::RewindableAudioStream {
+public:
+ RawZorkStream(uint32 rate, bool stereo, DisposeAfterUse::Flag disposeStream, Common::SeekableReadStream *stream);
+
+ ~RawZorkStream() {
+ }
+
+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;
+
+ /**
+ * Holds the frequency and index from the last sample
+ * 0 holds the left channel, 1 holds the right channel
+ */
+ struct {
+ int32 sample;
+ int16 index;
+ } _lastSample[2];
+
+ static const int16 _stepAdjustmentTable[8];
+ static const int32 _amplitudeLookupTable[89];
+
+public:
+ int readBuffer(int16 *buffer, const int numSamples);
+
+ bool isStereo() const { return true; }
+ 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 buffer.
+ *
+ * @param buffer Buffer to play from.
+ * @param size Size of the buffer in bytes.
+ * @param rate Rate of the sound data.
+ * @param dispose AfterUse Whether to free the buffer after use (with free!).
+ * @return The new SeekableAudioStream (or 0 on failure).
+ */
+Audio::RewindableAudioStream *makeRawZorkStream(const byte *buffer, uint32 size,
+ int rate,
+ bool stereo,
+ DisposeAfterUse::Flag disposeAfterUse = DisposeAfterUse::YES);
+
+/**
+ * Creates an audio stream, which plays from the given stream.
+ *
+ * @param stream Stream object to play from.
+ * @param rate Rate of the sound data.
+ * @param dispose AfterUse Whether to delete the stream after use.
+ * @return The new SeekableAudioStream (or 0 on failure).
+ */
+Audio::RewindableAudioStream *makeRawZorkStream(Common::SeekableReadStream *stream,
+ int rate,
+ bool stereo,
+ DisposeAfterUse::Flag disposeAfterUse = DisposeAfterUse::YES);
+
+Audio::RewindableAudioStream *makeRawZorkStream(const Common::String &filePath, ZVision *engine);
+
+} // End of namespace ZVision
+
+#endif
diff --git a/engines/zvision/strings/string_manager.cpp b/engines/zvision/strings/string_manager.cpp
new file mode 100644
index 0000000000..77ed501672
--- /dev/null
+++ b/engines/zvision/strings/string_manager.cpp
@@ -0,0 +1,255 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public 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/strings/string_manager.h b/engines/zvision/strings/string_manager.h
new file mode 100644
index 0000000000..86bb9638d7
--- /dev/null
+++ b/engines/zvision/strings/string_manager.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 ZVISION_STRING_MANAGER_H
+#define ZVISION_STRING_MANAGER_H
+
+#include "zvision/detection.h"
+#include "zvision/fonts/truetype_font.h"
+
+
+namespace Graphics {
+class FontManager;
+}
+
+namespace ZVision {
+
+class ZVision;
+
+class StringManager {
+public:
+ StringManager(ZVision *engine);
+ ~StringManager();
+
+public:
+ struct TextStyle {
+ TruetypeFont *font;
+ uint16 color; // In RBG 565
+ Graphics::TextAlign align;
+ };
+
+ struct TextFragment {
+ TextStyle style;
+ Common::String text;
+ };
+
+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;
+
+public:
+ void initialize(ZVisionGameId gameId);
+ StringManager::TextStyle getTextStyle(uint stringNumber);
+
+private:
+ void parseStrFile(const Common::String &fileName);
+ void parseTag(const Common::String &tagString, uint lineNumber);
+
+ static Common::String readWideLine(Common::SeekableReadStream &stream);
+};
+
+} // End of namespace ZVision
+
+#endif
diff --git a/engines/zvision/subtitles/subtitles.h b/engines/zvision/subtitles/subtitles.h
new file mode 100644
index 0000000000..13426e03e4
--- /dev/null
+++ b/engines/zvision/subtitles/subtitles.h
@@ -0,0 +1,29 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public 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_SUBTITLES_H
+#define ZVISION_SUBTITLES_H
+
+// TODO: Implement Subtitles
+
+#endif
diff --git a/engines/zvision/utility/clock.cpp b/engines/zvision/utility/clock.cpp
new file mode 100644
index 0000000000..49e4b32054
--- /dev/null
+++ b/engines/zvision/utility/clock.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 "zvision/utility/clock.h"
+
+#include "common/system.h"
+
+
+namespace ZVision {
+
+Clock::Clock(OSystem *system)
+ : _system(system),
+ _lastTime(0),
+ _deltaTime(0),
+ _pausedTime(0),
+ _paused(false) {
+}
+
+void Clock::update() {
+ uint32 currentTime = _system->getMillis();
+
+ _deltaTime = (currentTime - _lastTime);
+ if (_paused) {
+ _deltaTime -= (currentTime - _pausedTime);
+ }
+
+ if (_deltaTime < 0) {
+ _deltaTime = 0;
+ }
+
+ _lastTime = currentTime;
+}
+
+void Clock::start() {
+ if (_paused) {
+ _lastTime = _system->getMillis();
+ _paused = false;
+ }
+}
+
+void Clock::stop() {
+ if (!_paused) {
+ _pausedTime = _system->getMillis();
+ _paused = true;
+ }
+}
+
+} // End of namespace ZVision
diff --git a/engines/zvision/utility/clock.h b/engines/zvision/utility/clock.h
new file mode 100644
index 0000000000..3939ba1612
--- /dev/null
+++ b/engines/zvision/utility/clock.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 ZVISION_CLOCK_H
+#define ZVISION_CLOCK_H
+
+#include "common/types.h"
+
+class OSystem;
+
+namespace ZVision {
+
+/* Class for handling frame to frame deltaTime while keeping track of time pauses/un-pauses */
+class Clock {
+public:
+ Clock(OSystem *system);
+
+private:
+ OSystem *_system;
+ uint32 _lastTime;
+ int32 _deltaTime;
+ uint32 _pausedTime;
+ bool _paused;
+
+public:
+ /**
+ * Updates _deltaTime with the difference between the current time and
+ * 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; }
+ /**
+ * 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; }
+
+ /**
+ * 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.
+ */
+ void stop();
+};
+
+} // End of namespace ZVision
+
+#endif
diff --git a/engines/zvision/utility/lzss_read_stream.cpp b/engines/zvision/utility/lzss_read_stream.cpp
new file mode 100644
index 0000000000..dc537cd8ab
--- /dev/null
+++ b/engines/zvision/utility/lzss_read_stream.cpp
@@ -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.
+*
+*/
+
+#include "common/scummsys.h"
+
+#include "zvision/utility/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);
+}
+
+uint32 LzssReadStream::decompressBytes(byte *destination, uint32 numberOfBytes) {
+ uint32 destinationCursor = 0;
+
+ while (destinationCursor < numberOfBytes) {
+ byte flagbyte = _source->readByte();
+ if (_source->eos())
+ break;
+ uint mask = 1;
+
+ for (int i = 0; i < 8; ++i) {
+ if ((flagbyte & mask) == mask) {
+ byte data = _source->readByte();
+ if (_source->eos()) {
+ return destinationCursor;
+ }
+
+ _window[_windowCursor] = data;
+ destination[destinationCursor++] = data;
+
+ // Increment and wrap the window cursor
+ _windowCursor = (_windowCursor + 1) & 0xFFF;
+ } else {
+ byte low = _source->readByte();
+ if (_source->eos()) {
+ return destinationCursor;
+ }
+
+ byte high = _source->readByte();
+ if (_source->eos()) {
+ return destinationCursor;
+ }
+
+ uint16 length = (high & 0xF) + 2;
+ uint16 offset = low | ((high & 0xF0)<<4);
+
+ for(int j = 0; j <= length; ++j) {
+ byte temp = _window[(offset + j) & 0xFFF];
+ _window[_windowCursor] = temp;
+ destination[destinationCursor++] = temp;
+ _windowCursor = (_windowCursor + 1) & 0xFFF;
+ }
+ }
+
+ mask = mask << 1;
+ }
+ }
+
+ return destinationCursor;
+}
+
+bool LzssReadStream::eos() const {
+ return _eosFlag;
+}
+
+uint32 LzssReadStream::read(void *dataPtr, uint32 dataSize) {
+ uint32 bytesRead = decompressBytes(static_cast<byte *>(dataPtr), dataSize);
+ if (bytesRead < dataSize) {
+ // Flag that we're at EOS
+ _eosFlag = true;
+ }
+
+ return dataSize;
+}
+
+} // End of namespace ZVision
diff --git a/engines/zvision/utility/lzss_read_stream.h b/engines/zvision/utility/lzss_read_stream.h
new file mode 100644
index 0000000000..f6b1eb1a65
--- /dev/null
+++ b/engines/zvision/utility/lzss_read_stream.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 ZVISION_LZSS_STREAM_H
+#define ZVISION_LZSS_STREAM_H
+
+#include "common/stream.h"
+#include "common/array.h"
+
+
+namespace Common {
+class SeekableReadStream;
+}
+
+namespace ZVision {
+
+class LzssReadStream : public Common::ReadStream {
+public:
+ /**
+ * A class that decompresses LZSS data and implements ReadStream for easy access
+ * to the decompiled data.
+ *
+ * @param source The source data
+ */
+ LzssReadStream(Common::SeekableReadStream *source);
+
+private:
+ enum {
+ BLOCK_SIZE = 0x1000
+ };
+
+private:
+ Common::SeekableReadStream *_source;
+ byte _window[BLOCK_SIZE];
+ uint _windowCursor;
+ bool _eosFlag;
+
+public:
+ bool eos() const;
+ uint32 read(void *dataPtr, uint32 dataSize);
+
+private:
+ /**
+ * Decompress the next <numberOfBytes> from the source stream. Or until EOS
+ *
+ * @param numberOfBytes How many bytes to decompress. This is a count of source bytes, not destination bytes
+ */
+ uint32 decompressBytes(byte* destination, uint32 numberOfBytes);
+};
+
+}
+
+#endif
diff --git a/engines/zvision/utility/single_value_container.cpp b/engines/zvision/utility/single_value_container.cpp
new file mode 100644
index 0000000000..2667b27b75
--- /dev/null
+++ b/engines/zvision/utility/single_value_container.cpp
@@ -0,0 +1,348 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public 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
new file mode 100644
index 0000000000..45b5a89e95
--- /dev/null
+++ b/engines/zvision/utility/single_value_container.h
@@ -0,0 +1,183 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public 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
new file mode 100644
index 0000000000..6471d21e6c
--- /dev/null
+++ b/engines/zvision/utility/utility.cpp
@@ -0,0 +1,237 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public 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
new file mode 100644
index 0000000000..fb571f3fe8
--- /dev/null
+++ b/engines/zvision/utility/utility.h
@@ -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.
+ *
+ *
+ */
+
+#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/video.cpp b/engines/zvision/video/video.cpp
new file mode 100644
index 0000000000..efaecb5045
--- /dev/null
+++ b/engines/zvision/video/video.cpp
@@ -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.
+ *
+ */
+
+#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"
+
+#include "engines/util.h"
+
+#include "graphics/surface.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;
+ }
+ }
+}
+
+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;
+ // 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;
+
+ uint16 finalWidth = origWidth * scale;
+ uint16 finalHeight = origHeight * scale;
+
+ byte *scaledVideoFrameBuffer = 0;
+ if (scale != 1) {
+ scaledVideoFrameBuffer = new byte[finalWidth * finalHeight * bytesPerPixel];
+ }
+
+ uint16 x = ((WINDOW_WIDTH - finalWidth) / 2) + destRect.left;
+ uint16 y = ((WINDOW_HEIGHT - finalHeight) / 2) + destRect.top;
+
+ _clock.stop();
+ videoDecoder.start();
+
+ // Only continue while the video is still playing
+ while (!shouldQuit() && !videoDecoder.endOfVideo() && videoDecoder.isPlaying()) {
+ // Check for engine quit and video stop key presses
+ while (!videoDecoder.endOfVideo() && videoDecoder.isPlaying() && _eventMan->pollEvent(_event)) {
+ switch (_event.type) {
+ case Common::EVENT_KEYDOWN:
+ switch (_event.kbd.keycode) {
+ case Common::KEYCODE_q:
+ if (_event.kbd.hasFlags(Common::KBD_CTRL))
+ quitGame();
+ break;
+ case Common::KEYCODE_SPACE:
+ if (skippable) {
+ videoDecoder.stop();
+ }
+ break;
+ default:
+ break;
+ }
+ default:
+ break;
+ }
+ }
+
+ if (videoDecoder.needsUpdate()) {
+ const Graphics::Surface *frame = videoDecoder.decodeNextFrame();
+
+ 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);
+ }
+ }
+ }
+
+ // Always update the screen so the mouse continues to render
+ _system->updateScreen();
+
+ _system->delayMillis(videoDecoder.getTimeToNextFrame());
+ }
+
+ _clock.start();
+
+ if (scale != 1) {
+ delete[] scaledVideoFrameBuffer;
+ }
+}
+
+} // End of namespace ZVision
diff --git a/engines/zvision/video/zork_avi_decoder.cpp b/engines/zvision/video/zork_avi_decoder.cpp
new file mode 100644
index 0000000000..d3db3421af
--- /dev/null
+++ b/engines/zvision/video/zork_avi_decoder.cpp
@@ -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.
+ *
+ *
+ */
+
+#include "common/scummsys.h"
+
+#include "zvision/video/zork_avi_decoder.h"
+
+#include "zvision/sound/zork_raw.h"
+
+#include "common/stream.h"
+
+#include "audio/audiostream.h"
+
+
+namespace ZVision {
+
+Video::AVIDecoder::AVIAudioTrack *ZorkAVIDecoder::createAudioTrack(Video::AVIDecoder::AVIStreamHeader sHeader, Video::AVIDecoder::PCMWaveFormat wvInfo) {
+ ZorkAVIDecoder::ZorkAVIAudioTrack *audioTrack = new ZorkAVIDecoder::ZorkAVIAudioTrack(sHeader, wvInfo, _soundType);
+ return (Video::AVIDecoder::AVIAudioTrack *)audioTrack;
+}
+
+void ZorkAVIDecoder::ZorkAVIAudioTrack::queueSound(Common::SeekableReadStream *stream) {
+ if (_audStream) {
+ if (_wvInfo.tag == kWaveFormatZorkPCM) {
+ assert(_wvInfo.size == 8);
+ _audStream->queueAudioStream(makeRawZorkStream(stream, _wvInfo.samplesPerSec, _audStream->isStereo(), DisposeAfterUse::YES), DisposeAfterUse::YES);
+ }
+ } else {
+ delete stream;
+ }
+}
+
+} // End of namespace ZVision
diff --git a/engines/zvision/video/zork_avi_decoder.h b/engines/zvision/video/zork_avi_decoder.h
new file mode 100644
index 0000000000..ec2be1bb13
--- /dev/null
+++ b/engines/zvision/video/zork_avi_decoder.h
@@ -0,0 +1,60 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public 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"
+
+
+namespace ZVision {
+
+class ZorkAVIDecoder : public Video::AVIDecoder {
+public:
+ ZorkAVIDecoder(Audio::Mixer::SoundType soundType = Audio::Mixer::kPlainSoundType) :
+ Video::AVIDecoder(soundType) {}
+
+ 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() {}
+
+ void queueSound(Common::SeekableReadStream *stream);
+ };
+
+ Video::AVIDecoder::AVIAudioTrack *createAudioTrack(Video::AVIDecoder::AVIStreamHeader sHeader, Video::AVIDecoder::PCMWaveFormat wvInfo);
+
+private:
+ // Audio Codecs
+ enum {
+ kWaveFormatZorkPCM = 17 // special Zork PCM audio format (clashes with MS IMA ADPCM)
+ };
+};
+
+} // End of namespace ZVision
+
+#endif
diff --git a/engines/zvision/zvision.cpp b/engines/zvision/zvision.cpp
new file mode 100644
index 0000000000..f57e225ac1
--- /dev/null
+++ b/engines/zvision/zvision.cpp
@@ -0,0 +1,184 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public 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/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/detection.h"
+
+#include "common/config-manager.h"
+#include "common/debug.h"
+#include "common/debug-channels.h"
+#include "common/textconsole.h"
+#include "common/error.h"
+#include "common/system.h"
+#include "common/file.h"
+
+#include "engines/util.h"
+
+#include "audio/mixer.h"
+
+
+namespace ZVision {
+
+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) {
+
+ debug(1, "ZVision::ZVision");
+}
+
+ZVision::~ZVision() {
+ debug(1, "ZVision::~ZVision");
+
+ // Dispose of resources
+ delete _console;
+ delete _cursorManager;
+ delete _stringManager;
+ delete _saveManager;
+ delete _renderManager;
+ delete _scriptManager;
+ delete _rnd;
+
+ // Remove all of our debug levels
+ DebugMan.clearAllDebugChannels();
+}
+
+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);
+ }
+
+ initGraphics(WINDOW_WIDTH, WINDOW_HEIGHT, true, &_pixelFormat);
+
+ // Register random source
+ _rnd = new Common::RandomSource("zvision");
+
+ // Create managers
+ _scriptManager = new ScriptManager(this);
+ _renderManager = new RenderManager(_system, WINDOW_WIDTH, WINDOW_HEIGHT, _workingWindow, _pixelFormat);
+ _saveManager = new SaveManager(this);
+ _stringManager = new StringManager(this);
+ _cursorManager = new CursorManager(this, &_pixelFormat);
+
+ // Initialize the managers
+ _cursorManager->initialize();
+ _scriptManager->initialize();
+ _stringManager->initialize(_gameDescription->gameId);
+
+ // Create debugger console. It requires GFX to be initialized
+ _console = new Console(this);
+}
+
+Common::Error ZVision::run() {
+ initialize();
+
+ // Main loop
+ while (!shouldQuit()) {
+ _clock.update();
+ uint32 currentTime = _clock.getLastMeasuredTime();
+ uint32 deltaTime = _clock.getDeltaTime();
+
+ processEvents();
+
+ // Call _renderManager->update() first so the background renders
+ // before anything that puzzles/controls will render
+ _renderManager->update(deltaTime);
+ _scriptManager->update(deltaTime);
+
+ // Render the backBuffer to the screen
+ _renderManager->renderBackbufferToScreen();
+
+ // Update the screen
+ _system->updateScreen();
+
+ // 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;
+ _system->delayMillis(delay);
+ }
+
+ return Common::kNoError;
+}
+
+void ZVision::pauseEngineIntern(bool pause) {
+ _mixer->pauseAll(pause);
+
+ if (pause) {
+ _clock.stop();
+ } else {
+ _clock.start();
+ }
+}
+
+Common::String ZVision::generateSaveFileName(uint slot) {
+ return Common::String::format("%s.%02u", _targetName.c_str(), slot);
+}
+
+Common::String ZVision::generateAutoSaveFileName() {
+ return Common::String::format("%s.auto", _targetName.c_str());
+}
+
+} // End of namespace ZVision
diff --git a/engines/zvision/zvision.h b/engines/zvision/zvision.h
new file mode 100644
index 0000000000..7c130fc87f
--- /dev/null
+++ b/engines/zvision/zvision.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 ZVISION_ZVISION_H
+#define ZVISION_ZVISION_H
+
+#include "zvision/core/console.h"
+#include "zvision/detection.h"
+#include "zvision/utility/clock.h"
+
+#include "common/random.h"
+#include "common/events.h"
+
+#include "engines/engine.h"
+
+#include "graphics/pixelformat.h"
+
+#include "gui/debugger.h"
+
+
+namespace Video {
+class VideoDecoder;
+}
+
+namespace ZVision {
+
+struct ZVisionGameDescription;
+class ScriptManager;
+class RenderManager;
+class CursorManager;
+class StringManager;
+class SaveManager;
+class RlfAnimation;
+
+class ZVision : public Engine {
+public:
+ ZVision(OSystem *syst, const ZVisionGameDescription *gameDesc);
+ ~ZVision();
+
+public:
+ /**
+ * 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;
+ const Graphics::PixelFormat _pixelFormat;
+
+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;
+
+ const int _desiredFrameTime;
+
+ // We need random numbers
+ Common::RandomSource *_rnd;
+
+ // Managers
+ ScriptManager *_scriptManager;
+ RenderManager *_renderManager;
+ CursorManager *_cursorManager;
+ SaveManager *_saveManager;
+ StringManager *_stringManager;
+
+ // Clock
+ Clock _clock;
+
+ // To prevent allocation every time we process events
+ Common::Event _event;
+
+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; }
+
+ /**
+ * Play a video until it is finished. This is a blocking call. It will call
+ * _clock.stop() when the video starts and _clock.start() when the video finishes.
+ * It will also consume all events during video playback.
+ *
+ * @param videoDecoder The video to play
+ * @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);
+
+ Common::String generateSaveFileName(uint slot);
+ Common::String generateAutoSaveFileName();
+
+private:
+ void initialize();
+ void initFonts();
+
+ void parseStrFile(const Common::String fileName);
+
+ /** 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);
+};
+
+} // End of namespace ZVision
+
+#endif
diff --git a/graphics/VectorRendererSpec.cpp b/graphics/VectorRendererSpec.cpp
index 491a9d7f42..a3ec66a29d 100644
--- a/graphics/VectorRendererSpec.cpp
+++ b/graphics/VectorRendererSpec.cpp
@@ -620,7 +620,10 @@ applyScreenShading(GUI::ThemeEngine::ShadingStyle shadingStyle) {
template<typename PixelType>
inline void VectorRendererSpec<PixelType>::
blendPixelPtr(PixelType *ptr, PixelType color, uint8 alpha) {
- if (sizeof(PixelType) == 4) {
+ if (alpha == 0xff) {
+ // fully opaque pixel, don't blend
+ *ptr = color | _alphaMask;
+ } else if (sizeof(PixelType) == 4) {
const byte sR = (color & _redMask) >> _format.rShift;
const byte sG = (color & _greenMask) >> _format.gShift;
const byte sB = (color & _blueMask) >> _format.bShift;
@@ -628,15 +631,17 @@ blendPixelPtr(PixelType *ptr, PixelType color, uint8 alpha) {
byte dR = (*ptr & _redMask) >> _format.rShift;
byte dG = (*ptr & _greenMask) >> _format.gShift;
byte dB = (*ptr & _blueMask) >> _format.bShift;
+ byte dA = (*ptr & _alphaMask) >> _format.aShift;
dR += ((sR - dR) * alpha) >> 8;
dG += ((sG - dG) * alpha) >> 8;
dB += ((sB - dB) * alpha) >> 8;
+ dA += ((0xff - dA) * alpha) >> 8;
*ptr = ((dR << _format.rShift) & _redMask)
| ((dG << _format.gShift) & _greenMask)
| ((dB << _format.bShift) & _blueMask)
- | (*ptr & _alphaMask);
+ | ((dA << _format.aShift) & _alphaMask);
} else if (sizeof(PixelType) == 2) {
int idst = *ptr;
int isrc = color;
@@ -651,7 +656,9 @@ blendPixelPtr(PixelType *ptr, PixelType color, uint8 alpha) {
(_blueMask & ((idst & _blueMask) +
((int)(((int)(isrc & _blueMask) -
(int)(idst & _blueMask)) * alpha) >> 8))) |
- (idst & _alphaMask));
+ (_alphaMask & ((idst & _alphaMask) +
+ ((int)(((int)(_alphaMask) -
+ (int)(idst & _alphaMask)) * alpha) >> 8))));
} else {
error("Unsupported BPP format: %u", (uint)sizeof(PixelType));
}
@@ -691,8 +698,7 @@ darkenFill(PixelType *ptr, PixelType *end) {
// assuming at least 3 alpha bits
mask |= 3 << _format.aShift;
- PixelType addA = (PixelType)(255 >> _format.aLoss) << _format.aShift;
- addA -= (addA >> 2);
+ PixelType addA = (PixelType)(3 << (_format.aShift + 6 - _format.aLoss));
while (ptr != end) {
// Darken the colour, and increase the alpha
@@ -1266,51 +1272,50 @@ template<typename PixelType>
void VectorRendererSpec<PixelType>::
drawBevelSquareAlg(int x, int y, int w, int h, int bevel, PixelType top_color, PixelType bottom_color, bool fill) {
int pitch = _activeSurface->pitch / _activeSurface->format.bytesPerPixel;
+ int i, j;
+ PixelType *ptr_left;
- int height = h;
- PixelType *ptr_fill = (PixelType *)_activeSurface->getBasePtr(x, y);
-
+ // Fill Background
+ ptr_left = (PixelType *)_activeSurface->getBasePtr(x, y);
+ i = h;
if (fill) {
assert((_bgColor & ~_alphaMask) == 0); // only support black
- while (height--) {
- darkenFill(ptr_fill, ptr_fill + w);
- ptr_fill += pitch;
+ while (i--) {
+ darkenFill(ptr_left, ptr_left + w);
+ ptr_left += pitch;
}
}
- int i, j;
-
x = MAX(x - bevel, 0);
y = MAX(y - bevel, 0);
w = MIN(w + (bevel * 2), (int)_activeSurface->w);
h = MIN(h + (bevel * 2), (int)_activeSurface->h);
- PixelType *ptr_left = (PixelType *)_activeSurface->getBasePtr(x, y);
-
+ ptr_left = (PixelType *)_activeSurface->getBasePtr(x, y);
i = bevel;
while (i--) {
colorFill<PixelType>(ptr_left, ptr_left + w, top_color);
ptr_left += pitch;
}
- i = h - bevel;
ptr_left = (PixelType *)_activeSurface->getBasePtr(x, y + bevel);
+ i = h - bevel;
while (i--) {
colorFill<PixelType>(ptr_left, ptr_left + bevel, top_color);
ptr_left += pitch;
}
- i = bevel;
ptr_left = (PixelType *)_activeSurface->getBasePtr(x, y + h - bevel);
+ i = bevel;
while (i--) {
colorFill<PixelType>(ptr_left + i, ptr_left + w, bottom_color);
ptr_left += pitch;
}
+ ptr_left = (PixelType *)_activeSurface->getBasePtr(x + w - bevel, y);
i = h - bevel;
j = bevel - 1;
- ptr_left = (PixelType *)_activeSurface->getBasePtr(x + w - bevel, y);
while (i--) {
colorFill<PixelType>(ptr_left + j, ptr_left + bevel, bottom_color);
if (j > 0) j--;
diff --git a/graphics/cursorman.cpp b/graphics/cursorman.cpp
index 6825767dfd..133ee5fd71 100644
--- a/graphics/cursorman.cpp
+++ b/graphics/cursorman.cpp
@@ -253,6 +253,7 @@ CursorManager::Cursor::Cursor(const void *data, uint w, uint h, int hotspotX, in
_hotspotX = hotspotX;
_hotspotY = hotspotY;
_dontScale = dontScale;
+ _visible = false;
}
CursorManager::Cursor::~Cursor() {
diff --git a/graphics/decoders/iff.cpp b/graphics/decoders/iff.cpp
index 7b37969fc1..fe27258d28 100644
--- a/graphics/decoders/iff.cpp
+++ b/graphics/decoders/iff.cpp
@@ -30,6 +30,10 @@ namespace Graphics {
IFFDecoder::IFFDecoder() {
_surface = 0;
_palette = 0;
+
+ // these 2 properties are not reset by destroy(), so the default is set here.
+ _numRelevantPlanes = 8;
+ _pixelPacking = false;
destroy();
}
@@ -54,8 +58,6 @@ void IFFDecoder::destroy() {
_paletteRanges.clear();
_type = TYPE_UNKNOWN;
_paletteColorCount = 0;
- _numRelevantPlanes = 8;
- _pixelPacking = false;
}
bool IFFDecoder::loadStream(Common::SeekableReadStream &stream) {
diff --git a/graphics/decoders/iff.h b/graphics/decoders/iff.h
index beac62e519..37cb4b38c1 100644
--- a/graphics/decoders/iff.h
+++ b/graphics/decoders/iff.h
@@ -85,6 +85,8 @@ public:
/**
* The number of planes to decode, also determines the pixel packing if _packPixels is true.
* 8 == decode all planes, map 1 pixel in 1 byte. (default, no packing even if _packPixels is true)
+ *
+ * NOTE: this property must be reset manually, and is not reset by a call to destroy().
*/
void setNumRelevantPlanes(const uint8 numRelevantPlanes) { _numRelevantPlanes = numRelevantPlanes; }
@@ -94,6 +96,8 @@ public:
* 2 == decode first 2 planes, pack 4 pixels in 1 byte. This makes _surface->w 1/4th of _header.width
* 4 == decode first 4 planes, pack 2 pixels in 1 byte. This makes _surface->w half of _header.width
* Packed bitmaps won't have a proper surface format since there is no way to tell it to use 1, 2 or 4 bits per pixel
+ *
+ * NOTE: this property must be reset manually, and is not reset by a call to destroy().
*/
void setPixelPacking(const bool pixelPacking) { _pixelPacking = pixelPacking; }
private:
diff --git a/graphics/decoders/image_decoder.h b/graphics/decoders/image_decoder.h
index 49e31c6e3a..a39a9a1493 100644
--- a/graphics/decoders/image_decoder.h
+++ b/graphics/decoders/image_decoder.h
@@ -44,6 +44,9 @@ public:
/**
* Load an image from the specified stream
+ *
+ * loadStream() should implicitly call destroy() to free the memory
+ * of the last loadStream() call.
*
* @param stream the input stream
* @return whether loading the file succeeded
@@ -54,6 +57,9 @@ public:
/**
* Destroy this decoder's surface and palette
+ *
+ * This should be called by a loadStream() implementation as well
+ * as the destructor.
*/
virtual void destroy() = 0;
diff --git a/graphics/decoders/png.cpp b/graphics/decoders/png.cpp
index 505475213f..c4fee46fec 100644
--- a/graphics/decoders/png.cpp
+++ b/graphics/decoders/png.cpp
@@ -38,7 +38,7 @@
namespace Graphics {
-PNGDecoder::PNGDecoder() : _outputSurface(0), _palette(0), _paletteColorCount(0) {
+PNGDecoder::PNGDecoder() : _outputSurface(0), _palette(0), _paletteColorCount(0), _stream(0) {
}
PNGDecoder::~PNGDecoder() {
@@ -163,7 +163,13 @@ bool PNGDecoder::loadStream(Common::SeekableReadStream &stream) {
_outputSurface->create(width, height, Graphics::PixelFormat::createFormatCLUT8());
png_set_packing(pngPtr);
} else {
- _outputSurface->create(width, height, Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0));
+ bool isAlpha = (colorType & PNG_COLOR_MASK_ALPHA);
+ if (png_get_valid(pngPtr, infoPtr, PNG_INFO_tRNS)) {
+ isAlpha = true;
+ png_set_expand(pngPtr);
+ }
+ _outputSurface->create(width, height, Graphics::PixelFormat(4,
+ 8, 8, 8, isAlpha ? 8 : 0, 24, 16, 8, 0));
if (!_outputSurface->getPixels()) {
error("Could not allocate memory for output image.");
}
@@ -171,8 +177,6 @@ bool PNGDecoder::loadStream(Common::SeekableReadStream &stream) {
png_set_strip_16(pngPtr);
if (bitDepth < 8)
png_set_expand(pngPtr);
- if (png_get_valid(pngPtr, infoPtr, PNG_INFO_tRNS))
- png_set_expand(pngPtr);
if (colorType == PNG_COLOR_TYPE_GRAY ||
colorType == PNG_COLOR_TYPE_GRAY_ALPHA)
png_set_gray_to_rgb(pngPtr);
diff --git a/graphics/decoders/tga.cpp b/graphics/decoders/tga.cpp
index a9f136d238..bc27f18a49 100644
--- a/graphics/decoders/tga.cpp
+++ b/graphics/decoders/tga.cpp
@@ -50,6 +50,8 @@ void TGADecoder::destroy() {
}
bool TGADecoder::loadStream(Common::SeekableReadStream &tga) {
+ destroy();
+
byte imageType, pixelDepth;
bool success;
success = readHeader(tga, imageType, pixelDepth);
diff --git a/graphics/decoders/tga.h b/graphics/decoders/tga.h
index d8ccf8f766..5b1e87d4c5 100644
--- a/graphics/decoders/tga.h
+++ b/graphics/decoders/tga.h
@@ -26,6 +26,7 @@
/*
* TGA decoder used in engines:
* - wintermute
+ * - zvision
*/
#ifndef GRAPHICS_DECODERS_TGA_H
diff --git a/graphics/font.cpp b/graphics/font.cpp
index a852274b06..e9f139c478 100644
--- a/graphics/font.cpp
+++ b/graphics/font.cpp
@@ -26,93 +26,32 @@
namespace Graphics {
-int Font::getKerningOffset(byte left, byte right) const {
+int Font::getKerningOffset(uint32 left, uint32 right) const {
return 0;
}
-int Font::getStringWidth(const Common::String &str) const {
+namespace {
+
+template<class StringType>
+int getStringWidthImpl(const Font &font, const StringType &str) {
int space = 0;
- uint last = 0;
+ typename StringType::unsigned_type last = 0;
for (uint i = 0; i < str.size(); ++i) {
- const uint cur = str[i];
- space += getCharWidth(cur) + getKerningOffset(last, cur);
+ const typename StringType::unsigned_type cur = str[i];
+ space += font.getCharWidth(cur) + font.getKerningOffset(last, cur);
last = cur;
}
return space;
}
-void Font::drawString(Surface *dst, const Common::String &sOld, int x, int y, int w, uint32 color, TextAlign align, int deltax, bool useEllipsis) const {
+template<class StringType>
+void drawStringImpl(const Font &font, Surface *dst, const StringType &str, int x, int y, int w, uint32 color, TextAlign align, int deltax) {
assert(dst != 0);
- const int leftX = x, rightX = x + w;
- uint i;
- Common::String s = sOld;
- int width = getStringWidth(s);
- Common::String str;
-
- if (useEllipsis && width > w && s.hasSuffix("...")) {
- // String is too wide. Check whether it ends in an ellipsis
- // ("..."). If so, remove that and try again!
- s.deleteLastChar();
- s.deleteLastChar();
- s.deleteLastChar();
- width = getStringWidth(s);
- }
-
- if (useEllipsis && width > w) {
- // String is too wide. So we shorten it "intelligently" by
- // replacing parts of the string by an ellipsis. There are
- // three possibilities for this: replace the start, the end, or
- // the middle of the string. What is best really depends on the
- // context; but unless we want to make this configurable,
- // replacing the middle seems to be a good compromise.
-
- const int ellipsisWidth = getStringWidth("...");
-
- // SLOW algorithm to remove enough of the middle. But it is good enough
- // for now.
- const int halfWidth = (w - ellipsisWidth) / 2;
- int w2 = 0;
- uint last = 0;
-
- for (i = 0; i < s.size(); ++i) {
- const uint cur = s[i];
- int charWidth = getCharWidth(cur) + getKerningOffset(last, cur);
- if (w2 + charWidth > halfWidth)
- break;
- last = cur;
- w2 += charWidth;
- str += cur;
- }
-
- // At this point we know that the first 'i' chars are together 'w2'
- // pixels wide. We took the first i-1, and add "..." to them.
- str += "...";
- last = '.';
- // The original string is width wide. Of those we already skipped past
- // w2 pixels, which means (width - w2) remain.
- // The new str is (w2+ellipsisWidth) wide, so we can accommodate about
- // (w - (w2+ellipsisWidth)) more pixels.
- // Thus we skip ((width - w2) - (w - (w2+ellipsisWidth))) =
- // (width + ellipsisWidth - w)
- int skip = width + ellipsisWidth - w;
- for (; i < s.size() && skip > 0; ++i) {
- const uint cur = s[i];
- skip -= getCharWidth(cur) + getKerningOffset(last, cur);
- last = cur;
- }
-
- // Append the remaining chars, if any
- for (; i < s.size(); ++i) {
- str += s[i];
- }
-
- width = getStringWidth(str);
- } else {
- str = s;
- }
+ const int leftX = x, rightX = x + w;
+ int width = font.getStringWidth(str);
if (align == kTextAlignCenter)
x = x + (w - width)/2;
@@ -120,29 +59,29 @@ void Font::drawString(Surface *dst, const Common::String &sOld, int x, int y, in
x = x + w - width;
x += deltax;
- uint last = 0;
- for (i = 0; i < str.size(); ++i) {
- const uint cur = str[i];
- x += getKerningOffset(last, cur);
+ typename StringType::unsigned_type last = 0;
+ for (typename StringType::const_iterator i = str.begin(), end = str.end(); i != end; ++i) {
+ const typename StringType::unsigned_type cur = *i;
+ x += font.getKerningOffset(last, cur);
last = cur;
- w = getCharWidth(cur);
+ w = font.getCharWidth(cur);
if (x+w > rightX)
break;
if (x+w >= leftX)
- drawChar(dst, str[i], x, y, color);
+ font.drawChar(dst, cur, x, y, color);
x += w;
}
}
-
+template<class StringType>
struct WordWrapper {
- Common::Array<Common::String> &lines;
+ Common::Array<StringType> &lines;
int actualMaxLineWidth;
- WordWrapper(Common::Array<Common::String> &l) : lines(l), actualMaxLineWidth(0) {
+ WordWrapper(Common::Array<StringType> &l) : lines(l), actualMaxLineWidth(0) {
}
- void add(Common::String &line, int &w) {
+ void add(StringType &line, int &w) {
if (actualMaxLineWidth < w)
actualMaxLineWidth = w;
@@ -153,10 +92,11 @@ struct WordWrapper {
}
};
-int Font::wordWrapText(const Common::String &str, int maxWidth, Common::Array<Common::String> &lines) const {
- WordWrapper wrapper(lines);
- Common::String line;
- Common::String tmpStr;
+template<class StringType>
+int wordWrapTextImpl(const Font &font, const StringType &str, int maxWidth, Common::Array<StringType> &lines) {
+ WordWrapper<StringType> wrapper(lines);
+ StringType line;
+ StringType tmpStr;
int lineWidth = 0;
int tmpWidth = 0;
@@ -173,10 +113,10 @@ int Font::wordWrapText(const Common::String &str, int maxWidth, Common::Array<Co
// of a line. If we encounter such a word, we have to wrap it over multiple
// lines.
- uint last = 0;
- for (Common::String::const_iterator x = str.begin(); x != str.end(); ++x) {
- const byte c = *x;
- const int w = getCharWidth(c) + getKerningOffset(last, c);
+ typename StringType::unsigned_type last = 0;
+ for (typename StringType::const_iterator x = str.begin(); x != str.end(); ++x) {
+ const typename StringType::unsigned_type c = *x;
+ const int w = font.getCharWidth(c) + font.getKerningOffset(last, c);
last = c;
const bool wouldExceedWidth = (lineWidth + tmpWidth + w > maxWidth);
@@ -212,7 +152,7 @@ int Font::wordWrapText(const Common::String &str, int maxWidth, Common::Array<Co
tmpStr.deleteChar(0);
// This is not very fast, but it is the simplest way to
// assure we do not mess something up because of kerning.
- tmpWidth = getStringWidth(tmpStr);
+ tmpWidth = font.getStringWidth(tmpStr);
}
} else {
wrapper.add(tmpStr, tmpWidth);
@@ -232,5 +172,98 @@ int Font::wordWrapText(const Common::String &str, int maxWidth, Common::Array<Co
return wrapper.actualMaxLineWidth;
}
+} // End of anonymous namespace
+
+int Font::getStringWidth(const Common::String &str) const {
+ return getStringWidthImpl(*this, str);
+}
+
+int Font::getStringWidth(const Common::U32String &str) const {
+ return getStringWidthImpl(*this, str);
+}
+
+void Font::drawString(Surface *dst, const Common::String &sOld, int x, int y, int w, uint32 color, TextAlign align, int deltax, bool useEllipsis) const {
+ Common::String s = sOld;
+ int width = getStringWidth(s);
+ Common::String str;
+
+ if (useEllipsis && width > w && s.hasSuffix("...")) {
+ // String is too wide. Check whether it ends in an ellipsis
+ // ("..."). If so, remove that and try again!
+ s.deleteLastChar();
+ s.deleteLastChar();
+ s.deleteLastChar();
+ width = getStringWidth(s);
+ }
+
+ if (useEllipsis && width > w) {
+ // String is too wide. So we shorten it "intelligently" by
+ // replacing parts of the string by an ellipsis. There are
+ // three possibilities for this: replace the start, the end, or
+ // the middle of the string. What is best really depends on the
+ // context; but unless we want to make this configurable,
+ // replacing the middle seems to be a good compromise.
+
+ const int ellipsisWidth = getStringWidth("...");
+
+ // SLOW algorithm to remove enough of the middle. But it is good enough
+ // for now.
+ const int halfWidth = (w - ellipsisWidth) / 2;
+ int w2 = 0;
+ Common::String::unsigned_type last = 0;
+ uint i;
+
+ for (i = 0; i < s.size(); ++i) {
+ const Common::String::unsigned_type cur = s[i];
+ int charWidth = getCharWidth(cur) + getKerningOffset(last, cur);
+ if (w2 + charWidth > halfWidth)
+ break;
+ last = cur;
+ w2 += charWidth;
+ str += cur;
+ }
+
+ // At this point we know that the first 'i' chars are together 'w2'
+ // pixels wide. We took the first i-1, and add "..." to them.
+ str += "...";
+ last = '.';
+
+ // The original string is width wide. Of those we already skipped past
+ // w2 pixels, which means (width - w2) remain.
+ // The new str is (w2+ellipsisWidth) wide, so we can accommodate about
+ // (w - (w2+ellipsisWidth)) more pixels.
+ // Thus we skip ((width - w2) - (w - (w2+ellipsisWidth))) =
+ // (width + ellipsisWidth - w)
+ int skip = width + ellipsisWidth - w;
+ for (; i < s.size() && skip > 0; ++i) {
+ const Common::String::unsigned_type cur = s[i];
+ skip -= getCharWidth(cur) + getKerningOffset(last, cur);
+ last = cur;
+ }
+
+ // Append the remaining chars, if any
+ for (; i < s.size(); ++i) {
+ str += s[i];
+ }
+
+ width = getStringWidth(str);
+ } else {
+ str = s;
+ }
+
+ drawStringImpl(*this, dst, str, x, y, w, color, align, deltax);
+}
+
+void Font::drawString(Surface *dst, const Common::U32String &str, int x, int y, int w, uint32 color, TextAlign align) const {
+ drawStringImpl(*this, dst, str, x, y, w, color, align, 0);
+}
+
+int Font::wordWrapText(const Common::String &str, int maxWidth, Common::Array<Common::String> &lines) const {
+ return wordWrapTextImpl(*this, str, maxWidth, lines);
+}
+
+int Font::wordWrapText(const Common::U32String &str, int maxWidth, Common::Array<Common::U32String> &lines) const {
+ return wordWrapTextImpl(*this, str, maxWidth, lines);
+}
} // End of namespace Graphics
diff --git a/graphics/font.h b/graphics/font.h
index 6819b42f52..77b7623a85 100644
--- a/graphics/font.h
+++ b/graphics/font.h
@@ -23,6 +23,7 @@
#define GRAPHICS_FONT_H
#include "common/str.h"
+#include "common/ustr.h"
namespace Common {
template<class T> class Array;
@@ -70,7 +71,7 @@ public:
* @param chr The character to query the width of.
* @return The character's width.
*/
- virtual int getCharWidth(byte chr) const = 0;
+ virtual int getCharWidth(uint32 chr) const = 0;
/**
* Query the kerning offset between two characters.
@@ -79,7 +80,7 @@ public:
* @param right The right character. May be 0.
* @return The horizontal displacement.
*/
- virtual int getKerningOffset(byte left, byte right) const;
+ virtual int getKerningOffset(uint32 left, uint32 right) const;
/**
* Draw a character at a specific point on a surface.
@@ -96,15 +97,17 @@ public:
* @param y The y coordinate where to draw the character.
* @param color The color of the character.
*/
- virtual void drawChar(Surface *dst, byte chr, int x, int y, uint32 color) const = 0;
+ virtual void drawChar(Surface *dst, uint32 chr, int x, int y, uint32 color) const = 0;
// TODO: Add doxygen comments to this
void drawString(Surface *dst, const Common::String &str, int x, int y, int w, uint32 color, TextAlign align = kTextAlignLeft, int deltax = 0, bool useEllipsis = true) const;
+ void drawString(Surface *dst, const Common::U32String &str, int x, int y, int w, uint32 color, TextAlign align = kTextAlignLeft) const;
/**
* Compute and return the width the string str has when rendered using this font.
*/
int getStringWidth(const Common::String &str) const;
+ int getStringWidth(const Common::U32String &str) const;
/**
* Take a text (which may contain newline characters) and word wrap it so that
@@ -120,6 +123,7 @@ public:
* @return the maximal width of any of the lines added to lines
*/
int wordWrapText(const Common::String &str, int maxWidth, Common::Array<Common::String> &lines) const;
+ int wordWrapText(const Common::U32String &str, int maxWidth, Common::Array<Common::U32String> &lines) const;
};
} // End of namespace Graphics
diff --git a/graphics/fonts/bdf.cpp b/graphics/fonts/bdf.cpp
index e523a36ad5..7b2290cc3a 100644
--- a/graphics/fonts/bdf.cpp
+++ b/graphics/fonts/bdf.cpp
@@ -51,7 +51,7 @@ int BdfFont::getMaxCharWidth() const {
return _data.maxAdvance;
}
-int BdfFont::getCharWidth(byte chr) const {
+int BdfFont::getCharWidth(uint32 chr) const {
// In case all font have the same advance value, we use the maximum.
if (!_data.advances)
return _data.maxAdvance;
@@ -85,9 +85,9 @@ void drawCharIntern(byte *ptr, uint pitch, const byte *src, int h, int width, in
}
}
-int BdfFont::mapToIndex(byte ch) const {
+int BdfFont::mapToIndex(uint32 ch) const {
// Check whether the character is included
- if (_data.firstCharacter <= ch && ch <= _data.firstCharacter + _data.numCharacters) {
+ if (_data.firstCharacter <= (int)ch && (int)ch <= _data.firstCharacter + _data.numCharacters) {
if (_data.bitmaps[ch - _data.firstCharacter])
return ch - _data.firstCharacter;
}
@@ -95,7 +95,7 @@ int BdfFont::mapToIndex(byte ch) const {
return _data.defaultCharacter - _data.firstCharacter;
}
-void BdfFont::drawChar(Surface *dst, byte chr, const int tx, const int ty, const uint32 color) const {
+void BdfFont::drawChar(Surface *dst, uint32 chr, const int tx, const int ty, const uint32 color) const {
assert(dst != 0);
// TODO: Where is the relation between the max advance being smaller or
diff --git a/graphics/fonts/bdf.h b/graphics/fonts/bdf.h
index b0166a2095..842e54f851 100644
--- a/graphics/fonts/bdf.h
+++ b/graphics/fonts/bdf.h
@@ -61,14 +61,14 @@ public:
virtual int getFontHeight() const;
virtual int getMaxCharWidth() const;
- virtual int getCharWidth(byte chr) const;
- virtual void drawChar(Surface *dst, byte chr, int x, int y, uint32 color) const;
+ virtual int getCharWidth(uint32 chr) const;
+ virtual void drawChar(Surface *dst, uint32 chr, int x, int y, uint32 color) const;
static BdfFont *loadFont(Common::SeekableReadStream &stream);
static bool cacheFontData(const BdfFont &font, const Common::String &filename);
static BdfFont *loadFromCache(Common::SeekableReadStream &stream);
private:
- int mapToIndex(byte ch) const;
+ int mapToIndex(uint32 ch) const;
const BdfFontData _data;
const DisposeAfterUse::Flag _dispose;
diff --git a/graphics/fonts/ttf.cpp b/graphics/fonts/ttf.cpp
index b9e9610d77..93f119f028 100644
--- a/graphics/fonts/ttf.cpp
+++ b/graphics/fonts/ttf.cpp
@@ -107,11 +107,11 @@ public:
virtual int getMaxCharWidth() const;
- virtual int getCharWidth(byte chr) const;
+ virtual int getCharWidth(uint32 chr) const;
- virtual int getKerningOffset(byte left, byte right) const;
+ virtual int getKerningOffset(uint32 left, uint32 right) const;
- virtual void drawChar(Surface *dst, byte chr, int x, int y, uint32 color) const;
+ virtual void drawChar(Surface *dst, uint32 chr, int x, int y, uint32 color) const;
private:
bool _initialized;
FT_Face _face;
@@ -126,13 +126,14 @@ private:
Surface image;
int xOffset, yOffset;
int advance;
+ FT_UInt slot;
};
- bool cacheGlyph(Glyph &glyph, FT_UInt &slot, uint chr);
- typedef Common::HashMap<byte, Glyph> GlyphCache;
- GlyphCache _glyphs;
-
- FT_UInt _glyphSlots[256];
+ bool cacheGlyph(Glyph &glyph, uint32 chr) const;
+ typedef Common::HashMap<uint32, Glyph> GlyphCache;
+ mutable GlyphCache _glyphs;
+ bool _allowLateCaching;
+ void assureCached(uint32 chr) const;
bool _monochrome;
bool _hasKerning;
@@ -140,7 +141,7 @@ private:
TTFFont::TTFFont()
: _initialized(false), _face(), _ttfFile(0), _size(0), _width(0), _height(0), _ascent(0),
- _descent(0), _glyphs(), _glyphSlots(), _monochrome(false), _hasKerning(false) {
+ _descent(0), _glyphs(), _monochrome(false), _hasKerning(false), _allowLateCaching(false) {
}
TTFFont::~TTFFont() {
@@ -212,19 +213,26 @@ bool TTFFont::load(Common::SeekableReadStream &stream, int size, uint dpi, bool
_height = _ascent - _descent + 1;
if (!mapping) {
+ // Allow loading of all unicode characters.
+ _allowLateCaching = true;
+
// Load all ISO-8859-1 characters.
for (uint i = 0; i < 256; ++i) {
- if (!cacheGlyph(_glyphs[i], _glyphSlots[i], i))
- _glyphSlots[i] = 0;
+ if (!cacheGlyph(_glyphs[i], i)) {
+ _glyphs.erase(i);
+ }
}
} else {
+ // We have a fixed map of characters do not load more later.
+ _allowLateCaching = false;
+
for (uint i = 0; i < 256; ++i) {
const uint32 unicode = mapping[i] & 0x7FFFFFFF;
const bool isRequired = (mapping[i] & 0x80000000) != 0;
// Check whether loading an important glyph fails and error out if
// that is the case.
- if (!cacheGlyph(_glyphs[i], _glyphSlots[i], unicode)) {
- _glyphSlots[i] = 0;
+ if (!cacheGlyph(_glyphs[i], unicode)) {
+ _glyphs.erase(i);
if (isRequired)
return false;
}
@@ -243,7 +251,8 @@ int TTFFont::getMaxCharWidth() const {
return _width;
}
-int TTFFont::getCharWidth(byte chr) const {
+int TTFFont::getCharWidth(uint32 chr) const {
+ assureCached(chr);
GlyphCache::const_iterator glyphEntry = _glyphs.find(chr);
if (glyphEntry == _glyphs.end())
return 0;
@@ -251,12 +260,29 @@ int TTFFont::getCharWidth(byte chr) const {
return glyphEntry->_value.advance;
}
-int TTFFont::getKerningOffset(byte left, byte right) const {
+int TTFFont::getKerningOffset(uint32 left, uint32 right) const {
if (!_hasKerning)
return 0;
- FT_UInt leftGlyph = _glyphSlots[left];
- FT_UInt rightGlyph = _glyphSlots[right];
+ assureCached(left);
+ assureCached(right);
+
+ FT_UInt leftGlyph, rightGlyph;
+ GlyphCache::const_iterator glyphEntry;
+
+ glyphEntry = _glyphs.find(left);
+ if (glyphEntry != _glyphs.end()) {
+ leftGlyph = glyphEntry->_value.slot;
+ } else {
+ return 0;
+ }
+
+ glyphEntry = _glyphs.find(right);
+ if (glyphEntry != _glyphs.end()) {
+ rightGlyph = glyphEntry->_value.slot;
+ } else {
+ return 0;
+ }
if (!leftGlyph || !rightGlyph)
return 0;
@@ -304,7 +330,8 @@ void renderGlyph(uint8 *dstPos, const int dstPitch, const uint8 *srcPos, const i
} // End of anonymous namespace
-void TTFFont::drawChar(Surface *dst, byte chr, int x, int y, uint32 color) const {
+void TTFFont::drawChar(Surface *dst, uint32 chr, int x, int y, uint32 color) const {
+ assureCached(chr);
GlyphCache::const_iterator glyphEntry = _glyphs.find(chr);
if (glyphEntry == _glyphs.end())
return;
@@ -376,11 +403,13 @@ void TTFFont::drawChar(Surface *dst, byte chr, int x, int y, uint32 color) const
}
}
-bool TTFFont::cacheGlyph(Glyph &glyph, FT_UInt &slot, uint chr) {
- slot = FT_Get_Char_Index(_face, chr);
+bool TTFFont::cacheGlyph(Glyph &glyph, uint32 chr) const {
+ FT_UInt slot = FT_Get_Char_Index(_face, chr);
if (!slot)
return false;
+ glyph.slot = slot;
+
// We use the light target and render mode to improve the looks of the
// glyphs. It is most noticable in FreeSansBold.ttf, where otherwise the
// 't' glyph looks like it is cut off on the right side.
@@ -456,12 +485,24 @@ bool TTFFont::cacheGlyph(Glyph &glyph, FT_UInt &slot, uint chr) {
default:
warning("TTFFont::cacheGlyph: Unsupported pixel mode %d", bitmap.pixel_mode);
+ glyph.image.free();
return false;
}
return true;
}
+void TTFFont::assureCached(uint32 chr) const {
+ if (!chr || !_allowLateCaching || _glyphs.contains(chr)) {
+ return;
+ }
+
+ Glyph newGlyph;
+ if (cacheGlyph(newGlyph, chr)) {
+ _glyphs[chr] = newGlyph;
+ }
+}
+
Font *loadTTFFont(Common::SeekableReadStream &stream, int size, uint dpi, bool monochrome, const uint32 *mapping) {
TTFFont *font = new TTFFont();
diff --git a/graphics/fonts/ttf.h b/graphics/fonts/ttf.h
index e1464b1f45..65aba32fbf 100644
--- a/graphics/fonts/ttf.h
+++ b/graphics/fonts/ttf.h
@@ -32,6 +32,24 @@
namespace Graphics {
class Font;
+
+/**
+ * Loads a TTF font file from a given data stream object.
+ *
+ * @param stream Stream object to load font data from.
+ * @param size The point size to load.
+ * @param dpi The dpi to use for size calculations, by default 72dpi
+ * are used.
+ * @param monochrome Whether the font should be loaded in pure monochrome
+ * mode. In case this is true no aliasing is used.
+ * @param mapping A mapping from code points 0-255 into UTF-32 code points.
+ * This can be used to support various 8bit character sets.
+ * In case the msb of the UTF-32 code point is set the font
+ * loading fails in case no glyph for it is found. When this
+ * is non-null only characters given in the mapping are
+ * supported.
+ * @return 0 in case loading fails, otherwise a pointer to the Font object.
+ */
Font *loadTTFFont(Common::SeekableReadStream &stream, int size, uint dpi = 0, bool monochrome = false, const uint32 *mapping = 0);
void shutdownTTF();
diff --git a/graphics/fonts/winfont.cpp b/graphics/fonts/winfont.cpp
index 3bad92236d..c0ebab19ba 100644
--- a/graphics/fonts/winfont.cpp
+++ b/graphics/fonts/winfont.cpp
@@ -200,7 +200,7 @@ char WinFont::indexToCharacter(uint16 index) const {
return index + _firstChar;
}
-uint16 WinFont::characterToIndex(byte character) const {
+uint16 WinFont::characterToIndex(uint32 character) const {
// Go to the default character if we didn't find a mapping
if (character < _firstChar || character > _lastChar)
character = _defaultChar;
@@ -208,7 +208,7 @@ uint16 WinFont::characterToIndex(byte character) const {
return character - _firstChar;
}
-int WinFont::getCharWidth(byte chr) const {
+int WinFont::getCharWidth(uint32 chr) const {
return _glyphs[characterToIndex(chr)].charWidth;
}
@@ -324,7 +324,7 @@ bool WinFont::loadFromFNT(Common::SeekableReadStream &stream) {
return true;
}
-void WinFont::drawChar(Surface *dst, byte chr, int x, int y, uint32 color) const {
+void WinFont::drawChar(Surface *dst, uint32 chr, int x, int y, uint32 color) const {
assert(dst);
assert(dst->format.bytesPerPixel == 1 || dst->format.bytesPerPixel == 2 || dst->format.bytesPerPixel == 4);
assert(_glyphs);
diff --git a/graphics/fonts/winfont.h b/graphics/fonts/winfont.h
index 4382d7ed6b..2c7ba07b41 100644
--- a/graphics/fonts/winfont.h
+++ b/graphics/fonts/winfont.h
@@ -62,8 +62,8 @@ public:
// Font API
int getFontHeight() const { return _pixHeight; }
int getMaxCharWidth() const { return _maxWidth; }
- int getCharWidth(byte chr) const;
- void drawChar(Surface *dst, byte chr, int x, int y, uint32 color) const;
+ int getCharWidth(uint32 chr) const;
+ void drawChar(Surface *dst, uint32 chr, int x, int y, uint32 color) const;
private:
bool loadFromPE(const Common::String &fileName, const WinFontDirEntry &dirEntry);
@@ -72,7 +72,7 @@ private:
uint32 getFontIndex(Common::SeekableReadStream &stream, const WinFontDirEntry &dirEntry);
bool loadFromFNT(Common::SeekableReadStream &stream);
char indexToCharacter(uint16 index) const;
- uint16 characterToIndex(byte character) const;
+ uint16 characterToIndex(uint32 character) const;
uint16 _pixHeight;
uint16 _maxWidth;
diff --git a/graphics/sjis.cpp b/graphics/sjis.cpp
index 33f0e562cb..59ee5af8c4 100644
--- a/graphics/sjis.cpp
+++ b/graphics/sjis.cpp
@@ -40,31 +40,25 @@ FontSJIS *FontSJIS::createFont(const Common::Platform platform) {
// Try the font ROM of the specified platform
if (platform == Common::kPlatformFMTowns) {
ret = new FontTowns();
- if (ret) {
- if (ret->loadData())
- return ret;
- }
+ if (ret->loadData())
+ return ret;
delete ret;
} else if (platform == Common::kPlatformPCEngine) {
ret = new FontPCEngine();
- if (ret) {
- if (ret->loadData())
- return ret;
- }
+ if (ret->loadData())
+ return ret;
delete ret;
} // TODO: PC98 font rom support
/* else if (platform == Common::kPlatformPC98) {
ret = new FontPC98();
- if (ret) {
- if (ret->loadData())
- return ret;
- }
+ if (ret->loadData())
+ return ret;
delete ret;
}*/
// Try ScummVM's font.
ret = new FontSjisSVM(platform);
- if (ret && ret->loadData())
+ if (ret->loadData())
return ret;
delete ret;
diff --git a/graphics/surface.cpp b/graphics/surface.cpp
index 929157203e..777c1058fb 100644
--- a/graphics/surface.cpp
+++ b/graphics/surface.cpp
@@ -133,6 +133,30 @@ const Surface Surface::getSubArea(const Common::Rect &area) const {
return subSurface;
}
+void Surface::copyRectToSurface(const void *buffer, int srcPitch, int destX, int destY, int width, int height) {
+ assert(buffer);
+
+ assert(destX >= 0 && destX < w);
+ assert(destY >= 0 && destY < h);
+ assert(height > 0 && destY + height <= h);
+ assert(width > 0 && destX + width <= w);
+
+ // Copy buffer data to internal buffer
+ const byte *src = (const byte *)buffer;
+ byte *dst = (byte *)getBasePtr(destX, destY);
+ for (int i = 0; i < height; i++) {
+ memcpy(dst, src, width * format.bytesPerPixel);
+ src += srcPitch;
+ dst += pitch;
+ }
+}
+
+void Surface::copyRectToSurface(const Graphics::Surface &srcSurface, int destX, int destY, const Common::Rect subRect) {
+ assert(srcSurface.format == format);
+
+ copyRectToSurface(srcSurface.getBasePtr(subRect.left, subRect.top), srcSurface.pitch, destX, destY, subRect.width(), subRect.height());
+}
+
void Surface::hLine(int x, int y, int x2, uint32 color) {
// Clipping
if (y < 0 || y >= h)
diff --git a/graphics/surface.h b/graphics/surface.h
index b08d4a5cb7..f1b2aa64ab 100644
--- a/graphics/surface.h
+++ b/graphics/surface.h
@@ -209,6 +209,30 @@ public:
const Surface getSubArea(const Common::Rect &area) const;
/**
+ * Copies a bitmap to the Surface internal buffer. The pixel format
+ * of buffer must match the pixel format of the Surface.
+ *
+ * @param buffer The buffer containing the graphics data source
+ * @param pitch The pitch of the buffer (number of bytes in a scanline)
+ * @param destX The x coordinate of the destination rectangle
+ * @param destY The y coordinate of the destination rectangle
+ * @param width The width of the destination rectangle
+ * @param height The height of the destination rectangle
+ */
+ void copyRectToSurface(const void *buffer, int srcPitch, int destX, int destY, int width, int height);
+ /**
+ * Copies a bitmap to the Surface internal buffer. The pixel format
+ * of buffer must match the pixel format of the Surface.
+ *
+ * @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
+ * @return
+ */
+ void copyRectToSurface(const Graphics::Surface &srcSurface, int destX, int destY, const Common::Rect subRect);
+
+ /**
* Convert the data to another pixel format.
*
* This works in-place. This means it will not create an additional buffer
@@ -310,7 +334,9 @@ public:
*/
struct SharedPtrSurfaceDeleter {
void operator()(Surface *ptr) {
- ptr->free();
+ if (ptr) {
+ ptr->free();
+ }
delete ptr;
}
};
diff --git a/gui/ThemeEngine.cpp b/gui/ThemeEngine.cpp
index 688654d208..9fe482ddcc 100644
--- a/gui/ThemeEngine.cpp
+++ b/gui/ThemeEngine.cpp
@@ -1360,17 +1360,17 @@ bool ThemeEngine::createCursor(const Common::String &filename, int hotspotX, int
// If there is no entry yet for this color in the palette: Add one
if (!colorToIndex.contains(col)) {
+ if (colorsFound >= MAX_CURS_COLORS) {
+ warning("Cursor contains too many colors (%d, but only %d are allowed)", colorsFound, MAX_CURS_COLORS);
+ return false;
+ }
+
const int index = colorsFound++;
colorToIndex[col] = index;
_cursorPal[index * 3 + 0] = r;
_cursorPal[index * 3 + 1] = g;
_cursorPal[index * 3 + 2] = b;
-
- if (colorsFound > MAX_CURS_COLORS) {
- warning("Cursor contains too many colors (%d, but only %d are allowed)", colorsFound, MAX_CURS_COLORS);
- return false;
- }
}
// Copy pixel from the 16 bit source surface to the 8bit target surface
diff --git a/gui/about.cpp b/gui/about.cpp
index 3bb1934e28..459a6b5490 100644
--- a/gui/about.cpp
+++ b/gui/about.cpp
@@ -56,7 +56,7 @@ enum {
static const char *copyright_text[] = {
"",
-"C0""Copyright (C) 2001-2013 The ScummVM project",
+"C0""Copyright (C) 2001-2014 The ScummVM Team",
"C0""http://www.scummvm.org",
"",
"C0""ScummVM is the legal property of its developers, whose names are too numerous to list here. Please refer to the COPYRIGHT file distributed with this binary.",
diff --git a/gui/console.cpp b/gui/console.cpp
index 49e2fccd98..7e88b6dfb5 100644
--- a/gui/console.cpp
+++ b/gui/console.cpp
@@ -82,8 +82,6 @@ ConsoleDialog::ConsoleDialog(float widthPercent, float heightPercent)
_historyIndex = 0;
_historyLine = 0;
_historySize = 0;
- for (int i = 0; i < kHistorySize; i++)
- _history[i][0] = '\0';
// Display greetings & prompt
print(gScummVMFullVersion);
@@ -274,24 +272,19 @@ void ConsoleDialog::handleKeyDown(Common::KeyState state) {
if (len > 0) {
- // We have to allocate the string buffer with new, since VC++ sadly does not
- // comply to the C++ standard, so we can't use a dynamic sized stack array.
- char *str = new char[len + 1];
+ Common::String str;
// Copy the user input to str
for (i = 0; i < len; i++)
- str[i] = buffer(_promptStartPos + i);
- str[len] = '\0';
+ str.insertChar(buffer(_promptStartPos + i), i);
// Add the input to the history
addToHistory(str);
// Pass it to the input callback, if any
if (_callbackProc)
- keepRunning = (*_callbackProc)(this, str, _callbackRefCon);
+ keepRunning = (*_callbackProc)(this, str.c_str(), _callbackRefCon);
- // Get rid of the string buffer
- delete[] str;
}
print(PROMPT);
@@ -575,8 +568,8 @@ void ConsoleDialog::killLastWord() {
}
}
-void ConsoleDialog::addToHistory(const char *str) {
- strcpy(_history[_historyIndex], str);
+void ConsoleDialog::addToHistory(const Common::String &str) {
+ _history[_historyIndex] = str;
_historyIndex = (_historyIndex + 1) % kHistorySize;
_historyLine = 0;
if (_historySize < kHistorySize)
@@ -590,8 +583,7 @@ void ConsoleDialog::historyScroll(int direction) {
if (_historyLine == 0 && direction > 0) {
int i;
for (i = 0; i < _promptEndPos - _promptStartPos; i++)
- _history[_historyIndex][i] = buffer(_promptStartPos + i);
- _history[_historyIndex][i] = '\0';
+ _history[_historyIndex].insertChar(buffer(_promptStartPos + i), i);
}
// Advance to the next line in the history
@@ -617,7 +609,8 @@ void ConsoleDialog::historyScroll(int direction) {
idx = (_historyIndex - _historyLine + _historySize) % _historySize;
else
idx = _historyIndex;
- for (int i = 0; i < kLineBufferSize && _history[idx][i] != '\0'; i++)
+ int length = _history[idx].size();
+ for (int i = 0; i < length; i++)
printCharIntern(_history[idx][i]);
_promptEndPos = _currentPos;
diff --git a/gui/console.h b/gui/console.h
index 50a00a1ad1..194bfd6fc0 100644
--- a/gui/console.h
+++ b/gui/console.h
@@ -23,6 +23,7 @@
#define CONSOLE_DIALOG_H
#include "gui/dialog.h"
+#include "common/str.h"
namespace GUI {
@@ -69,7 +70,6 @@ protected:
enum {
kBufferSize = 32768,
kCharsPerLine = 128,
- kLineBufferSize = 256,
kHistorySize = 20
};
@@ -112,7 +112,7 @@ protected:
CompletionCallbackProc _completionCallbackProc;
void *_completionCallbackRefCon;
- char _history[kHistorySize][kLineBufferSize];
+ Common::String _history[kHistorySize];
int _historySize;
int _historyIndex;
int _historyLine;
@@ -184,7 +184,7 @@ protected:
void killLastWord();
// History
- void addToHistory(const char *str);
+ void addToHistory(const Common::String &str);
void historyScroll(int direction);
};
diff --git a/gui/credits.h b/gui/credits.h
index 3a4d7769f6..bcace12d13 100644
--- a/gui/credits.h
+++ b/gui/credits.h
@@ -77,6 +77,12 @@ static const char *credits[] = {
"C0""Ludvig Strigeus",
"C2""(retired)",
"",
+"C1""Avalanche",
+"A0""Peter Bozso",
+"C0""Peter Bozs\363",
+"A0""Arnaud Boutonne",
+"C0""Arnaud Boutonn\351",
+"",
"C1""CGE",
"A0""Arnaud Boutonne",
"C0""Arnaud Boutonn\351",
@@ -297,6 +303,9 @@ static const char *credits[] = {
"A0""Einar Johan T. Somaaen",
"C0""Einar Johan T. S\370m\345en",
"",
+"C1""ZVision",
+"C0""Adrian Astley",
+"",
"",
"C1""Backend Teams",
"C1""Android",
@@ -513,7 +522,7 @@ static const char *credits[] = {
"C0""Johannes Schickel",
"",
"",
-"C1""Translations",
+"C1""GUI Translations",
"C0""Thierry Crozat",
"C2""Translation Lead",
"C1""Basque",
@@ -583,6 +592,28 @@ static const char *credits[] = {
"C0""Lubomyr Lisen",
"",
"",
+"C1""Game Translations",
+"C1""CGE",
+"C0""Dan Serban",
+"C2""Soltys English translation",
+"A0""Victor Gonzalez",
+"C0""V\355ctor Gonz\341lez",
+"C2""Soltys Spanish translation",
+"A0""Alejandro Gomez de la Munoza",
+"C0""Alejandro G\363mez de la Mu\361oza",
+"C2""Soltys Spanish translation",
+"",
+"C1""Drascula",
+"C0""Thierry Crozat",
+"C2""Improve French translation",
+"",
+"C1""Mortevielle",
+"C0""Hugo Labrande",
+"C2""Improve English translation",
+"C0""Thierry Crozat",
+"C2""Improve English translation",
+"",
+"",
"C1""Websites (design)",
"A0""Dobo Balazs",
"C0""Dob\363 Bal\341zs",
@@ -618,6 +649,8 @@ static const char *credits[] = {
"C2""Several fixes for Simon1",
"C0""Jeroen Janssen",
"C2""Numerous readability and bugfix patches",
+"C0""Keith Kaisershot",
+"C2""Several Pegasus Prime patches",
"C0""Andreas Karlsson",
"C2""Initial port for SymbianOS",
"C0""Claudio Matsuoka",
@@ -769,6 +802,8 @@ static const char *credits[] = {
"C2""For additional work on the original MT-32 emulator",
"C0""James Woodcock",
"C2""Soundtrack enhancements",
+"C0""Anton Yartsev",
+"C2""For the original re-implementation of the ZVision engine",
"C0""Tony Warriner and everyone at Revolution Software Ltd. for sharing with us the source of some of their brilliant games, allowing us to release Beneath a Steel Sky as freeware... and generally being supportive above and beyond the call of duty.",
"C0""",
"C0""John Passfield and Steve Stamatiadis for sharing the source of their classic title, Flight of the Amazon Queen and also being incredibly supportive.",
diff --git a/gui/debugger.cpp b/gui/debugger.cpp
index 35627dd584..9aa322e12e 100644
--- a/gui/debugger.cpp
+++ b/gui/debugger.cpp
@@ -133,6 +133,14 @@ Debugger *g_readline_debugger;
char *readline_completionFunction(const char *text, int state) {
return g_readline_debugger->readlineComplete(text, state);
}
+
+#ifdef USE_READLINE_INT_COMPLETION
+typedef int RLCompFunc_t(const char *, int);
+#else
+typedef char *RLCompFunc_t(const char *, int);
+#endif
+
+
} // end of anonymous namespace
#endif
@@ -162,7 +170,7 @@ void Debugger::enter() {
// TODO: add support for saving/loading history?
g_readline_debugger = this;
- rl_completion_entry_function = &readline_completionFunction;
+ rl_completion_entry_function = (RLCompFunc_t *)&readline_completionFunction;
char *line_read = 0;
do {
diff --git a/gui/gui-manager.cpp b/gui/gui-manager.cpp
index 1505c8c707..999d61e854 100644
--- a/gui/gui-manager.cpp
+++ b/gui/gui-manager.cpp
@@ -309,6 +309,19 @@ void GuiManager::runLoop() {
Common::Event event;
while (eventMan->pollEvent(event)) {
+ // We will need to check whether the screen changed while polling
+ // for an event here. While we do send EVENT_SCREEN_CHANGED
+ // whenever this happens we still cannot be sure that we get such
+ // an event immediately. For example, we might have an mouse move
+ // event queued before an screen changed event. In some rare cases
+ // this would make the GUI redraw (with the code a few lines
+ // below) when it is not yet updated for new overlay dimensions.
+ // As a result ScummVM would crash because it tries to copy data
+ // outside the actual overlay screen.
+ if (event.type != Common::EVENT_SCREEN_CHANGED) {
+ checkScreenChange();
+ }
+
// The top dialog can change during the event loop. In that case, flush all the
// dialog-related events since they were probably generated while the old dialog
// was still visible, and therefore not intended for the new one.
diff --git a/gui/predictivedialog.cpp b/gui/predictivedialog.cpp
index 5ce093e054..5d45a3060e 100644
--- a/gui/predictivedialog.cpp
+++ b/gui/predictivedialog.cpp
@@ -69,7 +69,7 @@ enum {
PredictiveDialog::PredictiveDialog() : Dialog("Predictive") {
new StaticTextWidget(this, "Predictive.Headline", "Enter Text");
- _btns = (ButtonWidget **)calloc(1, sizeof(ButtonWidget *) * 16);
+ _btns = (ButtonWidget **)calloc(16, sizeof(ButtonWidget *));
_btns[kCancelAct] = new ButtonWidget(this, "Predictive.Cancel", _("Cancel") , 0, kCancelCmd);
_btns[kOkAct] = new ButtonWidget(this, "Predictive.OK", _("Ok") , 0, kOkCmd);
@@ -144,6 +144,7 @@ PredictiveDialog::PredictiveDialog() : Dialog("Predictive") {
_currentWord.clear();
_wordNumber = 0;
_numMatchingWords = 0;
+ memset(_predictiveResult, 0, sizeof(_predictiveResult));
_lastbutton = kNoAct;
_mode = kModePre;
@@ -420,6 +421,9 @@ void PredictiveDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 d
case kCancelCmd:
saveUserDictToFile();
close();
+ // When we cancel the dialog no result should be returned. Thus, we
+ // will invalidate any result here.
+ _predictiveResult[0] = 0;
return;
case kOkCmd:
_currBtn = kOkAct;
@@ -614,7 +618,7 @@ void PredictiveDialog::handleTickle() {
void PredictiveDialog::mergeDicts() {
_unitedDict.dictLineCount = _predictiveDict.dictLineCount + _userDict.dictLineCount;
- _unitedDict.dictLine = (char **)calloc(1, sizeof(char *) * _unitedDict.dictLineCount);
+ _unitedDict.dictLine = (char **)calloc(_unitedDict.dictLineCount, sizeof(char *));
if (!_unitedDict.dictLine) {
debug("Predictive Dialog: cannot allocate memory for united dic");
@@ -748,7 +752,8 @@ bool PredictiveDialog::matchWord() {
char tmp[kMaxLineLen];
strncpy(tmp, _unitedDict.dictLine[line], kMaxLineLen);
tmp[kMaxLineLen - 1] = 0;
- char *tok = strtok(tmp, " ");
+ char *tok;
+ strtok(tmp, " ");
tok = strtok(NULL, " ");
_currentWord = Common::String(tok, _currentCode.size());
return true;
@@ -853,7 +858,7 @@ void PredictiveDialog::addWord(Dict &dict, const Common::String &word, const Com
}
// start from here are INSERTING new line to dictionaty ( dict )
- char **newDictLine = (char **)calloc(1, sizeof(char *) * (dict.dictLineCount + 1));
+ char **newDictLine = (char **)calloc(dict.dictLineCount + 1, sizeof(char *));
if (!newDictLine) {
warning("Predictive Dialog: cannot allocate memory for index buffer");
@@ -861,7 +866,6 @@ void PredictiveDialog::addWord(Dict &dict, const Common::String &word, const Com
return;
}
- newDictLine[dict.dictLineCount] = '\0';
int k = 0;
bool inserted = false;
@@ -883,7 +887,7 @@ void PredictiveDialog::addWord(Dict &dict, const Common::String &word, const Com
free(dict.dictLine);
dict.dictLineCount += 1;
- dict.dictLine = (char **)calloc(1, sizeof(char *) * dict.dictLineCount);
+ dict.dictLine = (char **)calloc(dict.dictLineCount, sizeof(char *));
if (!dict.dictLine) {
warning("Predictive Dialog: cannot allocate memory for index buffer");
free(newDictLine);
@@ -935,7 +939,7 @@ void PredictiveDialog::loadDictionary(Common::SeekableReadStream *in, Dict &dict
ptr++;
}
- dict.dictLine = (char **)calloc(1, sizeof(char *) * lines);
+ dict.dictLine = (char **)calloc(lines, sizeof(char *));
if (dict.dictLine == NULL) {
warning("Predictive Dialog: Cannot allocate memory for line index buffer");
return;
diff --git a/gui/recorderdialog.h b/gui/recorderdialog.h
index eb690a4f38..9c5965f56d 100644
--- a/gui/recorderdialog.h
+++ b/gui/recorderdialog.h
@@ -34,6 +34,8 @@ class ContainerWidget;
class StaticTextWidget;
class RecorderDialog : public GUI::Dialog {
+ using GUI::Dialog::runModal;
+
private:
bool _firstScreenshotUpdate;
Common::PlaybackFile _playbackFile;
diff --git a/gui/themes/default.inc b/gui/themes/default.inc
index 352cc86852..fe1bf041ad 100644
--- a/gui/themes/default.inc
+++ b/gui/themes/default.inc
@@ -1,615 +1,4 @@
"<?xml version = '1.0'?>"
-"<render_info>"
-"<palette>"
-"<color name='black' "
-"rgb='0,0,0' "
-"/>"
-"<color name='lightgrey' "
-"rgb='104,104,104' "
-"/>"
-"<color name='darkgrey' "
-"rgb='64,64,64' "
-"/>"
-"<color name='green' "
-"rgb='32,160,32' "
-"/>"
-"<color name='green2' "
-"rgb='0,255,0' "
-"/>"
-"</palette>"
-"<fonts>"
-"<font id='text_default' "
-"file='helvb12.bdf' "
-"/>"
-"<font resolution='y<400' "
-"id='text_default' "
-"file='clR6x12.bdf' "
-"/>"
-"<font id='text_button' "
-"file='helvb12.bdf' "
-"/>"
-"<font resolution='y<400' "
-"id='text_button' "
-"file='clR6x12.bdf' "
-"/>"
-"<font id='text_normal' "
-"file='helvb12.bdf' "
-"/>"
-"<font resolution='y<400' "
-"id='text_normal' "
-"file='clR6x12.bdf' "
-"/>"
-"<font id='tooltip_normal' "
-"file='fixed5x8.bdf' "
-"/>"
-"<text_color id='color_normal' "
-"color='green' "
-"/>"
-"<text_color id='color_normal_inverted' "
-"color='black' "
-"/>"
-"<text_color id='color_normal_hover' "
-"color='green2' "
-"/>"
-"<text_color id='color_normal_disabled' "
-"color='lightgrey' "
-"/>"
-"<text_color id='color_alternative' "
-"color='lightgrey' "
-"/>"
-"<text_color id='color_alternative_inverted' "
-"color='255,255,255' "
-"/>"
-"<text_color id='color_alternative_hover' "
-"color='176,176,176' "
-"/>"
-"<text_color id='color_alternative_disabled' "
-"color='darkgrey' "
-"/>"
-"<text_color id='color_button' "
-"color='green' "
-"/>"
-"<text_color id='color_button_hover' "
-"color='green2' "
-"/>"
-"<text_color id='color_button_disabled' "
-"color='lightgrey' "
-"/>"
-"</fonts>"
-"<defaults fill='foreground' fg_color='darkgrey' bg_color='black' shadow='0' bevel_color='lightgrey'/>"
-"<drawdata id='text_selection' cache='false'>"
-"<drawstep func='square' "
-"fill='foreground' "
-"fg_color='lightgrey' "
-"/>"
-"</drawdata>"
-"<drawdata id='text_selection_focus' cache='false'>"
-"<drawstep func='square' "
-"fill='foreground' "
-"fg_color='green' "
-"/>"
-"</drawdata>"
-"<drawdata id='mainmenu_bg' cache='false'>"
-"<drawstep func='fill' "
-"fill='foreground' "
-"fg_color='black' "
-"/>"
-"</drawdata>"
-"<drawdata id='special_bg' cache='false'>"
-"<drawstep func='bevelsq' "
-"bevel='2' "
-"/>"
-"</drawdata>"
-"<drawdata id='tooltip_bg' cache='false'>"
-"<drawstep func='bevelsq' "
-"bevel='2' "
-"fill='foreground' "
-"fg_color='black' "
-"/>"
-"</drawdata>"
-"<drawdata id='separator' cache='false'>"
-"<drawstep func='square' "
-"fill='foreground' "
-"height='2' "
-"ypos='center' "
-"fg_color='lightgrey' "
-"/>"
-"</drawdata>"
-"<drawdata id='scrollbar_base' cache='false'>"
-"<drawstep func='bevelsq' "
-"bevel='2' "
-"/>"
-"</drawdata>"
-"<drawdata id='scrollbar_handle_hover' cache='false'>"
-"<drawstep func='square' "
-"fill='foreground' "
-"fg_color='green2' "
-"/>"
-"</drawdata>"
-"<drawdata id='scrollbar_handle_idle' cache='false'>"
-"<drawstep func='square' "
-"fill='foreground' "
-"fg_color='green' "
-"/>"
-"</drawdata>"
-"<drawdata id='scrollbar_button_idle' cache='false' resolution='y>399'>"
-"<drawstep func='bevelsq' "
-"bevel='2' "
-"fill='none' "
-"/>"
-"<drawstep func='triangle' "
-"fg_color='green' "
-"fill='foreground' "
-"width='10' "
-"height='10' "
-"xpos='right' "
-"ypos='center' "
-"padding='0,0,3,0' "
-"orientation='top' "
-"/>"
-"</drawdata>"
-"<drawdata id='scrollbar_button_idle' cache='false' resolution='y<400'>"
-"<drawstep func='bevelsq' "
-"bevel='2' "
-"fill='none' "
-"/>"
-"<drawstep func='triangle' "
-"fg_color='green' "
-"fill='foreground' "
-"width='5' "
-"height='5' "
-"xpos='right' "
-"ypos='center' "
-"padding='0,0,2,0' "
-"orientation='top' "
-"/>"
-"</drawdata>"
-"<drawdata id='scrollbar_button_hover' cache='false' resolution='y>399'>"
-"<drawstep func='bevelsq' "
-"bevel='2' "
-"fill='none' "
-"/>"
-"<drawstep func='triangle' "
-"fg_color='green' "
-"fill='foreground' "
-"width='10' "
-"height='10' "
-"xpos='right' "
-"ypos='center' "
-"padding='0,0,3,0' "
-"orientation='top' "
-"/>"
-"</drawdata>"
-"<drawdata id='scrollbar_button_hover' cache='false' resolution='y<400'>"
-"<drawstep func='bevelsq' "
-"bevel='2' "
-"fill='none' "
-"/>"
-"<drawstep func='triangle' "
-"fg_color='green' "
-"fill='foreground' "
-"width='5' "
-"height='5' "
-"xpos='right' "
-"ypos='center' "
-"padding='0,0,2,0' "
-"orientation='top' "
-"/>"
-"</drawdata>"
-"<drawdata id='tab_active' cache='false'>"
-"<text font='text_default' "
-"text_color='color_normal_hover' "
-"vertical_align='center' "
-"horizontal_align='center' "
-"/>"
-"<drawstep func='tab' "
-"bevel='2' "
-"radius='0' "
-"fill='none' "
-"/>"
-"</drawdata>"
-"<drawdata id='tab_inactive' cache='false'>"
-"<text font='text_default' "
-"text_color='color_normal' "
-"vertical_align='center' "
-"horizontal_align='center' "
-"/>"
-"<drawstep func='tab' "
-"bevel='2' "
-"radius='0' "
-"fill='none' "
-"/>"
-"</drawdata>"
-"<drawdata id='tab_background' cache='false'>"
-"</drawdata>"
-"<drawdata id='widget_slider' cache='false'>"
-"<drawstep func='bevelsq' "
-"bevel='2' "
-"fill='none' "
-"/>"
-"</drawdata>"
-"<drawdata id='slider_disabled' cache='false'>"
-"<drawstep func='square' "
-"fill='foreground' "
-"fg_color='lightgrey' "
-"/>"
-"</drawdata>"
-"<drawdata id='slider_full' cache='false'>"
-"<drawstep func='square' "
-"fill='foreground' "
-"fg_color='green' "
-"/>"
-"</drawdata>"
-"<drawdata id='slider_hover' cache='false'>"
-"<drawstep func='square' "
-"fill='foreground' "
-"fg_color='green2' "
-"/>"
-"</drawdata>"
-"<drawdata id='widget_small' cache='false'>"
-"<drawstep func='bevelsq' "
-"bevel='2' "
-"fill='none' "
-"/>"
-"</drawdata>"
-"<drawdata id='popup_idle' cache='false' resolution='y>399'>"
-"<drawstep func='bevelsq' "
-"bevel='2' "
-"fill='none' "
-"/>"
-"<drawstep func='triangle' "
-"fg_color='green' "
-"fill='foreground' "
-"width='10' "
-"height='5' "
-"xpos='right' "
-"ypos='10' "
-"padding='0,0,7,0' "
-"orientation='bottom' "
-"/>"
-"<drawstep func='triangle' "
-"fg_color='green' "
-"fill='foreground' "
-"width='10' "
-"height='5' "
-"xpos='right' "
-"ypos='4' "
-"padding='0,0,7,0' "
-"orientation='top' "
-"/>"
-"<text font='text_default' "
-"text_color='color_normal' "
-"vertical_align='center' "
-"horizontal_align='left' "
-"/>"
-"</drawdata>"
-"<drawdata id='popup_idle' cache='false' resolution='y<400'>"
-"<drawstep func='bevelsq' "
-"bevel='2' "
-"fill='none' "
-"/>"
-"<drawstep func='triangle' "
-"fg_color='green' "
-"fill='foreground' "
-"width='7' "
-"height='4' "
-"xpos='right' "
-"ypos='9' "
-"padding='0,0,3,0' "
-"orientation='bottom' "
-"/>"
-"<drawstep func='triangle' "
-"fg_color='green' "
-"fill='foreground' "
-"width='7' "
-"height='4' "
-"xpos='right' "
-"ypos='4' "
-"padding='0,0,3,0' "
-"orientation='top' "
-"/>"
-"<text font='text_default' "
-"text_color='color_normal' "
-"vertical_align='center' "
-"horizontal_align='left' "
-"/>"
-"</drawdata>"
-"<drawdata id='popup_disabled' cache='false' resolution='y>399'>"
-"<drawstep func='bevelsq' "
-"bevel='2' "
-"fill='none' "
-"/>"
-"<drawstep func='triangle' "
-"fg_color='green' "
-"fill='foreground' "
-"width='10' "
-"height='5' "
-"xpos='right' "
-"ypos='10' "
-"padding='0,0,7,0' "
-"orientation='bottom' "
-"/>"
-"<drawstep func='triangle' "
-"fg_color='green' "
-"fill='foreground' "
-"width='10' "
-"height='5' "
-"xpos='right' "
-"ypos='4' "
-"padding='0,0,7,0' "
-"orientation='top' "
-"/>"
-"<text font='text_default' "
-"text_color='color_normal_disabled' "
-"vertical_align='center' "
-"horizontal_align='left' "
-"/>"
-"</drawdata>"
-"<drawdata id='popup_disabled' cache='false' resolution='y<400'>"
-"<drawstep func='bevelsq' "
-"bevel='2' "
-"fill='none' "
-"/>"
-"<drawstep func='triangle' "
-"fg_color='green' "
-"fill='foreground' "
-"width='7' "
-"height='4' "
-"xpos='right' "
-"ypos='9' "
-"padding='0,0,3,0' "
-"orientation='bottom' "
-"/>"
-"<drawstep func='triangle' "
-"fg_color='green' "
-"fill='foreground' "
-"width='7' "
-"height='4' "
-"xpos='right' "
-"ypos='4' "
-"padding='0,0,3,0' "
-"orientation='top' "
-"/>"
-"<text font='text_default' "
-"text_color='color_normal' "
-"vertical_align='center' "
-"horizontal_align='left' "
-"/>"
-"</drawdata>"
-"<drawdata id='popup_hover' cache='false' resolution='y>399'>"
-"<drawstep func='bevelsq' "
-"bevel='2' "
-"fill='none' "
-"/>"
-"<drawstep func='triangle' "
-"fg_color='green' "
-"fill='foreground' "
-"width='10' "
-"height='5' "
-"xpos='right' "
-"ypos='10' "
-"padding='0,0,7,0' "
-"orientation='bottom' "
-"/>"
-"<drawstep func='triangle' "
-"fg_color='green' "
-"fill='foreground' "
-"width='10' "
-"height='5' "
-"xpos='right' "
-"ypos='4' "
-"padding='0,0,7,0' "
-"orientation='top' "
-"/>"
-"<text font='text_default' "
-"text_color='color_normal_hover' "
-"vertical_align='center' "
-"horizontal_align='left' "
-"/>"
-"</drawdata>"
-"<drawdata id='popup_hover' cache='false' resolution='y<400'>"
-"<drawstep func='bevelsq' "
-"bevel='2' "
-"fill='none' "
-"/>"
-"<drawstep func='triangle' "
-"fg_color='green' "
-"fill='foreground' "
-"width='7' "
-"height='4' "
-"xpos='right' "
-"ypos='9' "
-"padding='0,0,3,0' "
-"orientation='bottom' "
-"/>"
-"<drawstep func='triangle' "
-"fg_color='green' "
-"fill='foreground' "
-"width='7' "
-"height='4' "
-"xpos='right' "
-"ypos='4' "
-"padding='0,0,3,0' "
-"orientation='top' "
-"/>"
-"<text font='text_default' "
-"text_color='color_normal' "
-"vertical_align='center' "
-"horizontal_align='left' "
-"/>"
-"</drawdata>"
-"<drawdata id='widget_textedit' cache='false'>"
-"<drawstep func='bevelsq' "
-"bevel='2' "
-"fill='none' "
-"/>"
-"</drawdata>"
-"<drawdata id='plain_bg' cache='false'>"
-"<drawstep func='bevelsq' "
-"bevel='2' "
-"/>"
-"</drawdata>"
-"<drawdata id='caret' cache='false'>"
-"<drawstep func='square' "
-"fill='foreground' "
-"fg_color='lightgrey' "
-"/>"
-"</drawdata>"
-"<drawdata id='default_bg' cache='false'>"
-"<drawstep func='bevelsq' "
-"bevel='2' "
-"/>"
-"</drawdata>"
-"<drawdata id='button_pressed' cache='false'>"
-"<text font='text_button' "
-"text_color='color_alternative_inverted' "
-"vertical_align='center' "
-"horizontal_align='center' "
-"/>"
-"<drawstep func='square' "
-"fill='foreground' "
-"fg_color='green' "
-"/>"
-"</drawdata>"
-"<drawdata id='button_idle' cache='false'>"
-"<text font='text_button' "
-"text_color='color_button' "
-"vertical_align='center' "
-"horizontal_align='center' "
-"/>"
-"<drawstep func='bevelsq' "
-"bevel='2' "
-"fill='none' "
-"/>"
-"</drawdata>"
-"<drawdata id='button_hover' cache='false'>"
-"<text font='text_button' "
-"text_color='color_button_hover' "
-"vertical_align='center' "
-"horizontal_align='center' "
-"/>"
-"<drawstep func='bevelsq' "
-"bevel='2' "
-"fill='none' "
-"/>"
-"</drawdata>"
-"<drawdata id='button_disabled' cache='false'>"
-"<text font='text_button' "
-"text_color='color_button_disabled' "
-"vertical_align='center' "
-"horizontal_align='center' "
-"/>"
-"<drawstep func='bevelsq' "
-"bevel='2' "
-"fill='none' "
-"/>"
-"</drawdata>"
-"<drawdata id='checkbox_disabled' cache='false'>"
-"<text font='text_default' "
-"text_color='color_normal_disabled' "
-"vertical_align='top' "
-"horizontal_align='left' "
-"/>"
-"<drawstep func='bevelsq' "
-"bevel='2' "
-"fill='none' "
-"/>"
-"</drawdata>"
-"<drawdata id='checkbox_selected' cache='false'>"
-"<text font='text_default' "
-"text_color='color_normal' "
-"vertical_align='top' "
-"horizontal_align='left' "
-"/>"
-"<drawstep func='bevelsq' "
-"bevel='2' "
-"fill='none' "
-"/>"
-"<drawstep func='cross' "
-"fill='foreground' "
-"stroke='2' "
-"fg_color='green' "
-"/>"
-"</drawdata>"
-"<drawdata id='checkbox_default' cache='false'>"
-"<text font='text_default' "
-"text_color='color_normal' "
-"vertical_align='top' "
-"horizontal_align='left' "
-"/>"
-"<drawstep func='bevelsq' "
-"bevel='2' "
-"fill='none' "
-"/>"
-"</drawdata>"
-"<drawdata id='radiobutton_default' cache='false'>"
-"<text font='text_default' "
-"text_color='color_normal' "
-"vertical_align='center' "
-"horizontal_align='left' "
-"/>"
-"<drawstep func='circle' "
-"width='7' "
-"height='7' "
-"radius='7' "
-"fill='background' "
-"bg_color='darkgrey' "
-"xpos='0' "
-"ypos='0' "
-"/>"
-"</drawdata>"
-"<drawdata id='radiobutton_selected' cache='false'>"
-"<text font='text_default' "
-"text_color='color_normal' "
-"vertical_align='center' "
-"horizontal_align='left' "
-"/>"
-"<drawstep func='circle' "
-"width='7' "
-"height='7' "
-"radius='7' "
-"fg_color='darkgrey' "
-"fill='none' "
-"xpos='0' "
-"ypos='0' "
-"/>"
-"<drawstep func='circle' "
-"width='7' "
-"height='7' "
-"radius='5' "
-"fg_color='green' "
-"fill='foreground' "
-"xpos='2' "
-"ypos='2' "
-"/>"
-"</drawdata>"
-"<drawdata id='radiobutton_disabled' cache='false'>"
-"<text font='text_default' "
-"text_color='color_normal_disabled' "
-"vertical_align='center' "
-"horizontal_align='left' "
-"/>"
-"<drawstep func='circle' "
-"width='7' "
-"height='7' "
-"radius='7' "
-"bg_color='lightgrey' "
-"fill='background' "
-"xpos='0' "
-"ypos='0' "
-"/>"
-"</drawdata>"
-"<drawdata id='widget_default' cache='false'>"
-"<drawstep func='bevelsq' "
-"bevel='2' "
-"/>"
-"</drawdata>"
-"<drawdata id='widget_small' cache='false'>"
-"<drawstep func='square' "
-"stroke='0' "
-"/>"
-"</drawdata>"
-"</render_info>"
"<layout_info resolution='y>399'>"
"<globals>"
"<def var='Line.Height' value='16' />"
@@ -1873,6 +1262,617 @@
"</layout>"
"</dialog>"
"</layout_info>"
+"<render_info>"
+"<palette>"
+"<color name='black' "
+"rgb='0,0,0' "
+"/>"
+"<color name='lightgrey' "
+"rgb='104,104,104' "
+"/>"
+"<color name='darkgrey' "
+"rgb='64,64,64' "
+"/>"
+"<color name='green' "
+"rgb='32,160,32' "
+"/>"
+"<color name='green2' "
+"rgb='0,255,0' "
+"/>"
+"</palette>"
+"<fonts>"
+"<font id='text_default' "
+"file='helvb12.bdf' "
+"/>"
+"<font resolution='y<400' "
+"id='text_default' "
+"file='clR6x12.bdf' "
+"/>"
+"<font id='text_button' "
+"file='helvb12.bdf' "
+"/>"
+"<font resolution='y<400' "
+"id='text_button' "
+"file='clR6x12.bdf' "
+"/>"
+"<font id='text_normal' "
+"file='helvb12.bdf' "
+"/>"
+"<font resolution='y<400' "
+"id='text_normal' "
+"file='clR6x12.bdf' "
+"/>"
+"<font id='tooltip_normal' "
+"file='fixed5x8.bdf' "
+"/>"
+"<text_color id='color_normal' "
+"color='green' "
+"/>"
+"<text_color id='color_normal_inverted' "
+"color='black' "
+"/>"
+"<text_color id='color_normal_hover' "
+"color='green2' "
+"/>"
+"<text_color id='color_normal_disabled' "
+"color='lightgrey' "
+"/>"
+"<text_color id='color_alternative' "
+"color='lightgrey' "
+"/>"
+"<text_color id='color_alternative_inverted' "
+"color='255,255,255' "
+"/>"
+"<text_color id='color_alternative_hover' "
+"color='176,176,176' "
+"/>"
+"<text_color id='color_alternative_disabled' "
+"color='darkgrey' "
+"/>"
+"<text_color id='color_button' "
+"color='green' "
+"/>"
+"<text_color id='color_button_hover' "
+"color='green2' "
+"/>"
+"<text_color id='color_button_disabled' "
+"color='lightgrey' "
+"/>"
+"</fonts>"
+"<defaults fill='foreground' fg_color='darkgrey' bg_color='black' shadow='0' bevel_color='lightgrey'/>"
+"<drawdata id='text_selection' cache='false'>"
+"<drawstep func='square' "
+"fill='foreground' "
+"fg_color='lightgrey' "
+"/>"
+"</drawdata>"
+"<drawdata id='text_selection_focus' cache='false'>"
+"<drawstep func='square' "
+"fill='foreground' "
+"fg_color='green' "
+"/>"
+"</drawdata>"
+"<drawdata id='mainmenu_bg' cache='false'>"
+"<drawstep func='fill' "
+"fill='foreground' "
+"fg_color='black' "
+"/>"
+"</drawdata>"
+"<drawdata id='special_bg' cache='false'>"
+"<drawstep func='bevelsq' "
+"bevel='2' "
+"/>"
+"</drawdata>"
+"<drawdata id='tooltip_bg' cache='false'>"
+"<drawstep func='bevelsq' "
+"bevel='2' "
+"fill='foreground' "
+"fg_color='black' "
+"/>"
+"</drawdata>"
+"<drawdata id='separator' cache='false'>"
+"<drawstep func='square' "
+"fill='foreground' "
+"height='2' "
+"ypos='center' "
+"fg_color='lightgrey' "
+"/>"
+"</drawdata>"
+"<drawdata id='scrollbar_base' cache='false'>"
+"<drawstep func='bevelsq' "
+"bevel='2' "
+"/>"
+"</drawdata>"
+"<drawdata id='scrollbar_handle_hover' cache='false'>"
+"<drawstep func='square' "
+"fill='foreground' "
+"fg_color='green2' "
+"/>"
+"</drawdata>"
+"<drawdata id='scrollbar_handle_idle' cache='false'>"
+"<drawstep func='square' "
+"fill='foreground' "
+"fg_color='green' "
+"/>"
+"</drawdata>"
+"<drawdata id='scrollbar_button_idle' cache='false' resolution='y>399'>"
+"<drawstep func='bevelsq' "
+"bevel='2' "
+"fill='none' "
+"/>"
+"<drawstep func='triangle' "
+"fg_color='green' "
+"fill='foreground' "
+"width='10' "
+"height='10' "
+"xpos='right' "
+"ypos='center' "
+"padding='0,0,3,0' "
+"orientation='top' "
+"/>"
+"</drawdata>"
+"<drawdata id='scrollbar_button_idle' cache='false' resolution='y<400'>"
+"<drawstep func='bevelsq' "
+"bevel='2' "
+"fill='none' "
+"/>"
+"<drawstep func='triangle' "
+"fg_color='green' "
+"fill='foreground' "
+"width='5' "
+"height='5' "
+"xpos='right' "
+"ypos='center' "
+"padding='0,0,2,0' "
+"orientation='top' "
+"/>"
+"</drawdata>"
+"<drawdata id='scrollbar_button_hover' cache='false' resolution='y>399'>"
+"<drawstep func='bevelsq' "
+"bevel='2' "
+"fill='none' "
+"/>"
+"<drawstep func='triangle' "
+"fg_color='green' "
+"fill='foreground' "
+"width='10' "
+"height='10' "
+"xpos='right' "
+"ypos='center' "
+"padding='0,0,3,0' "
+"orientation='top' "
+"/>"
+"</drawdata>"
+"<drawdata id='scrollbar_button_hover' cache='false' resolution='y<400'>"
+"<drawstep func='bevelsq' "
+"bevel='2' "
+"fill='none' "
+"/>"
+"<drawstep func='triangle' "
+"fg_color='green' "
+"fill='foreground' "
+"width='5' "
+"height='5' "
+"xpos='right' "
+"ypos='center' "
+"padding='0,0,2,0' "
+"orientation='top' "
+"/>"
+"</drawdata>"
+"<drawdata id='tab_active' cache='false'>"
+"<text font='text_default' "
+"text_color='color_normal_hover' "
+"vertical_align='center' "
+"horizontal_align='center' "
+"/>"
+"<drawstep func='tab' "
+"bevel='2' "
+"radius='0' "
+"fill='none' "
+"/>"
+"</drawdata>"
+"<drawdata id='tab_inactive' cache='false'>"
+"<text font='text_default' "
+"text_color='color_normal' "
+"vertical_align='center' "
+"horizontal_align='center' "
+"/>"
+"<drawstep func='tab' "
+"bevel='2' "
+"radius='0' "
+"fill='none' "
+"/>"
+"</drawdata>"
+"<drawdata id='tab_background' cache='false'>"
+"</drawdata>"
+"<drawdata id='widget_slider' cache='false'>"
+"<drawstep func='bevelsq' "
+"bevel='2' "
+"fill='none' "
+"/>"
+"</drawdata>"
+"<drawdata id='slider_disabled' cache='false'>"
+"<drawstep func='square' "
+"fill='foreground' "
+"fg_color='lightgrey' "
+"/>"
+"</drawdata>"
+"<drawdata id='slider_full' cache='false'>"
+"<drawstep func='square' "
+"fill='foreground' "
+"fg_color='green' "
+"/>"
+"</drawdata>"
+"<drawdata id='slider_hover' cache='false'>"
+"<drawstep func='square' "
+"fill='foreground' "
+"fg_color='green2' "
+"/>"
+"</drawdata>"
+"<drawdata id='widget_small' cache='false'>"
+"<drawstep func='bevelsq' "
+"bevel='2' "
+"fill='none' "
+"/>"
+"</drawdata>"
+"<drawdata id='popup_idle' cache='false' resolution='y>399'>"
+"<drawstep func='bevelsq' "
+"bevel='2' "
+"fill='none' "
+"/>"
+"<drawstep func='triangle' "
+"fg_color='green' "
+"fill='foreground' "
+"width='10' "
+"height='5' "
+"xpos='right' "
+"ypos='10' "
+"padding='0,0,7,0' "
+"orientation='bottom' "
+"/>"
+"<drawstep func='triangle' "
+"fg_color='green' "
+"fill='foreground' "
+"width='10' "
+"height='5' "
+"xpos='right' "
+"ypos='4' "
+"padding='0,0,7,0' "
+"orientation='top' "
+"/>"
+"<text font='text_default' "
+"text_color='color_normal' "
+"vertical_align='center' "
+"horizontal_align='left' "
+"/>"
+"</drawdata>"
+"<drawdata id='popup_idle' cache='false' resolution='y<400'>"
+"<drawstep func='bevelsq' "
+"bevel='2' "
+"fill='none' "
+"/>"
+"<drawstep func='triangle' "
+"fg_color='green' "
+"fill='foreground' "
+"width='7' "
+"height='4' "
+"xpos='right' "
+"ypos='9' "
+"padding='0,0,3,0' "
+"orientation='bottom' "
+"/>"
+"<drawstep func='triangle' "
+"fg_color='green' "
+"fill='foreground' "
+"width='7' "
+"height='4' "
+"xpos='right' "
+"ypos='4' "
+"padding='0,0,3,0' "
+"orientation='top' "
+"/>"
+"<text font='text_default' "
+"text_color='color_normal' "
+"vertical_align='center' "
+"horizontal_align='left' "
+"/>"
+"</drawdata>"
+"<drawdata id='popup_disabled' cache='false' resolution='y>399'>"
+"<drawstep func='bevelsq' "
+"bevel='2' "
+"fill='none' "
+"/>"
+"<drawstep func='triangle' "
+"fg_color='green' "
+"fill='foreground' "
+"width='10' "
+"height='5' "
+"xpos='right' "
+"ypos='10' "
+"padding='0,0,7,0' "
+"orientation='bottom' "
+"/>"
+"<drawstep func='triangle' "
+"fg_color='green' "
+"fill='foreground' "
+"width='10' "
+"height='5' "
+"xpos='right' "
+"ypos='4' "
+"padding='0,0,7,0' "
+"orientation='top' "
+"/>"
+"<text font='text_default' "
+"text_color='color_normal_disabled' "
+"vertical_align='center' "
+"horizontal_align='left' "
+"/>"
+"</drawdata>"
+"<drawdata id='popup_disabled' cache='false' resolution='y<400'>"
+"<drawstep func='bevelsq' "
+"bevel='2' "
+"fill='none' "
+"/>"
+"<drawstep func='triangle' "
+"fg_color='green' "
+"fill='foreground' "
+"width='7' "
+"height='4' "
+"xpos='right' "
+"ypos='9' "
+"padding='0,0,3,0' "
+"orientation='bottom' "
+"/>"
+"<drawstep func='triangle' "
+"fg_color='green' "
+"fill='foreground' "
+"width='7' "
+"height='4' "
+"xpos='right' "
+"ypos='4' "
+"padding='0,0,3,0' "
+"orientation='top' "
+"/>"
+"<text font='text_default' "
+"text_color='color_normal' "
+"vertical_align='center' "
+"horizontal_align='left' "
+"/>"
+"</drawdata>"
+"<drawdata id='popup_hover' cache='false' resolution='y>399'>"
+"<drawstep func='bevelsq' "
+"bevel='2' "
+"fill='none' "
+"/>"
+"<drawstep func='triangle' "
+"fg_color='green' "
+"fill='foreground' "
+"width='10' "
+"height='5' "
+"xpos='right' "
+"ypos='10' "
+"padding='0,0,7,0' "
+"orientation='bottom' "
+"/>"
+"<drawstep func='triangle' "
+"fg_color='green' "
+"fill='foreground' "
+"width='10' "
+"height='5' "
+"xpos='right' "
+"ypos='4' "
+"padding='0,0,7,0' "
+"orientation='top' "
+"/>"
+"<text font='text_default' "
+"text_color='color_normal_hover' "
+"vertical_align='center' "
+"horizontal_align='left' "
+"/>"
+"</drawdata>"
+"<drawdata id='popup_hover' cache='false' resolution='y<400'>"
+"<drawstep func='bevelsq' "
+"bevel='2' "
+"fill='none' "
+"/>"
+"<drawstep func='triangle' "
+"fg_color='green' "
+"fill='foreground' "
+"width='7' "
+"height='4' "
+"xpos='right' "
+"ypos='9' "
+"padding='0,0,3,0' "
+"orientation='bottom' "
+"/>"
+"<drawstep func='triangle' "
+"fg_color='green' "
+"fill='foreground' "
+"width='7' "
+"height='4' "
+"xpos='right' "
+"ypos='4' "
+"padding='0,0,3,0' "
+"orientation='top' "
+"/>"
+"<text font='text_default' "
+"text_color='color_normal' "
+"vertical_align='center' "
+"horizontal_align='left' "
+"/>"
+"</drawdata>"
+"<drawdata id='widget_textedit' cache='false'>"
+"<drawstep func='bevelsq' "
+"bevel='2' "
+"fill='none' "
+"/>"
+"</drawdata>"
+"<drawdata id='plain_bg' cache='false'>"
+"<drawstep func='bevelsq' "
+"bevel='2' "
+"/>"
+"</drawdata>"
+"<drawdata id='caret' cache='false'>"
+"<drawstep func='square' "
+"fill='foreground' "
+"fg_color='lightgrey' "
+"/>"
+"</drawdata>"
+"<drawdata id='default_bg' cache='false'>"
+"<drawstep func='bevelsq' "
+"bevel='2' "
+"/>"
+"</drawdata>"
+"<drawdata id='button_pressed' cache='false'>"
+"<text font='text_button' "
+"text_color='color_alternative_inverted' "
+"vertical_align='center' "
+"horizontal_align='center' "
+"/>"
+"<drawstep func='square' "
+"fill='foreground' "
+"fg_color='green' "
+"/>"
+"</drawdata>"
+"<drawdata id='button_idle' cache='false'>"
+"<text font='text_button' "
+"text_color='color_button' "
+"vertical_align='center' "
+"horizontal_align='center' "
+"/>"
+"<drawstep func='bevelsq' "
+"bevel='2' "
+"fill='none' "
+"/>"
+"</drawdata>"
+"<drawdata id='button_hover' cache='false'>"
+"<text font='text_button' "
+"text_color='color_button_hover' "
+"vertical_align='center' "
+"horizontal_align='center' "
+"/>"
+"<drawstep func='bevelsq' "
+"bevel='2' "
+"fill='none' "
+"/>"
+"</drawdata>"
+"<drawdata id='button_disabled' cache='false'>"
+"<text font='text_button' "
+"text_color='color_button_disabled' "
+"vertical_align='center' "
+"horizontal_align='center' "
+"/>"
+"<drawstep func='bevelsq' "
+"bevel='2' "
+"fill='none' "
+"/>"
+"</drawdata>"
+"<drawdata id='checkbox_disabled' cache='false'>"
+"<text font='text_default' "
+"text_color='color_normal_disabled' "
+"vertical_align='top' "
+"horizontal_align='left' "
+"/>"
+"<drawstep func='bevelsq' "
+"bevel='2' "
+"fill='none' "
+"/>"
+"</drawdata>"
+"<drawdata id='checkbox_selected' cache='false'>"
+"<text font='text_default' "
+"text_color='color_normal' "
+"vertical_align='top' "
+"horizontal_align='left' "
+"/>"
+"<drawstep func='bevelsq' "
+"bevel='2' "
+"fill='none' "
+"/>"
+"<drawstep func='cross' "
+"fill='foreground' "
+"stroke='2' "
+"fg_color='green' "
+"/>"
+"</drawdata>"
+"<drawdata id='checkbox_default' cache='false'>"
+"<text font='text_default' "
+"text_color='color_normal' "
+"vertical_align='top' "
+"horizontal_align='left' "
+"/>"
+"<drawstep func='bevelsq' "
+"bevel='2' "
+"fill='none' "
+"/>"
+"</drawdata>"
+"<drawdata id='radiobutton_default' cache='false'>"
+"<text font='text_default' "
+"text_color='color_normal' "
+"vertical_align='center' "
+"horizontal_align='left' "
+"/>"
+"<drawstep func='circle' "
+"width='7' "
+"height='7' "
+"radius='7' "
+"fill='background' "
+"bg_color='darkgrey' "
+"xpos='0' "
+"ypos='0' "
+"/>"
+"</drawdata>"
+"<drawdata id='radiobutton_selected' cache='false'>"
+"<text font='text_default' "
+"text_color='color_normal' "
+"vertical_align='center' "
+"horizontal_align='left' "
+"/>"
+"<drawstep func='circle' "
+"width='7' "
+"height='7' "
+"radius='7' "
+"fg_color='darkgrey' "
+"fill='none' "
+"xpos='0' "
+"ypos='0' "
+"/>"
+"<drawstep func='circle' "
+"width='7' "
+"height='7' "
+"radius='5' "
+"fg_color='green' "
+"fill='foreground' "
+"xpos='2' "
+"ypos='2' "
+"/>"
+"</drawdata>"
+"<drawdata id='radiobutton_disabled' cache='false'>"
+"<text font='text_default' "
+"text_color='color_normal_disabled' "
+"vertical_align='center' "
+"horizontal_align='left' "
+"/>"
+"<drawstep func='circle' "
+"width='7' "
+"height='7' "
+"radius='7' "
+"bg_color='lightgrey' "
+"fill='background' "
+"xpos='0' "
+"ypos='0' "
+"/>"
+"</drawdata>"
+"<drawdata id='widget_default' cache='false'>"
+"<drawstep func='bevelsq' "
+"bevel='2' "
+"/>"
+"</drawdata>"
+"<drawdata id='widget_small' cache='false'>"
+"<drawstep func='square' "
+"stroke='0' "
+"/>"
+"</drawdata>"
+"</render_info>"
"<layout_info resolution='y<400'>"
"<globals>"
"<def var='Line.Height' value='12' />"
@@ -2506,16 +2506,16 @@
"</layout>"
"</dialog>"
"<dialog name='GlobalMenu' overlays='screen_center'>"
-"<layout type='vertical' padding='2,2,4,6' center='true' spacing='6'>"
+"<layout type='vertical' padding='2,2,2,6' center='true' spacing='0'>"
"<widget name='Title' "
"width='160' "
-"height='4' "
+"height='12' "
"/>"
"<widget name='Version' "
"width='160' "
-"height='4' "
+"height='14' "
"/>"
-"<space size='1'/>"
+"<layout type='vertical' padding='0,0,3,0' center='true' spacing='6'>"
"<widget name='Load' "
"width='120' "
"height='12' "
@@ -2551,6 +2551,7 @@
"height='12' "
"/>"
"</layout>"
+"</layout>"
"</dialog>"
"<dialog name='GlobalConfig' overlays='screen_center'>"
"<layout type='vertical' padding='8,8,8,8'>"
diff --git a/gui/themes/scummclassic.zip b/gui/themes/scummclassic.zip
index 1085aa64a4..7115849aa0 100644
--- a/gui/themes/scummclassic.zip
+++ b/gui/themes/scummclassic.zip
Binary files differ
diff --git a/gui/themes/scummclassic/classic_layout_lowres.stx b/gui/themes/scummclassic/classic_layout_lowres.stx
index 802998df3c..506657ef31 100644
--- a/gui/themes/scummclassic/classic_layout_lowres.stx
+++ b/gui/themes/scummclassic/classic_layout_lowres.stx
@@ -687,50 +687,51 @@
</dialog>
<dialog name = 'GlobalMenu' overlays = 'screen_center'>
- <layout type = 'vertical' padding = '2, 2, 4, 6' center = 'true' spacing='6'>
+ <layout type = 'vertical' padding = '2, 2, 2, 6' center = 'true' spacing='0'>
<widget name = 'Title'
width = '160'
- height = '4'
+ height = '12'
/>
<widget name = 'Version'
width = '160'
- height = '4'
- />
- <space size = '1'/>
- <widget name = 'Load'
- width = '120'
- height = '12'
- />
- <widget name = 'Save'
- width = '120'
- height = '12'
- />
- <space size = '1'/>
- <widget name = 'Options'
- width = '120'
- height = '12'
- />
- <widget name = 'Help'
- width = '120'
- height = '12'
- />
- <widget name = 'About'
- width = '120'
- height = '12'
- />
- <space size = '1'/>
- <widget name = 'Resume'
- width = '120'
- height = '12'
- />
- <widget name = 'RTL'
- width = '120'
- height = '12'
- />
- <widget name = 'Quit'
- width = '120'
- height = '12'
+ height = '14'
/>
+ <layout type = 'vertical' padding = '0, 0, 3, 0' center = 'true' spacing='6'>
+ <widget name = 'Load'
+ width = '120'
+ height = '12'
+ />
+ <widget name = 'Save'
+ width = '120'
+ height = '12'
+ />
+ <space size = '1'/>
+ <widget name = 'Options'
+ width = '120'
+ height = '12'
+ />
+ <widget name = 'Help'
+ width = '120'
+ height = '12'
+ />
+ <widget name = 'About'
+ width = '120'
+ height = '12'
+ />
+ <space size = '1'/>
+ <widget name = 'Resume'
+ width = '120'
+ height = '12'
+ />
+ <widget name = 'RTL'
+ width = '120'
+ height = '12'
+ />
+ <widget name = 'Quit'
+ width = '120'
+ height = '12'
+ />
+ </layout>
</layout>
</dialog>
diff --git a/gui/widgets/editable.cpp b/gui/widgets/editable.cpp
index 667850d6cc..6f550b5642 100644
--- a/gui/widgets/editable.cpp
+++ b/gui/widgets/editable.cpp
@@ -261,23 +261,45 @@ void EditableWidget::drawCaret(bool erase) {
int x = editRect.left;
int y = editRect.top;
- x += getCaretOffset();
+ const int caretOffset = getCaretOffset();
+ x += caretOffset;
- if (y < 0 || y + editRect.height() - 2 >= _h)
+ if (y < 0 || y + editRect.height() > _h)
return;
x += getAbsX();
y += getAbsY();
- g_gui.theme()->drawCaret(Common::Rect(x, y, x + 1, y + editRect.height() - 2), erase);
+ g_gui.theme()->drawCaret(Common::Rect(x, y, x + 1, y + editRect.height()), erase);
if (erase) {
+ GUI::EditableWidget::String character;
+ int width;
+
if ((uint)_caretPos < _editString.size()) {
- GUI::EditableWidget::String chr(_editString[_caretPos]);
- int chrWidth = g_gui.getCharWidth(_editString[_caretPos], _font);
+ const byte chr = _editString[_caretPos];
+ width = g_gui.getCharWidth(chr, _font);
+ character = chr;
+
const uint last = (_caretPos > 0) ? _editString[_caretPos - 1] : 0;
- x += g_gui.getKerningOffset(last, _editString[_caretPos], _font);
- g_gui.theme()->drawText(Common::Rect(x, y, x + chrWidth, y + editRect.height() - 2), chr, _state, Graphics::kTextAlignLeft, _inversion, 0, false, _font, ThemeEngine::kFontColorNormal, true, _textDrawableArea);
+ x += g_gui.getKerningOffset(last, chr, _font);
+ } else {
+ // We draw a fake space here to assure that removing the caret
+ // does not result in color glitches in case the edit rect is
+ // drawn with an inversion.
+ width = g_gui.getCharWidth(' ', _font);
+ character = " ";
+ }
+
+ // TODO: Right now we manually prevent text from being drawn outside
+ // the edit area here. We might want to consider to use
+ // setTextDrawableArea for this. However, it seems that only
+ // EditTextWidget uses that but not ListWidget. Thus, one should check
+ // whether we can unify the drawing in the text area first to avoid
+ // possible glitches due to different methods used.
+ width = MIN(editRect.width() - caretOffset, width);
+ if (width > 0) {
+ g_gui.theme()->drawText(Common::Rect(x, y, x + width, y + editRect.height()), character, _state, Graphics::kTextAlignLeft, _inversion, 0, false, _font, ThemeEngine::kFontColorNormal, true, _textDrawableArea);
}
}
diff --git a/gui/widgets/editable.h b/gui/widgets/editable.h
index 4a18d5e689..63a1942311 100644
--- a/gui/widgets/editable.h
+++ b/gui/widgets/editable.h
@@ -78,6 +78,11 @@ protected:
virtual void startEditMode() = 0;
virtual void endEditMode() = 0;
virtual void abortEditMode() = 0;
+ /**
+ * The area where text input is being made. This should exactly match the
+ * rect with which the actual edit string is drawn otherwise nasty
+ * graphics glitches when redrawing the caret can occur.
+ */
virtual Common::Rect getEditRect() const = 0;
virtual int getCaretOffset() const;
void drawCaret(bool erase);
diff --git a/gui/widgets/edittext.cpp b/gui/widgets/edittext.cpp
index 52527effd8..c54ca573ba 100644
--- a/gui/widgets/edittext.cpp
+++ b/gui/widgets/edittext.cpp
@@ -101,7 +101,7 @@ void EditTextWidget::drawWidget() {
}
Common::Rect EditTextWidget::getEditRect() const {
- Common::Rect r(2 + _leftPadding, 2, _w - 2 - _leftPadding - _rightPadding, _h - 1);
+ Common::Rect r(2 + _leftPadding, 2, _w - 2 - _leftPadding - _rightPadding, _h);
return r;
}
diff --git a/gui/widgets/list.cpp b/gui/widgets/list.cpp
index 473d5f04df..8b8eb31db9 100644
--- a/gui/widgets/list.cpp
+++ b/gui/widgets/list.cpp
@@ -91,6 +91,9 @@ ListWidget::ListWidget(Dialog *boss, int x, int y, int w, int h, const char *too
// FIXME: This flag should come from widget definition
_editable = true;
+
+ _quickSelect = true;
+ _editColor = ThemeEngine::kFontColorNormal;
}
ListWidget::~ListWidget() {
@@ -538,7 +541,7 @@ void ListWidget::drawWidget() {
}
Common::Rect ListWidget::getEditRect() const {
- Common::Rect r(_hlLeftPadding, 0, _w - _hlLeftPadding - _hlRightPadding, kLineHeight - 1);
+ Common::Rect r(_hlLeftPadding, 0, _w - _hlLeftPadding - _hlRightPadding, kLineHeight - 2);
const int offset = (_selectedItem - _currentPos) * kLineHeight + _topPadding;
r.top += offset;
r.bottom += offset;
diff --git a/po/be_BY.po b/po/be_BY.po
index 4c36c65f71..20b03b7725 100644
--- a/po/be_BY.po
+++ b/po/be_BY.po
@@ -1,5 +1,5 @@
# Belarusian translation for ScummVM.
-# Copyright (C) 2010-2013 ScummVM Team
+# Copyright (C) 2010-2014 ScummVM Team
# This file is distributed under the same license as the ScummVM package.
# Ivan Lukyanov <greencis@mail.ru>, 2013.
#
diff --git a/po/ca_ES.po b/po/ca_ES.po
index f201be5cba..b8238939a0 100644
--- a/po/ca_ES.po
+++ b/po/ca_ES.po
@@ -1,5 +1,5 @@
# Catalan translation for ScummVM.
-# Copyright (C) 2007-2013 ScummVM Team
+# Copyright (C) 2007-2014 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 4b330af830..67a21573b4 100644
--- a/po/cs_CZ.po
+++ b/po/cs_CZ.po
@@ -1,5 +1,5 @@
# Czech translation for ScummVM.
-# Copyright (C) 2001-2013 ScummVM Team
+# Copyright (C) 2001-2014 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 bb7ed32c83..192ceeb50d 100644
--- a/po/da_DA.po
+++ b/po/da_DA.po
@@ -1,5 +1,5 @@
# Dansk translation for ScummVM
-# Copyright (C) 2010-2013 ScummVM Team
+# Copyright (C) 2010-2014 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 fac3c1f103..7275e136f2 100644
--- a/po/de_DE.po
+++ b/po/de_DE.po
@@ -1,5 +1,5 @@
# German translation for ScummVM.
-# Copyright (C) 2010-2013 ScummVM Team
+# Copyright (C) 2010-2014 ScummVM Team
# This file is distributed under the same license as the ScummVM package.
# Simon Sawatzki <SimSaw@gmx.de>, Lothar Serra Mari, 2013.
#
diff --git a/po/es_ES.po b/po/es_ES.po
index 6bc001682d..a859019924 100644
--- a/po/es_ES.po
+++ b/po/es_ES.po
@@ -1,5 +1,5 @@
# Spanish translation for ScummVM.
-# Copyright (C) 2010-2013 ScummVM Team
+# Copyright (C) 2010-2014 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 87a78ed044..13d947d80f 100644
--- a/po/eu.po
+++ b/po/eu.po
@@ -1,5 +1,5 @@
# Basque translation for ScummVM.
-# Copyright (C) 2012-2013 ScummVM Team
+# Copyright (C) 2012-2014 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 5471e5db58..73aac4cc9c 100644
--- a/po/fi_FI.po
+++ b/po/fi_FI.po
@@ -1,5 +1,5 @@
# Finnish translation for ScummVM.
-# Copyright (c) 2012-2013 ScummVM Team
+# Copyright (c) 2012-2014 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 a853d190aa..c4978d4292 100644
--- a/po/fr_FR.po
+++ b/po/fr_FR.po
@@ -1,5 +1,5 @@
# French translation for ScummVM.
-# Copyright (C) 2010-2013 ScummVM Team
+# Copyright (C) 2010-2014 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 cce9a5dfa7..3e0b92bef0 100644
--- a/po/gl_ES.po
+++ b/po/gl_ES.po
@@ -1,5 +1,5 @@
# Galician translation for ScummVM.
-# Copyright (C) 2010-2013 ScummVM Team
+# Copyright (C) 2010-2014 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 89bfa80d56..ae8f7a5aa9 100644
--- a/po/hu_HU.po
+++ b/po/hu_HU.po
@@ -1,5 +1,5 @@
# Hungarian translation for ScummVM.
-# Copyright (C) 2010-2013 ScummVM Team
+# Copyright (C) 2010-2014 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 cd449c269a..ddba2a0066 100644
--- a/po/it_IT.po
+++ b/po/it_IT.po
@@ -1,5 +1,5 @@
# Italian translation for ScummVM.
-# Copyright (C) 2010-2013 ScummVM Team
+# Copyright (C) 2010-2014 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 f41e71f8ae..b438b53d78 100644
--- a/po/nb_NO.po
+++ b/po/nb_NO.po
@@ -1,5 +1,5 @@
# Norwegian (Bokmaal) translation for ScummVM.
-# Copyright (C) 2010-2013 ScummVM Team
+# Copyright (C) 2010-2014 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/nn_NO.po b/po/nn_NO.po
index 2c09192d5c..443fae2970 100644
--- a/po/nn_NO.po
+++ b/po/nn_NO.po
@@ -1,5 +1,5 @@
# Norwegian (Nynorsk) translation for ScummVM.
-# Copyright (C) 2010-2013 ScummVM Team
+# Copyright (C) 2010-2014 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 38cedb55d7..826846dfcb 100644
--- a/po/pl_PL.po
+++ b/po/pl_PL.po
@@ -1,5 +1,5 @@
# Polish translation for ScummVM.
-# Copyright (C) 2010-2013 ScummVM Team
+# Copyright (C) 2010-2014 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 a3a5c3935c..595f36d56c 100644
--- a/po/pt_BR.po
+++ b/po/pt_BR.po
@@ -1,5 +1,5 @@
# Portuguese (Brazilian) translation for ScummVM.
-# Copyright (C) 2010-2013 ScummVM Team
+# Copyright (C) 2010-2014 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 8e52f3f342..dc0fc6cc80 100644
--- a/po/ru_RU.po
+++ b/po/ru_RU.po
@@ -1,5 +1,5 @@
# Russian translation for ScummVM.
-# Copyright (C) 2010-2013 ScummVM Team
+# Copyright (C) 2010-2014 ScummVM Team
# This file is distributed under the same license as the ScummVM package.
# Eugene Sandulenko <sev@scummvm.org>, 2010`
#
diff --git a/po/se_SE.po b/po/se_SE.po
index 0031e2dc06..eaff1de836 100644
--- a/po/se_SE.po
+++ b/po/se_SE.po
@@ -1,5 +1,5 @@
# Swedish translation for ScummVM.
-# Copyright (C) 2011-2013 ScummVM Team
+# Copyright (C) 2011-2014 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 2a42ff47d9..5c27fcd479 100644
--- a/po/uk_UA.po
+++ b/po/uk_UA.po
@@ -1,5 +1,5 @@
# Ukrainian translation for ScummVM.
-# Copyright (C) 2010-2013 ScummVM Team
+# Copyright (C) 2010-2014 ScummVM Team
# This file is distributed under the same license as the ScummVM package.
# Lubomyr Lisen, 2010.
#
diff --git a/ports.mk b/ports.mk
index f9d075707b..9b54b3533b 100644
--- a/ports.mk
+++ b/ports.mk
@@ -318,15 +318,15 @@ else ifeq "$(CUR_BRANCH)" ""
$(error You must be on a release branch)
endif
@echo Creating Code::Blocks project files...
- @cd $(srcdir)/dists/codeblocks && ../../devtools/create_project/create_project ../.. --codeblocks >/dev/null && git add -f *.workspace *.cbp
+ @cd $(srcdir)/dists/codeblocks && ../../devtools/create_project/create_project ../.. --codeblocks >/dev/null && git add -f engines/plugins_table.h *.workspace *.cbp
@echo Creating MSVC8 project files...
- @cd $(srcdir)/dists/msvc8 && ../../devtools/create_project/create_project ../.. --msvc --msvc-version 8 >/dev/null && git add -f *.sln *.vcproj *.vsprops
+ @cd $(srcdir)/dists/msvc8 && ../../devtools/create_project/create_project ../.. --msvc --msvc-version 8 >/dev/null && git add -f engines/plugins_table.h *.sln *.vcproj *.vsprops
@echo Creating MSVC9 project files...
- @cd $(srcdir)/dists/msvc9 && ../../devtools/create_project/create_project ../.. --msvc --msvc-version 9 >/dev/null && git add -f *.sln *.vcproj *.vsprops
+ @cd $(srcdir)/dists/msvc9 && ../../devtools/create_project/create_project ../.. --msvc --msvc-version 9 >/dev/null && git add -f engines/plugins_table.h *.sln *.vcproj *.vsprops
@echo Creating MSVC10 project files...
- @cd $(srcdir)/dists/msvc10 && ../../devtools/create_project/create_project ../.. --msvc --msvc-version 10 >/dev/null && git add -f *.sln *.vcxproj *.vcxproj.filters *.props
+ @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 *.sln *.vcxproj *.vcxproj.filters *.props
+ @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
@echo All is done.
@echo Now run
diff --git a/video/avi_decoder.cpp b/video/avi_decoder.cpp
index 5e4b91d1bd..bae5b7babd 100644
--- a/video/avi_decoder.cpp
+++ b/video/avi_decoder.cpp
@@ -36,6 +36,7 @@
// Video Codecs
#include "video/codecs/cinepak.h"
#include "video/codecs/indeo3.h"
+#include "video/codecs/mjpeg.h"
#include "video/codecs/mpeg.h"
#include "video/codecs/msvideo1.h"
#include "video/codecs/msrle.h"
@@ -59,6 +60,8 @@ namespace Video {
#define ID_MIDS MKTAG('m','i','d','s')
#define ID_TXTS MKTAG('t','x','t','s')
#define ID_JUNK MKTAG('J','U','N','K')
+#define ID_JUNQ MKTAG('J','U','N','Q')
+#define ID_DMLH MKTAG('d','m','l','h')
#define ID_STRF MKTAG('s','t','r','f')
#define ID_MOVI MKTAG('m','o','v','i')
#define ID_REC MKTAG('r','e','c',' ')
@@ -69,6 +72,7 @@ namespace Video {
#define ID_ISFT MKTAG('I','S','F','T')
#define ID_DISP MKTAG('D','I','S','P')
#define ID_PRMI MKTAG('P','R','M','I')
+#define ID_STRN MKTAG('s','t','r','n')
// Codec tags
#define ID_RLE MKTAG('R','L','E',' ')
@@ -79,6 +83,7 @@ namespace Video {
#define ID_IV32 MKTAG('i','v','3','2')
#define ID_DUCK MKTAG('D','U','C','K')
#define ID_MPG2 MKTAG('m','p','g','2')
+#define ID_MJPG MKTAG('m','j','p','g')
// Stream Types
enum {
@@ -101,10 +106,15 @@ AVIDecoder::~AVIDecoder() {
close();
}
+AVIDecoder::AVIAudioTrack *AVIDecoder::createAudioTrack(AVIStreamHeader sHeader, PCMWaveFormat wvInfo) {
+ return new AVIAudioTrack(sHeader, wvInfo, _soundType);
+}
+
void AVIDecoder::initCommon() {
_decodedHeader = false;
_foundMovieList = false;
_movieListStart = 0;
+ _movieListEnd = 0;
_fileStream = 0;
memset(&_header, 0, sizeof(_header));
}
@@ -149,21 +159,15 @@ bool AVIDecoder::parseNextChunk() {
case ID_STRD: // Extra stream info, safe to ignore
case ID_VEDT: // Unknown, safe to ignore
case ID_JUNK: // Alignment bytes, should be ignored
+ case ID_JUNQ: // Same as JUNK, safe to ignore
case ID_ISFT: // Metadata, safe to ignore
case ID_DISP: // Metadata, should be safe to ignore
+ case ID_STRN: // Metadata, safe to ignore
+ case ID_DMLH: // OpenDML extension, contains an extra total frames field, safe to ignore
skipChunk(size);
break;
case ID_IDX1:
- debug(0, "%d Indices", size / 16);
- for (uint32 i = 0; i < size / 16; i++) {
- OldIndex indexEntry;
- indexEntry.id = _fileStream->readUint32BE();
- indexEntry.flags = _fileStream->readUint32LE();
- indexEntry.offset = _fileStream->readUint32LE() + _movieListStart - 4; // Adjust to absolute
- indexEntry.size = _fileStream->readUint32LE();
- _indexEntries.push_back(indexEntry);
- debug(0, "Index %d == Tag \'%s\', Offset = %d, Size = %d (Flags = %d)", i, tag2str(indexEntry.id), indexEntry.offset, indexEntry.size, indexEntry.flags);
- }
+ readOldIndex(size);
break;
default:
error("Unknown tag \'%s\' found", tag2str(tag));
@@ -189,6 +193,7 @@ void AVIDecoder::handleList(uint32 listSize) {
// We found the movie block
_foundMovieList = true;
_movieListStart = curPos;
+ _movieListEnd = _movieListStart + listSize + (listSize & 1);
_fileStream->skip(listSize);
return;
case ID_HDRL: // Header List
@@ -293,7 +298,7 @@ void AVIDecoder::handleStreamHeader(uint32 size) {
if (wvInfo.channels == 2)
sHeader.sampleSize /= 2;
- addTrack(new AVIAudioTrack(sHeader, wvInfo, _soundType));
+ addTrack(createAudioTrack(sHeader, wvInfo));
}
// Ensure that we're at the end of the chunk
@@ -349,17 +354,27 @@ void AVIDecoder::close() {
_decodedHeader = false;
_foundMovieList = false;
_movieListStart = 0;
+ _movieListEnd = 0;
_indexEntries.clear();
memset(&_header, 0, sizeof(_header));
}
void AVIDecoder::readNextPacket() {
+ if ((uint32)_fileStream->pos() >= _movieListEnd) {
+ // Ugh, reached the end premature.
+ forceVideoEnd();
+ return;
+ }
+
uint32 nextTag = _fileStream->readUint32BE();
uint32 size = _fileStream->readUint32LE();
- if (_fileStream->eos())
+ if (_fileStream->eos()) {
+ // Also premature end.
+ forceVideoEnd();
return;
+ }
if (nextTag == ID_LIST) {
// A list of audio/video chunks
@@ -428,12 +443,10 @@ bool AVIDecoder::seekIntern(const Audio::Timestamp &time) {
if (time > getDuration())
return false;
- // Track down our video track (optionally audio too).
- // We only support seeking with one track right now.
+ // Track down our video track.
+ // We only support seeking with one video track right now.
AVIVideoTrack *videoTrack = 0;
- AVIAudioTrack *audioTrack = 0;
int videoIndex = -1;
- int audioIndex = -1;
uint trackID = 0;
for (TrackListIterator it = getTrackListBegin(); it != getTrackListEnd(); it++, trackID++) {
@@ -446,15 +459,6 @@ bool AVIDecoder::seekIntern(const Audio::Timestamp &time) {
videoTrack = (AVIVideoTrack *)*it;
videoIndex = trackID;
- } else if ((*it)->getTrackType() == Track::kTrackTypeAudio) {
- if (audioTrack) {
- // Already have one
- // -> Not supported
- return false;
- }
-
- audioTrack = (AVIAudioTrack *)*it;
- audioIndex = trackID;
}
}
@@ -467,8 +471,9 @@ bool AVIDecoder::seekIntern(const Audio::Timestamp &time) {
if (time == getDuration()) {
videoTrack->setCurFrame(videoTrack->getFrameCount() - 1);
- if (audioTrack)
- audioTrack->resetStream();
+ for (TrackListIterator it = getTrackListBegin(); it != getTrackListEnd(); it++)
+ if ((*it)->getTrackType() == Track::kTrackTypeAudio)
+ ((AVIAudioTrack *)*it)->resetStream();
return true;
}
@@ -529,7 +534,15 @@ bool AVIDecoder::seekIntern(const Audio::Timestamp &time) {
if (frameIndex < 0) // This shouldn't happen.
return false;
- if (audioTrack) {
+ // 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.
@@ -617,6 +630,69 @@ byte AVIDecoder::getStreamIndex(uint32 tag) const {
return strtol(string, 0, 16);
}
+void AVIDecoder::readOldIndex(uint32 size) {
+ uint32 entryCount = size / 16;
+
+ debug(0, "Old Index: %d entries", entryCount);
+
+ if (entryCount == 0)
+ return;
+
+ // Read the first index separately
+ OldIndex firstEntry;
+ firstEntry.id = _fileStream->readUint32BE();
+ firstEntry.flags = _fileStream->readUint32LE();
+ firstEntry.offset = _fileStream->readUint32LE();
+ firstEntry.size = _fileStream->readUint32LE();
+
+ // Check if the offset is already absolute
+ // If it's absolute, the offset will equal the start of the movie list
+ bool isAbsolute = firstEntry.offset == _movieListStart;
+
+ debug(1, "Old index is %s", isAbsolute ? "absolute" : "relative");
+
+ if (!isAbsolute)
+ firstEntry.offset += _movieListStart - 4;
+
+ debug(0, "Index 0: Tag '%s', Offset = %d, Size = %d (Flags = %d)", tag2str(firstEntry.id), firstEntry.offset, firstEntry.size, firstEntry.flags);
+ _indexEntries.push_back(firstEntry);
+
+ for (uint32 i = 1; i < entryCount; i++) {
+ OldIndex indexEntry;
+ indexEntry.id = _fileStream->readUint32BE();
+ indexEntry.flags = _fileStream->readUint32LE();
+ indexEntry.offset = _fileStream->readUint32LE();
+ indexEntry.size = _fileStream->readUint32LE();
+
+ // Adjust to absolute, if necessary
+ if (!isAbsolute)
+ indexEntry.offset += _movieListStart - 4;
+
+ _indexEntries.push_back(indexEntry);
+ debug(0, "Index %d: Tag '%s', Offset = %d, Size = %d (Flags = %d)", i, tag2str(indexEntry.id), indexEntry.offset, indexEntry.size, indexEntry.flags);
+ }
+}
+
+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();
+}
+
+VideoDecoder::AudioTrack *AVIDecoder::getAudioTrack(int index) {
+ // AVI audio track indexes are relative to the first track
+ Track *track = getTrack(index);
+
+ if (!track || track->getTrackType() != Track::kTrackTypeAudio)
+ return 0;
+
+ return (AudioTrack *)track;
+}
+
AVIDecoder::AVIVideoTrack::AVIVideoTrack(int frameCount, const AVIStreamHeader &streamHeader, const BitmapInfoHeader &bitmapInfoHeader, byte *initialPalette)
: _frameCount(frameCount), _vidsHeader(streamHeader), _bmInfo(bitmapInfoHeader), _initialPalette(initialPalette) {
_videoCodec = createCodec();
@@ -712,6 +788,8 @@ Codec *AVIDecoder::AVIVideoTrack::createCodec() {
case ID_MPG2:
return new MPEGDecoder();
#endif
+ case ID_MJPG:
+ return new MJPEGDecoder();
default:
warning("Unknown/Unhandled compression format \'%s\'", tag2str(_vidsHeader.streamHandler));
}
@@ -719,6 +797,10 @@ Codec *AVIDecoder::AVIVideoTrack::createCodec() {
return 0;
}
+void AVIDecoder::AVIVideoTrack::forceTrackEnd() {
+ _curFrame = _frameCount - 1;
+}
+
AVIDecoder::AVIAudioTrack::AVIAudioTrack(const AVIStreamHeader &streamHeader, const PCMWaveFormat &waveFormat, Audio::Mixer::SoundType soundType)
: _audsHeader(streamHeader), _wvInfo(waveFormat), _soundType(soundType) {
_audStream = createAudioStream();
diff --git a/video/avi_decoder.h b/video/avi_decoder.h
index fffcbfbe16..811f7f82f7 100644
--- a/video/avi_decoder.h
+++ b/video/avi_decoder.h
@@ -54,6 +54,7 @@ class Codec;
* - sci
* - sword1
* - sword2
+ * - zvision
*/
class AVIDecoder : public VideoDecoder {
public:
@@ -71,10 +72,12 @@ public:
bool isSeekable() const;
protected:
- void readNextPacket();
- bool seekIntern(const Audio::Timestamp &time);
+ // VideoDecoder API
+ void readNextPacket();
+ bool seekIntern(const Audio::Timestamp &time);
+ bool supportsAudioTrackSwitching() const { return true; }
+ AudioTrack *getAudioTrack(int index);
-private:
struct BitmapInfoHeader {
uint32 size;
uint32 width;
@@ -166,6 +169,7 @@ private:
~AVIVideoTrack();
void decodeFrame(Common::SeekableReadStream *stream);
+ void forceTrackEnd();
uint16 getWidth() const { return _bmInfo.width; }
uint16 getHeight() const { return _bmInfo.height; }
@@ -203,7 +207,7 @@ private:
AVIAudioTrack(const AVIStreamHeader &streamHeader, const PCMWaveFormat &waveFormat, Audio::Mixer::SoundType soundType);
~AVIAudioTrack();
- void queueSound(Common::SeekableReadStream *stream);
+ 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();
@@ -214,7 +218,6 @@ private:
protected:
Audio::AudioStream *getAudioStream() const;
- private:
// Audio Codecs
enum {
kWaveFormatNone = 0,
@@ -231,13 +234,15 @@ private:
Audio::QueuingAudioStream *createAudioStream();
};
- Common::Array<OldIndex> _indexEntries;
AVIHeader _header;
+ void readOldIndex(uint32 size);
+ Common::Array<OldIndex> _indexEntries;
+
Common::SeekableReadStream *_fileStream;
bool _decodedHeader;
bool _foundMovieList;
- uint32 _movieListStart;
+ uint32 _movieListStart, _movieListEnd;
Audio::Mixer::SoundType _soundType;
Common::Rational _frameRateOverride;
@@ -249,6 +254,10 @@ private:
void handleStreamHeader(uint32 size);
uint16 getStreamType(uint32 tag) const { return tag & 0xFFFF; }
byte getStreamIndex(uint32 tag) const;
+ void forceVideoEnd();
+
+public:
+ virtual AVIAudioTrack *createAudioTrack(AVIStreamHeader sHeader, PCMWaveFormat wvInfo);
};
} // End of namespace Video
diff --git a/video/bink_decoder.cpp b/video/bink_decoder.cpp
index 45dec0887b..bad34e8373 100644
--- a/video/bink_decoder.cpp
+++ b/video/bink_decoder.cpp
@@ -214,6 +214,16 @@ void BinkDecoder::readNextPacket() {
frame.bits = 0;
}
+VideoDecoder::AudioTrack *BinkDecoder::getAudioTrack(int index) {
+ // Bink audio track indexes are relative to the first audio track
+ Track *track = getTrack(index + 1);
+
+ if (!track || track->getTrackType() != Track::kTrackTypeAudio)
+ return 0;
+
+ return (AudioTrack *)track;
+}
+
BinkDecoder::VideoFrame::VideoFrame() : bits(0) {
}
diff --git a/video/bink_decoder.h b/video/bink_decoder.h
index 08800c2223..fb2998fb6e 100644
--- a/video/bink_decoder.h
+++ b/video/bink_decoder.h
@@ -74,6 +74,8 @@ public:
protected:
void readNextPacket();
+ bool supportsAudioTrackSwitching() const { return true; }
+ AudioTrack *getAudioTrack(int index);
private:
static const int kAudioChannelsMax = 2;
diff --git a/video/codecs/jpeg.cpp b/video/codecs/jpeg.cpp
new file mode 100644
index 0000000000..f3886f334a
--- /dev/null
+++ b/video/codecs/jpeg.cpp
@@ -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.
+ *
+ */
+
+#include "common/system.h"
+#include "common/textconsole.h"
+#include "graphics/surface.h"
+#include "graphics/decoders/jpeg.h"
+
+#include "video/codecs/jpeg.h"
+
+namespace Common {
+class SeekableReadStream;
+}
+
+namespace Video {
+
+JPEGDecoder::JPEGDecoder() : Codec() {
+ _pixelFormat = g_system->getScreenFormat();
+ _surface = NULL;
+}
+
+JPEGDecoder::~JPEGDecoder() {
+ if (_surface) {
+ _surface->free();
+ delete _surface;
+ }
+}
+
+const Graphics::Surface *JPEGDecoder::decodeImage(Common::SeekableReadStream *stream) {
+ Graphics::JPEGDecoder jpeg;
+
+ if (!jpeg.loadStream(*stream)) {
+ warning("Failed to decode JPEG frame");
+ return 0;
+ }
+
+ if (_surface) {
+ _surface->free();
+ delete _surface;
+ }
+
+ _surface = jpeg.getSurface()->convertTo(_pixelFormat);
+
+ return _surface;
+}
+
+} // End of namespace Video
diff --git a/video/codecs/jpeg.h b/video/codecs/jpeg.h
new file mode 100644
index 0000000000..1023d97779
--- /dev/null
+++ b/video/codecs/jpeg.h
@@ -0,0 +1,60 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public 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_CODECS_JPEG_H
+#define VIDEO_CODECS_JPEG_H
+
+#include "video/codecs/codec.h"
+#include "graphics/pixelformat.h"
+
+namespace Common {
+class SeekableReadStream;
+}
+
+namespace Graphics {
+struct Surface;
+}
+
+namespace Video {
+
+/**
+ * JPEG decoder.
+ *
+ * Used in video:
+ * - QuickTimeDecoder
+ */
+class JPEGDecoder : public Codec {
+public:
+ JPEGDecoder();
+ ~JPEGDecoder();
+
+ const Graphics::Surface *decodeImage(Common::SeekableReadStream *stream);
+ Graphics::PixelFormat getPixelFormat() const { return _pixelFormat; }
+
+private:
+ Graphics::PixelFormat _pixelFormat;
+ Graphics::Surface *_surface;
+};
+
+} // End of namespace Video
+
+#endif
diff --git a/video/codecs/mjpeg.cpp b/video/codecs/mjpeg.cpp
index 10fd9d7c50..61f9eb5881 100644
--- a/video/codecs/mjpeg.cpp
+++ b/video/codecs/mjpeg.cpp
@@ -20,6 +20,12 @@
*
*/
+// Based on LGPL MJPEG/AVI to JPEG/JFIF conversion code from libav
+// Copyright (c) 2010 Adrian Daerr and Nicolas George
+// That in turn was adapted from mjpeg2jpeg.c, with original copyright:
+// Paris 2010 Adrian Daerr, public domain
+
+#include "common/memstream.h"
#include "common/system.h"
#include "common/textconsole.h"
#include "graphics/surface.h"
@@ -33,23 +39,168 @@ class SeekableReadStream;
namespace Video {
-JPEGDecoder::JPEGDecoder() : Codec() {
+MJPEGDecoder::MJPEGDecoder() : Codec() {
_pixelFormat = g_system->getScreenFormat();
- _surface = NULL;
+ _surface = 0;
}
-JPEGDecoder::~JPEGDecoder() {
+MJPEGDecoder::~MJPEGDecoder() {
if (_surface) {
_surface->free();
delete _surface;
}
}
-const Graphics::Surface *JPEGDecoder::decodeImage(Common::SeekableReadStream *stream) {
+// Header to be inserted
+static const byte s_jpegHeader[] = {
+ 0xff, 0xd8, // SOI
+ 0xff, 0xe0, // APP0
+ 0x00, 0x10, // APP0 header size (including
+ // this field, but excluding preceding)
+ 'J', 'F', 'I', 'F', 0x00, // ID string 'JFIF\0'
+ 0x01, 0x01, // version
+ 0x00, // bits per type
+ 0x00, 0x00, // X density
+ 0x00, 0x00, // Y density
+ 0x00, // X thumbnail size
+ 0x00
+};
+
+enum {
+ DHT_SEGMENT_SIZE = 420
+};
+
+static const byte s_dhtSegmentHead[] = { 0xFF, 0xC4, 0x01, 0xA2, 0x00 };
+static const byte s_dhtSegmentFrag[] = {
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
+ 0x0a, 0x0b, 0x01, 0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+// Set up the standard Huffman tables (cf. JPEG standard section K.3)
+// IMPORTANT: these are only valid for 8-bit data precision!
+static const byte s_mjpegBitsDCLuminance[17] = {
+ /* 0-base */ 0, 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0
+};
+
+static const byte s_mjpegValDC[12] = {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11
+};
+
+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
+};
+
+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
+};
+
+static const byte s_mjpegValACLuminance[] = {
+ 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12,
+ 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07,
+ 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08,
+ 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0,
+ 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16,
+ 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28,
+ 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
+ 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
+ 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
+ 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
+ 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
+ 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
+ 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
+ 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
+ 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6,
+ 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5,
+ 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4,
+ 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2,
+ 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea,
+ 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
+ 0xf9, 0xfa
+};
+
+static const byte s_mjpegBitsACChrominance[17] = {
+ /* 0-base */ 0, 0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, 0x77
+};
+
+static const byte s_mjpegValACChrominance[] = {
+ 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21,
+ 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71,
+ 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91,
+ 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0,
+ 0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34,
+ 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26,
+ 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38,
+ 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
+ 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
+ 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
+ 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
+ 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
+ 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96,
+ 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5,
+ 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4,
+ 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3,
+ 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2,
+ 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda,
+ 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9,
+ 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
+ 0xf9, 0xfa
+};
+
+const Graphics::Surface *MJPEGDecoder::decodeImage(Common::SeekableReadStream *stream) {
+ // We need to reconstruct an actual JPEG stream here, then feed it to the JPEG decoder
+ // Yes, this is a pain.
+
+ stream->readUint32BE(); // Skip nonsense JPEG header
+ uint16 inputSkip = stream->readUint16BE() + 4;
+ uint32 tag = stream->readUint32BE();
+
+ if (tag != MKTAG('A', 'V', 'I', '1')) {
+ warning("Invalid MJPEG tag found");
+ return 0;
+ }
+
+ uint32 outputSize = stream->size() - inputSkip + sizeof(s_jpegHeader) + DHT_SEGMENT_SIZE;
+ byte *data = (byte *)malloc(outputSize);
+
+ if (!data) {
+ warning("Failed to allocate data for MJPEG conversion");
+ return 0;
+ }
+
+ // Copy the header
+ memcpy(data, s_jpegHeader, sizeof(s_jpegHeader));
+ uint32 dataOffset = sizeof(s_jpegHeader);
+
+ // Write the fake DHT segment
+ memcpy(data + dataOffset, s_dhtSegmentHead, sizeof(s_dhtSegmentHead));
+ dataOffset += sizeof(s_dhtSegmentHead);
+ memcpy(data + dataOffset, s_mjpegBitsDCLuminance + 1, 16);
+ dataOffset += 16;
+ memcpy(data + dataOffset, s_dhtSegmentFrag, sizeof(s_dhtSegmentFrag));
+ dataOffset += sizeof(s_dhtSegmentFrag);
+ memcpy(data + dataOffset, s_mjpegValDC, 12);
+ dataOffset += 12;
+ data[dataOffset++] = 0x10;
+ memcpy(data + dataOffset, s_mjpegBitsACLuminance + 1, 16);
+ dataOffset += 16;
+ memcpy(data + dataOffset, s_mjpegValACLuminance, 162);
+ dataOffset += 162;
+ data[dataOffset++] = 0x11;
+ memcpy(data + dataOffset, s_mjpegBitsACChrominance + 1, 16);
+ dataOffset += 16;
+ memcpy(data + dataOffset, s_mjpegValACChrominance, 162);
+ dataOffset += 162;
+
+ // Write the actual data
+ stream->seek(inputSkip);
+ stream->read(data + dataOffset, stream->size() - inputSkip);
+
+ Common::MemoryReadStream convertedStream(data, outputSize, DisposeAfterUse::YES);
Graphics::JPEGDecoder jpeg;
- if (!jpeg.loadStream(*stream)) {
- warning("Failed to decode JPEG frame");
+ if (!jpeg.loadStream(convertedStream)) {
+ warning("Failed to decode MJPEG frame");
return 0;
}
diff --git a/video/codecs/mjpeg.h b/video/codecs/mjpeg.h
index d71454799c..16eefa68a7 100644
--- a/video/codecs/mjpeg.h
+++ b/video/codecs/mjpeg.h
@@ -40,12 +40,12 @@ namespace Video {
* Motion JPEG decoder.
*
* Used in video:
- * - QuickTimeDecoder
+ * - AVIDecoder
*/
-class JPEGDecoder : public Codec {
+class MJPEGDecoder : public Codec {
public:
- JPEGDecoder();
- ~JPEGDecoder();
+ MJPEGDecoder();
+ ~MJPEGDecoder();
const Graphics::Surface *decodeImage(Common::SeekableReadStream *stream);
Graphics::PixelFormat getPixelFormat() const { return _pixelFormat; }
diff --git a/video/codecs/mpeg.h b/video/codecs/mpeg.h
index 0082844537..3560f4b8b7 100644
--- a/video/codecs/mpeg.h
+++ b/video/codecs/mpeg.h
@@ -37,7 +37,7 @@
typedef signed short int16_t;
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
-#elif defined(_MSC_VER)
+#elif defined(_MSC_VER) || defined (__SYMBIAN32__)
typedef signed char int8_t;
typedef signed short int16_t;
typedef unsigned char uint8_t;
diff --git a/video/codecs/truemotion1.h b/video/codecs/truemotion1.h
index b2a35cf873..6ac09af24b 100644
--- a/video/codecs/truemotion1.h
+++ b/video/codecs/truemotion1.h
@@ -22,8 +22,8 @@
// Based on the TrueMotion 1 decoder by Alex Beregszaszi & Mike Melanson in FFmpeg
-// Only compile if SCI32 is enabled or if we're building dynamic modules
-#if defined(ENABLE_SCI32) || defined(DYNAMIC_MODULES)
+// Only compile if SCI32 is enabled, ZVISION is enabled, or if we're building dynamic modules
+#if defined(ENABLE_SCI32) || defined(ENABLE_ZVISION) || defined(DYNAMIC_MODULES)
#ifndef VIDEO_CODECS_TRUEMOTION1_H
#define VIDEO_CODECS_TRUEMOTION1_H
diff --git a/video/module.mk b/video/module.mk
index a491947aaf..d836371182 100644
--- a/video/module.mk
+++ b/video/module.mk
@@ -12,6 +12,7 @@ MODULE_OBJS := \
codecs/cdtoons.o \
codecs/cinepak.o \
codecs/indeo3.o \
+ codecs/jpeg.o \
codecs/mjpeg.o \
codecs/msrle.o \
codecs/msvideo1.o \
diff --git a/video/qt_decoder.cpp b/video/qt_decoder.cpp
index 7539d4a1e2..11a27beb10 100644
--- a/video/qt_decoder.cpp
+++ b/video/qt_decoder.cpp
@@ -40,7 +40,7 @@
// Video codecs
#include "video/codecs/cinepak.h"
-#include "video/codecs/mjpeg.h"
+#include "video/codecs/jpeg.h"
#include "video/codecs/qtrle.h"
#include "video/codecs/rpza.h"
#include "video/codecs/smc.h"
@@ -296,7 +296,7 @@ void QuickTimeDecoder::VideoSampleDesc::initCodec() {
warning("Sorenson Video 3 not yet supported");
break;
case MKTAG('j','p','e','g'):
- // Motion JPEG: Used by some Myst ME 10th Anniversary videos.
+ // JPEG: Used by some Myst ME 10th Anniversary videos.
_videoCodec = new JPEGDecoder();
break;
case MKTAG('Q','k','B','k'):
diff --git a/video/smk_decoder.cpp b/video/smk_decoder.cpp
index 3dbcebcde4..b31ad109ad 100644
--- a/video/smk_decoder.cpp
+++ b/video/smk_decoder.cpp
@@ -369,8 +369,7 @@ bool SmackerDecoder::loadStream(Common::SeekableReadStream *stream) {
if (_header.audioInfo[i].compression == kCompressionRDFT || _header.audioInfo[i].compression == kCompressionDCT)
warning("Unhandled Smacker v2 audio compression");
- if (i == 0)
- addTrack(new SmackerAudioTrack(_header.audioInfo[i], _soundType));
+ addTrack(new SmackerAudioTrack(_header.audioInfo[i], _soundType));
}
}
@@ -477,7 +476,10 @@ void SmackerDecoder::readNextPacket() {
}
void SmackerDecoder::handleAudioTrack(byte track, uint32 chunkSize, uint32 unpackedSize) {
- if (_header.audioInfo[track].hasAudio && chunkSize > 0 && track == 0) {
+ if (chunkSize == 0)
+ return;
+
+ if (_header.audioInfo[track].hasAudio) {
// Get the audio track, which start at offset 1 (first track is video)
SmackerAudioTrack *audioTrack = (SmackerAudioTrack *)getTrack(track + 1);
@@ -501,14 +503,21 @@ void SmackerDecoder::handleAudioTrack(byte track, uint32 chunkSize, uint32 unpac
audioTrack->queuePCM(soundBuffer, chunkSize);
}
} else {
- // Ignore the rest of the audio tracks, if they exist
- // TODO: Are there any Smacker videos with more than one audio stream?
- // If yes, we should play the rest of the audio streams as well
- if (chunkSize > 0)
- _fileStream->skip(chunkSize);
+ // Ignore possibly unused data
+ _fileStream->skip(chunkSize);
}
}
+VideoDecoder::AudioTrack *SmackerDecoder::getAudioTrack(int index) {
+ // Smacker audio track indexes are relative to the first audio track
+ Track *track = getTrack(index + 1);
+
+ if (!track || track->getTrackType() != Track::kTrackTypeAudio)
+ return 0;
+
+ return (AudioTrack *)track;
+}
+
SmackerDecoder::SmackerVideoTrack::SmackerVideoTrack(uint32 width, uint32 height, uint32 frameCount, const Common::Rational &frameRate, uint32 flags, uint32 signature) {
_surface = new Graphics::Surface();
_surface->create(width, height * (flags ? 2 : 1), Graphics::PixelFormat::createFormatCLUT8());
@@ -726,16 +735,15 @@ void SmackerDecoder::SmackerVideoTrack::unpackPalette(Common::SeekableReadStream
} else { // top 2 bits are 00
sz++;
// get the lower 6 bits for each component (0x3f = 00111111)
- byte b = b0 & 0x3f;
+ byte r = b0 & 0x3f;
byte g = (*p++) & 0x3f;
- byte r = (*p++) & 0x3f;
-
- assert(g < 0xc0 && b < 0xc0);
+ byte b = (*p++) & 0x3f;
- // upscale to full 8-bit color values by multiplying by 4
- *pal++ = b * 4;
- *pal++ = g * 4;
- *pal++ = r * 4;
+ // upscale to full 8-bit color values. The Multimedia Wiki suggests
+ // a lookup table for this, but this should produce the same result.
+ *pal++ = (r * 4 + r / 16);
+ *pal++ = (g * 4 + g / 16);
+ *pal++ = (b * 4 + b / 16);
}
}
diff --git a/video/smk_decoder.h b/video/smk_decoder.h
index e4bc9bab42..5298158833 100644
--- a/video/smk_decoder.h
+++ b/video/smk_decoder.h
@@ -69,6 +69,8 @@ public:
protected:
void readNextPacket();
+ bool supportsAudioTrackSwitching() const { return true; }
+ AudioTrack *getAudioTrack(int index);
virtual void handleAudioTrack(byte track, uint32 chunkSize, uint32 unpackedSize);
diff --git a/video/video_decoder.cpp b/video/video_decoder.cpp
index 0ab1478727..931bde20d0 100644
--- a/video/video_decoder.cpp
+++ b/video/video_decoder.cpp
@@ -46,6 +46,7 @@ VideoDecoder::VideoDecoder() {
_endTime = 0;
_endTimeSet = false;
_nextVideoTrack = 0;
+ _mainAudioTrack = 0;
// Find the best format for output
_defaultHighColorFormat = g_system->getScreenFormat();
@@ -75,6 +76,7 @@ void VideoDecoder::close() {
_endTime = 0;
_endTimeSet = false;
_nextVideoTrack = 0;
+ _mainAudioTrack = 0;
}
bool VideoDecoder::loadFile(const Common::String &filename) {
@@ -553,6 +555,9 @@ Audio::Timestamp VideoDecoder::FixedRateVideoTrack::getDuration() const {
return getFrameTime(getFrameCount());
}
+VideoDecoder::AudioTrack::AudioTrack() : _volume(Audio::Mixer::kMaxChannelVolume), _balance(0), _muted(false) {
+}
+
bool VideoDecoder::AudioTrack::endOfTrack() const {
Audio::AudioStream *stream = getAudioStream();
return !stream || !g_system->getMixer()->isSoundHandleActive(_handle) || stream->endOfData();
@@ -562,7 +567,7 @@ void VideoDecoder::AudioTrack::setVolume(byte volume) {
_volume = volume;
if (g_system->getMixer()->isSoundHandleActive(_handle))
- g_system->getMixer()->setChannelVolume(_handle, _volume);
+ g_system->getMixer()->setChannelVolume(_handle, _muted ? 0 : _volume);
}
void VideoDecoder::AudioTrack::setBalance(int8 balance) {
@@ -578,7 +583,7 @@ void VideoDecoder::AudioTrack::start() {
Audio::AudioStream *stream = getAudioStream();
assert(stream);
- g_system->getMixer()->playStream(getSoundType(), &_handle, stream, -1, getVolume(), getBalance(), DisposeAfterUse::NO);
+ g_system->getMixer()->playStream(getSoundType(), &_handle, stream, -1, _muted ? 0 : getVolume(), getBalance(), DisposeAfterUse::NO);
// Pause the audio again if we're still paused
if (isPaused())
@@ -597,7 +602,7 @@ void VideoDecoder::AudioTrack::start(const Audio::Timestamp &limit) {
stream = Audio::makeLimitingAudioStream(stream, limit, DisposeAfterUse::NO);
- g_system->getMixer()->playStream(getSoundType(), &_handle, stream, -1, getVolume(), getBalance(), DisposeAfterUse::YES);
+ g_system->getMixer()->playStream(getSoundType(), &_handle, stream, -1, _muted ? 0 : getVolume(), getBalance(), DisposeAfterUse::YES);
// Pause the audio again if we're still paused
if (isPaused())
@@ -611,6 +616,16 @@ uint32 VideoDecoder::AudioTrack::getRunningTime() const {
return 0;
}
+void VideoDecoder::AudioTrack::setMute(bool mute) {
+ // Update the mute settings, if required
+ if (_muted != mute) {
+ _muted = mute;
+
+ if (g_system->getMixer()->isSoundHandleActive(_handle))
+ g_system->getMixer()->setChannelVolume(_handle, mute ? 0 : _volume);
+ }
+}
+
void VideoDecoder::AudioTrack::pauseIntern(bool shouldPause) {
if (g_system->getMixer()->isSoundHandleActive(_handle))
g_system->getMixer()->pauseHandle(_handle, shouldPause);
@@ -669,6 +684,17 @@ void VideoDecoder::addTrack(Track *track, bool isExternal) {
// Update volume settings if it's an audio track
((AudioTrack *)track)->setVolume(_audioVolume);
((AudioTrack *)track)->setBalance(_audioBalance);
+
+ if (!isExternal && supportsAudioTrackSwitching()) {
+ if (_mainAudioTrack) {
+ // The main audio track has already been found
+ ((AudioTrack *)track)->setMute(true);
+ } else {
+ // First audio track found -> now the main one
+ _mainAudioTrack = (AudioTrack *)track;
+ _mainAudioTrack->setMute(false);
+ }
+ }
} else if (track->getTrackType() == Track::kTrackTypeVideo) {
// If this track has a better time, update _nextVideoTrack
if (!_nextVideoTrack || ((VideoTrack *)track)->getNextFrameStartTime() < _nextVideoTrack->getNextFrameStartTime())
@@ -701,6 +727,34 @@ bool VideoDecoder::addStreamFileTrack(const Common::String &baseName) {
return result;
}
+bool VideoDecoder::setAudioTrack(int index) {
+ if (!supportsAudioTrackSwitching())
+ return false;
+
+ AudioTrack *audioTrack = getAudioTrack(index);
+
+ if (!audioTrack)
+ return false;
+
+ if (_mainAudioTrack == audioTrack)
+ return true;
+
+ _mainAudioTrack->setMute(true);
+ audioTrack->setMute(false);
+ _mainAudioTrack = audioTrack;
+ return true;
+}
+
+uint VideoDecoder::getAudioTrackCount() const {
+ uint count = 0;
+
+ for (TrackList::const_iterator it = _internalTracks.begin(); it != _internalTracks.end(); it++)
+ if ((*it)->getTrackType() == Track::kTrackTypeAudio)
+ count++;
+
+ return count;
+}
+
void VideoDecoder::setEndTime(const Audio::Timestamp &endTime) {
Audio::Timestamp startTime = 0;
diff --git a/video/video_decoder.h b/video/video_decoder.h
index ac6586d8dd..99161d6f97 100644
--- a/video/video_decoder.h
+++ b/video/video_decoder.h
@@ -407,6 +407,21 @@ public:
*/
bool addStreamFileTrack(const Common::String &baseName);
+ /**
+ * Set the internal audio track.
+ *
+ * Has no effect if the container does not support this.
+ * @see supportsAudioTrackSwitching()
+ *
+ * @param index The index of the track, whose meaning is dependent on the container
+ */
+ bool setAudioTrack(int index);
+
+ /**
+ * Get the number of internal audio tracks.
+ */
+ uint getAudioTrackCount() const;
+
protected:
/**
* An abstract representation of a track in a movie. Since tracks here are designed
@@ -612,7 +627,7 @@ protected:
*/
class AudioTrack : public Track {
public:
- AudioTrack() {}
+ AudioTrack();
virtual ~AudioTrack() {}
TrackType getTrackType() const { return kTrackTypeAudio; }
@@ -662,6 +677,11 @@ protected:
*/
virtual Audio::Mixer::SoundType getSoundType() const { return Audio::Mixer::kPlainSoundType; }
+ /**
+ * Mute the track
+ */
+ void setMute(bool mute);
+
protected:
void pauseIntern(bool shouldPause);
@@ -674,6 +694,7 @@ protected:
Audio::SoundHandle _handle;
byte _volume;
int8 _balance;
+ bool _muted;
};
/**
@@ -833,6 +854,25 @@ protected:
*/
virtual bool seekIntern(const Audio::Timestamp &time);
+ /**
+ * Does this video format support switching between audio tracks?
+ *
+ * Returning true implies this format supports multiple audio tracks,
+ * can switch tracks, and defaults to playing the first found audio
+ * track.
+ */
+ virtual bool supportsAudioTrackSwitching() const { return false; }
+
+ /**
+ * Get the audio track for the given index.
+ *
+ * This is used only if supportsAudioTrackSwitching() returns true.
+ *
+ * @param index The index of the track, whose meaning is dependent on the container
+ * @return The audio track for the index, or 0 if not found
+ */
+ virtual AudioTrack *getAudioTrack(int index) { return 0; }
+
private:
// Tracks owned by this VideoDecoder
TrackList _tracks;
@@ -865,6 +905,8 @@ private:
uint32 _pauseStartTime;
byte _audioVolume;
int8 _audioBalance;
+
+ AudioTrack *_mainAudioTrack;
};
} // End of namespace Video